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