code wiki / (root) / nx_tls13_server_session_derive_traffic.nx

nx_tls13_server_session_derive_traffic.nx source

↩ module page · 113 lines · 4533 B

1// nx_tls13_server_session_derive_traffic.nx -- 5th TLS server stone. 2// 3// After derive_hs_secrets produced the Handshake-Secret, derive the 4// per-direction handshake traffic secrets + their AEAD key + IV 5// per RFC 8446 ยง7.1: 6// 7// c_hs_traffic = Derive-Secret(HS, "c hs traffic", ClientHello..ServerHello) 8// s_hs_traffic = Derive-Secret(HS, "s hs traffic", ClientHello..ServerHello) 9// *_hs_key = HKDF-Expand-Label(*_hs_traffic, "key", "", aead_key_len) 10// *_hs_iv = HKDF-Expand-Label(*_hs_traffic, "iv", "", aead_iv_len) 11// 12// For ChaCha20-Poly1305: key=32 bytes, iv=12 bytes. 13// 14// This stone is the precondition for emit_ee_cert (next stone), 15// which must AEAD-encrypt the EncryptedExtensions + Certificate 16// messages under server_hs_key + server_hs_iv. 17// 18// State: requires EE_SENT (set by derive_hs_secrets); does not 19// advance state -- it's a continuation of the key-schedule 20// preparation. Subsequent emit_ee_cert advances state CERT_SENT. 21// 22// license_tier: ORIGINAL 23 24import "nx_syscalls.nx" 25import "nx_tls13.nx" 26import "nx_tls13_kdf.nx" 27import "nx_tls13_transcript.nx" 28import "nx_tls13_server_session.nx" 29 30const NX_TLS13_TRAFFIC_HASH_LEN: i64 = 32 // SHA-256 for ChaCha20-Poly1305 31const NX_TLS13_AEAD_KEY_LEN: i64 = 32 // ChaCha20 key length 32const NX_TLS13_AEAD_IV_LEN: i64 = 12 // AEAD nonce length 33 34func nx_tls13_server_session_derive_traffic( 35 session: *Tls13ServerSession 36) -> i64 { 37 if (session as i64) == 0 { return NX_TLS13_SSESSION_BAD_STATE } 38 // Precondition: handshake_secret has been derived (i.e., we're 39 // past derive_hs_secrets, which set state = EE_SENT). 40 if session.state != NX_TLS13_SSTATE_EE_SENT { 41 return NX_TLS13_SSESSION_BAD_STATE 42 } 43 if (session.handshake_secret as i64) == 0 { 44 return NX_TLS13_SSESSION_INTERNAL 45 } 46 47 // 1. Snapshot transcript hash over ClientHello..ServerHello. 48 let th: *u8 = sys_mmap(NX_TLS13_TRAFFIC_HASH_LEN) 49 let r_th: i64 = nx_tls13_transcript_snapshot(session.transcript, th) 50 if r_th != NX_TLS13_TX_VERDICT_OK { return NX_TLS13_SSESSION_INTERNAL } 51 52 // 2. Derive-Secret(HS, "c hs traffic", th) -> client_hs_traffic_secret 53 let c_label: *u8 = "c hs traffic" 54 let c_label_len: i64 = 12 55 let c_secret: *u8 = sys_mmap(NX_TLS13_TRAFFIC_HASH_LEN) 56 let r1: i64 = tls13_derive_secret( 57 session.handshake_secret, 58 c_label, c_label_len, 59 th, NX_TLS13_TRAFFIC_HASH_LEN, 60 c_secret) 61 if r1 != NX_TLS13_KDF_VERDICT_OK { return NX_TLS13_SSESSION_INTERNAL } 62 session.client_hs_traffic_secret = c_secret 63 64 // 3. Derive-Secret(HS, "s hs traffic", th) -> server_hs_traffic_secret 65 let s_label: *u8 = "s hs traffic" 66 let s_label_len: i64 = 12 67 let s_secret: *u8 = sys_mmap(NX_TLS13_TRAFFIC_HASH_LEN) 68 let r2: i64 = tls13_derive_secret( 69 session.handshake_secret, 70 s_label, s_label_len, 71 th, NX_TLS13_TRAFFIC_HASH_LEN, 72 s_secret) 73 if r2 != NX_TLS13_KDF_VERDICT_OK { return NX_TLS13_SSESSION_INTERNAL } 74 session.server_hs_traffic_secret = s_secret 75 76 // 4. Derive AEAD keys + IVs via HKDF-Expand-Label. 77 let key_label: *u8 = "key" 78 let iv_label: *u8 = "iv" 79 let empty: *u8 = sys_mmap(1) 80 // AEAD key length depends on the negotiated cipher: AES-128-GCM=16, 81 // ChaCha20-Poly1305=32. IV stays 12 for both. 82 let akl: i64 = nx_tls13_aead_key_len(session.cipher_suite) 83 84 let c_key: *u8 = sys_mmap(akl) 85 let r3: i64 = tls13_hkdf_expand_label( 86 c_secret, key_label, 3, empty, 0, 87 akl, c_key) 88 if r3 != NX_TLS13_KDF_VERDICT_OK { return NX_TLS13_SSESSION_INTERNAL } 89 session.client_hs_traffic_key = c_key 90 91 let c_iv: *u8 = sys_mmap(NX_TLS13_AEAD_IV_LEN) 92 let r4: i64 = tls13_hkdf_expand_label( 93 c_secret, iv_label, 2, empty, 0, 94 NX_TLS13_AEAD_IV_LEN, c_iv) 95 if r4 != NX_TLS13_KDF_VERDICT_OK { return NX_TLS13_SSESSION_INTERNAL } 96 session.client_hs_iv = c_iv 97 98 let s_key: *u8 = sys_mmap(akl) 99 let r5: i64 = tls13_hkdf_expand_label( 100 s_secret, key_label, 3, empty, 0, 101 akl, s_key) 102 if r5 != NX_TLS13_KDF_VERDICT_OK { return NX_TLS13_SSESSION_INTERNAL } 103 session.server_hs_traffic_key = s_key 104 105 let s_iv: *u8 = sys_mmap(NX_TLS13_AEAD_IV_LEN) 106 let r6: i64 = tls13_hkdf_expand_label( 107 s_secret, iv_label, 2, empty, 0, 108 NX_TLS13_AEAD_IV_LEN, s_iv) 109 if r6 != NX_TLS13_KDF_VERDICT_OK { return NX_TLS13_SSESSION_INTERNAL } 110 session.server_hs_iv = s_iv 111 112 return NX_TLS13_SSESSION_OK 113}