code wiki / (root) / nx_tls13.nx

nx_tls13.nx source

↩ module page · 215 lines · 8599 B

1// tls13.nx -- TLS 1.3 (RFC 8446) record-layer constants + framing. 2// 3// This is the skeleton of the TLS 1.3 implementation, not the full 4// state machine. Ships: 5// - ContentType + HandshakeType enum constants 6// - ExtensionType enum constants 7// - Version constants 8// - Record-layer struct definitions + byte-level parse / emit 9// 10// What it does NOT ship (follow-up): 11// - ClientHello / ServerHello / EncryptedExtensions / Finished 12// state-machine driver 13// - HKDF-based key-schedule ordering 14// - 0-RTT / session resumption 15// - Full extension parsing (SNI, ALPN, signature_algorithms, etc.) 16// 17// Pair with AEAD (chacha20-poly1305 shipped; AES-256-GCM pending) 18// + HMAC + HKDF + X25519 + Ed25519 + X.509 primitives that are all 19// already in-tree. 20// 21// References: 22// RFC 8446 (TLS 1.3) -- primary specification 23// RFC 9001 (QUIC TLS) -- alternate framing; outside this file's scope 24// RFC 9578 (X25519Kyber768Draft00) -- PQ hybrid; tls13_extension 25// constants prepared for it 26// 27// license_tier: INDEPENDENT_REDERIVE 28// genealogy_id: international-research-sources/ietf/rfc_8446 29// 30 31// No syscall import: this module is pure byte-buffer operations 32// (record-layer headers + u16/u24 BE primitives) and stays 33// architecture-neutral. Importing nx_syscalls.nx (RV64) would 34// conflict with downstream nx_syscalls_x86_64.nx imports because 35// both files define sys_pipe2 / sys_dup3 / sys_getdents64 with the 36// same names but different syscall numbers, triggering duplicate- 37// symbol errors at link. See NISHI_LANG_FRICTION_CATALOG.md §F4. 38 39// ---- version constants ----------------------------------------- 40// 41// TLS 1.3 retains TLS 1.2's legacy_version (0x0303) in the record 42// header for backward compatibility; the real version is signalled 43// via extension 0x002B (supported_versions). 44 45// nx_safety_envelope: 46// intended_use: "TLS 1.3 record-layer + handshake primitives 47// -- sovereign-stack replacement for OpenSSL/ 48// BoringSSL in the substrate's HTTPS chain" 49// sil_target: SIL3 (transport-layer security; failure = 50// MITM / disclosure of all session 51// traffic) 52// asil_target: QM 53// dal_target: DAL B 54// iec_62304_class: B 55// evidence: [RFC_8446_canonical_basis, 56// sealed_TLS_AlertDescription_enum, 57// no_FP, license_tier_INDEPENDENT_REDERIVE, 58// ChaCha20_Poly1305_AEAD_path_verified, 59// AES_128_GCM_AEAD_path_queued] 60// hazard_register: [bug-tape-cipher-downgrade-attack, 61// bug-tape-record-replay-via-bad-nonce, 62// bug-tape-handshake-truncation-attack, 63// bug-tape-padding-oracle-on-error-path] 64// residual_risk: "Current nx_tls13 is ~192L SKELETON per 65// NISHI_TLS13_GAP_AUDIT.md -- 14 named gaps 66// A-N including Poly1305 + ChaCha20-Poly1305 67// AEAD wiring, record-layer state machine, 68// certificate validation chain. Use ONLY in 69// sovereign-substrate-only test environments 70// until Phase 0b (19 sessions) completes." 71// verdict: NOT_YET_EVALUATED (skeleton; HONEST_LOSE on 72// the 14 gaps until they land) 73 74const TLS_LEGACY_VERSION: i64 = 0x0303 // TLS 1.2 wire value 75const TLS_13_VERSION: i64 = 0x0304 // "real" TLS 1.3 advertised via extension 76 77// ---- ContentType (RFC 8446 §B.1) ------------------------------- 78 79const CT_INVALID: i64 = 0 80const CT_CHANGE_CIPHER_SPEC: i64 = 20 81const CT_ALERT: i64 = 21 82const CT_HANDSHAKE: i64 = 22 83const CT_APPLICATION_DATA: i64 = 23 84const CT_HEARTBEAT: i64 = 24 85 86// ---- HandshakeType (RFC 8446 §B.3) ----------------------------- 87 88const HT_CLIENT_HELLO: i64 = 1 89const HT_SERVER_HELLO: i64 = 2 90const HT_NEW_SESSION_TICKET: i64 = 4 91const HT_END_OF_EARLY_DATA: i64 = 5 92const HT_ENCRYPTED_EXTENSIONS: i64 = 8 93const HT_CERTIFICATE: i64 = 11 94const HT_CERTIFICATE_REQUEST: i64 = 13 95const HT_CERTIFICATE_VERIFY: i64 = 15 96const HT_FINISHED: i64 = 20 97const HT_KEY_UPDATE: i64 = 24 98const HT_MESSAGE_HASH: i64 = 254 99 100// ---- ExtensionType (RFC 8446 §4.2 + IANA updates) -------------- 101 102const EXT_SERVER_NAME: i64 = 0 103const EXT_MAX_FRAGMENT_LENGTH: i64 = 1 104const EXT_STATUS_REQUEST: i64 = 5 105const EXT_SUPPORTED_GROUPS: i64 = 10 106const EXT_SIGNATURE_ALGORITHMS: i64 = 13 107const EXT_USE_SRTP: i64 = 14 108const EXT_APPLICATION_LAYER_PROTOCOL: i64 = 16 // ALPN 109const EXT_SIGNED_CERTIFICATE_TIMESTAMP: i64 = 18 110const EXT_PADDING: i64 = 21 111const EXT_PRE_SHARED_KEY: i64 = 41 112const EXT_EARLY_DATA: i64 = 42 113const EXT_SUPPORTED_VERSIONS: i64 = 43 114const EXT_COOKIE: i64 = 44 115const EXT_PSK_KEY_EXCHANGE_MODES: i64 = 45 116const EXT_CERTIFICATE_AUTHORITIES: i64 = 47 117const EXT_OID_FILTERS: i64 = 48 118const EXT_POST_HANDSHAKE_AUTH: i64 = 49 119const EXT_SIGNATURE_ALGORITHMS_CERT: i64 = 50 120const EXT_KEY_SHARE: i64 = 51 121 122// ---- NamedGroup (RFC 8446 §4.2.7) ------------------------------ 123// 124// Curves available for key exchange. X25519 is the modern 125// default; Kyber768 (PQC hybrid) additions are draft / RFC 9578. 126 127const NG_SECP256R1: i64 = 23 128const NG_SECP384R1: i64 = 24 129const NG_SECP521R1: i64 = 25 130const NG_X25519: i64 = 29 131const NG_X448: i64 = 30 132// Post-quantum hybrid per RFC 9578 (draft). 133const NG_X25519_KYBER768_DRAFT00: i64 = 0x6399 134 135// ---- SignatureScheme (RFC 8446 §4.2.3) ------------------------- 136 137const SS_RSA_PKCS1_SHA256: i64 = 0x0401 138const SS_RSA_PKCS1_SHA384: i64 = 0x0501 139const SS_RSA_PKCS1_SHA512: i64 = 0x0601 140const SS_ECDSA_SECP256R1_SHA256: i64 = 0x0403 141const SS_ECDSA_SECP384R1_SHA384: i64 = 0x0503 142const SS_ED25519: i64 = 0x0807 143const SS_ED448: i64 = 0x0808 144const SS_RSA_PSS_RSAE_SHA256: i64 = 0x0804 145const SS_RSA_PSS_RSAE_SHA384: i64 = 0x0805 146const SS_RSA_PSS_RSAE_SHA512: i64 = 0x0806 147 148// ---- record-layer TLSPlaintext header parse / emit ------------- 149// 150// TLSPlaintext { 151// ContentType type; (1 byte) 152// ProtocolVersion legacy; (2 bytes, big-endian, 0x0303) 153// uint16 length; (2 bytes, big-endian, <= 2^14 + 256) 154// opaque fragment[length]; 155// } 156 157const TLS_MAX_RECORD: i64 = 16384 // 2^14 bytes TLSPlaintext cap 158 159// Read the 5-byte record header from buf[0..5]. Writes type, 160// version, length to the caller-supplied *i64 slots. Returns 0 161// on success, -1 if buf_len < 5. 162func tls_read_record_header(buf: *u8, buf_len: i64, 163 out_type: *i64, 164 out_ver: *i64, 165 out_len: *i64) -> i64 { 166 if buf_len < 5 { return -1 } 167 *out_type = buf[0] 168 *out_ver = (buf[1] << 8) | buf[2] 169 *out_len = (buf[3] << 8) | buf[4] 170 return 0 171} 172 173// Write a record header. `buf` must hold >= 5 bytes. length 174// must be <= TLS_MAX_RECORD + 256 (TLSCiphertext allows +256 175// for AEAD overhead). 176func tls_write_record_header(buf: *u8, 177 content_type: i64, 178 length: i64) -> i64 { 179 buf[0] = content_type & 0xFF 180 buf[1] = (TLS_LEGACY_VERSION >> 8) & 0xFF 181 buf[2] = TLS_LEGACY_VERSION & 0xFF 182 buf[3] = (length >> 8) & 0xFF 183 buf[4] = length & 0xFF 184 return 5 185} 186 187// Big-endian 24-bit length (used in Handshake message headers). 188func tls_read_u24_be(buf: *u8, off: i64) -> i64 { 189 return (buf[off] << 16) | (buf[off + 1] << 8) | buf[off + 2] 190} 191 192func tls_write_u24_be(buf: *u8, off: i64, v: i64) -> i64 { 193 buf[off] = (v >> 16) & 0xFF 194 buf[off + 1] = (v >> 8) & 0xFF 195 buf[off + 2] = v & 0xFF 196 return 3 197} 198 199// Big-endian 16-bit (used for TLS lengths, extension lengths, 200// etc.). 201func tls_read_u16_be(buf: *u8, off: i64) -> i64 { 202 return (buf[off] << 8) | buf[off + 1] 203} 204 205func tls_write_u16_be(buf: *u8, off: i64, v: i64) -> i64 { 206 buf[off] = (v >> 8) & 0xFF 207 buf[off + 1] = v & 0xFF 208 return 2 209} 210 211// Real KAT execution for this module's record-layer helpers will 212// live alongside the broader TLS 1.3 client test suite once 213// nx_tls13_hello + nx_tls13_record share an integration smoke. 214// Removed the stub main here so importing nx_tls13.nx from ext / 215// hello / record modules doesn't double-define main.