Skip to content

feat(tbor): implement HmacGenerateKey + Hmac (masked-key HMAC crypto) - #580

Merged
vsonims merged 1 commit into
mainfrom
tbor/hmac-keygen-mac
Jul 29, 2026
Merged

feat(tbor): implement HmacGenerateKey + Hmac (masked-key HMAC crypto)#580
vsonims merged 1 commit into
mainfrom
tbor/hmac-keygen-mac

Conversation

@vsonims

@vsonims vsonims commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds the TBOR HMAC crypto command pair, stacked on top of the
RSA-AES key-unwrap commands (#583).

Reordered stack: this PR now sits above the key-unwrap PR (#583).
It reuses the shared session/masking helpers and the shared HashAlgo
wire enum introduced by #583, so this layer is purely the HMAC command
surface.

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 (unmask-on-use).

Hmac (opcode 0x12)

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_check classifiers, and
op::SessionCtrl::from_tbor_opcode (InSession, CO/CU).

Tests / validation

  • Emu: keygen round-trip across all hashes/scopes, MAC round-trip,
    tamper-reject, scope/hash rejects.
  • Full TBOR emu suite green (126 tests at this layer); clippy clean;
    nightly fmt + copyright clean; Uno (thumbv7em) build passes.
  • Docs: docs/tbor-ddi/commands/{hmac_generate_key,hmac}.md + README
    rows (0x11, 0x12).

@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from 1690b7f to 8dd3b8d Compare July 18, 2026 20:06
@vsonims
vsonims changed the base branch from tbor/shared-hmac-hash to tbor/unwrap-key July 18, 2026 20:06
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from 8dd3b8d to 435e34c Compare July 18, 2026 20:23
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from 435e34c to 6a7dce2 Compare July 18, 2026 21:40
@vsonims

vsonims commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator Author

Update (rebased on #583): HmacGenerateKey now uses the encoder's reserve + fill support from #583 — the masked-blob length is fixed by the SHA variant, so the handler reserves the response slot up front and masks the generated key straight into it (masked_key_reserve + decode_mut), with no scratch buffer and no copy.

@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from 6a7dce2 to c119302 Compare July 18, 2026 22:01
@vsonims
vsonims force-pushed the tbor/unwrap-key branch 2 times, most recently from b3e53f6 to 427588b Compare July 19, 2026 03:32
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from c119302 to 8b9fe26 Compare July 19, 2026 03:33
Comment thread ddi/tbor/types/src/hmac.rs
Comment thread ddi/tbor/types/src/hmac_generate_key.rs
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from 8b9fe26 to 87e5279 Compare July 20, 2026 19:26
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from 87e5279 to b8fd1d5 Compare July 20, 2026 19:35
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from b8fd1d5 to 5a923c4 Compare July 20, 2026 19:55
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch 4 times, most recently from f899e21 to 5f470ca Compare July 22, 2026 22:13
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from 5f470ca to 3e14f88 Compare July 29, 2026 16:29
@vsonims
vsonims changed the base branch from tbor/unwrap-key to main July 29, 2026 16:30
Copilot AI review requested due to automatic review settings July 29, 2026 16:59
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from 3e14f88 to f37ee8e Compare July 29, 2026 16:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) and 0x12 (Hmac) to dispatcher routing, session classification, and SessionCtrl::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.

Comment thread fw/core/lib/src/ddi/tbor/hmac_generate_key.rs Outdated
Comment thread docs/tbor-ddi/commands/hmac_generate_key.md Outdated
Comment thread docs/tbor-ddi/commands/hmac.md Outdated
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
Copilot AI review requested due to automatic review settings July 29, 2026 18:18
@vsonims
vsonims force-pushed the tbor/hmac-keygen-mac branch from f37ee8e to 8926bc5 Compare July 29, 2026 18:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_key is called after generating the random key. For scopes that are unavailable (e.g., SecurityDomain before CreateSD, or Session on 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)?;

@vsonims
vsonims added this pull request to the merge queue Jul 29, 2026
Merged via the queue into main with commit 9de4a87 Jul 29, 2026
30 checks passed
@jaygmsft
jaygmsft deleted the tbor/hmac-keygen-mac branch August 4, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants