code wiki / (root) / nx_quic_handshake_sm.nx

nx_quic_handshake_sm.nx source

↩ module page · 54 lines · 2484 B

1// nx_quic_handshake_sm.nx -- RUNG 6d of the sovereign QUIC transport: the TLS 1.3 handshake STATE MACHINE 2// (RFC 8446 App. A, client perspective) + the Finished-message MAC (RFC 8446 sec 4.4.4). This drives the 3// CRYPTO-frame message stream (R6b) through SH -> EE -> Cert -> CertVerify -> Finished, deriving keys via 4// R6c at each step; the Finished MAC binds the whole transcript so a tampered handshake is rejected. The 5// ECDHE/cert/signature primitives reuse the live sovereign TLS stack. No float. license_tier: ORIGINAL 6import "nx_quic_keys.nx" 7import "nx_hmac.nx" 8 9// states (RFC 8446 App. A.1, client) 10const HS_START: i64 = 0 11const HS_WAIT_SH: i64 = 1 12const HS_WAIT_EE: i64 = 2 13const HS_WAIT_CERT: i64 = 3 14const HS_WAIT_CV: i64 = 4 15const HS_WAIT_FIN: i64 = 5 16const HS_CONNECTED: i64 = 6 17const HS_ERROR: i64 = 7 18 19// client transition: (state, received handshake msg type) -> next state (HS_ERROR on any out-of-order msg). 20// msg types per RFC 8446 sec 4: server_hello=2, encrypted_extensions=8, certificate=11, 21// certificate_verify=15, finished=20. 22func quic_hs_sm_step(state: i64, msg_type: i64) -> i64 { 23 if state == HS_WAIT_SH { if msg_type == 2 { return HS_WAIT_EE } return HS_ERROR } 24 if state == HS_WAIT_EE { if msg_type == 8 { return HS_WAIT_CERT } return HS_ERROR } 25 if state == HS_WAIT_CERT { if msg_type == 11 { return HS_WAIT_CV } return HS_ERROR } 26 if state == HS_WAIT_CV { if msg_type == 15 { return HS_WAIT_FIN } return HS_ERROR } 27 if state == HS_WAIT_FIN { if msg_type == 20 { return HS_CONNECTED } return HS_ERROR } 28 return HS_ERROR 29} 30 31// finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) (RFC 8446 sec 4.4.4) 32func quic_hs_finished_key(base_key: *u8, out: *u8) -> i64 { 33 hkdf_expand_label(base_key, "finished" as *u8, 8, 0 as *u8, 0, 32, out) 34 return 0 35} 36 37// Finished.verify_data = HMAC(finished_key, Transcript-Hash(...)) -- binds the whole handshake transcript. 38func quic_hs_finished_verify(base_key: *u8, transcript_hash: *u8, out: *u8) -> i64 { 39 let fk: *u8 = sys_mmap(32) 40 quic_hs_finished_key(base_key, fk) 41 hmac_sha256(fk, 32, transcript_hash, 32, out) 42 return 0 43} 44 45// constant-time-ish equality for verify_data checking (compare all 32 bytes; returns 1 if equal). 46func quic_hs_verify_eq(a: *u8, b: *u8) -> i64 { 47 var diff: i64 = 0 48 var i: i64 = 0 49 while i < 32 { if a[i] != b[i] { diff = 1 } i = i + 1 } 50 if diff == 0 { return 1 } 51 return 0 52} 53 54func main() -> i64 { return 0 }