code wiki / _hdl_build / nx_doc_at_rest_gate.nx

nx_doc_at_rest_gate.nx source

↩ module page · 139 lines · 8264 B

1// nx_doc_at_rest_gate.nx -- MEASURED hermetic gate for the at-rest wiring (nx_doc_at_rest). Fresh nonce domain per 2// run (sys_now_realtime_sec). Proves encrypt-on-write + transparent read + legacy coexistence + crypto-shred: 3// T1 doc_put a confidential doc -> the STORED bytes start with the NXENC1 magic (encrypted, NOT plaintext) and 4// doc_get round-trips BYTE-IDENTICAL. 5// T2 a LEGACY plaintext value (raw ss_add, no magic, in the confidential shard) -> doc_get passes it through 6// unchanged (existing pre-encryption docs still readable). 7// T3 the raw STORED encrypted bytes DO NOT contain the doc's distinctive plaintext canary (at-rest protection). 8// T4 crypto_shred(domain) -> doc_get of the encrypted doc FAILS (erased) while the legacy-plaintext doc reads. 9// Print pass=4 + GREEN/RED, append knowledge/status/dp_at_rest_gate.log. STANDALONE -- no daemon, no deploy. 10// (nx_chacha20_poly1305_decrypt prints one 'A' to STDERR on first call -- shipped-AEAD scratch marker; harmless.) 11// license_tier: ORIGINAL 12import "nx_doc_at_rest.nx" // doc_put / doc_get / at_is_magic / crypto_shred (+ dp_*/ss_*/DP_VIS_* transitively) 13import "nx_docportal_lib.nx" // dp_prefix / dp_key / DP_VIS_PRIVATE + ss_begin/ss_add/ss_commit/ss_open/ss_hget (explicit) 14 15func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 16func g_num(v: i64) -> i64 { 17 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 18 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 19 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 20 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 21} 22func g_w(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 } 23func g_wn(fd: i64, v: i64) -> i64 { 24 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m } 25 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 26 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 27 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(fd, bb, k); return 0 28} 29func g_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 30func g_cat(out: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { out[o] = s[i]; o = o + 1; i = i + 1 } return o } 31func g_catnum(out: *u8, o: i64, v: i64) -> i64 { 32 if v == 0 { out[o] = 48 as u8; return o + 1 } 33 var m: i64 = v; let t: *u8 = sys_mmap(28); var k: i64 = 0 34 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 35 var i: i64 = 0; while i < k { out[o] = t[k - 1 - i]; o = o + 1; i = i + 1 } return o 36} 37func g_eqbytes(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 } 38func g_contains(hay: *u8, hn: i64, ndl: *u8) -> i64 { 39 let nl: i64 = g_slen(ndl); if nl == 0 { return 0 } 40 if hn < nl { return 0 } 41 var i: i64 = 0 42 while i + nl <= hn { 43 var j: i64 = 0; var hit: i64 = 1 44 while j < nl { if hay[i + j] != ndl[j] { hit = 0; j = nl } else { j = j + 1 } } 45 if hit == 1 { return 1 } 46 i = i + 1 47 } 48 return 0 49} 50 51func main() -> i64 { 52 g_puts("=== DP AT-REST GATE (encrypt-on-write confidential + transparent read + legacy coexistence) ===\n" as *u8) 53 let nonce: i64 = sys_now_realtime_sec() 54 let dom: *u8 = sys_mmap(64) 55 var dn: i64 = g_cat(dom, 0, "dpatrest" as *u8); dn = g_catnum(dom, dn, nonce); dom[dn] = 0 as u8 56 57 let cidE: i64 = 700001 // the encrypted-on-write doc 58 let cidL: i64 = 700002 // the legacy plaintext doc 59 let ptE: *u8 = "ATREST-PLAINTEXT-CANARY confidential client record for the at-rest wiring gate." as *u8 60 let ptElen: i64 = g_slen(ptE) 61 let legacy: *u8 = "LEGACY-PLAINTEXT existing pre-encryption client doc, still readable today." as *u8 62 let legacyLen: i64 = g_slen(legacy) 63 64 var pass: i64 = 0 65 66 // T1: doc_put confidential -> stored bytes carry magic (encrypted) -> doc_get round-trips 67 let put: i64 = doc_put(dom, DP_VIS_PRIVATE, cidE, ptE, ptElen) 68 let prefix: *u8 = sys_mmap(512); dp_prefix(dom, DP_VIS_PRIVATE, prefix) 69 let dkeyE: *u8 = sys_mmap(64); dp_key(cidE, dkeyE) 70 let rawSave: *u8 = sys_mmap(ptElen + 128) 71 var rawElen: i64 = 0 72 var magicok: i64 = 0 73 let h1: *i64 = ss_open(prefix) 74 if (h1 as i64) != 0 { 75 let pq: *i64 = sys_mmap(16) as *i64 76 let lq: *i64 = sys_mmap(16) as *i64 77 if ss_hget(h1, dkeyE, pq, lq) == 1 { 78 rawElen = lq[0] 79 let vp: *u8 = pq[0] as *u8 80 var c: i64 = 0 81 while c < rawElen { rawSave[c] = vp[c]; c = c + 1 } 82 magicok = at_is_magic(rawSave, rawElen) 83 } 84 } 85 let outE: *u8 = sys_mmap(ptElen + 128) 86 let gotE: i64 = doc_get(dom, DP_VIS_PRIVATE, cidE, outE) 87 var t1: i64 = 0 88 if put == 0 { if magicok == 1 { if gotE == ptElen { if g_eqbytes(outE, ptE, ptElen) == 1 { t1 = 1 } } } } 89 pass = pass + t1 90 g_puts(" T1 confidential doc_put stored ENCRYPTED (magic=" as *u8); g_num(magicok); g_puts(" rawlen=" as *u8); g_num(rawElen); g_puts(") + doc_get round-trips (len=" as *u8); g_num(gotE); g_puts("): " as *u8) 91 if t1 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 92 93 // T2: LEGACY plaintext (raw ss_add, no magic) -> doc_get passthrough unchanged 94 let dkeyL: *u8 = sys_mmap(64); dp_key(cidL, dkeyL) 95 let w: *i64 = ss_begin() 96 ss_add(w, 1, dkeyL, legacy, legacyLen) 97 let segid: i64 = ss_next_segid(prefix) 98 ss_commit(prefix, w, segid) 99 let outL: *u8 = sys_mmap(legacyLen + 64) 100 let gotL: i64 = doc_get(dom, DP_VIS_PRIVATE, cidL, outL) 101 var t2: i64 = 0 102 if gotL == legacyLen { if g_eqbytes(outL, legacy, legacyLen) == 1 { t2 = 1 } } 103 pass = pass + t2 104 g_puts(" T2 legacy plaintext reads through unchanged (len=" as *u8); g_num(gotL); g_puts(" of " as *u8); g_num(legacyLen); g_puts("): " as *u8) 105 if t2 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 106 107 // T3: the raw STORED encrypted bytes DO NOT contain the plaintext canary 108 let canary: *u8 = "ATREST-PLAINTEXT-CANARY" as *u8 109 let hascanary: i64 = g_contains(rawSave, rawElen, canary) 110 var t3: i64 = 0 111 if magicok == 1 { if hascanary == 0 { t3 = 1 } } 112 pass = pass + t3 113 g_puts(" T3 plaintext canary ABSENT from stored ciphertext (found=" as *u8); g_num(hascanary); g_puts(", expect 0): " as *u8) 114 if t3 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 115 116 // T4: crypto-shred -> encrypted doc_get FAILS (erased) while legacy plaintext still reads 117 let sh: i64 = crypto_shred(dom) 118 let outE2: *u8 = sys_mmap(ptElen + 128) 119 let gotE2: i64 = doc_get(dom, DP_VIS_PRIVATE, cidE, outE2) 120 let outL2: *u8 = sys_mmap(legacyLen + 64) 121 let gotL2: i64 = doc_get(dom, DP_VIS_PRIVATE, cidL, outL2) 122 var t4: i64 = 0 123 if sh == 0 { if gotE2 < 0 { if gotL2 == legacyLen { if g_eqbytes(outL2, legacy, legacyLen) == 1 { t4 = 1 } } } } 124 pass = pass + t4 125 g_puts(" T4 crypto-shred erases encrypted (get=" as *u8); g_num(gotE2); g_puts(") legacy still reads (get=" as *u8); g_num(gotL2); g_puts("): " as *u8) 126 if t4 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 127 128 g_puts("----\nDP-AT-REST rows=4 pass=" as *u8); g_num(pass); g_puts("\n" as *u8) 129 let lg: i64 = sys_openat_append("knowledge/status/dp_at_rest_gate.log" as *u8, 0x1a4) 130 if lg >= 0 { 131 g_w(lg, "DP-AT-REST encrypted_write=" as *u8); g_wn(lg, t1); g_w(lg, " legacy_passthrough=" as *u8); g_wn(lg, t2) 132 g_w(lg, " canary_absent=" as *u8); g_wn(lg, t3); g_w(lg, " shred_erases=" as *u8); g_wn(lg, t4) 133 g_w(lg, " rows=4 pass=" as *u8); g_wn(lg, pass) 134 if pass == 4 { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 135 sys_close(lg) 136 } 137 if pass == 4 { g_puts("DP-AT-REST GREEN (confidential writes encrypted at rest, legacy plaintext coexists, crypto-shred erases -- measured)\n" as *u8); sys_exit(0); return 0 } 138 g_puts("DP-AT-REST RED\n" as *u8); sys_exit(1); return 1 139}