code wiki / _hdl_build / nx_tor_aes_gate.nx
nx_tor_aes_gate.nx source
↩ module page · 84 lines · 7279 B
1// nx_tor_aes_gate.nx -- KAT for nx_tor_aes (AES-128-CTR, the Tor relay cipher) vs NIST SP 800-38A F.5.
2// AT1 F.5.1 CTR-AES128.Encrypt byte-exact (64B, key/ICB/PT/CT from nx_aes_ctr_test.nx = on-disk NIST vector)
3// AT2 F.5.2 CTR-AES128.Decrypt byte-exact (CT -> PT, symmetric)
4// AT3 FULL-128-bit carry: a counter with low 32 bits = 0xffffffff carries into byte 11 (the 32-bit-only
5// incrementer in nx_aes_ctr.nx would get this WRONG -- this is why Tor needs nx_tor_aes)
6// AT4 round-trip on a block-crossing + partial-tail buffer
7// license_tier: ORIGINAL expect_exit: 0
8import "nx_syscalls.nx"
9import "nx_aes.nx"
10import "nx_tor_aes.nx"
11
12func g_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
13func g_n(v: i64) -> i64 { var m: i64=v; if m<0{g_w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let o:*u8=sys_mmap(24); var i:i64=0; while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
14func g_fw(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
15func g_fn(fd: i64, v: i64) -> i64 { var m: i64=v; let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let o:*u8=sys_mmap(24); var i:i64=0; while i<k{o[i]=t[k-1-i];i=i+1} sys_write(fd,o,k); return 0 }
16func g_row(id: *u8, ok: i64, pass: *i64, tot: *i64) -> i64 { tot[0]=tot[0]+1; g_w(" " as *u8); g_w(id); if ok==1 { g_w(": OK\n" as *u8); pass[0]=pass[0]+1 } else { g_w(": FAIL\n" as *u8) } return 0 }
17func g_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 }
18
19func main() -> i64 {
20 let pass: *i64 = sys_mmap(8) as *i64; pass[0]=0
21 let tot: *i64 = sys_mmap(8) as *i64; tot[0]=0
22 g_w("=== NX-TOR-AES GATE (AES-128-CTR relay cipher vs NIST SP 800-38A F.5) ===\n" as *u8)
23
24 let key: *u8 = sys_mmap(16)
25 key[0]=0x2b;key[1]=0x7e;key[2]=0x15;key[3]=0x16;key[4]=0x28;key[5]=0xae;key[6]=0xd2;key[7]=0xa6;key[8]=0xab;key[9]=0xf7;key[10]=0x15;key[11]=0x88;key[12]=0x09;key[13]=0xcf;key[14]=0x4f;key[15]=0x3c
26 let icb: *u8 = sys_mmap(16); var i: i64=0; while i<16 { icb[i]=(0xf0+i)&0xff; i=i+1 }
27 let pt: *u8 = sys_mmap(64)
28 pt[0]=0x6b;pt[1]=0xc1;pt[2]=0xbe;pt[3]=0xe2;pt[4]=0x2e;pt[5]=0x40;pt[6]=0x9f;pt[7]=0x96;pt[8]=0xe9;pt[9]=0x3d;pt[10]=0x7e;pt[11]=0x11;pt[12]=0x73;pt[13]=0x93;pt[14]=0x17;pt[15]=0x2a
29 pt[16]=0xae;pt[17]=0x2d;pt[18]=0x8a;pt[19]=0x57;pt[20]=0x1e;pt[21]=0x03;pt[22]=0xac;pt[23]=0x9c;pt[24]=0x9e;pt[25]=0xb7;pt[26]=0x6f;pt[27]=0xac;pt[28]=0x45;pt[29]=0xaf;pt[30]=0x8e;pt[31]=0x51
30 pt[32]=0x30;pt[33]=0xc8;pt[34]=0x1c;pt[35]=0x46;pt[36]=0xa3;pt[37]=0x5c;pt[38]=0xe4;pt[39]=0x11;pt[40]=0xe5;pt[41]=0xfb;pt[42]=0xc1;pt[43]=0x19;pt[44]=0x1a;pt[45]=0x0a;pt[46]=0x52;pt[47]=0xef
31 pt[48]=0xf6;pt[49]=0x9f;pt[50]=0x24;pt[51]=0x45;pt[52]=0xdf;pt[53]=0x4f;pt[54]=0x9b;pt[55]=0x17;pt[56]=0xad;pt[57]=0x2b;pt[58]=0x41;pt[59]=0x7b;pt[60]=0xe6;pt[61]=0x6c;pt[62]=0x37;pt[63]=0x10
32 let ctexp: *u8 = sys_mmap(64)
33 ctexp[0]=0x87;ctexp[1]=0x4d;ctexp[2]=0x61;ctexp[3]=0x91;ctexp[4]=0xb6;ctexp[5]=0x20;ctexp[6]=0xe3;ctexp[7]=0x26;ctexp[8]=0x1b;ctexp[9]=0xef;ctexp[10]=0x68;ctexp[11]=0x64;ctexp[12]=0x99;ctexp[13]=0x0d;ctexp[14]=0xb6;ctexp[15]=0xce
34 ctexp[16]=0x98;ctexp[17]=0x06;ctexp[18]=0xf6;ctexp[19]=0x6b;ctexp[20]=0x79;ctexp[21]=0x70;ctexp[22]=0xfd;ctexp[23]=0xff;ctexp[24]=0x86;ctexp[25]=0x17;ctexp[26]=0x18;ctexp[27]=0x7b;ctexp[28]=0xb9;ctexp[29]=0xff;ctexp[30]=0xfd;ctexp[31]=0xff
35 ctexp[32]=0x5a;ctexp[33]=0xe4;ctexp[34]=0xdf;ctexp[35]=0x3e;ctexp[36]=0xdb;ctexp[37]=0xd5;ctexp[38]=0xd3;ctexp[39]=0x5e;ctexp[40]=0x5b;ctexp[41]=0x4f;ctexp[42]=0x09;ctexp[43]=0x02;ctexp[44]=0x0d;ctexp[45]=0xb0;ctexp[46]=0x3e;ctexp[47]=0xab
36 ctexp[48]=0x1e;ctexp[49]=0x03;ctexp[50]=0x1d;ctexp[51]=0xda;ctexp[52]=0x2f;ctexp[53]=0xbe;ctexp[54]=0x03;ctexp[55]=0xd1;ctexp[56]=0x79;ctexp[57]=0x21;ctexp[58]=0x70;ctexp[59]=0xa0;ctexp[60]=0xf3;ctexp[61]=0x00;ctexp[62]=0x9c;ctexp[63]=0xee
37
38 // AT1 encrypt
39 let ivc: *u8 = sys_mmap(16); var j: i64=0; while j<16 { ivc[j]=icb[j]; j=j+1 }
40 let ct: *u8 = sys_mmap(64); tor_aes128_ctr(key, ivc, pt, 64, ct)
41 var at1: i64=0; if g_eq(ct, ctexp, 64)==1 { at1=1 }
42 g_row("AT1 NIST F.5.1 CTR-AES128.Encrypt byte-exact (64B)" as *u8, at1, pass, tot)
43
44 // AT2 decrypt (F.5.2): crypt the CT -> PT
45 let iv2: *u8 = sys_mmap(16); j=0; while j<16 { iv2[j]=icb[j]; j=j+1 }
46 let rt: *u8 = sys_mmap(64); tor_aes128_ctr(key, iv2, ctexp, 64, rt)
47 var at2: i64=0; if g_eq(rt, pt, 64)==1 { at2=1 }
48 g_row("AT2 NIST F.5.2 CTR-AES128.Decrypt byte-exact (CT->PT)" as *u8, at2, pass, tot)
49
50 // AT3 full-128 carry
51 let sched: *u8 = sys_mmap(AES_EXP_LEN + 16); aes128_expand_key(key, sched)
52 let icb2: *u8 = sys_mmap(16); j=0; while j<16 { icb2[j]=0 as u8; j=j+1 } icb2[11]=0x41;icb2[12]=0xff;icb2[13]=0xff;icb2[14]=0xff;icb2[15]=0xff
53 let ks0: *u8 = sys_mmap(16); aes128_encrypt_block(icb2, sched, ks0)
54 let icb2c: *u8 = sys_mmap(16); j=0; while j<16 { icb2c[j]=icb2[j]; j=j+1 } tor_ctr_inc128(icb2c)
55 let ks1: *u8 = sys_mmap(16); aes128_encrypt_block(icb2c, sched, ks1)
56 let zin: *u8 = sys_mmap(32); j=0; while j<32 { zin[j]=0 as u8; j=j+1 }
57 let cout: *u8 = sys_mmap(32)
58 let ctr3: *u8 = sys_mmap(16); j=0; while j<16 { ctr3[j]=icb2[j]; j=j+1 }
59 tor_aes128_ctr_crypt(sched, ctr3, zin, 32, cout)
60 var at3: i64=1
61 if (icb2c[11]&0xff)!=0x42 { at3=0 } // carry incremented byte 11
62 if (icb2c[12]&0xff)!=0x00 { at3=0 } // low 4 bytes wrapped to 0
63 if g_eq(cout, ks0, 16)!=1 { at3=0 } // block0 keystream = AES(ICB)
64 if g_eq((cout as i64 + 16) as *u8, ks1, 16)!=1 { at3=0 } // block1 keystream = AES(carried ICB)
65 g_row("AT3 full-128-bit counter carry (low 0xffffffff -> byte 11) [32-bit inc would FAIL]" as *u8, at3, pass, tot)
66
67 // AT4 round-trip on 100 bytes (6 full blocks + 4-byte partial tail)
68 let src: *u8 = sys_mmap(100); j=0; while j<100 { src[j]=((j*7+3)&0xff) as u8; j=j+1 }
69 let iv4: *u8 = sys_mmap(16); j=0; while j<16 { iv4[j]=0 as u8; j=j+1 } // Tor relay IV = zeros
70 let enc: *u8 = sys_mmap(100); tor_aes128_ctr(key, iv4, src, 100, enc)
71 let iv4b: *u8 = sys_mmap(16); j=0; while j<16 { iv4b[j]=0 as u8; j=j+1 }
72 let dec: *u8 = sys_mmap(100); tor_aes128_ctr(key, iv4b, enc, 100, dec)
73 var at4: i64=0; if g_eq(dec, src, 100)==1 { if g_eq(enc, src, 100)==0 { at4=1 } } // decrypts back AND actually encrypted
74 g_row("AT4 round-trip 100B (block-crossing + partial tail), Tor IV=0" as *u8, at4, pass, tot)
75
76 g_w("TOR-AES-GATE rows=" as *u8); g_n(tot[0]); g_w(" pass=" as *u8); g_n(pass[0])
77 if pass[0]==tot[0] {
78 g_w(" verdict=GREEN\n" as *u8)
79 let lg: i64 = sys_openat_append("knowledge/status/tor_aes_gate.log" as *u8, 0x1a4)
80 if lg>=0 { g_fw(lg, "TOR-AES-GATE pass=" as *u8); g_fn(lg, pass[0]); g_fw(lg, "/" as *u8); g_fn(lg, tot[0]); g_fw(lg, " verdict=GREEN scope=AES128-CTR-NIST-F.5-byte-exact+full128-carry epoch=" as *u8); g_fn(lg, sys_now_realtime_sec()); g_fw(lg, "\n" as *u8); sys_close(lg) }
81 sys_exit(0); return 0
82 }
83 g_w(" verdict=RED\n" as *u8); sys_exit(1); return 1
84}