nx_hkdf.nx
buildroot/runtime/nx_hkdf.nx
about
hkdf.nx -- HKDF-SHA-256 (RFC 5869).
HMAC-based Extract-and-Expand Key Derivation Function. Central
to TLS 1.3 (RFC 8446 §7.1) key schedule:
Early Secret = HKDF-Extract(0, PSK)
Handshake Secret = HKDF-Extract(Derive-Secret(Early, ""), ECDHE)
Master Secret = HKDF-Extract(Derive-Secret(Handshake, ""), 0)
<traffic secrets> = Derive-Secret(<stage>, "<label>", transcript)
Two-stage design:
Extract(salt, IKM) -> PRK
Treats IKM as an entropy source; produces a uniformly-random
pseudorandom key. Implemented as HMAC-SHA-256(salt, IKM).
Expand(PRK, info, L) -> OKM
Deterministically derives L bytes of keying material from PRK
and a context string `info`. Iterates HMAC over a counter.
Properties (RFC 5869 §3.3):
- Deterministic: same (salt, IKM, info, L) -> same OKM.
- Context-binding: different `info` -> independent OKMs.
- Output limited to 255 * HashLen = 8160 bytes for SHA-256.
Invariants:
HK1 PRK is always exactly HashLen (32 bytes for SHA-256).
HK2 Expand iterates exactly ceil(L / HashLen) times; each
iteration feeds the previous output back in, creating a
chain that prevents block-substitution attacks.
HK3 Counter bytes are 1-indexed; wraps at 255 per RFC 5869
§2.3. We cap L at 8160 and refuse larger requests.
HK4 No branches on salt/IKM/info VALUES; branches only on
LENGTHS.
license_tier: INDEPENDENT_REDERIVE
genealogy_id: international-research-sources/ietf/rfc_5869
nx_safety_envelope: (schema: nishi-library/seeds/safety-critical-standards.toml)
intended_use: "HKDF-SHA-256 key derivation -- TLS 1.3
record-protection schedule (RFC 8446 §7.1) +
Noise protocol KDF + any KDF needing
dependencies 3 imports · 19 importers
diagram shows first 10 each side; +0 more imports, +9 more importers in the complete lists below.
imports: nx_syscalls.nxnx_hmac.nxnx_hmac_sha384.nx
imported by: _tlskdf_minrepro.nxnx_hkdf384_gate.nxnx_hkdf_test.nxnx_mtls_identity.nxnx_opaque_3dh.nxnx_opaque_core.nxnx_opaque_envelope.nxnx_opaque_pake.nxnx_password_vault.nxnx_profile_backup.nxnx_quic_keys.nxnx_tls13_kdf.nxnx_tls13_kdf_test.nxnx_tls13_mtls_finished.nxnx_tls13_schedule.nxnx_tls13_server_session_derive_hs.nxnx_tls13_server_session_recv_cf.nxnx_tls13_server_session_run_mtls.nxnx_tor_ntor.nx
structs
| none |
consts
| 66 | const HKDF_HASH: i64 = 32 // SHA-256 output |
| 67 | const HKDF_MAX_L: i64 = 8160 // 255 * 32 |
| 68 | const HKDF_HASH384: i64 = 48 // SHA-384 output |
| 69 | const HKDF_MAX_L384: i64 = 12240 // 255 * 48 |
functions
| 74 | func hkdf_extract(salt: *u8, salt_len: i64, called by 17: mainmainmainnx_opq_derive_keysnx_opq_randomized_passwordnx_vault_derive_key+11 calls 2: sys_mmaphmac_sha256 |
| 90 | func hkdf_expand(prk: *u8, called by 15: mainmainmainnx_mtls_derive_identity_keypairnx_opq_expand_label_opqe_derive_from_rwd+9 calls 2: sys_mmaphmac_sha256 |
| 159 | func hkdf_extract_h(salt: *u8, salt_len: i64, |
| 184 | func hkdf_expand_h(prk: *u8, hash_len: i64, |