code wiki / _hdl_build / nx_fw_uefi_capsule_gate.nx

nx_fw_uefi_capsule_gate.nx source

↩ module page · 96 lines · 4193 B

1// nx_fw_uefi_capsule_gate.nx -- proves the real-EFI-header signed capsule. 2// 3// T1 authentic-verifies : a platform-signed UEFI capsule verifies 4// T2 valid-EFI-header : it is a well-formed EFI_CAPSULE_HEADER (Nishi GUID, HeaderSize==28, CapsuleImageSize==total) 5// N1 corrupted-rejected : flip a payload byte -> verify == 0 6// N2 forged-rejected : signed with a different key -> verify == 0 7// N3 wrong-GUID-rejected : corrupt the CapsuleGuid -> verify == 0 8// 9// GREEN only if all five hold. Evidence -> knowledge/status/fw_uefi_capsule_gate.log. 10// Sovereign: imports nx_fw_uefi_capsule (-> nx_fw_capsule -> nx_ed25519) + nx_framed_append + nx_syscalls. license_tier: ORIGINAL 11import "nx_fw_uefi_capsule.nx" 12import "nx_framed_append.nx" 13import "nx_syscalls.nx" 14 15const UCG_LOG: *u8 = "knowledge/status/fw_uefi_capsule_gate.log" 16const UCG_PAY: *u8 = "NISHI-fw-uefi-capsule-payload-image" 17 18func ucg_len(s: *u8) -> i64 { var i: i64 = 0; while s[i] != 0 as u8 { i = i + 1 } return i } 19func uc_copy(src: *u8, dst: *u8) -> i64 { 20 let lb: *i64 = sys_mmap(16) as *i64; lb[0] = 0 21 let b: *u8 = cp_read(src, lb) 22 if (b as i64) == 0 { return 0 - 1 } 23 cp_write(dst, b, lb[0]) 24 return 0 25} 26func ucg_row(name: *u8, pass: i64) -> i64 { 27 let buf: *u8 = sys_mmap(528) 28 var o: i64 = 0 29 o = cp_cat(buf, o, "UCAPG row=\x00" as *u8) 30 o = cp_cat(buf, o, name) 31 if pass == 1 { o = cp_cat(buf, o, " verdict=PASS\x00" as *u8) } else { o = cp_cat(buf, o, " verdict=FAIL\x00" as *u8) } 32 buf[o] = 0 as u8 33 fa_appendz(UCG_LOG, buf, 512) 34 cp_puts(" "); cp_puts(name) 35 if pass == 1 { cp_puts(" PASS\n") } else { cp_puts(" FAIL\n") } 36 return 0 37} 38 39func main() -> i64 { 40 cp_puts("fw-uefi-capsule gate (real EFI_CAPSULE_HEADER + ed25519)\n") 41 let e: i64 = sys_now_realtime_sec() 42 let p: i64 = __syscall(39, 0, 0, 0, 0, 0, 0) 43 let pl: i64 = ucg_len(UCG_PAY) 44 let plat: *u8 = sys_mmap(32); cap_plat_seed(plat) 45 let forged: *u8 = sys_mmap(32); var i: i64 = 0; while i < 32 { forged[i] = ((i * 3 + 99) & 0xff) as u8; i = i + 1 } 46 47 let authcap: *u8 = sys_mmap(256); cap_path(authcap, "/tmp/ucg_auth." as *u8, e, p); uc_make(authcap, UCG_PAY, pl, plat) 48 let forgcap: *u8 = sys_mmap(256); cap_path(forgcap, "/tmp/ucg_forg." as *u8, e, p); uc_make(forgcap, UCG_PAY, pl, forged) 49 50 // T1 authentic 51 var t1: i64 = 0; if uc_verify(authcap) == 1 { t1 = 1 } 52 53 // T2 real EFI_CAPSULE_HEADER 54 let lb: *i64 = sys_mmap(16) as *i64; lb[0] = 0 55 let b: *u8 = cp_read(authcap, lb) 56 var t2: i64 = 0 57 if (b as i64) != 0 { if uc_header_ok(b, lb[0]) == 1 { if cp_rd_u32(b, 16) == 28 { if cp_rd_u32(b, 24) == lb[0] { t2 = 1 } } } } 58 59 // N1 corrupted payload 60 let n1cap: *u8 = sys_mmap(256); cap_path(n1cap, "/tmp/ucg_n1." as *u8, e, p); uc_copy(authcap, n1cap); uc_corrupt(n1cap) 61 var n1: i64 = 0; if uc_verify(n1cap) == 0 { n1 = 1 } 62 63 // N2 forged 64 var n2: i64 = 0; if uc_verify(forgcap) == 0 { n2 = 1 } 65 66 // N3 wrong GUID 67 let n3cap: *u8 = sys_mmap(256); cap_path(n3cap, "/tmp/ucg_n3." as *u8, e, p); uc_copy(authcap, n3cap); uc_flip_guid(n3cap) 68 var n3: i64 = 0; if uc_verify(n3cap) == 0 { n3 = 1 } 69 70 var passes: i64 = 0 71 if t1 == 1 { passes = passes + 1 } 72 if t2 == 1 { passes = passes + 1 } 73 if n1 == 1 { passes = passes + 1 } 74 if n2 == 1 { passes = passes + 1 } 75 if n3 == 1 { passes = passes + 1 } 76 var green: i64 = 0 77 if passes == 5 { green = 1 } 78 79 ucg_row("T1-authentic-verifies \x00" as *u8, t1) 80 ucg_row("T2-valid-EFI-header \x00" as *u8, t2) 81 ucg_row("N1-corrupted-rejected \x00" as *u8, n1) 82 ucg_row("N2-forged-rejected \x00" as *u8, n2) 83 ucg_row("N3-wrong-GUID-rejected \x00" as *u8, n3) 84 85 let vb: *u8 = sys_mmap(528) 86 var o: i64 = 0 87 o = cp_cat(vb, o, "FW-UEFI-CAPSULE verdict=\x00" as *u8) 88 if green == 1 { o = cp_cat(vb, o, "GREEN\x00" as *u8) } else { o = cp_cat(vb, o, "RED\x00" as *u8) } 89 o = cp_cat(vb, o, " passes=\x00" as *u8); o = cp_catn(vb, o, passes); o = cp_cat(vb, o, "/5 END\x00" as *u8) 90 vb[o] = 0 as u8 91 fa_appendz(UCG_LOG, vb, 512) 92 cp_puts(vb); cp_puts("\n") 93 94 if green == 1 { return 0 } 95 return 1 96}