Skip to content

feat(pal/std): enforce session-scoped key isolation at vault access#591

Merged
jaygmsft merged 1 commit into
mainfrom
user/jayg/session-key-isolation
Jul 20, 2026
Merged

feat(pal/std): enforce session-scoped key isolation at vault access#591
jaygmsft merged 1 commit into
mainfrom
user/jayg/session-key-isolation

Conversation

@jaygmsft

Copy link
Copy Markdown
Contributor

A key created with Session availability was resolvable — and thus usable and deletable — from any other session on the same partition, because the std PAL vault resolved key ids without checking the session binding. Only the mock enforced this. This closes that gap so the std PAL / emulator matches the reference firmware behaviour.

Enforcement is added at the vault access chokepoint: a new assert_key_session_access gates vault_key, vault_key_kind, and vault_key_attrs. Session-bound keys are only visible from the session that created them (mapped via the SQE session id → physical session id); from any other session they report KeyNotFound. Partition-scoped App/persistent keys carry no binding and stay accessible everywhere, including internal firmware IOs whose SQE has no session. Because DeleteKey resolves attrs through the guarded path, delete inherits the same isolation.

Adds a cross_session_key_access_smoke suite (9 smoke tests) covering the App-vs-Session semantics across three handler paths — use (vault_key), masked-blob re-import (UnmaskKey), and delete — over AES and ECC keys, plus RSA-unwrapped keys:

  • App key usable / unmaskable / deletable from another session
  • Session key not usable / not unmaskable / not deletable elsewhere
  • ECC App key signable cross-session; Session key only in its session
  • Session-key blob never re-importable (MK_SESSION is fresh-random per session, not seed-derived), same or different session seed

The uno PAL vault is a separate crate and does not yet enforce this; tracked as a follow-up for the hardware bring-up.

Test: emu azihsm_ddi_mbor_types full 597/597 passed; emu smoke gate 94/94 passed; mock cross-session suite 9/9 passed.

Copilot-Session: 82c8bd53-6639-46fc-8a79-a7539921e4c1

Copilot AI review requested due to automatic review settings July 20, 2026 21:30

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 tightens session-scoped key isolation in the std PAL by enforcing session bindings at the vault access chokepoint, making the emulator/std PAL behavior match the reference firmware and the mock backend for session-availability keys.

Changes:

  • Added session-binding enforcement in StdHsmPal vault lookups so Session-availability keys are only visible within their creating session.
  • Exposed the stored per-key session binding from the std PAL KeyVault driver to support the new enforcement check.
  • Added a new cross-session smoke test suite covering use-by-id, unmask/re-import, and delete semantics for App vs Session keys.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
fw/plat/std/pal/src/vault.rs Adds assert_key_session_access and gates vault read/metadata access based on SQE session → physical session key mapping.
fw/plat/std/pal/src/drivers/vault.rs Adds key_session_binding accessor to expose per-key session binding (session_key_id).
fw/plat/std/pal/Cargo.toml Adds azihsm_fw_hsm_io dependency to interpret SQE session flags/IDs (Sqe).
ddi/mbor/types/tests/integration/cross_session_key_access_smoke.rs Introduces new integration smoke tests validating App vs Session access across sessions for AES/ECC/RSA-unwrapped keys.
ddi/mbor/types/tests/azihsm_ddi_tests.rs Registers the new cross-session smoke test module.

Comment thread fw/plat/std/pal/src/vault.rs Outdated
Comment thread ddi/mbor/types/tests/integration/cross_session_key_access_smoke.rs Outdated
Comment thread ddi/mbor/types/tests/integration/cross_session_key_access_smoke.rs Outdated
Copilot AI review requested due to automatic review settings July 20, 2026 21:38
@jaygmsft
jaygmsft force-pushed the user/jayg/session-key-isolation branch from eec13d2 to 1698dc8 Compare July 20, 2026 21:38

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

Comments suppressed due to low confidence (1)

ddi/mbor/types/tests/integration/cross_session_key_access_smoke.rs:372

  • ecc_sign_with builds a 20-byte digest but passes DdiHashAlgorithm::Sha256. The EccSign handler requires at least the hash algorithm’s native digest length (32 bytes for SHA-256), so this will be rejected with InvalidArg (or could start failing if encoding changes). Use a 32-byte digest (matching other ECC sign tests) to ensure the test is validating session isolation rather than digest-length validation.
        MborByteArray::new([1u8; 96], 20).expect("digest byte array"),

A key created with `Session` availability was resolvable — and thus
usable and deletable — from any other session on the same partition,
because the std PAL vault resolved key ids without checking the session
binding. Only the mock enforced this. This closes that gap so the std
PAL / emulator matches the reference firmware behaviour.

Enforcement is added at the vault access chokepoint: a new
`assert_key_session_access` gates `vault_key`, `vault_key_kind`, and
`vault_key_attrs`. Session-bound keys are only visible from the session
that created them (mapped via the SQE session id → physical session id);
from any other session they report `KeyNotFound`. Partition-scoped
`App`/persistent keys carry no binding and stay accessible everywhere,
including internal firmware IOs whose SQE has no session. Because
DeleteKey resolves attrs through the guarded path, delete inherits the
same isolation.

Adds a `cross_session_key_access_smoke` suite (9 smoke tests) covering
the App-vs-Session semantics across three handler paths — use
(`vault_key`), masked-blob re-import (`UnmaskKey`), and delete — over
AES and ECC keys, plus RSA-unwrapped keys:
- App key usable / unmaskable / deletable from another session
- Session key not usable / not unmaskable / not deletable elsewhere
- ECC App key signable cross-session; Session key only in its session
- Session-key blob never re-importable (MK_SESSION is fresh-random per
  session, not seed-derived), same or different session seed

The uno PAL vault is a separate crate and does not yet enforce this;
tracked as a follow-up for the hardware bring-up.

Test: emu azihsm_ddi_mbor_types full 597/597 passed; emu smoke gate
94/94 passed; mock cross-session suite 9/9 passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 82c8bd53-6639-46fc-8a79-a7539921e4c1
Copilot AI review requested due to automatic review settings July 20, 2026 22:14
@jaygmsft
jaygmsft force-pushed the user/jayg/session-key-isolation branch from 1698dc8 to 884c0f3 Compare July 20, 2026 22:14

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

Comment thread ddi/mbor/types/tests/integration/cross_session_key_access_smoke.rs
Comment thread ddi/mbor/types/tests/integration/cross_session_key_access_smoke.rs
Comment thread ddi/mbor/types/tests/integration/cross_session_key_access_smoke.rs
Comment thread ddi/mbor/types/tests/integration/cross_session_key_access_smoke.rs
@jaygmsft
jaygmsft enabled auto-merge July 20, 2026 22:19
@jaygmsft
jaygmsft added this pull request to the merge queue Jul 20, 2026
Merged via the queue into main with commit 8f37b88 Jul 20, 2026
30 checks passed
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