Skip to content

feat(fw): implement GetUnwrappingKey DDI handler#501

Merged
jaygmsft merged 5 commits into
mainfrom
user/jayg/get_unwrap_key
Jul 1, 2026
Merged

feat(fw): implement GetUnwrappingKey DDI handler#501
jaygmsft merged 5 commits into
mainfrom
user/jayg/get_unwrap_key

Conversation

@jaygmsft

Copy link
Copy Markdown
Contributor

Within an open session, return the partition's RSA-2048 unwrapping public key (raw wire n_le || e_le) plus its vault key id, for the host to RSA-AES key-wrap a payload for RsaUnwrap.

  • Lazy RSA-2048 keygen via a new HsmPartitionManager:: part_ensure_unwrapping_key: the std PAL generates on first use (keygen is too slow to run at partition enable); hardware PALs generate in the background from part-init and report PendingKeyGeneration until ready, prompting the host to retry.
  • Derive the public key from the vault-stored private key on demand (no separate pub cached, matching the reference firmware) via a new HsmRsa::rsa_priv_pub_key that converts the PAL's vault representation (raw on hardware, DER in the std/OpenSSL PAL) into wire form; the std driver owns the big-endian->little-endian flip.
  • Serialize the public key straight into the response frame's reserved slot (query/alloc/use) — no intermediate buffer or copy.
  • Centralize the BE<->LE reverse_copy helper in drivers/mod.rs, shared by the ecc and rsa drivers.
  • Fix ras_gen_keypair -> rsa_gen_keypair typo.

masked_key is emitted empty for now (firmware-side masking pending the unmask path). Uno PAL methods are stubbed (PendingKeyGeneration / UnsupportedCmd).

Adds get_unwrapping_key smoke tests (happy path, stable-across-calls, no-session). Full smoke 53/53; std PAL unit 157/157.

Within an open session, return the partition's RSA-2048 unwrapping
public key (raw wire `n_le || e_le`) plus its vault key id, for the
host to RSA-AES key-wrap a payload for RsaUnwrap.

- Lazy RSA-2048 keygen via a new HsmPartitionManager::
  part_ensure_unwrapping_key: the std PAL generates on first use
  (keygen is too slow to run at partition enable); hardware PALs
  generate in the background from part-init and report
  PendingKeyGeneration until ready, prompting the host to retry.
- Derive the public key from the vault-stored private key on demand
  (no separate pub cached, matching the reference firmware) via a new
  HsmRsa::rsa_priv_pub_key that converts the PAL's vault representation
  (raw on hardware, DER in the std/OpenSSL PAL) into wire form; the
  std driver owns the big-endian->little-endian flip.
- Serialize the public key straight into the response frame's reserved
  slot (query/alloc/use) — no intermediate buffer or copy.
- Centralize the BE<->LE reverse_copy helper in drivers/mod.rs, shared
  by the ecc and rsa drivers.
- Fix ras_gen_keypair -> rsa_gen_keypair typo.

masked_key is emitted empty for now (firmware-side masking pending the
unmask path). Uno PAL methods are stubbed (PendingKeyGeneration /
UnsupportedCmd).

Adds get_unwrapping_key smoke tests (happy path, stable-across-calls,
no-session). Full smoke 53/53; std PAL unit 157/157.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 30, 2026 17:45

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

Implements the MBOR GetUnwrappingKey DDI command to return a partition’s RSA-2048 unwrapping public key (wire n_le || e_le) and its vault key id, with PAL support for ensuring/deriving the key and emulator smoke tests.

Changes:

  • Added core MBOR handler + type plumbing for GetUnwrappingKey and wired it into the dispatcher.
  • Added PAL APIs to (a) ensure the partition unwrapping key exists and (b) derive a wire-format public key from a vault-stored private key (std PAL implemented; Uno stubs).
  • Centralized the BE↔LE byte reversal helper and added std RSA public-key wire serialization; added MBOR integration smoke tests.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
fw/plat/uno/fw/pal/src/part.rs Adds Uno stub for part_ensure_unwrapping_key (returns PendingKeyGeneration).
fw/plat/uno/fw/pal/src/crypto/rsa.rs Fixes ras_gen_keypair typo to rsa_gen_keypair; adds Uno stub for rsa_priv_pub_key.
fw/plat/std/pal/src/rsa.rs Implements rsa_priv_pub_key for std PAL by parsing vault DER and emitting wire `n_le
fw/plat/std/pal/src/part.rs Adds std PAL lazy generation + vault persistence for the unwrapping key id.
fw/plat/std/pal/src/drivers/rsa.rs Adds rsa_pub_wire helper to serialize OpenSSL public key components into wire form.
fw/plat/std/pal/src/drivers/mod.rs Centralizes reverse_copy for BE↔LE component conversion shared across drivers.
fw/plat/std/pal/src/drivers/ecc.rs Switches ECC driver to use centralized reverse_copy.
fw/pal/traits/src/part.rs Extends HsmPartitionManager trait with part_ensure_unwrapping_key and docs.
fw/pal/traits/src/crypto/rsa.rs Renames ras_gen_keypairrsa_gen_keypair; adds rsa_priv_pub_key to HsmRsa trait.
fw/core/lib/src/ddi/mbor/mod.rs Registers and dispatches the new GetUnwrappingKey handler.
fw/core/lib/src/ddi/mbor/get_unwrapping_key.rs New MBOR command handler that allocates the response and writes pubkey directly into the reserved frame slot.
fw/core/ddi/mbor/types/src/get_unwrapping_key.rs Marks pub_key as a framed field for correct encoding/layout.
ddi/mbor/types/tests/integration/get_unwrapping_key_smoke.rs Adds integration smoke tests (happy path, stability across calls, and no-session rejection).
ddi/mbor/types/tests/azihsm_ddi_tests.rs Includes the new smoke test module in the test suite.

Comment thread fw/pal/traits/src/part.rs Outdated
Comment thread fw/plat/std/pal/src/part.rs Outdated
Comment thread fw/plat/std/pal/src/drivers/rsa.rs Outdated
Comment thread fw/core/lib/src/ddi/mbor/get_unwrapping_key.rs Outdated
- part_ensure_unwrapping_key (std): close a TOCTOU race across the
  keygen await — re-check unwrapping_key_id while holding the mutable
  entry borrow before creating the vault key, so two concurrent callers
  on one partition can't both insert (leaking one) and return different
  ids. The re-check -> create -> store window is await-free, hence
  atomic on the single-threaded executor.
- rsa_pub_wire (std driver): bound the modulus length against the fixed
  512-byte scratch buffer and error out, so a malformed/oversized vault
  key can never panic across the PAL trust boundary.
- Docs: drop the stale PartPropId::RSA_UNWRAPPING_PUB_KEY reference (no
  such property — the public key is derived on demand, not cached), and
  reword the unwrapping-key caching as the partition's current enabled
  incarnation (clear_enabled_state deletes it on disable/free).
- Smoke test: drop the `key_id != 0` assertion — key_id is an opaque
  handle and the sim/mock backend (which CI runs this suite under)
  legitimately assigns 0; the stability test already covers id
  consistency.

Validation: get_unwrapping_key smoke 3/3 under both mock and emu; full
mock smoke 45/45; std unit 157/157; host + Uno build clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jaygmsft jaygmsft enabled auto-merge June 30, 2026 18:25
Comment thread fw/pal/traits/src/part.rs Outdated
Address PR feedback: follow the existing property model instead of
adding a new PAL trait method for the unwrapping key.

- Remove HsmPartitionManager::part_ensure_unwrapping_key. The handler
  now just reads the partition's RSA_UNWRAPPING_KEY_ID property via
  part_unwrapping_key_id; an absent id (PartPropNotFound) means
  generation is still pending, surfaced as PendingKeyGeneration so the
  host retries. This keeps the core handler PAL-agnostic — real
  hardware generates the key in the background at part-init and only
  ever exposes it through the property.
- std PAL: provision the key lazily behind the property read. A new
  private provision_unwrapping_key runs inside part_prop_get_u16 for
  RSA_UNWRAPPING_KEY_ID, generating the RSA-2048 key synchronously on
  first read so only a GetUnwrappingKey request pays the keygen cost
  (never partition enable — avoids a ~19x smoke-test slowdown). The
  routine is await-free, so on the single-threaded executor it runs
  atomically: concurrent reads cannot race to generate two keys (first
  write wins, the rest reuse it).
- Uno PAL: drop the part_ensure_unwrapping_key stub; its getter stays
  uniform with every other key-id property (PartPropNotFound when
  unset), which the handler maps to PendingKeyGeneration.

Validation: get_unwrapping_key smoke 3/3 under both mock and emu; std
unit 157/157; host + Uno build clean; fmt/copyright clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 30, 2026 23:34
@jaygmsft jaygmsft requested a review from vsonims June 30, 2026 23:36

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 12 out of 12 changed files in this pull request and generated 4 comments.

Comment thread fw/core/lib/src/ddi/mbor/get_unwrapping_key.rs
Comment thread fw/plat/std/pal/src/drivers/rsa.rs
Comment thread fw/plat/std/pal/src/part.rs Outdated
Comment thread fw/pal/traits/src/crypto/rsa.rs Outdated
vsonims
vsonims previously approved these changes Jul 1, 2026
Co-authored-by: jaygmsft <22506014+jaygmsft@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 22:27

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 12 out of 12 changed files in this pull request and generated 2 comments.

Comment thread fw/core/lib/src/ddi/mbor/get_unwrapping_key.rs
Comment thread ddi/mbor/types/tests/integration/get_unwrapping_key_smoke.rs
@jaygmsft jaygmsft disabled auto-merge July 1, 2026 22:39
@jaygmsft jaygmsft enabled auto-merge July 1, 2026 22:51
@jaygmsft jaygmsft added this pull request to the merge queue Jul 1, 2026
Merged via the queue into main with commit 9533fe3 Jul 1, 2026
23 checks passed
@jaygmsft jaygmsft deleted the user/jayg/get_unwrap_key branch July 1, 2026 23:56
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.

4 participants