code wiki / _hdl_build / nx_cenc_gate.nx

nx_cenc_gate.nx source

↩ module page · 77 lines · 4800 B

1import "nx_gate_gn.nx" 2import "nx_gate_base.nx" 3// nx_cenc_gate.nx -- proves the standards-based encrypted-media primitives: (1) AES-128-CTR is NIST-correct 4// (SP800-38A F.5.1 vectors, decrypt path), (2) CENC subsample decrypt preserves clear ranges + decrypts the 5// encrypted ranges (continuous keystream), (3) ClearKey JWK key acquisition (base64url). license_tier: ORIGINAL expect_exit: 0 6import "nx_syscalls.nx" 7import "nx_aes.nx" 8import "nx_aes_ctr.nx" 9import "base64.nx" 10import "nx_cenc.nx" 11 12func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 13" as *u8); return ok } 14func hexval(c: i64) -> i64 { if c>=48 { if c<=57 { return c-48 } } if c>=97 { if c<=102 { return c-87 } } if c>=65 { if c<=70 { return c-55 } } return 0 } 15func hx(s: *u8, out: *u8) -> i64 { var i: i64=0; var o: i64=0; while (s[i]&0xff)!=0 { let hi: i64=hexval(s[i]&0xff); let lo: i64=hexval(s[i+1]&0xff); out[o]=(hi*16+lo) as u8; o=o+1; i=i+2 } return o } 16func beq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if (a[i]&0xff)!=(b[i]&0xff){ return 0 } i=i+1 } return 1 } 17func gsl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 18 19func main() -> i64 { 20 gw("cenc/clearkey SOVEREIGN gate (AES-CTR NIST KAT + CENC subsample decrypt + ClearKey JWK)\n" as *u8) 21 var pass: i64 = 0 22 var ttl: i64 = 0 23 24 let key: *u8 = sys_mmap(16) 25 hx("2b7e151628aed2a6abf7158809cf4f3c\x00" as *u8, key) 26 let sched: *u8 = sys_mmap(176) 27 aes128_expand_key(key, sched) 28 let iv: *u8 = sys_mmap(16) 29 hx("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\x00" as *u8, iv) 30 31 // K1: NIST SP800-38A F.5.1 block 1 -- decrypt CT -> PT (whole-sample, nsub=0). 32 let ct1: *u8 = sys_mmap(16); hx("874d6191b620e3261bef6864990db6ce\x00" as *u8, ct1) 33 let pt1: *u8 = sys_mmap(16); hx("6bc1bee22e409f96e93d7e117393172a\x00" as *u8, pt1) 34 let out1: *u8 = sys_mmap(16) 35 cenc_decrypt_subsamples(sched, iv, 16, ct1, 16, 0 as *i64, 0, out1) 36 ttl=ttl+1; pass=pass+grow("K1 AES-CTR NIST F.5.1 block1 decrypt\x00" as *u8, beq(out1, pt1, 16)) 37 38 // K2: NIST F.5.1 blocks 1+2 (32 bytes) -- proves the counter increments across blocks. 39 let ct2: *u8 = sys_mmap(32); hx("874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff\x00" as *u8, ct2) 40 let pt2: *u8 = sys_mmap(32); hx("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51\x00" as *u8, pt2) 41 let out2: *u8 = sys_mmap(32) 42 cenc_decrypt_subsamples(sched, iv, 16, ct2, 32, 0 as *i64, 0, out2) 43 ttl=ttl+1; pass=pass+grow("K2 AES-CTR NIST F.5.1 blocks1+2 (counter carry)\x00" as *u8, beq(out2, pt2, 32)) 44 45 // K3: CENC SUBSAMPLE -- layout [clear 4, enc 16, clear 2, enc 16] (38B). Make a "ciphertext sample" by 46 // CTR-encrypting only the enc ranges of a known plaintext (CTR is symmetric), then decrypt it back: 47 // clear bytes must survive untouched, enc bytes must round-trip, and the cipher must differ from plain. 48 let subs: *i64 = sys_mmap(8*4) as *i64 49 subs[0]=4; subs[1]=16; subs[2]=2; subs[3]=16 50 let ptS: *u8 = sys_mmap(38) 51 var z: i64=0; while z<38 { ptS[z]=(z+1) as u8; z=z+1 } // known plaintext 1..38 52 let ctS: *u8 = sys_mmap(38) 53 cenc_decrypt_subsamples(sched, iv, 16, ptS, 38, subs, 2, ctS) // symmetric -> "encrypts" the enc ranges 54 let decS: *u8 = sys_mmap(38) 55 cenc_decrypt_subsamples(sched, iv, 16, ctS, 38, subs, 2, decS) // decrypt back 56 var m3: i64 = 1 57 if beq(decS, ptS, 38) == 0 { m3 = 0 } // round-trip 58 if (ctS[0]&0xff) != (ptS[0]&0xff) { m3 = 0 } // clear byte 0 untouched 59 if (ctS[20]&0xff) != (ptS[20]&0xff) { m3 = 0 } // clear byte 20 untouched 60 if (ctS[4]&0xff) == (ptS[4]&0xff) { m3 = 0 } // enc byte 4 actually changed 61 ttl=ttl+1; pass=pass+grow("K3 CENC subsample: clear kept, enc round-trips\x00" as *u8, m3) 62 63 // K4: ClearKey JWK -- k = base64url of bytes 01..10 -> 16-byte key. 64 let json: *u8 = "{\"keys\":[{\"kty\":\"oct\",\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":\"AAAAAAAAAAAAAAAAAAAAAA\"}],\"type\":\"temporary\"}" as *u8 65 let ckkey: *u8 = sys_mmap(32) 66 let kl: i64 = clearkey_first_key(json, gsl(json), ckkey) 67 let want: *u8 = sys_mmap(16) 68 var q: i64=0; while q<16 { want[q]=(q+1) as u8; q=q+1 } 69 var m4: i64 = 1 70 if kl != 16 { m4 = 0 } 71 if m4 == 1 { if beq(ckkey, want, 16) == 0 { m4 = 0 } } 72 ttl=ttl+1; pass=pass+grow("K4 ClearKey JWK -> 16-byte key\x00" as *u8, m4) 73 74 gw("pass=" as *u8); gn(pass); gw("/" as *u8); gn(ttl); gw("\n" as *u8) 75 if pass == ttl { gw("verdict=GREEN (AES-CTR NIST-correct + CENC subsample decrypt + ClearKey key acquisition)\n" as *u8); sys_exit(0); return 0 } 76 gw("verdict=RED\n" as *u8); sys_exit(1); return 1 77}