code wiki / _hdl_build / nx_quic_aead_test.nx
nx_quic_aead_test.nx source
↩ module page · 69 lines · 4636 B
1// nx_quic_aead_gate.nx -- RUNG 5b gate: QUIC AEAD packet protection. Exact vectors: nonce (RFC 9001 sec
2// 5.3, A.2 -> fa044b2f42a3fd3b46fb255e) + header-protection mask (RFC 9001 sec 5.4.2 -> 437b9aec36) +
3// AES-128-GCM seal->open round-trip + tamper rejection + HP apply/remove symmetry. Native, sovereign.
4// license_tier: ORIGINAL
5import "nx_quic_aead.nx"
6import "nx_gate_emit_lib.nx"
7
8func hexnib(c: i64) -> i64 { if c>=48 { if c<=57 { return c-48 } } if c>=97 { if c<=102 { return c-87 } } return 0 }
9func set_hex(out: *u8, hex: *u8, nbytes: i64) -> i64 { var i: i64=0; while i<nbytes { out[i]=((hexnib(hex[i*2] as i64)<<4)|hexnib(hex[i*2+1] as i64)) as u8; i=i+1 } return 0 }
10func eq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if a[i]!=b[i] { return 0 } i=i+1 } return 1 }
11func g_phex(b: *u8, n: i64) -> i64 {
12 let h: *u8 = "0123456789abcdef" as *u8
13 var i: i64=0
14 while i<n { let o: *u8=sys_mmap(2); o[0]=h[(b[i] as i64 >> 4) & 0xf]; o[1]=h[(b[i] as i64) & 0xf]; sys_write(1,o,2); i=i+1 }
15 return 0
16}
17
18func main() -> i64 {
19 g_puts("nx_quic_aead gate -- AEAD packet protection vs RFC 9001 sec 5.3/5.4\n" as *u8)
20 var pass: i64=0; var total: i64=0
21
22 // ---- nonce (RFC 9001 A.2): iv ^ pn(=2) ----
23 let iv: *u8 = sys_mmap(12); set_hex(iv, "fa044b2f42a3fd3b46fb255c" as *u8, 12)
24 let nonce: *u8 = sys_mmap(12); quic_nonce(iv, 2, nonce)
25 let exp_nonce: *u8 = sys_mmap(12); set_hex(exp_nonce, "fa044b2f42a3fd3b46fb255e" as *u8, 12)
26 pass = pass + g_check("nonce = iv XOR pn(2) == fa044b2f42a3fd3b46fb255e (RFC 9001 A.2)" as *u8, eq(nonce, exp_nonce, 12)); total=total+1
27
28 // ---- header-protection mask = AES-ECB(hp, sample) (RFC 9001 sec 5.4.2) ----
29 let hp: *u8 = sys_mmap(16); set_hex(hp, "9f50449e04a0e810283a1e9933adedd2" as *u8, 16)
30 let sample: *u8 = sys_mmap(16); set_hex(sample, "d1b1c98dd7689fb8ec11d242b123dc9b" as *u8, 16)
31 let mask: *u8 = sys_mmap(16); quic_hp_mask(hp, sample, mask)
32 g_puts(" computed mask[0..5] = " as *u8); g_phex(mask, 5); g_puts(" (RFC expects 437b9aec36)\n" as *u8)
33 let exp_mask: *u8 = sys_mmap(5); set_hex(exp_mask, "437b9aec36" as *u8, 5)
34 pass = pass + g_check("HP mask AES-ECB(hp,sample)[0..5] == 437b9aec36 (RFC 9001 5.4.2)" as *u8, eq(mask, exp_mask, 5)); total=total+1
35
36 // ---- AES-128-GCM seal -> open round-trip (client key, nonce pn=2, aad=header) ----
37 let key: *u8 = sys_mmap(16); set_hex(key, "1f369613dd76d5467730efcbe3b1a22d" as *u8, 16)
38 let aad: *u8 = sys_mmap(16); set_hex(aad, "c30000000108 8394c8f03e515708" as *u8, 13) // (spaces ignored by set_hex? no) -- build clean
39 // build a clean 13-byte aad header instead
40 set_hex(aad, "c3000000010883" as *u8, 7)
41 let pt: *u8 = sys_mmap(32); var i: i64=0; while i<32 { pt[i]=((i*9+1)&255) as u8; i=i+1 }
42 let ct: *u8 = sys_mmap(48); let tag: *u8 = sys_mmap(16)
43 quic_seal(key, iv, 2, aad, 7, pt, 32, ct, tag)
44 let dec: *u8 = sys_mmap(48)
45 let orc: i64 = quic_open(key, iv, 2, aad, 7, ct, 32, tag, dec)
46 var rt_ok: i64=0
47 if orc==0 { rt_ok=1; var k: i64=0; while k<32 { if dec[k]!=pt[k] { rt_ok=0; k=32 } else { k=k+1 } } }
48 pass = pass + g_check("AES-128-GCM seal->open recovers plaintext, tag verified (rc=0)" as *u8, rt_ok); total=total+1
49
50 // ---- tamper: flip a ciphertext byte -> open MUST fail (rc != 0) ----
51 ct[0] = (ct[0] as i64 ^ 0xff) as u8
52 let trc: i64 = quic_open(key, iv, 2, aad, 7, ct, 32, tag, dec)
53 pass = pass + g_check("tampered ciphertext rejected by GCM tag (rc != 0)" as *u8, (trc != 0) as i64); total=total+1
54
55 // ---- header protection apply/remove symmetry ----
56 let hdr: *u8 = sys_mmap(16)
57 hdr[0]=0xc3 as u8; hdr[1]=0x00 as u8; hdr[2]=0x00 as u8; hdr[3]=0x00 as u8; hdr[4]=0x02 as u8 // pn at off 1, 4 bytes
58 let saved: *u8 = sys_mmap(16); var z: i64=0; while z<5 { saved[z]=hdr[z]; z=z+1 }
59 quic_hp_apply(hdr, 1, 4, mask, 1) // apply (long header)
60 var changed: i64=0; if hdr[0]!=saved[0] { changed=1 }
61 quic_hp_apply(hdr, 1, 4, mask, 1) // remove
62 var sym_ok: i64=0; if changed==1 { sym_ok=1; z=0; while z<5 { if hdr[z]!=saved[z] { sym_ok=0; z=5 } else { z=z+1 } } }
63 pass = pass + g_check("HP apply (mutates) then re-apply restores header exactly (symmetric)" as *u8, sym_ok); total=total+1
64
65 g_puts("---- quic_aead gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
66 if pass == total { g_puts("VERDICT: GREEN (QUIC AEAD packet protection, RFC 9001 5.3/5.4, sovereign AES-128-GCM) -- R5 packet protection COMPLETE\n" as *u8); return 0 }
67 g_puts("VERDICT: RED\n" as *u8)
68 return 1
69}