nx_drbg_hmac_test.nx source
↩ module page · 83 lines · 2935 B
1// nx_drbg_hmac_test.nx -- self-consistency smoke for HMAC-DRBG.
2//
3// Tests:
4// 1. Same seed -> same output (determinism)
5// 2. Different seed -> different output (sensitivity)
6// 3. Successive Generate calls advance state (no repetition)
7// 4. Non-block-multiple length works (e.g. 17 bytes)
8// 5. Reseed counter advances on Generate
9//
10// expect_exit: 0
11//
12// license_tier: ORIGINAL
13
14import "nx_syscalls.nx"
15import "nx_sha256.nx"
16import "nx_hmac.nx"
17import "nx_drbg_hmac.nx"
18
19func _bytes_equal(a: *u8, b: *u8, n: i64) -> i64 {
20 var i: i64 = 0
21 while i < n {
22 if a[i] != b[i] { return 0 }
23 i = i + 1
24 }
25 return 1
26}
27
28func main() -> i64 {
29 let state1: *u8 = sys_mmap(DRBG_STATE_LEN + 16)
30 let state2: *u8 = sys_mmap(DRBG_STATE_LEN + 16)
31 let state3: *u8 = sys_mmap(DRBG_STATE_LEN + 16)
32 let out1: *u8 = sys_mmap(128)
33 let out2: *u8 = sys_mmap(128)
34 let out3: *u8 = sys_mmap(128)
35
36 // Two distinct seeds.
37 let seed_a: *u8 = "abcdefghijklmnopqrstuvwxyz012345" as *u8
38 let seed_b: *u8 = "ZYXWVUTSRQPONMLKJIHGFEDCBA987654" as *u8
39
40 // ---- Test 1: determinism ---------------------------------------
41 drbg_hmac_init(state1, seed_a, 32)
42 drbg_hmac_generate(state1, out1, 32)
43 drbg_hmac_init(state2, seed_a, 32)
44 drbg_hmac_generate(state2, out2, 32)
45 if _bytes_equal(out1, out2, 32) != 1 { return 1 }
46
47 // ---- Test 2: sensitivity ---------------------------------------
48 drbg_hmac_init(state3, seed_b, 32)
49 drbg_hmac_generate(state3, out3, 32)
50 if _bytes_equal(out1, out3, 32) == 1 { return 2 }
51
52 // ---- Test 3: state advances ------------------------------------
53 // Generate twice from the same state; second 32-byte chunk must
54 // differ from the first.
55 let state4: *u8 = sys_mmap(DRBG_STATE_LEN + 16)
56 let chunk1: *u8 = sys_mmap(32)
57 let chunk2: *u8 = sys_mmap(32)
58 drbg_hmac_init(state4, seed_a, 32)
59 drbg_hmac_generate(state4, chunk1, 32)
60 drbg_hmac_generate(state4, chunk2, 32)
61 if _bytes_equal(chunk1, chunk2, 32) == 1 { return 3 }
62
63 // ---- Test 4: odd lengths ---------------------------------------
64 let state5: *u8 = sys_mmap(DRBG_STATE_LEN + 16)
65 let odd_out: *u8 = sys_mmap(32)
66 drbg_hmac_init(state5, seed_a, 32)
67 drbg_hmac_generate(state5, odd_out, 17)
68 // Bytes 0..16 should match first 17 bytes of out1 (same seed,
69 // first Generate call).
70 if _bytes_equal(odd_out, out1, 17) != 1 { return 4 }
71
72 // ---- Test 5: reseed counter -----------------------------------
73 let state6: *u8 = sys_mmap(DRBG_STATE_LEN + 16)
74 let dummy: *u8 = sys_mmap(32)
75 drbg_hmac_init(state6, seed_a, 32)
76 if drbg_hmac_reseed_counter(state6) != 1 { return 5 }
77 drbg_hmac_generate(state6, dummy, 32)
78 if drbg_hmac_reseed_counter(state6) != 2 { return 6 }
79 drbg_hmac_generate(state6, dummy, 32)
80 if drbg_hmac_reseed_counter(state6) != 3 { return 7 }
81
82 return 0
83}