hkdf_sha512.nx source
↩ module page · 89 lines · 2745 B
1// hkdf_sha512.nx -- HKDF-SHA-512 (RFC 5869).
2//
3// Final HKDF variant, parallel to hkdf.nx (SHA-256) and
4// hkdf_sha384.nx (SHA-384). Used where a downstream primitive
5// requires the full 512-bit output width or where the whole key
6// ladder is anchored on SHA-512.
7//
8// Output capacity: 255 * 64 = 16320 bytes. Ample for any TLS /
9// SSH session derivation.
10
11import "syscalls.nx"
12import "hmac_sha512.nx"
13
14const HKDF512_HASH: i64 = 64
15const HKDF512_MAX_L: i64 = 16320
16
17func hkdf512_extract(salt: *u8, salt_len: i64,
18 ikm: *u8, ikm_len: i64,
19 prk: *u8) -> i64 {
20 if salt_len == 0 {
21 let zero_salt: *u8 = sys_mmap(HKDF512_HASH)
22 var i: i64 = 0
23 while i < HKDF512_HASH { zero_salt[i] = 0; i = i + 1 }
24 hmac_sha512(zero_salt, HKDF512_HASH, ikm, ikm_len, prk)
25 } else {
26 hmac_sha512(salt, salt_len, ikm, ikm_len, prk)
27 }
28 return 0
29}
30
31func hkdf512_expand(prk: *u8,
32 info: *u8, info_len: i64,
33 l: i64, out: *u8) -> i64 {
34 if l > HKDF512_MAX_L { return -1 }
35 if l < 0 { return -1 }
36
37 let t_prev: *u8 = sys_mmap(HKDF512_HASH)
38 let t_curr: *u8 = sys_mmap(HKDF512_HASH)
39 let buf_cap: i64 = HKDF512_HASH + info_len + 1
40 let buf: *u8 = sys_mmap(buf_cap)
41
42 var prev_len: i64 = 0
43 var produced: i64 = 0
44 var counter: i64 = 1
45 while produced < l {
46 var bi: i64 = 0
47 var k: i64 = 0
48 while k < prev_len { buf[bi + k] = t_prev[k]; k = k + 1 }
49 bi = bi + prev_len
50 k = 0
51 while k < info_len { buf[bi + k] = info[k]; k = k + 1 }
52 bi = bi + info_len
53 buf[bi] = counter & 0xFF
54 bi = bi + 1
55
56 hmac_sha512(prk, HKDF512_HASH, buf, bi, t_curr)
57
58 let remain: i64 = l - produced
59 var take: i64 = HKDF512_HASH
60 if remain < HKDF512_HASH { take = remain }
61 k = 0
62 while k < take { out[produced + k] = t_curr[k]; k = k + 1 }
63 produced = produced + take
64
65 k = 0
66 while k < HKDF512_HASH { t_prev[k] = t_curr[k]; k = k + 1 }
67 prev_len = HKDF512_HASH
68 counter = counter + 1
69 }
70 return 0
71}
72
73func main() -> i64 {
74 let ikm: *u8 = sys_mmap(22)
75 let salt: *u8 = sys_mmap(13)
76 let info: *u8 = sys_mmap(10)
77 let prk: *u8 = sys_mmap(64)
78 let okm: *u8 = sys_mmap(128)
79 var i: i64 = 0
80 while i < 22 { ikm[i] = 0x0B; i = i + 1 }
81 i = 0
82 while i < 13 { salt[i] = i as i64; i = i + 1 }
83 i = 0
84 while i < 10 { info[i] = 0xF0 + (i as i64); i = i + 1 }
85
86 hkdf512_extract(salt, 13, ikm, 22, prk)
87 hkdf512_expand(prk, info, 10, 128, okm)
88 return okm[0] as i64
89}