nx_hkdf_test.nx source
↩ module page · 135 lines · 4897 B
1// nx_hkdf_test.nx -- RFC 5869 Appendix A KAT for HKDF-SHA-256.
2//
3// Three worked examples from the spec (the SHA-256 ones, A.1-A.3):
4//
5// A.1 Basic (IKM=22B 0x0b, salt=13B 0x00..0x0c, info=10B 0xf0..0xf9, L=42)
6// PRK = 077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5
7// OKM = 3cb25f25faacd57a90434f64d0362f2a
8// 2d2d0a90cf1a5a4c5db02d56ecc4c5bf
9// 34007208d5b887185865
10//
11// A.2 Longer (IKM=80B 0x00..0x4f, salt=80B 0x60..0xaf, info=80B 0xb0..0xff, L=82)
12// PRK = 06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244
13// OKM = b11e398dc80327a1c8e7f78c596a4934
14// 4f012eda2d4efad8a050cc4c19afa97c
15// 59045a99cac7827271cb41c65e590e09
16// da3275600c2f09b8367793a9aca3db71
17// cc30c58179ec3e87c14c01d5c1f3434f
18// 1d87
19//
20// A.3 Zero salt/info (IKM=22B 0x0b, salt=empty, info=empty, L=42)
21// PRK = 19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04
22// OKM = 8da4e775a563c18f715f802a063c5a31
23// b8a11f5c5ee1879ec3454e5f3c738d2d
24// 9d201395faa4b61a96c8
25//
26// expect_exit: 0
27// license_tier: ORIGINAL
28
29import "nx_syscalls.nx"
30import "nx_hkdf.nx"
31
32func main() -> i64 {
33 // ---- Test Case 1 (RFC 5869 §A.1) ----
34 let ikm1: *u8 = sys_mmap(32)
35 var i: i64 = 0
36 while i < 22 { ikm1[i] = 0x0b; i = i + 1 }
37 let salt1: *u8 = sys_mmap(16)
38 i = 0
39 while i < 13 { salt1[i] = i; i = i + 1 }
40 let info1: *u8 = sys_mmap(16)
41 i = 0
42 while i < 10 { info1[i] = 0xf0 + i; i = i + 1 }
43
44 let prk1: *u8 = sys_mmap(32)
45 hkdf_extract(salt1, 13, ikm1, 22, prk1)
46
47 // Expected PRK1 first 8 bytes: 07 77 09 36 2c 2e 32 df + last 8: 22 ec 84 4a d7 c2 b3 e5
48 if (prk1[0] & 0xff) != 0x07 { return 1 }
49 if (prk1[1] & 0xff) != 0x77 { return 2 }
50 if (prk1[7] & 0xff) != 0xdf { return 3 }
51 if (prk1[24] & 0xff) != 0x22 { return 4 }
52 if (prk1[31] & 0xff) != 0xe5 { return 5 }
53
54 let okm1: *u8 = sys_mmap(64)
55 hkdf_expand(prk1, info1, 10, 42, okm1)
56
57 // Expected OKM1: 3c b2 5f 25 fa ac d5 7a 90 43 4f 64 d0 36 2f 2a ... 58 65
58 if (okm1[0] & 0xff) != 0x3c { return 6 }
59 if (okm1[1] & 0xff) != 0xb2 { return 7 }
60 if (okm1[15] & 0xff) != 0x2a { return 8 }
61 if (okm1[16] & 0xff) != 0x2d { return 9 }
62 if (okm1[31] & 0xff) != 0xbf { return 10 }
63 if (okm1[40] & 0xff) != 0x58 { return 11 }
64 if (okm1[41] & 0xff) != 0x65 { return 12 }
65
66 // ---- Test Case 2 (RFC 5869 §A.2) ----
67 let ikm2: *u8 = sys_mmap(128)
68 i = 0
69 while i < 80 { ikm2[i] = i; i = i + 1 }
70 let salt2: *u8 = sys_mmap(128)
71 i = 0
72 while i < 80 { salt2[i] = 0x60 + i; i = i + 1 }
73 let info2: *u8 = sys_mmap(128)
74 i = 0
75 while i < 80 { info2[i] = 0xb0 + i; i = i + 1 }
76
77 let prk2: *u8 = sys_mmap(32)
78 hkdf_extract(salt2, 80, ikm2, 80, prk2)
79
80 // Expected PRK2: 06 a6 b8 8c 58 53 36 1a 06 10 4c 9c eb 35 b4 5c
81 // ef 76 00 14 90 46 71 01 4a 19 3f 40 c1 5f c2 44
82 if (prk2[0] & 0xff) != 0x06 { return 20 }
83 if (prk2[1] & 0xff) != 0xa6 { return 21 }
84 if (prk2[15] & 0xff) != 0x5c { return 22 }
85 if (prk2[16] & 0xff) != 0xef { return 23 }
86 if (prk2[31] & 0xff) != 0x44 { return 24 }
87
88 let okm2: *u8 = sys_mmap(128)
89 hkdf_expand(prk2, info2, 80, 82, okm2)
90
91 // Expected OKM2 first 8 + last 2:
92 // b1 1e 39 8d c8 03 27 a1 ... 1d 87
93 if (okm2[0] & 0xff) != 0xb1 { return 30 }
94 if (okm2[1] & 0xff) != 0x1e { return 31 }
95 if (okm2[7] & 0xff) != 0xa1 { return 32 }
96 if (okm2[80] & 0xff) != 0x1d { return 33 }
97 if (okm2[81] & 0xff) != 0x87 { return 34 }
98
99 // ---- Test Case 3 (RFC 5869 §A.3, empty salt + info) ----
100 let ikm3: *u8 = sys_mmap(32)
101 i = 0
102 while i < 22 { ikm3[i] = 0x0b; i = i + 1 }
103 let empty: *u8 = sys_mmap(16)
104
105 let prk3: *u8 = sys_mmap(32)
106 hkdf_extract(empty, 0, ikm3, 22, prk3)
107
108 // Expected PRK3: 19 ef 24 a3 2c 71 7b 16 ... ac 43 4c 1c 29 3c cb 04
109 if (prk3[0] & 0xff) != 0x19 { return 40 }
110 if (prk3[1] & 0xff) != 0xef { return 41 }
111 if (prk3[7] & 0xff) != 0x16 { return 42 }
112 if (prk3[24] & 0xff) != 0xac { return 43 }
113 if (prk3[31] & 0xff) != 0x04 { return 44 }
114
115 let okm3: *u8 = sys_mmap(64)
116 hkdf_expand(prk3, empty, 0, 42, okm3)
117
118 // Expected OKM3 first 8 + last 2:
119 // 8d a4 e7 75 a5 63 c1 8f ... 96 c8
120 if (okm3[0] & 0xff) != 0x8d { return 50 }
121 if (okm3[1] & 0xff) != 0xa4 { return 51 }
122 if (okm3[7] & 0xff) != 0x8f { return 52 }
123 if (okm3[40] & 0xff) != 0x96 { return 53 }
124 if (okm3[41] & 0xff) != 0xc8 { return 54 }
125
126 // ---- Bounds: oversize OKM length must be rejected ----
127 let big_out: *u8 = sys_mmap(32)
128 let rc: i64 = hkdf_expand(prk3, empty, 0, 8161, big_out)
129 if rc != 0 - 1 { return 60 }
130
131 let rc2: i64 = hkdf_expand(prk3, empty, 0, 0 - 5, big_out)
132 if rc2 != 0 - 1 { return 61 }
133
134 return 0
135}