nx_entropy.nx source
↩ module page · 42 lines · 1853 B
1// nx_entropy.nx -- the team's CSPRNG organ (security ladder rung: random IV/salt + secret
2// rotation both REQUIRE real randomness; the vault's path-derived IV was a flagged debt and
3// becomes an AES-GCM nonce-reuse BREAK the moment a path is re-sealed with a new value).
4// Source = the kernel CSPRNG via getrandom(2), x86_64 syscall 318 called DIRECT (the frozen
5// kg syscall table lacks a row; runtime-computed numbers are the blessed escape hatch).
6// Fails CLOSED: callers must treat a nonzero return as fatal -- never fall back to weak bits.
7// license_tier: ORIGINAL
8
9// fill buf[0..n) with kernel CSPRNG bytes; 0 = ok, -1 = entropy unavailable (FAIL CLOSED)
10func ent_fill(buf: *u8, n: i64) -> i64 {
11 var got: i64 = 0
12 var tries: i64 = 0
13 while got < n {
14 let base: i64 = buf as i64
15 let r: i64 = __syscall(318, (base + got) as *u8, n - got, 0, 0, 0, 0)
16 if r <= 0 {
17 tries = tries + 1
18 if tries > 8 { return 0 - 1 }
19 } else { got = got + r }
20 }
21 return 0
22}
23
24// generate a password of exactly len chars into buf (NUL-terminated; buf cap >= len+1).
25// Alphabet is EXACTLY 64 chars (A-Za-z0-9-_) so 6-bit indexing is uniform -- no modulo
26// bias (a 62-char alphabet with % would skew the first 4 chars' frequency by ~3%).
27// 24 chars * 6 bits = 144 bits of entropy. 0 = ok, -1 = entropy unavailable.
28func ent_pw(buf: *u8, len: i64) -> i64 {
29 let ab: *u8 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" as *u8
30 let raw: *u8 = sys_mmap(len + 16)
31 if ent_fill(raw, len) != 0 { return 0 - 1 }
32 var i: i64 = 0
33 while i < len {
34 buf[i] = ab[(raw[i] as i64) & 63]
35 i = i + 1
36 }
37 buf[len] = 0 as u8
38 // shred the raw bytes (they map 1:1 to the password)
39 i = 0
40 while i < len { raw[i] = 0 as u8; i = i + 1 }
41 return 0
42}