code wiki / (root) / nx_tls13_client_session_emit_finished_test.nx

nx_tls13_client_session_emit_finished_test.nx source

↩ module page · 88 lines · 4155 B

1// nx_tls13_client_session_emit_finished_test.nx -- KAT for 2// step 3c.4: emit + encrypt client Finished. 3// 4// Full happy-path of the underlying tls13_client_emit_finished + 5// nx_tls13_record_encrypt round-trip is proven by the shipped 6// nx_tls13_loopback_test. This KAT verifies the WRAPPER's 7// contract surface: 8// - state guards (must be at WAIT_CLIENT_FIN) 9// - buf-overflow guard (need at least 58 bytes) 10// - client_seq increments on every call 11// - state advances to WAIT_APP_KEYS on success, preserved on 12// state-guard failure 13// - sealed verdict gate 14// 15// expect_exit: 0 16// license_tier: ORIGINAL 17 18import "nx_syscalls.nx" 19import "nx_tls13.nx" 20import "nx_tls13_client_session.nx" 21import "nx_tls13_client_session_emit_finished.nx" 22 23func main() -> i64 { 24 let client_random: *u8 = sys_mmap(32) 25 var i: i64 = 0 26 while i < 32 { client_random[i] = (0xC0 + i) as u8; i = i + 1 } 27 let priv: *u8 = sys_mmap(32) 28 i = 0 29 while i < 32 { priv[i] = (0x40 + i) as u8; i = i + 1 } 30 31 // ---- Test A: emit_finished from INIT state -> BAD_STATE ---- 32 let s1: *Tls13ClientSession = nx_tls13_client_session_new(client_random, priv) 33 let buf: *u8 = sys_mmap(128) 34 let v_a: i64 = nx_tls13_client_session_emit_finished(s1, buf, 128) 35 if v_a != (0 - NX_TLS13_EMIT_CF_BAD_STATE) { return 1 } 36 // State unchanged on failure 37 if s1.state != NX_TLS13_CSESSION_STATE_INIT { return 2 } 38 // client_seq unchanged on state-guard failure (we never reached encrypt) 39 if s1.client_seq != 0 { return 3 } 40 41 // ---- Test B: emit_finished from WAIT_APP_KEYS -> BAD_STATE ---- 42 s1.state = NX_TLS13_CSESSION_STATE_WAIT_APP_KEYS 43 if nx_tls13_client_session_emit_finished(s1, buf, 128) != (0 - NX_TLS13_EMIT_CF_BAD_STATE) { return 5 } 44 if s1.state != NX_TLS13_CSESSION_STATE_WAIT_APP_KEYS { return 6 } 45 46 // ---- Test C: emit_finished with tiny buf -> BUF_OVERFLOW ---- 47 s1.state = NX_TLS13_CSESSION_STATE_WAIT_CLIENT_FIN 48 let tiny_buf: *u8 = sys_mmap(32) 49 if nx_tls13_client_session_emit_finished(s1, tiny_buf, 32) != (0 - NX_TLS13_EMIT_CF_BUF_OVERFLOW) { return 10 } 50 // State preserved on cap failure 51 if s1.state != NX_TLS13_CSESSION_STATE_WAIT_CLIENT_FIN { return 11 } 52 if s1.client_seq != 0 { return 12 } 53 54 // ---- Test D: emit_finished happy path returns 58 bytes ---- 55 // We need a valid client_hs_traffic_secret + key + iv for the 56 // encrypt to produce output. The session_new() call mmap'd 57 // these (zeros). HMAC over zero secret + ChaCha20 over zero 58 // key + zero IV both produce DETERMINISTIC output (HMAC is 59 // well-defined for any key length including all-zero; 60 // ChaCha20-Poly1305 likewise). So even with all-zero crypto 61 // state the round-trip is byte-deterministic. 62 let buf2: *u8 = sys_mmap(128) 63 let v_d: i64 = nx_tls13_client_session_emit_finished(s1, buf2, 128) 64 if v_d != NX_TLS13_CF_RECORD_BYTES { return 20 } // 58 65 // State advances to WAIT_APP_KEYS 66 if s1.state != NX_TLS13_CSESSION_STATE_WAIT_APP_KEYS { return 21 } 67 // client_seq increments by 1 68 if s1.client_seq != 1 { return 22 } 69 // Record header: TLSCiphertext byte = 23 (application_data) 70 if (buf2[0] & 0xff) != 0x17 { return 23 } 71 // Legacy version 0x03 0x03 72 if (buf2[1] & 0xff) != 0x03 { return 24 } 73 if (buf2[2] & 0xff) != 0x03 { return 25 } 74 // Record length field = 58 - 5 = 53 (= 37 inner + 16 tag) 75 let rec_len: i64 = ((buf2[3] & 0xff) << 8) | (buf2[4] & 0xff) 76 if rec_len != 53 { return 26 } 77 78 // ---- Test E: sealed verdict gate ---- 79 if nx_tls13_emit_cf_verdict_is_valid(NX_TLS13_EMIT_CF_OK) != 1 { return 30 } 80 if nx_tls13_emit_cf_verdict_is_valid(NX_TLS13_EMIT_CF_BAD_STATE) != 1 { return 31 } 81 if nx_tls13_emit_cf_verdict_is_valid(NX_TLS13_EMIT_CF_BUF_OVERFLOW) != 1 { return 32 } 82 if nx_tls13_emit_cf_verdict_is_valid(NX_TLS13_EMIT_CF_INTERNAL) != 1 { return 33 } 83 if nx_tls13_emit_cf_verdict_is_valid(NX_TLS13_EMIT_CF_VERDICT_N) != 0 { return 34 } 84 if nx_tls13_emit_cf_verdict_is_valid(0) != 0 { return 35 } 85 if nx_tls13_emit_cf_verdict_is_valid(0 - 1) != 0 { return 36 } 86 87 return 0 88}