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}