code wiki / _hdl_build / nx_device_cert.nx
nx_device_cert.nx source
↩ module page · 41 lines · 1986 B
1// nx_device_cert.nx -- DEVICE provisioning for the access wall (the "provision certain devices to certain
2// areas even over the internet" layer, L3). A provisioned device = (device_id, ed25519 PUBLIC key) in the
3// registry; the device holds the matching PRIVATE key. To access, the device signs a FRESH server challenge
4// (nonce) with its private key; the server verifies the signature against the registered public key -> the
5// device_ok signal the PDP (nx_access_wall) consumes. Spoof-proof (no private key => no valid signature),
6// replay-resistant (fresh challenge), and works over the public internet -- the mTLS essence without a shared
7// secret. Does NOT roll crypto: reuses the KAT-verified ed25519 (ed25519_verify_full, RFC 8032).
8// license_tier: ORIGINAL
9import "nx_ed25519_signature.nx"
10import "nx_syscalls.nx"
11
12func dc_streq(a: *u8, b: *u8) -> i64 {
13 var i: i64 = 0
14 var go: i64 = 1
15 while go == 1 {
16 let ca: i64 = a[i] as i64
17 let cb: i64 = b[i] as i64
18 if ca != cb { return 0 }
19 if ca == 0 { return 1 }
20 i = i + 1
21 }
22 return 0
23}
24
25// find device_id's slot in the registry (ids = parallel array of *u8 cast to i64); -1 if not provisioned.
26func dc_find(ids: *i64, n: i64, id: *u8) -> i64 {
27 var i: i64 = 0
28 while i < n { if dc_streq(ids[i] as *u8, id) == 1 { return i } i = i + 1 }
29 return 0 - 1
30}
31
32// device_ok: the device must be PROVISIONED (registered) AND prove possession of its private key with a valid
33// ed25519 signature over the fresh challenge. Unknown device -> 0 (deny-by-default). pubs = parallel array of
34// 32-byte pubkey pointers (cast to i64). sig is 64 bytes. Returns 1 (device_ok) / 0.
35func dc_verify(ids: *i64, pubs: *i64, n: i64, id: *u8, challenge: *u8, clen: i64, sig: *u8) -> i64 {
36 let s: i64 = dc_find(ids, n, id)
37 if s < 0 { return 0 }
38 let pub: *u8 = pubs[s] as *u8
39 if ed25519_verify_full(pub, challenge, clen, sig) == NX_ED25519_SIG_OK { return 1 }
40 return 0
41}