code wiki / (root) / nx_hmac_candidate_t187.nx

nx_hmac_candidate_t187.nx

buildroot/runtime/nx_hmac_candidate_t187.nx

6674 B155 linesdepth 5pulls 5 transitivereach 0 importersview sourcekind tooltopic hmac
docsdependenciesstructsconstsfunctions

about

hmac.nx -- HMAC-SHA-256 (RFC 2104, FIPS 198-1). license_tier: INDEPENDENT_REDERIVE genealogy_id: international-research-sources/nist/fips_198_1 Keyed-hash MAC built on sha256.nx. Used throughout TLS 1.3 key schedule (RFC 8446 ยง7.1) as the HKDF primitive, in older TLS as Finished-message signer, and wherever we need a symmetric authenticator without a fresh nonce (unlike Poly1305). Construction (RFC 2104): HMAC(K, M) = H( (K' xor opad) || H( (K' xor ipad) || M ) ) where H = SHA-256, block size B = 64 bytes, and K' = - H(K) if len(K) > B -- pre-hash oversized keys - K || zeros if len(K) < B -- zero-pad short keys - K if len(K) == B ipad = 0x36 repeated; opad = 0x5c repeated. Why not Poly1305 everywhere: - Poly1305 is one-time-key (P4 in poly1305.nx); reusing a key across messages breaks it. HMAC is many-to-one: a long-lived HMAC key authenticates many messages safely. TLS transcripts span the whole handshake so HMAC is the right tool there. Invariants: HM1 Key processing depends only on key LENGTH, not key VALUE: short keys zero-padded, long keys pre-hashed through SHA- 256 (which is constant-time by construction). HM2 XOR loops read every byte of the block regardless of key content; no early exit. HM3 Output is exactly 32 bytes (SHA-256 digest width). References: RFC 2104 (HMAC), FIPS 198-1, NIST SP 800-107. Test vectors from RFC 4231 (HMAC-SHA-256 specifically). nx_safety_envelope: intended_use: "HMAC-SHA-256 -- TLS 1.3 MAC + HKDF foundation + general keyed-hash authentication" sil_target: SIL3 (authentication primitive; MAC

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_sha256.nx nx_hmac_candidate_t187.nx

imports: nx_syscalls.nxnx_sha256.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_mmap nxa_die sys_write sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ hmac_sha256 sys_mmap ↻ sha256_digest sys_mmap ↻ sha256_init sys_mmap ↻ sha256_seed_allocated sha256_k sha256_update sha256_compress_ni_blocks blk_set_byte sha256_compress sha256_compress_ni blk_word blk_byte sha256_final blk_set_byte ↻ sha256_compress ↻ sha256_destroy sys_munmap sys_munmap ↻ sha256_init ↻ sha256_update ↻ sha256_final ↻

structs

none

consts

62const HMAC_BLOCK: i64 = 64 // SHA-256 block size
63const HMAC_HASH: i64 = 32 // SHA-256 output size
64const IPAD: i64 = 0x36
65const OPAD: i64 = 0x5C
128const HMAC_E_WORKSPACE:i64=0-2
129const HMAC_E_INPUT:i64=0-1

functions

68func hmac_sha256(key: *u8, key_len: i64, msg: *u8, msg_len: i64,
116func main() -> i64 {
130func hmac_sha256_workspace_bytes()->i64
133func hmac_sha256_workspace(key:*u8,key_len:i64,msg:*u8,msg_len:i64,out:*u8,workspace:*u8,capacity:i64)->i64