code wiki / (root) / nx_tls13_server_session_emit_ee.nx

nx_tls13_server_session_emit_ee.nx source

↩ module page · 109 lines · 3764 B

1// nx_tls13_server_session_emit_ee.nx -- 6th TLS server stone. 2// 3// Emits a minimal EncryptedExtensions handshake message, 4// AEAD-encrypted under server_hs_traffic_key + iv as a TLS 1.3 5// record (type=23 application_data wrapper). 6// 7// Inner content (handshake plaintext): 8// HT_ENCRYPTED_EXTENSIONS = 0x08 (1 byte) 9// body_len = 0x000002 (3 bytes, u24 big-endian) 10// extensions_list_len = 0x0000 (2 bytes; no EE extensions in v1) 11// Total = 6 bytes 12// 13// Record format (on wire): 14// header(5 bytes) type=0x17 (app_data) + version=0x0303 + length(2) 15// ciphertext (encrypted plaintext + inner type byte) 16// auth_tag(16 bytes) 17// 18// Precondition: state == EE_SENT (set by derive_hs_secrets; 19// indicates handshake keys are derived and EE is the next message). 20// Postcondition: state == CERT_SENT. 21// 22// license_tier: ORIGINAL 23 24import "nx_syscalls.nx" 25import "nx_tls13.nx" 26import "nx_tls13_record.nx" 27import "nx_tls13_transcript.nx" 28import "nx_tls13_server_session.nx" 29 30const NX_TLS13_EE_INNER_LEN: i64 = 6 // HT + u24 + ext_list_len 31const NX_TLS13_REC_HEADER: i64 = 5 32const NX_TLS13_REC_TAG: i64 = 16 33 34func nx_tls13_server_session_emit_ee( 35 session: *Tls13ServerSession, 36 out: *u8, out_cap: i64 37) -> i64 { 38 if (session as i64) == 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 39 if (out as i64) == 0 { return 0 - NX_TLS13_SSESSION_BAD_STATE } 40 if session.state != NX_TLS13_SSTATE_EE_SENT { 41 return 0 - NX_TLS13_SSESSION_BAD_STATE 42 } 43 if (session.server_hs_traffic_key as i64) == 0 { 44 return 0 - NX_TLS13_SSESSION_INTERNAL 45 } 46 if (session.server_hs_iv as i64) == 0 { 47 return 0 - NX_TLS13_SSESSION_INTERNAL 48 } 49 50 // Build the 6-byte EncryptedExtensions plaintext. 51 let inner: *u8 = sys_mmap(NX_TLS13_EE_INNER_LEN) 52 inner[0] = HT_ENCRYPTED_EXTENSIONS & 0xff 53 inner[1] = 0 // body_len[0] 54 inner[2] = 0 // body_len[1] 55 inner[3] = 2 // body_len[2] = 2 56 inner[4] = 0 // ext_list_len[0] 57 inner[5] = 0 // ext_list_len[1] = 0 58 59 // record layout: header(5) + ct(6+1+pad) + tag(16) = ~28 bytes 60 let total_needed: i64 = NX_TLS13_REC_HEADER + NX_TLS13_EE_INNER_LEN + 1 + NX_TLS13_REC_TAG 61 if out_cap < total_needed { return 0 - NX_TLS13_SSESSION_BUF_OVERFLOW } 62 63 let header_buf: *u8 = sys_mmap(NX_TLS13_REC_HEADER) 64 let ct_len: i64 = NX_TLS13_EE_INNER_LEN + 1 // plaintext + inner type 65 let ct_buf: *u8 = sys_mmap(ct_len + 16) 66 let tag_buf: *u8 = sys_mmap(NX_TLS13_REC_TAG) 67 68 let rv: i64 = nx_tls13_record_encrypt_v2( 69 session.cipher_suite, 70 session.server_hs_traffic_key, 71 session.server_hs_iv, 72 session.server_seq, 73 inner, NX_TLS13_EE_INNER_LEN, 74 CT_HANDSHAKE, 75 0, // no padding 76 header_buf, ct_buf, tag_buf) 77 if rv != NX_TLS13_REC_VERDICT_OK { 78 return 0 - NX_TLS13_SSESSION_INTERNAL 79 } 80 81 // Write header + ct + tag to output buffer. 82 var w: i64 = 0 83 var i: i64 = 0 84 while i < NX_TLS13_REC_HEADER { 85 out[w + i] = header_buf[i] 86 i = i + 1 87 } 88 w = w + NX_TLS13_REC_HEADER 89 var j: i64 = 0 90 while j < ct_len { 91 out[w + j] = ct_buf[j] 92 j = j + 1 93 } 94 w = w + ct_len 95 var k: i64 = 0 96 while k < NX_TLS13_REC_TAG { 97 out[w + k] = tag_buf[k] 98 k = k + 1 99 } 100 w = w + NX_TLS13_REC_TAG 101 102 // Feed the PLAINTEXT EE handshake bytes into transcript hash. 103 // (Transcript captures handshake messages, not their AEAD records.) 104 nx_tls13_transcript_update(session.transcript, inner, NX_TLS13_EE_INNER_LEN) 105 106 session.server_seq = session.server_seq + 1 107 session.state = NX_TLS13_SSTATE_CERT_SENT 108 return w 109}