code wiki / (root) / hmac_sha512.nx

hmac_sha512.nx source

↩ module page · 75 lines · 2360 B

1// hmac_sha512.nx -- HMAC-SHA-512 (RFC 2104 / FIPS 198-1). 2// 3// Completes the HMAC family: SHA-256, SHA-384, SHA-512. Used 4// where TLS cipher suites or key-derivation ladders want the 5// full 512-bit MAC width (relatively rare, but present in some 6// SSH / OpenPGP / JWT profiles). 7// 8// Differences from hmac.nx: 9// - Block size B = 128 bytes (SHA-512 block), not 64. 10// - Hash output = 64 bytes (SHA-512), not 32. 11// - Uses sha512_init instead of sha256_init. 12 13import "syscalls.nx" 14import "sha512.nx" 15 16const HMAC512_BLOCK: i64 = 128 17const HMAC512_HASH: i64 = 64 18const IPAD_512: i64 = 0x36 19const OPAD_512: i64 = 0x5C 20 21func hmac_sha512(key: *u8, key_len: i64, msg: *u8, msg_len: i64, 22 out: *u8) -> i64 { 23 let kp: *u8 = sys_mmap(HMAC512_BLOCK) 24 var i: i64 = 0 25 while i < HMAC512_BLOCK { kp[i] = 0; i = i + 1 } 26 if key_len > HMAC512_BLOCK { 27 sha512_digest(key, key_len, kp) 28 } else { 29 var j: i64 = 0 30 while j < key_len { kp[j] = key[j]; j = j + 1 } 31 } 32 33 // Inner hash. 34 let inner_key: *u8 = sys_mmap(HMAC512_BLOCK) 35 let ii_raw: *u8 = sys_mmap(512) 36 let ii: *Sha512 = ii_raw as *Sha512 37 sha512_init(ii) 38 var b: i64 = 0 39 while b < HMAC512_BLOCK { 40 inner_key[b] = kp[b] ^ IPAD_512 41 b = b + 1 42 } 43 sha512_update(ii, inner_key, HMAC512_BLOCK) 44 sha512_update(ii, msg, msg_len) 45 let inner: *u8 = sys_mmap(HMAC512_HASH) 46 sha512_final(ii, inner) 47 48 // Outer hash. 49 let outer_key: *u8 = sys_mmap(HMAC512_BLOCK) 50 let oi_raw: *u8 = sys_mmap(512) 51 let oi: *Sha512 = oi_raw as *Sha512 52 sha512_init(oi) 53 b = 0 54 while b < HMAC512_BLOCK { 55 outer_key[b] = kp[b] ^ OPAD_512 56 b = b + 1 57 } 58 sha512_update(oi, outer_key, HMAC512_BLOCK) 59 sha512_update(oi, inner, HMAC512_HASH) 60 sha512_final(oi, out) 61 return 0 62} 63 64// Compile-only smoke. RFC 4231 test case 1: key = 0x0b*20, 65// data = "Hi There" -> 87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2 66// ce8f99401b2d9c29f88e3ac8 etc. 67func main() -> i64 { 68 let key: *u8 = sys_mmap(20) 69 let msg: *u8 = "Hi There" 70 let tag: *u8 = sys_mmap(64) 71 var i: i64 = 0 72 while i < 20 { key[i] = 0x0B; i = i + 1 } 73 hmac_sha512(key, 20, msg, 8, tag) 74 return tag[0] as i64 75}