feat(tbor): implement HKDF and single-step (X9.63 / SP 800-56A) KDF derivation - #589
Open
vsonims wants to merge 1 commit into
Open
feat(tbor): implement HKDF and single-step (X9.63 / SP 800-56A) KDF derivation#589vsonims wants to merge 1 commit into
vsonims wants to merge 1 commit into
Conversation
…erivation Add two in-session TBOR KDF commands that derive key material from a caller-held masked ECDH shared secret (from EcdhDerive) and return the derived key masked under the requested scope — the KDF analogues of the ECC crypto commands, re-masking the output instead of vaulting it: - HkdfDerive (0x1C): HKDF (RFC 5869) with optional salt + info. - ConcatKdfDerive (0x1D): single-step "concatenation" KDF, selecting ANSI X9.63 (SEC 1 §3.6.1) or NIST SP 800-56A r3 one-step (§5.8.2.1) via a kdf_alg discriminant; both take a single info octet string. Both handlers unmask the ECDH secret in place, verify it is an ECDH shared-secret kind carrying `derive`, run the KDF into scratch, mask the output (AES / fixed- or variable-length HMAC) under the target scope, and scrub the recovered secret and derived scratch on every path. The shared KdfKeyType output-type enum moves to key_props (used by both commands). Single-step KDF primitive (azihsm_crypto): the X9.63 and SP 800-56A concatenation KDFs are implemented once, generically, over the shared Hasher — they need nothing but a hash, so a single platform-agnostic ConcatKdfAlgo serves both the OpenSSL (Linux) and CNG (Windows) backends (unlike HKDF, which is per-backend). Known-answer tests validate both variants against independently computed vectors (SHA-256/384/512, single- and multi-block, absent info). The std PAL x963_kdf / sp800_56a_kdf hooks (previously todo!() stubs) now delegate to it via a new StdKdf::concat_kdf; the Uno PAL already implemented them. Adds HsmError::ConcatKdfError and three CryptoError variants. Wire schemas (fw + host mirror), dispatch / classifier / op.rs wiring (in-session, session-id cross-checked, default-PSK gated) for both opcodes. Emu tests cover every output key type under each KDF (and each X9.63 / SP 800-56A variant), all hashes and scopes, optional salt/info, and rejection of unknown hash / KDF variant / key type, variable-length HMAC without / out-of-range length, and a non-ECDH-secret IKM. Per-command docs added. Based on tbor/ecc-crypto for the ECDH shared-secret input (EcdhDerive); uses opcodes 0x1C / 0x1D after the sibling AES / ECC / RSA / Hash crypto branches (0x15..0x1B). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0b09e50a-a9be-4bae-b347-d42dc775a258
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds two in-session TBOR KDF commands that derive key material from a caller-held masked ECDH shared secret (from
EcdhDerive0x19) and return the derived key masked under the requested scope — the KDF analogues of the ECC crypto commands, re-masking the output instead of vaulting it.0x1CHkdfDerive0x1DConcatKdfDerivekdf_alg), single infoBoth derive AES (128/192/256) or HMAC (fixed SHA-256/384/512, or variable-length) keys.
Design
derive, run through the KDF into scratch, and the output masked under the target scope. The recovered secret and derived scratch are scrubbed on every path.KdfKeyTypeoutput-type enum lives inkey_props(used by both commands).azihsm_crypto: X9.63 and SP 800-56A are Hash-only, so one genericConcatKdfAlgoover the sharedHasherserves both OpenSSL (Linux) and CNG (Windows) — no per-backend code. The std PALx963_kdf/sp800_56a_kdfhooks (previouslytodo!()stubs) now delegate to it viaStdKdf::concat_kdf; the Uno PAL already implemented them.Changes
azihsm_crypto:ConcatKdfAlgo+ConcatKdfMode {X963, Sp800_56a}(crates/crypto/src/kdf/concat.rs), 3CryptoErrorvariants, known-answer tests (kdf/tests/concat_tests.rs).StdKdf::concat_kdf+ wired both PAL methods;HsmError::ConcatKdfError.op.rsfor0x1C/0x1D.hkdf_derive.md,concat_kdf_derive.md, README rows.Testing
azihsm_crypto: 501 lib tests pass (incl. X9.63 / SP 800-56A KATs vs. independently computed vectors).cargo checkfw core (host + Uno no_std) + Uno PAL ✅ · clippy (crypto / std-PAL / fw / host) ✅ · nightly fmt ✅ · copyright ✅.Notes
tbor/ecc-crypto) for the ECDH shared-secret input. Uses opcodes0x1C/0x1Dafter the sibling AES / ECC / RSA / Hash crypto branches (0x15..0x1B).ConcatKdfDeriveis TBOR-only (no MBOR analogue). The concat KDFs' byte-level correctness is proven by theazihsm_cryptoKATs; the emu tests verify command plumbing (the derived key is only observable masked).Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com