feat(tbor): implement HmacGenerateKey + Hmac (masked-key HMAC crypto) - #580
Conversation
1690b7f to
8dd3b8d
Compare
8dd3b8d to
435e34c
Compare
435e34c to
6a7dce2
Compare
|
Update (rebased on #583): HmacGenerateKey now uses the encoder's |
6a7dce2 to
c119302
Compare
b3e53f6 to
427588b
Compare
c119302 to
8b9fe26
Compare
8b9fe26 to
87e5279
Compare
87e5279 to
b8fd1d5
Compare
b8fd1d5 to
5a923c4
Compare
f899e21 to
5f470ca
Compare
5f470ca to
3e14f88
Compare
3e14f88 to
f37ee8e
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds two new TBOR crypto commands to the firmware + host stack: HmacGenerateKey (generate a caller-held masked HMAC key) and Hmac (unmask-on-use to compute an HMAC tag), building on the masked-key infrastructure and shared HashAlgo enum introduced by the RSA-AES unwrap layer.
Changes:
- Add new TBOR opcodes
0x11(HmacGenerateKey) and0x12(Hmac) to dispatcher routing, session classification, andSessionCtrl::from_tbor_opcode. - Implement firmware handlers to generate/mask variable-length HMAC keys and to unmask+MAC a host-provided message.
- Add wire schemas, host-side wrappers, emulator integration tests, and command documentation for both opcodes.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| fw/core/lib/src/op.rs | Marks HMAC_GENERATE_KEY/HMAC as InSession in SessionCtrl::from_tbor_opcode. |
| fw/core/lib/src/ddi/tbor/mod.rs | Adds modules, opcode constants, dispatcher routing, and opcode classifiers for 0x11/0x12. |
| fw/core/lib/src/ddi/tbor/hmac.rs | New firmware handler for Hmac (unmask-on-use and compute tag). |
| fw/core/lib/src/ddi/tbor/hmac_generate_key.rs | New firmware handler for HmacGenerateKey (generate key and mask into response). |
| fw/core/ddi/tbor/types/src/lib.rs | Exposes new firmware-side TBOR type modules/exports. |
| fw/core/ddi/tbor/types/src/hmac.rs | New firmware-side TBOR wire schema for Hmac. |
| fw/core/ddi/tbor/types/src/hmac_generate_key.rs | New firmware-side TBOR wire schema for HmacGenerateKey. |
| docs/tbor-ddi/README.md | Adds command table entries for 0x11/0x12. |
| docs/tbor-ddi/commands/hmac.md | New command documentation for Hmac. |
| docs/tbor-ddi/commands/hmac_generate_key.md | New command documentation for HmacGenerateKey. |
| ddi/tbor/types/tests/commands/mod.rs | Registers new emu integration test modules. |
| ddi/tbor/types/tests/commands/hmac.rs | New emu integration tests for MAC operation and unwrap→MAC integration. |
| ddi/tbor/types/tests/commands/hmac_generate_key.rs | New emu integration tests for keygen across hashes/scopes/lengths and failure cases. |
| ddi/tbor/types/src/lib.rs | Exposes new host-side TBOR wrapper modules/exports. |
| ddi/tbor/types/src/hmac.rs | New host-side wrapper types for Hmac. |
| ddi/tbor/types/src/hmac_generate_key.rs | New host-side wrapper types/constants for HmacGenerateKey. |
Add the TBOR HMAC crypto command pair, stacked on the RSA-AES key-unwrap commands. HmacGenerateKey (opcode 0x11): generate a fresh random HMAC key of the caller-selected SHA variant (SHA-256/384/512 -> 32/48/64 B) and return it masked (AEAD-GCM-256) under the requested scope's masking key. The key is not stored on-device; the caller holds the masked blob. The masked-blob length is fixed by the key length, so the handler reserves the response slot up front and masks the generated key straight into it (the encoder's `*_reserve` + `decode_mut` "reserve + fill") — no scratch buffer and no copy. Hmac (opcode 0x12): compute an HMAC tag over a host-supplied message using a caller-held masked HMAC key. The key is `#[tbor(mutable)]`, so the handler `decode_mut`s the request and `unmask`s the blob **in place** in the request buffer, then MACs directly from the recovered `target_key` (a `&DmaBuf` into that buffer) — no scratch copy of the blob or the key. The recovered key is wiped on every path. Both commands reuse the shared session/masking helpers (`validate_active_session`, `resolve_masking_key`) and the shared `HashAlgo` wire enum introduced with the key-unwrap commands below them in the stack; `HmacGenerateKey` selects its SHA variant via `HashAlgo` from the shared `key_props` module. Wires both opcodes through the fw dispatcher, the `is_known_opcode` / `is_in_session` / `needs_session_id_cross_check` classifiers, and `op::SessionCtrl::from_tbor_opcode`. Adds fw + host wire schemas, command docs, and emu tests: keygen round-trip across all hashes/scopes, MAC round-trip, tamper-reject, scope/hash rejects, plus a cross-command `UnwrapKey` -> `Hmac` round-trip that imports an HMAC key via RSA-AES unwrap and MACs with the recovered key. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0b09e50a-a9be-4bae-b347-d42dc775a258
f37ee8e to
8926bc5
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
fw/core/lib/src/ddi/tbor/hmac_generate_key.rs:167
resolve_masking_keyis called after generating the random key. For scopes that are unavailable (e.g.,SecurityDomainbeforeCreateSD, orSessionon PALs that don't support per-session masking), this still consumes RNG / creates key material before failing. Since the module docs state unavailable scopes should fail before any key is generated, resolve the masking key first and only then allocate/generate the key.
// Generate the random HMAC key into scratch.
let key_buf = alloc.dma_alloc(key_len)?;
pal.hmac_gen_key(io, algo, key_buf).await?;
let masking_key = resolve_masking_key(pal, io, scope, sess_id)?;
Summary
Adds the TBOR HMAC crypto command pair, stacked on top of the
RSA-AES key-unwrap commands (#583).
HmacGenerateKey(opcode0x11)Generate a fresh random HMAC key of the caller-selected SHA variant
(SHA-256/384/512 → 32/48/64 B) and return it masked (AEAD-GCM-256)
under the requested scope's masking key. The key is not stored
on-device; the caller holds the masked blob (unmask-on-use).
Hmac(opcode0x12)Compute an HMAC tag over a host-supplied message using a caller-held
masked HMAC key, unmasked on-device for the operation and then
discarded.
Wiring
Both opcodes are routed through the fw dispatcher, the
is_known_opcode/
is_in_session/needs_session_id_cross_checkclassifiers, andop::SessionCtrl::from_tbor_opcode(InSession, CO/CU).Tests / validation
tamper-reject, scope/hash rejects.
clippyclean;nightly
fmt+copyrightclean; Uno (thumbv7em) build passes.docs/tbor-ddi/commands/{hmac_generate_key,hmac}.md+ READMErows (
0x11,0x12).