code wiki / (root) / hkdf_sha512.nx

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}