Skip to content

Return INV_CRB_CTRL_DATA for empty CRB control data on Start#79

Merged
dymk merged 1 commit into
OpenDevicePartnership:mainfrom
dymk:dymk/tpm-spec-inv-crb-ctrl-data
Jun 12, 2026
Merged

Return INV_CRB_CTRL_DATA for empty CRB control data on Start#79
dymk merged 1 commit into
OpenDevicePartnership:mainfrom
dymk:dymk/tpm-spec-inv-crb-ctrl-data

Conversation

@dymk

@dymk dymk commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Per ARM DEN0138 TPM Service CRB Interface Over FF-A, the Start function's response codes have these semantics:

CRB_FFA_DENIED: the TPM has previously DISABLED locality requests and command processing at the given locality
CRB_FFA_INV_CRB_CTRL_DATA: CRB control data or locality control data at the given TPM locality is not valid

The SP currently returns DENIED for two scenarios that don't fit the spec's DENIED semantics:

  1. handle_command() falls through to a default Denied whenever no state-transition bit is set in the CRB control_request / control_start registers (e.g., the host issues Start(COMMAND) before writing cmdReady).
  2. handle_locality_request() returns Denied when neither the RELINQUISH nor REQUEST_ACCESS bit is set in locality_control.

Both cases are "host issued Start with empty CRB control data" — which per DEN0138 is INV_CRB_CTRL_DATA, not DENIED. The semantic distinction is corroborated by two independent authoritative consumers of DEN0138:

  • Linux kernel (drivers/char/tpm/tpm_crb_ffa.c): the CRB_FFA_START docstring lists the same four status codes with the same semantics.
  • TianoCore EDK2 (SecurityPkg/Library/Tpm2DeviceLibFfa/Tpm2ServiceFfaRaw.c::TranslateTpmReturnStatus): maps INV_CRB_CTRL_DATAEFI_COMPROMISED_DATA and DENIEDEFI_ACCESS_DENIED, confirming the distinction between "malformed CRB" and "access disabled."

Diff

Two minimal edits to ec-service-lib/src/services/tpm.rs:

// handle_command(): early-return InvCrbCtrlData when both
// crb_control_request and crb_control_start are zero (no operation requested).
if crb.crb_control_request == 0 && crb.crb_control_start == 0 {
    error!("CRB has no operation requested");
    return TpmStatus::InvCrbCtrlData;
}

// handle_locality_request(): change the "no bits set" branch
// from `Denied` to `InvCrbCtrlData`.

Other paths (locality mismatch, closed locality, invalid arguments, source-id check) are left as-is — their existing return codes are spec-conformant. SP unit tests are unaffected (none exercise the "no bits set" paths).

Surfaced from / verified by

Systematic debugging of odp-platform-qemu-sbsa's Phase 2 e2e tests (tpm_start_command_locality_mismatch, tpm_start_command_idle_no_bits, tpm_start_locality_no_crb_bits). Companion test-side change for the qemu-sbsa harness is being prepared as a super-PR that bundles 4 related fixes (TPM device wiring, CI gate, uart-logger retarget, TPM test alignment) — it bumps the submodule to this commit.

Verified locally inside the qemu-sbsa devcontainer: with this SP fix + the qemu-sbsa side fixes stacked, make e2e-test QEMU_TIMEOUT=900 reports RESULT: ALL TESTS PASSED (27/27).

Copilot AI review requested due to automatic review settings June 12, 2026 17:27
@dymk dymk requested a review from a team as a code owner June 12, 2026 17:27

Copilot AI left a comment

Copy link
Copy Markdown

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 aligns the TPM Service CRB-over-FF-A Start status codes with ARM DEN0138 semantics by returning INV_CRB_CTRL_DATA (instead of DENIED) when the host issues Start with empty/invalid CRB control data.

Changes:

  • In handle_command(), return InvCrbCtrlData when both crb_control_request and crb_control_start are zero (no operation requested).
  • In handle_locality_request(), return InvCrbCtrlData when neither RELINQUISH nor REQUEST_ACCESS is set in locality_control.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

kurtjd
kurtjd previously approved these changes Jun 12, 2026
Comment thread ec-service-lib/src/services/tpm.rs Outdated
Comment thread ec-service-lib/src/services/tpm.rs Outdated
Raymond-MS
Raymond-MS previously approved these changes Jun 12, 2026

@Raymond-MS Raymond-MS left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Good catch! Just some minor comments.

Per ARM DEN0138 'TPM Service CRB Interface Over FF-A':
  CRB_FFA_DENIED:           the TPM has previously DISABLED locality
                             requests and command processing at the
                             given locality
  CRB_FFA_INV_CRB_CTRL_DATA: CRB control data or locality control
                             data at the given TPM locality is not valid

The SP currently returns DENIED for two scenarios that don't match
the DENIED semantics:

  1. handle_command() falls through to a default 'Denied' status
     whenever no state-transition bit is set in the CRB control_request
     / control_start registers (e.g., the host issues Start(COMMAND)
     before writing cmdReady).

  2. handle_locality_request() returns 'Denied' when neither the
     RELINQUISH nor REQUEST_ACCESS bit is set in locality_control.

Both are 'host gave us a Start with empty CRB control data', which
per DEN0138 is INV_CRB_CTRL_DATA, not DENIED. The TianoCore EDK2
client maps INV_CRB_CTRL_DATA to EFI_COMPROMISED_DATA and DENIED to
EFI_ACCESS_DENIED — confirming the spec's semantic distinction
between 'malformed CRB' and 'access disabled'.

Fix is two minimal edits to ec-service-lib/src/services/tpm.rs:

  - handle_command(): early-return InvCrbCtrlData when both
    crb_control_request and crb_control_start are zero.
  - handle_locality_request(): change the 'no bits set' branch
    return from Denied to InvCrbCtrlData.

Other paths (locality mismatch, closed locality, invalid arguments)
are left as-is — their existing return codes are spec-conformant.

Surfaced from systematic debugging of qemu-sbsa Phase 2 e2e tests
(tpm_start_command_locality_mismatch, tpm_start_command_idle_no_bits,
tpm_start_locality_no_crb_bits). The qemu-sbsa test expectations
are updated in a companion commit.

References:
  - Linux kernel driver: drivers/char/tpm/tpm_crb_ffa.c (CRB_FFA_START documented function status codes)
  - TianoCore EDK2: SecurityPkg/Library/Tpm2DeviceLibFfa/Tpm2ServiceFfaRaw.c::TranslateTpmReturnStatus

Assisted-by: GitHub Copilot:claude-opus-4.7-1m-internal
@dymk dymk dismissed stale reviews from Raymond-MS and kurtjd via 6d164c9 June 12, 2026 19:42
@dymk dymk force-pushed the dymk/tpm-spec-inv-crb-ctrl-data branch from 5fd3231 to 6d164c9 Compare June 12, 2026 19:42
@dymk dymk enabled auto-merge (squash) June 12, 2026 20:00
@dymk dymk merged commit 29af461 into OpenDevicePartnership:main Jun 12, 2026
10 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.

4 participants