Skip to content

refactor(fw): make TBOR CU/CO session masking key 32 B AES-256-GCM - #578

Closed
vsonims wants to merge 1 commit into
mainfrom
tbor/session-mk-32
Closed

refactor(fw): make TBOR CU/CO session masking key 32 B AES-256-GCM#578
vsonims wants to merge 1 commit into
mainfrom
tbor/session-mk-32

Conversation

@vsonims

@vsonims vsonims commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Foundational fw-only change for the upcoming TBOR HMAC / crypto masked-key command family.

The TBOR SessionEx (CU/CO) per-session masking_key was an 80 B aes32 ‖ hmac48 key shaped for the legacy key_masking::cbc MBOR masked-key system. TBOR masked keys are wrapped with key_masking::aead (AES-256-GCM), which needs only a 32 B key — so the extra 48 B were dead weight and blurred the key's purpose.

This reshapes the SessionEx masking key to a native 32 B AES-256-GCM key.

Changes

  • SESSION_MASKING_KEY_LEN 80 → 32 (CU/CO only). The legacy MBOR Session blob keeps its 80 B cbc key via the std/uno-PAL-local SESSION_MASKING_KEY_SIZE, so MBOR's cbc masked-key system is unaffected.
  • std + uno PAL: CU/CO blob shrinks (CU 120→72 B, CO 216→168 B). The std session_masking_key reader now sizes the returned key by blob kind — 32 B for SessionEx blobs, 80 B for the legacy Session blob — so MBOR still reads its full 80 B key. session_promote validation follows the const.
  • session_open_finish: derives the 32 B key (auto via the const); bmk_session is variable-length (BMK_SESSION_MAX_LEN), so the shorter payload needs no schema change.

Why safe

The CU/CO masking key is consumed by nothing today — session_masking_key is only read by MBOR's masked-key handlers, and only from legacy Session blobs. The host never derives this key (fw-only).

Validation

  • TBOR emu 108/108 — CU + CO sessions, session_close, reopen, SD roundtrips.
  • MBOR emu 225/225masked_key, unmask_key, aes_gen, rsa_unwrap, live_migration/reopen (legacy 80 B path intact).
  • std + uno cargo check + clippy clean; nightly fmt clean.

The TBOR SessionEx (CU/CO) per-session `masking_key` was carried as an 80 B
`aes32 ‖ hmac48` key shaped for the legacy `key_masking::cbc` MBOR masked-key
system, even though TBOR masked keys are (and will be) wrapped with
`key_masking::aead` (AES-256-GCM), which needs only a 32 B key. The extra
48 B were dead weight in every CU/CO session blob and blurred the key's
purpose.

Reshape the SessionEx masking key to a native 32 B AES-256-GCM key:

* `SESSION_MASKING_KEY_LEN` 80 → 32 (CU/CO only). The legacy MBOR `Session`
  blob keeps its 80 B cbc key via the std/uno-PAL-local
  `SESSION_MASKING_KEY_SIZE`, so MBOR's cbc masked-key system is unaffected.
* std + uno PAL: CU/CO blob shrinks (CU 120→72 B, CO 216→168 B); the std
  `session_masking_key` reader now sizes the returned key by blob kind —
  32 B for SessionEx blobs, 80 B for the legacy Session blob — so MBOR still
  reads its full 80 B key. `session_promote` validation follows the const.
* `session_open_finish` derives the 32 B key (auto via the const); the
  `bmk_session` envelope is variable-length (`BMK_SESSION_MAX_LEN`), so the
  shorter payload needs no schema change.

Foundational for the upcoming TBOR HMAC/crypto masked-key commands, which
resolve a scope's 32 B AEAD masking key uniformly (Session → this key).

Validation: TBOR emu 108/108 (CU + CO sessions, close, reopen, SD
roundtrips); MBOR emu 225/225 (masked_key, unmask_key, aes_gen,
live-migration/reopen — legacy 80 B path intact); std + uno fmt + clippy clean.

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 18, 2026 17:58

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

Refactors the firmware’s TBOR SessionEx (CU/CO) per-session masking_key to be a native 32-byte AES-256-GCM key (for key_masking::aead) instead of the legacy 80-byte aes32 ‖ hmac48 shape used by MBOR’s CBC+HMAC masking system, reducing SessionEx blob sizes accordingly while keeping the legacy MBOR Session blob format intact.

Changes:

  • Shrinks SESSION_MASKING_KEY_LEN from 80 → 32 bytes (explicitly for TBOR SessionEx sessions).
  • Updates Std + Uno PAL SessionEx blob sizing/validation to use the new 32-byte masking key length (CU 72 B, CO 168 B).
  • Updates TBOR session_open_finish documentation/comments to describe the masking key as AES-256-GCM (32 B).

Reviewed changes

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

File Description
fw/plat/uno/fw/pal/src/session.rs Adjusts Uno PAL SessionEx blob layout and argument validation to use the 32-byte SessionEx masking key.
fw/plat/std/pal/src/session.rs Adjusts Std PAL SessionEx blob sizing and makes session_masking_key return a length based on blob kind (legacy Session vs SessionEx).
fw/pal/traits/src/lib.rs Redefines SESSION_MASKING_KEY_LEN to 32 bytes and clarifies it is for TBOR SessionEx sessions.
fw/core/lib/src/ddi/tbor/session_open_finish.rs Updates handler documentation to match the new 32-byte AES-256-GCM masking key intent for TBOR.

Comment on lines 266 to 270
// Build the length-discriminated SessionEx blob:
// PlainText: api_rev(8) ‖ param_key(32) ‖ masking_key(80) = 120 B
// Authenticated: above ‖ mac_tx(48) ‖ mac_rx(48) = 216 B
// PlainText: api_rev(8) ‖ param_key(32) ‖ masking_key(32) = 72 B
// Authenticated: above ‖ mac_tx(48) ‖ mac_rx(48) = 168 B
let blob_len = match mac_pair {
None => SESSION_CU_BLOB_SIZE,
Comment thread fw/pal/traits/src/lib.rs
Comment on lines +432 to +437
/// Length in bytes of the per-session `masking_key` for TBOR
/// **SessionEx (CU/CO)** sessions.
///
/// 80 B = AES-CBC-256 key (32 B) ‖ HMAC-SHA-384 key (48 B). Consumed
/// by the `key_masking::cbc`-based MBOR masked-key system; unrelated to
/// [`SESSION_PARAM_KEY_LEN`] which now refers to the AEAD-GCM
/// per-session wrap key. Present for both CO and CU sessions.
pub const SESSION_MASKING_KEY_LEN: usize = 80;
/// 32 B AES-256-GCM key used by the `key_masking::aead`-based TBOR
/// masked-key system (masked keys are scoped and wrapped under AES-GCM).
/// Present for both CO and CU SessionEx blobs. Distinct from the legacy
@vsonims

vsonims commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator Author

Folded into #583, which is now based on main and bundles this session-masking-key reshape with the hmac_hash move and the RSA-AES key-unwrap commands. Closing to collapse the stack into a single PR. The branch tbor/session-mk-32 is retained as an ancestor of tbor/unwrap-key.

@vsonims vsonims closed this Jul 18, 2026
@vsonims
vsonims deleted the tbor/session-mk-32 branch July 18, 2026 20:16
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.

2 participants