Skip to content

Add TPM2_PolicyTransportSPDM support for client and firmware TPM - #594

Open
aidangarske wants to merge 19 commits into
wolfSSL:masterfrom
aidangarske:spdm-policy-transport
Open

Add TPM2_PolicyTransportSPDM support for client and firmware TPM#594
aidangarske wants to merge 19 commits into
wolfSSL:masterfrom
aidangarske:spdm-policy-transport

Conversation

@aidangarske

Copy link
Copy Markdown
Member
  • Adds TPM2_PolicyTransportSPDM (CC 0x1A1) and TPM_CAP_SPDM_SESSION_INFO to the
    client command layer and the firmware TPM, per TPM 2.0 Library v1.84.
  • Binds a policy session to require the command arrive over an active SPDM
    session, optionally scoped to a requester and/or TPM identity key name folded
    into the policy digest.
  • Enforcement returns TPM_RC_CHANNEL outside SPDM and TPM_RC_CHANNEL_KEY on a
    bound-key mismatch.
  • Adds wolfTPM2_PolicyTransportSPDM, wolfTPM2_PolicyTransportSPDMMake (offline
    authPolicy), and wolfTPM2_GetCapability_SPDMSessionInfo, all under WOLFTPM_SPDM.
  • Only asymmetric SPDM sessions expose key names; vendor PSK sessions satisfy the
    secure-channel assertion but report empty names, since no asymmetric key
    authenticated them.
  • Rejects cross-exchange SPDM finish messages and identity-key rotation on an
    active session so a session cannot be relabeled as identity-key authenticated.
  • Fails closed on a truncated capability response and on hash errors while
    computing the policy key-name digest.
  • Adds an nv_bind example plus fwTPM unit and end-to-end coverage, including a
    tpmKeyName-bound policy that succeeds over its session and is rejected on a
    name mismatch.
  • fwtpm_unit, unit tests, spdm_test.sh tcg 15/15 and psk 27/27, guard
    sweep (no-policy, Nuvoton-only, NO_GETENV, fuzz+spdm), and a non-SPDM build.

@aidangarske aidangarske self-assigned this Sep 8, 2026
Copilot AI lite review requested due to automatic review settings September 8, 2026 02:23
@aidangarske
aidangarske marked this pull request as ready for review September 8, 2026 02:25

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.

🟡 Changes recommended

The new TPM_CAP_SPDM_SESSION_INFO parsing in src/tpm2.c can treat truncated responses as successful empty fields due to missing packet.overflow handling, undermining the intended fail-closed behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds TPM 2.0 Library v1.84 SPDM-aware policy and capability support to wolfTPM, including client-side wrappers, firmware TPM (fwTPM) enforcement, and examples/tests under WOLFTPM_SPDM. The main goal is to allow policies to require that authorizing commands arrive over an active SPDM secure session, optionally bound to SPDM key names.

Changes:

  • Add TPM2_PolicyTransportSPDM (CC 0x01A1), new return codes (TPM_RC_CHANNEL, TPM_RC_CHANNEL_KEY), and TPM_CAP_SPDM_SESSION_INFO capability structures/constants.
  • Implement SPDM session-info capability parsing and wrapper APIs (wolfTPM2_GetCapability_SPDMSessionInfo, wolfTPM2_PolicyTransportSPDM, offline wolfTPM2_PolicyTransportSPDMMake).
  • Extend fwTPM to compute/record the SPDM policy term and enforce it at authorization time; add responder-side session identity tracking and new example/tests.
File summaries
File Description
wolftpm/tpm2.h Adds SPDM command/capability constants, return codes, and capability data types for SPDM session info.
wolftpm/tpm2_wrap.h Declares new wrapper APIs for SPDM session-info capability and PolicyTransportSPDM (plus offline digest helper).
wolftpm/spdm/spdm_responder.h Documents new responder-side constraints and adds APIs to query session state/identity key.
wolftpm/fwtpm/fwtpm.h Extends fwTPM session/context state for tracking SPDM secure-channel policy enforcement.
src/tpm2.c Adds TPM_CAP_SPDM_SESSION_INFO parsing and client-side TPM2_PolicyTransportSPDM command marshaling.
src/tpm2_wrap.c Implements wrapper calls for session-info capability, PolicyTransportSPDM, and offline policy digest construction.
src/spdm/spdm_responder.c Tracks whether a connected session is asymmetric vs PSK and prevents finish/exchange mixing and mid-session key rotation.
src/fwtpm/include.am Ensures responder objects are linked into fwtpm_server and sets build flags for availability.
src/fwtpm/fwtpm_main.c Marks TPM commands as arriving over SPDM when dispatched from the SPDM secured-message path.
src/fwtpm/fwtpm_command.c Implements PolicyTransportSPDM, SPDM session-info capability, and enforcement of secure-channel/key-name bindings.
tests/unit_tests.c Adds wrapper/offline helper tests and a live SPDM path test to confirm policy digest behavior.
tests/fwtpm_unit_tests.c Adds fwTPM unit tests for PolicyTransportSPDM digest behavior, enforcement, and SPDM session-info capability behavior.
examples/spdm/spdm_test.sh Extends SPDM test script to cover session-info and PolicyTransportSPDM NV binding scenarios.
examples/spdm/spdm_ctrl.c Adds --session-info and --policy-nv flows demonstrating capability query and NV binding under SPDM.
examples/spdm/README.md Updates documentation and adds nv_bind usage guidance.
examples/spdm/nv_bind.c New focused example showing NV binding to SPDM (PolicyTransportSPDM) and denial off-channel.
examples/spdm/include.am Builds and distributes the new nv_bind example.
Review details
  • Files reviewed: 17/17 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/tpm2.c
Comment on lines +1246 to +1265
/* Parse a TPM2B_NAME from a capability response, consuming the full wire
* length even when the name exceeds the local buffer, so the remaining
* fields stay aligned. */
static int TPM2_ParseSpdmName(TPM2_Packet* packet, TPM2B_NAME* name)
{
UINT16 wireSz = 0;
int avail;

TPM2_Packet_ParseU16(packet, &wireSz);
avail = packet->size - packet->pos;
/* A declared length past the packet or larger than the Name buffer is a
* malformed capability response; fail rather than return a partial Name. */
if (avail < 0 || (int)wireSz > avail ||
(int)wireSz > (int)sizeof(name->name)) {
return TPM_RC_SIZE;
}
name->size = wireSz;
TPM2_Packet_ParseBytes(packet, name->name, (int)wireSz);
return TPM_RC_SUCCESS;
}
Comment thread src/tpm2.c
Comment on lines +1460 to +1464
TPML_SPDM_SESSION_INFO* sessInfo =
&out->capabilityData.data.spdmSessionInfo;
TPM2_Packet_ParseU32(&packet, &sessInfo->count);
if (sessInfo->count > MAX_SPDM_SESS_INFO)
sessInfo->count = MAX_SPDM_SESS_INFO;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants