code wiki / _hdl_build / nx_fw_uefi_capsule.nx
nx_fw_uefi_capsule.nx source
↩ module page · 119 lines · 5992 B
1// nx_fw_uefi_capsule.nx -- a REAL EFI_CAPSULE_HEADER + sovereign ed25519 authentication.
2//
3// module: nishi-core.genealogy.fw_uefi_capsule
4// capability: CORE_COMPUTE (real-firmware-shaped signed capsules)
5//
6// The NXC1 capsule (rung 8) was our own layout. A real UEFI capsule starts with the spec struct
7// EFI_CAPSULE_HEADER:
8// EFI_GUID CapsuleGuid; // 16 -- identifies the capsule type (here: the Nishi FW-capsule GUID)
9// UINT32 HeaderSize; // 4 -- size of this header (28)
10// UINT32 Flags; // 4
11// UINT32 CapsuleImageSize;// 4 -- total size of the capsule (header + body)
12// == 28 bytes, then the body. Here body = payload + a 64-byte ed25519 signature over
13// (header || payload). So a UEFI capsule parser sees a valid header+GUID+size; OUR verifier adds
14// authenticity via sovereign ed25519.
15// HONEST: the HEADER is the real UEFI struct; the AUTH is sovereign ed25519 (NOT the UEFI PKCS7 /
16// Authenticode EFI_FIRMWARE_IMAGE_AUTHENTICATION, which needs X.509/PKCS7 -- a separate lift).
17// Sandboxed. Sovereign: nx_fw_capsule (-> nx_ed25519, cp_* helpers) + nx_syscalls. license_tier: ORIGINAL
18import "nx_fw_capsule.nx"
19import "nx_syscalls.nx"
20
21const UC_HDR: i64 = 28 // sizeof(EFI_CAPSULE_HEADER)
22const UC_SIG: i64 = 64 // ed25519 signature
23const UC_HEADERSIZE: i64 = 28 // the HeaderSize field value
24const UC_MAXIMG: i64 = 16777216
25
26// the Nishi firmware-capsule GUID (our vendor capsule type; 16 bytes).
27func uc_guid_write(buf: *u8) -> i64 {
28 buf[0] = 0x4e as u8; buf[1] = 0x49 as u8; buf[2] = 0x53 as u8; buf[3] = 0x48 as u8 // N I S H
29 buf[4] = 0x49 as u8; buf[5] = 0x2d as u8; buf[6] = 0x46 as u8; buf[7] = 0x57 as u8 // I - F W
30 buf[8] = 0x43 as u8; buf[9] = 0x41 as u8; buf[10] = 0x50 as u8; buf[11] = 0x53 as u8 // C A P S
31 buf[12] = 0x01 as u8; buf[13] = 0x02 as u8; buf[14] = 0x03 as u8; buf[15] = 0x04 as u8 // version
32 return 0
33}
34func uc_guid_match(buf: *u8) -> i64 {
35 let g: *u8 = sys_mmap(16); uc_guid_write(g)
36 var i: i64 = 0
37 while i < 16 { if buf[i] != g[i] { return 0 } i = i + 1 }
38 return 1
39}
40
41// structural EFI_CAPSULE_HEADER check: GUID matches, HeaderSize==28, CapsuleImageSize==total.
42func uc_header_ok(buf: *u8, total: i64) -> i64 {
43 if total < (UC_HDR + UC_SIG) { return 0 }
44 if uc_guid_match(buf) == 0 { return 0 }
45 if cp_rd_u32(buf, 16) != UC_HEADERSIZE { return 0 }
46 if cp_rd_u32(buf, 24) != total { return 0 }
47 return 1
48}
49
50// build a real-UEFI-shaped capsule signed by `seed`.
51func uc_make(path: *u8, payload: *u8, plen: i64, seed: *u8) -> i64 {
52 let total: i64 = UC_HDR + plen + UC_SIG
53 let buf: *u8 = sys_mmap(total + 16)
54 uc_guid_write(buf)
55 cp_wr_u32(buf, 16, UC_HEADERSIZE)
56 cp_wr_u32(buf, 20, 0) // Flags
57 cp_wr_u32(buf, 24, total) // CapsuleImageSize (header + body)
58 var i: i64 = 0
59 while i < plen { buf[UC_HDR + i] = payload[i]; i = i + 1 }
60 let sig: *u8 = sys_mmap(UC_SIG)
61 ed25519_sign_full(seed, buf, UC_HDR + plen, sig) // sign header || payload
62 i = 0
63 while i < UC_SIG { buf[UC_HDR + plen + i] = sig[i]; i = i + 1 }
64 cp_write(path, buf, total)
65 return 0
66}
67
68// 1 ONLY IF the EFI header is well-formed (incl the Nishi GUID) AND the ed25519 sig verifies.
69func uc_verify(path: *u8) -> i64 {
70 let lb: *i64 = sys_mmap(16) as *i64; lb[0] = 0
71 let buf: *u8 = cp_read(path, lb)
72 if (buf as i64) == 0 { return 0 }
73 let total: i64 = lb[0]
74 if uc_header_ok(buf, total) == 0 { return 0 }
75 let plen: i64 = total - UC_HDR - UC_SIG
76 if plen < 0 { return 0 }
77 let pub: *u8 = sys_mmap(32); cap_trusted_pub(pub)
78 let sig: *u8 = ((buf as i64) + UC_HDR + plen) as *u8
79 if ed25519_verify_full(pub, buf, UC_HDR + plen, sig) == NX_ED25519_SIG_OK { return 1 }
80 return 0
81}
82
83func uc_corrupt(path: *u8) -> i64 {
84 let lb: *i64 = sys_mmap(16) as *i64; lb[0] = 0
85 let buf: *u8 = cp_read(path, lb)
86 if (buf as i64) == 0 { return 0 - 1 }
87 let n: i64 = lb[0]
88 if n > UC_HDR { buf[UC_HDR] = ((buf[UC_HDR] as i64) + 1) as u8 } // flip first payload byte
89 cp_write(path, buf, n)
90 return 0
91}
92func uc_flip_guid(path: *u8) -> i64 {
93 let lb: *i64 = sys_mmap(16) as *i64; lb[0] = 0
94 let buf: *u8 = cp_read(path, lb)
95 if (buf as i64) == 0 { return 0 - 1 }
96 let n: i64 = lb[0]
97 if n > 0 { buf[0] = ((buf[0] as i64) + 1) as u8 } // corrupt the GUID
98 cp_write(path, buf, n)
99 return 0
100}
101
102func main() -> i64 {
103 cp_puts("=== NISHI UEFI CAPSULE (real EFI_CAPSULE_HEADER + sovereign ed25519) ===\n")
104 let epoch: i64 = sys_now_realtime_sec()
105 let pid: i64 = __syscall(39, 0, 0, 0, 0, 0, 0)
106 let plat: *u8 = sys_mmap(32); cap_plat_seed(plat)
107 let forged: *u8 = sys_mmap(32); var i: i64 = 0; while i < 32 { forged[i] = ((i * 3 + 99) & 0xff) as u8; i = i + 1 }
108 let cap: *u8 = sys_mmap(256); cap_path(cap, "/tmp/nxucap_demo." as *u8, epoch, pid)
109
110 uc_make(cap, "NISHI-fw-image-in-a-real-EFI-capsule" as *u8, 36, plat)
111 let lb: *i64 = sys_mmap(16) as *i64; lb[0] = 0; let b: *u8 = cp_read(cap, lb)
112 cp_puts(" EFI header: HeaderSize="); cp_putn(cp_rd_u32(b, 16)); cp_puts(" CapsuleImageSize="); cp_putn(cp_rd_u32(b, 24)); cp_puts(" total="); cp_putn(lb[0]); cp_puts(" guid_ok="); cp_putn(uc_guid_match(b)); cp_puts("\n")
113 cp_puts(" authentic -> verify="); cp_putn(uc_verify(cap)); cp_puts("\n")
114 uc_corrupt(cap); cp_puts(" corrupted payload -> verify="); cp_putn(uc_verify(cap)); cp_puts("\n")
115 uc_make(cap, "NISHI-fw-image-in-a-real-EFI-capsule" as *u8, 36, forged); cp_puts(" FORGED key -> verify="); cp_putn(uc_verify(cap)); cp_puts("\n")
116 uc_make(cap, "NISHI-fw-image-in-a-real-EFI-capsule" as *u8, 36, plat); uc_flip_guid(cap); cp_puts(" wrong GUID -> verify="); cp_putn(uc_verify(cap)); cp_puts("\n")
117 cp_puts(" INVARIANT: real EFI_CAPSULE_HEADER + only a platform-signed body verifies\n")
118 sys_exit(0); return 0
119}