code wiki / _hdl_build / nx_profile_backup_gate.nx

nx_profile_backup_gate.nx source

↩ module page · 99 lines · 4792 B

1// nx_profile_backup_gate.nx -- gate for the ENCRYPTED PROFILE BACKUP (R5, "two is one one is none"). 2// Proves on /tmp fixtures with a FIXED test ikm (mechanism proof; the runner uses /etc/machine-id): 3// T1 backup-with-built-in-roundtrip returns 0 (a backup that doesn't restore is not a backup) 4// T2 restore to a new file is BYTE-IDENTICAL to the source (binary-safe incl NUL bytes) 5// T3 NEG: one flipped ciphertext byte -> restore MUST fail (Poly1305 auth = tamper-evident) 6// T4 NEG: wrong ikm (another machine) -> restore MUST fail (machine-bound) 7// T5 encrypted-at-rest: the blob must NOT contain the known plaintext marker (it is really encrypted) 8// expect_exit: 0 license_tier: ORIGINAL 9import "nx_profile_backup.nx" 10 11func t_pw(s: *u8) -> i64 { sys_write(1, s, pb_slen(s)); return 0 } 12func t_pn(v: i64) -> i64 { 13 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 14 let t: *u8=sys_mmap(28); 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} 15 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 16func chk(name: *u8, ok: i64, pass: *i64) -> i64 { 17 t_pw(" " as *u8) 18 if ok==1 { t_pw("PASS " as *u8); pass[0]=pass[0]+1 } else { t_pw("FAIL " as *u8) } 19 t_pw(name); t_pw("\n" as *u8) 20 return 0 } 21func t_contains(hay: *u8, n: i64, needle: *u8) -> i64 { 22 let nl: i64=pb_slen(needle); if nl==0 {return 1} 23 var i: i64=0 24 while i+nl<=n { var j: i64=0; var ok: i64=1; while j<nl { if hay[i+j]!=needle[j]{ok=0;j=nl} else {j=j+1} } if ok==1{return 1} i=i+1 } 25 return 0 } 26 27func main() -> i64 { 28 t_pw("=== nx_profile_backup_gate: encrypted OS backup (R5 two-is-one) ===\n" as *u8) 29 let pass: *i64 = sys_mmap(16) as *i64 30 pass[0] = 0 31 let SRC: *u8 = "/tmp/pbg_src.bin" 32 let BLOB: *u8 = "/tmp/pbg_blob.nxpb" 33 let REST: *u8 = "/tmp/pbg_restored.bin" 34 let IKM: *u8 = "gate-test-machine-ikm-0123456789abcdef" 35 let IKM2: *u8 = "DIFFERENT-machine-ikm-fedcba9876543210" 36 37 // fixture: 5000 bytes, patterned, includes NUL bytes + a known plaintext marker 38 let n: i64 = 5000 39 let src: *u8 = sys_mmap(8192) 40 var i: i64 = 0 41 while i < n { src[i] = ((i * 7 + (i / 251)) % 256) as u8; i = i + 1 } 42 let marker: *u8 = "NISHI-PLAINTEXT-MARKER" 43 i = 0 44 while marker[i] != (0 as u8) { src[100 + i] = marker[i]; i = i + 1 } 45 let fd: i64 = sys_openat_wr(SRC, 0x1a4) 46 if fd < 0 { t_pw("cannot write fixture\n" as *u8); return 1 } 47 sys_write(fd, src, n) 48 sys_close(fd) 49 50 // T1 backup (built-in re-read + decrypt + byte-compare) 51 let rc1: i64 = pb_backup_file(SRC, BLOB, IKM, pb_slen(IKM)) 52 var t1: i64 = 0 53 if rc1 == 0 { t1 = 1 } 54 chk("T1 backup + built-in restore-verify == 0 " as *u8, t1, pass) 55 56 // T2 restore to a new file, byte-identical 57 var t2: i64 = 0 58 if pb_restore_file(BLOB, REST, IKM, pb_slen(IKM)) == 0 { 59 let box: *i64 = sys_mmap(16) as *i64 60 let r: *u8 = sys_read_file(REST, box) 61 if (r as i64) != 0 { 62 if box[0] == n { 63 var same: i64 = 1 64 i = 0 65 while i < n { if r[i] != src[i] { same = 0; i = n } else { i = i + 1 } } 66 t2 = same 67 } 68 } 69 } 70 chk("T2 restore byte-identical (binary-safe) " as *u8, t2, pass) 71 72 // T5 encrypted-at-rest (checked before tampering): blob must NOT contain the plaintext marker 73 let bbox: *i64 = sys_mmap(16) as *i64 74 let blob: *u8 = sys_read_file(BLOB, bbox) 75 var t5: i64 = 0 76 if (blob as i64) != 0 { if t_contains(blob, bbox[0], marker) == 0 { t5 = 1 } } 77 chk("T5 encrypted-at-rest (no plaintext in blob) " as *u8, t5, pass) 78 79 // T3 NEG tamper: flip ONE ciphertext byte -> restore must FAIL 80 var t3: i64 = 0 81 if (blob as i64) != 0 { 82 blob[100] = ((blob[100] as i64) ^ 0xFF) as u8 // inside ct region (header = 74 bytes) 83 let tfd: i64 = sys_openat_wr("/tmp/pbg_tampered.nxpb" as *u8, 0x1a4) 84 sys_write(tfd, blob, bbox[0]) 85 sys_close(tfd) 86 if pb_restore_file("/tmp/pbg_tampered.nxpb" as *u8, "/tmp/pbg_tampered_out.bin" as *u8, IKM, pb_slen(IKM)) != 0 { t3 = 1 } 87 } 88 chk("T3 NEG tampered blob REFUSED (Poly1305) " as *u8, t3, pass) 89 90 // T4 NEG wrong machine ikm -> restore must FAIL 91 var t4: i64 = 0 92 if pb_restore_file(BLOB, "/tmp/pbg_wrongkey_out.bin" as *u8, IKM2, pb_slen(IKM2)) != 0 { t4 = 1 } 93 chk("T4 NEG wrong-machine ikm REFUSED " as *u8, t4, pass) 94 95 t_pw("PROFILE-BACKUP-GATE pass=" as *u8); t_pn(pass[0]); t_pw("/5" as *u8) 96 if pass[0]==5 { t_pw(" verdict=GREEN -- encrypted machine-bound backup proven: restores exactly, refuses tamper + foreign machine\n" as *u8); return 0 } 97 t_pw(" verdict=RED\n" as *u8) 98 return 1 99}