Kush Secure Protocol — v1.0
RFC-0001 · Author: Kush · Not an Internet standard
Status: Draft
Author: Kush
Created: 2026-07-08
Version: 1.0
1. Abstract
The Kush Secure Protocol (KSP) is a custom, binary-encoded, application-layer protocol designed for secure, low-latency, multiplexed communication over TCP. KSP provides authenticated encryption, forward secrecy, stream multiplexing, replay protection, and session resumption.
KSP is NOT a replacement for TLS/HTTPS. It is a purpose-built protocol optimized for scenarios requiring tight control over framing, encryption, and multiplexing — with clearly documented design decisions and measured performance characteristics.
1.1 Design Goals
1.2 Non-Goals
2. Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119).
3. Architecture Overview
3.1 Protocol Stack
┌─────────────────────────────────┐
│ Application Layer │ ← User data, RPC calls, file transfers
├─────────────────────────────────┤
│ KSP Stream Layer │ ← Multiplexing, flow control, priority
├─────────────────────────────────┤
│ KSP Session Layer │ ← Session mgmt, replay protection, keepalive
├─────────────────────────────────┤
│ KSP Encryption Layer │ ← AEAD encrypt/decrypt, key management
├─────────────────────────────────┤
│ KSP Handshake Layer │ ← Key exchange, auth, negotiation
├─────────────────────────────────┤
│ KSP Framing Layer │ ← Binary packet serialization/deserialization
├─────────────────────────────────┤
│ TCP │ ← Reliable, ordered byte stream
├─────────────────────────────────┤
│ IP │ ← Network routing
└─────────────────────────────────┘
4. Packet Format
4.1 Wire Format
All multi-byte integers are encoded in big-endian (network byte order). All KSP frames share a common header format.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Total header size: 48 bytes
4.2 Header Fields
4.3 Packet Types
4.4 Flags
5. Version Negotiation
5.1 Overview
KSP supports version negotiation to allow protocol evolution without breaking existing deployments.
5.2 Client Proposal
The ClientHello payload includes a list of supported protocol versions, ordered by client preference (most preferred first):
ClientHello.supported_versions = [
ProtocolVersion { major: 2, minor: 0 },
ProtocolVersion { major: 1, minor: 1 },
ProtocolVersion { major: 1, minor: 0 },
]
5.3 Server Selection
The server MUST select the highest version that appears in both the client's list and the server's supported versions. If no common version exists, the server MUST respond with an Error frame containing code VERSION_MISMATCH and close the connection.
5.4 Version Encoding
The Version field in the packet header encodes the negotiated version: (major << 4) | minor. Thus 0x10 = v1.0, 0x11 = v1.1, 0x20 = v2.0.
5.5 Version Compatibility Rules
6. Capability Negotiation
6.1 Overview
Capabilities allow endpoints to advertise and negotiate optional features without changing the protocol version.
6.2 Capability Encoding
Capabilities are encoded as a 32-bit bitfield:
6.3 Negotiation Algorithm
negotiated = client_caps & server_caps.6.4 Required Capabilities
All implementations MUST support at least one of AES_256_GCM or CHACHA20_POLY1305. All other capabilities are OPTIONAL.
7. Handshake Protocol
7.2 Message Sequence
Client Server
│ │
│──── [1] ClientHello ───────────────────────────→│
│ supported_versions, capabilities │
│ client_random, ephemeral_public_key │
│ │
│←─── [2] ServerHello ────────────────────────────│
│ selected_version, selected_capabilities │
│ server_random, ephemeral_public_key │
│ │
│←─── [3] Certificate ───────────────────────────│
│ server_certificate, binding_signature │
│ │
│ ═══════ ALL FURTHER MESSAGES ENCRYPTED ═══════ │
│ │
│──── [4] AuthRequest (encrypted) ───────────────→│
│←─── [5] AuthResponse (encrypted) ──────────────│
│──── [6] HandshakeFinish (encrypted) ───────────→│
│←─── [7] HandshakeFinish (encrypted) ───────────│
│ │
│ ══════ SESSION ESTABLISHED ═══════════════════ │
8. Encryption
8.1 Cipher Suites
8.3 Key Derivation (HKDF-SHA256)
salt = client_random || server_random (64 bytes)
PRK = HKDF-Extract(salt, shared_secret)
client_write_key = HKDF-Expand(PRK, "ksp1 client write key", 32)
server_write_key = HKDF-Expand(PRK, "ksp1 server write key", 32)
client_write_iv = HKDF-Expand(PRK, "ksp1 client write iv", 12)
server_write_iv = HKDF-Expand(PRK, "ksp1 server write iv", 12)
8.4 Nonce Construction
nonce = write_iv XOR (sequence_number padded to 12 bytes, left-padded with zeros)
Mirrors TLS 1.3 nonce construction (RFC 8446 §5.3).
9. Certificate System
9.1 Certificate Format
KSP certificates are binary-encoded:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
9.2 Signature
The signature covers all certificate fields except the signature itself, serialized in the order above. Signed using Ed25519.
9.3 Validation
Receivers MUST perform the following checks:
not_before and not_after.9.4 Certificate Pinning
Clients MAY implement certificate pinning by storing the expected server public key and rejecting connections whose certificate does not match.
9.5 Key Exchange Binding
To prevent Man-in-the-Middle (MITM) attacks where a malicious third-party intercepts the ephemeral key exchange and forwards the server's certificate, KSP requires binding the server's identity cryptographically to the handshake key exchange.
client_random || server_random || client_ephemeral_public_key || server_ephemeral_public_key (total 128 bytes of data)
Certificate handshake packet payload.10. Authentication
10.1 Supported Methods
10.2 Auth Flow
Authentication occurs after the encrypted channel is established (post-key-exchange). This ensures credentials are never sent in plaintext.
10.3 Credential Protection
10.4 Mutual Authentication
When MUTUAL_AUTH is negotiated:
11. Streaming & Multiplexing
11.1 Overview
KSP supports multiple concurrent bidirectional streams over a single session, inspired by HTTP/2's stream model.
11.2 Stream Identifiers
11.3 Stream Lifecycle
┌──────┐
send/recv │ │ recv/send
StreamOpen │ IDLE │ StreamOpen
│ │
└──┬───┘
│
┌──▼───┐
send/recv │ │
StreamData │ OPEN │
│ │
└──┬───┘
┌────┴────┐
send │ │ recv
END_STREAM│ │END_STREAM
┌────▼───┐ ┌───▼────┐
│HALF │ │HALF │
│CLOSED │ │CLOSED │
│(local) │ │(remote)│
└────┬───┘ └───┬────┘
│ recv │ send
│END_STREAM END_STREAM
│ │
└────┬────┘
┌──▼───┐
│CLOSED│
└──────┘
Any state ── StreamReset ──→ CLOSED
11.4 Stream Data
FRAGMENTED flag.FRAGMENTED flag cleared (or END_STREAM set).12. Flow Control
12.1 Overview
KSP implements window-based flow control at both the connection level and per-stream level. This prevents a fast sender from overwhelming a slow receiver.
12.2 Windows
12.3 WindowUpdate Frame
Payload of a WindowUpdate frame:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12.4 Backpressure
When a sender's window reaches zero, it MUST NOT send further data frames until a WindowUpdate is received. Control frames (KeepAlive, WindowUpdate, GoAway) are exempt from flow control.
13. Session Management
13.1 Session State
A session maintains:
13.2 Session Timeout
13.3 Keepalive
13.4 Session Resumption
13.5 Graceful Shutdown
14. Replay Protection
14.2 Algorithm
Maintain: highest_seq and a 1024-bit bitmap representing [highest_seq - 1023, highest_seq].
On receiving frame with sequence number seq:
seq > highest_seq: Accept. Advance window, set bit.seq ≤ highest_seq - 1024: Reject. Too old.seq is in window: Check bit. If set: reject (replay). If clear: accept, set bit.15. Error Handling
15.1 Error Codes
15.2 Error Frame Payload
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15.3 Error Behavior
16. Security Considerations
16.1 Threat Model
KSP is designed to protect against:
16.2 Known Limitations
Ed25519 key binding) is designed for lightweight service pinning and out-of-band key distribution. It does not implement full X.509 certificate chains, Certificate Revocation Lists (CRLs), or Online Certificate Status Protocol (OCSP). Revocation requiring centralized authorities is out of scope for v1.0.9876/tcp) to guarantee reliable ordered delivery, packet loss on the underlying TCP channel causes head-of-line (HoL) blocking across all multiplexed KSP streams on that connection (unlike UDP-based protocols such as QUIC where stream delivery is independent).X25519) and binding signatures (Ed25519) rely on classical elliptic curve cryptography. While forward secrecy (ECDHE) prevents retrospective decryption by classical attackers, v1.0 is vulnerable to future quantum computer decryption ("Harvest Now, Decrypt Later"). Post-quantum hybrid key exchange (Kyber/ML-KEM + X25519) is planned for RFC-0003.ClientHello packets requires server-side X25519 key share derivation and Ed25519 binding signature computation before invalid or flooded connections can be dropped. Stateless retry tokens (such as QUIC Retry or TLS Cookie) are not enforced by default in v1.0.17. Future Versions
17.1 Planned Extensions
17.2 Versioning Policy
Appendix A: Wire Examples
A.1 ClientHello Packet (Hex)
10 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68
[16-byte session_id (zeros for initial handshake)]
[32-byte client_random]
[32-byte ephemeral_public_key (X25519)]
[4-byte supported_versions count + versions list]
[4-byte capabilities bitfield]
[16-byte AEAD authentication tag]
Appendix B: Constants
*End of RFC-0001*
Status: Draft
Author: Kush
Created: 2026-07-08
Version: 1.0
┌─────────────────────────────────┐
│ Application Layer │ ← User data, RPC calls, file transfers
├─────────────────────────────────┤
│ KSP Stream Layer │ ← Multiplexing, flow control, priority
├─────────────────────────────────┤
│ KSP Session Layer │ ← Session mgmt, replay protection, keepalive
├─────────────────────────────────┤
│ KSP Encryption Layer │ ← AEAD encrypt/decrypt, key management
├─────────────────────────────────┤
│ KSP Handshake Layer │ ← Key exchange, auth, negotiation
├─────────────────────────────────┤
│ KSP Framing Layer │ ← Binary packet serialization/deserialization
├─────────────────────────────────┤
│ TCP │ ← Reliable, ordered byte stream
├─────────────────────────────────┤
│ IP │ ← Network routing
└─────────────────────────────────┘
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version | Type | Flags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Session ID (16 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Stream ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number (8 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Nonce (12 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Encrypted Payload (variable) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Authentication Tag (16 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ClientHello.supported_versions = [
ProtocolVersion { major: 2, minor: 0 },
ProtocolVersion { major: 1, minor: 1 },
ProtocolVersion { major: 1, minor: 0 },
]
Client Server
│ │
│──── [1] ClientHello ───────────────────────────→│
│ supported_versions, capabilities │
│ client_random, ephemeral_public_key │
│ │
│←─── [2] ServerHello ────────────────────────────│
│ selected_version, selected_capabilities │
│ server_random, ephemeral_public_key │
│ │
│←─── [3] Certificate ───────────────────────────│
│ server_certificate, binding_signature │
│ │
│ ═══════ ALL FURTHER MESSAGES ENCRYPTED ═══════ │
│ │
│──── [4] AuthRequest (encrypted) ───────────────→│
│←─── [5] AuthResponse (encrypted) ──────────────│
│──── [6] HandshakeFinish (encrypted) ───────────→│
│←─── [7] HandshakeFinish (encrypted) ───────────│
│ │
│ ══════ SESSION ESTABLISHED ═══════════════════ │
salt = client_random || server_random (64 bytes)
PRK = HKDF-Extract(salt, shared_secret)
client_write_key = HKDF-Expand(PRK, "ksp1 client write key", 32)
server_write_key = HKDF-Expand(PRK, "ksp1 server write key", 32)
client_write_iv = HKDF-Expand(PRK, "ksp1 client write iv", 12)
server_write_iv = HKDF-Expand(PRK, "ksp1 server write iv", 12)
nonce = write_iv XOR (sequence_number padded to 12 bytes, left-padded with zeros)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cert Version (1 byte) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Subject Length (2 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Subject (variable, UTF-8) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Public Key (32 bytes, Ed25519) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Issuer Length (2 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Issuer (variable, UTF-8) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Not Before (8 bytes, Unix timestamp seconds) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Not After (8 bytes, Unix timestamp seconds) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Serial Number (16 bytes, UUID) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Signature (64 bytes, Ed25519) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
┌──────┐
send/recv │ │ recv/send
StreamOpen │ IDLE │ StreamOpen
│ │
└──┬───┘
│
┌──▼───┐
send/recv │ │
StreamData │ OPEN │
│ │
└──┬───┘
┌────┴────┐
send │ │ recv
END_STREAM│ │END_STREAM
┌────▼───┐ ┌───▼────┐
│HALF │ │HALF │
│CLOSED │ │CLOSED │
│(local) │ │(remote)│
└────┬───┘ └───┬────┘
│ recv │ send
│END_STREAM END_STREAM
│ │
└────┬────┘
┌──▼───┐
│CLOSED│
└──────┘
Any state ── StreamReset ──→ CLOSED
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Window Size Increment (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Error Code (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Additional Data Length (2 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Additional Data (variable, UTF-8, optional) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68
[16-byte session_id (zeros for initial handshake)]
[32-byte client_random]
[32-byte ephemeral_public_key (X25519)]
[4-byte supported_versions count + versions list]
[4-byte capabilities bitfield]
[16-byte AEAD authentication tag]