Skip to content

Build SPDM from the wolfSPDM submodule - #617

Open
aidangarske wants to merge 4 commits into
wolfSSL:masterfrom
aidangarske:spdm-use-wolfspdm
Open

aidangarske wants to merge 4 commits into
wolfSSL:masterfrom
aidangarske:spdm-use-wolfspdm

Conversation

@aidangarske

Copy link
Copy Markdown
Member

Summary

wolfTPM's SPDM code (src/spdm/*.c, spdm_internal.h) now lives in the wolfSPDM library, and this PR consumes it as the lib/wolfSPDM git submodule. This removes the duplicated SPDM stack, so SPDM fixes land once in wolfSPDM and both projects pick them up.

--enable-spdm still compiles the SPDM sources into libwolftpm. wolfSPDM builds in its TPM profile, forced by WOLFTPM_SPDM, which compiles out:

  • the standard certificate requester
  • measurements, challenge, heartbeat and key update
  • chunking
  • PQC

libwolftpm exports no standard-requester symbols, and the SPDM context stays about 9.5 KB.

Paired with wolfSSL/wolfSPDM#34. The submodule is pinned to that branch; it moves to a wolfSPDM release tag once that PR merges.

Changes

  • Submodule. .gitmodules adds lib/wolfSPDM with ignore = dirty, because in-tree builds write objects there.
  • configure.ac. --enable-spdm fails with a clear message when the submodule isn't checked out, and adds lib/wolfSPDM and lib/wolfSPDM/src to the include path.
  • Sources. src/spdm/include.am and src/fwtpm/include.am compile from lib/wolfSPDM/src. The configure switches and their gating are unchanged.
  • Headers.
    • wolftpm/spdm/*.h are now forwarding headers to <wolfspdm/*.h>, so existing includes keep working.
    • The Nations TPM_CC/TPM_PT constants stay in wolftpm/spdm/spdm_nations.h.
    • Each forwarding header includes <wolftpm/tpm2_types.h> first, so it picks up wolfTPM's options, and forwards only when WOLFTPM_SPDM is set.
    • With SPDM enabled, make install also installs wolfspdm/*.h, plus a wolfspdm/options.h that includes <wolftpm/options.h>, so <wolfspdm/spdm.h> works as a first include.
    • wolfSPDM derives WOLFTPM_SPDM_TCG/WOLFTPM_SPDM_PSK from the vendor macros again, so user-settings builds that define only WOLFTPM_SPDM plus a vendor keep the TCG and PSK wrappers.
  • Tests. src/spdm/unit_test.c stays in wolfTPM and runs against the submodule code.
  • CI. Every workflow that checks out wolfTPM uses submodules: true. The SPDM build matrix installs each config and compiles consumers against only the installed headers, in both include orders. spdm-test.yml also triggers on lib/wolfSPDM and .gitmodules.
  • Docs and tooling. Semgrep's unbounded-libc and command-exec rules now scan lib/wolfSPDM/src/; the X-wrapper and copilot exemptions list lib/wolfSPDM/. src/spdm/README.md documents the submodule.

What wolfSPDM brings to wolfTPM

These fixes come from reviewing the consolidated stack. The wolfTPM-side ones also apply to wolfTPM master today.

Responder (fwTPM)

Area Fix
PSK_SET_ Cannot overwrite a configured PSK.
KEY_EXCHANGE and PSK_EXCHANGE Each is accepted only in its own mode, and never over a live session.
Secured vendor commands before FINISH Only GIVE_PUB is allowed.
SPDMONLY Must be exactly LOCK or UNLOCK; it no longer fails open.
TPM response length Checked.
Reset Wipes the ephemeral key, the application secrets and the transcript.
VERSION The count is at offset 5.

Requester

Area Fix
Connect and Disconnect Wipe all session state.
Secured exchange Refused before KEY_EXCHANGE completes.
TCG receive The size is checked against the buffer, and the scratch buffers are wiped.
HKDF labels Bounds-checked.
Vendor codes A VdCode shorter than 8 characters is rejected.

Upgrade notes

  • Existing checkouts need git submodule update --init. New clones should use --recursive.
  • git archive omits submodules. Build release tarballs with make dist, which includes the wolfSPDM files.

Testing

Check Result
The 14 SPDM configure permutations used by spdm-test.yml / make-test-swtpm.yml (base-only, tcg-only, both, nuvoton, nations, full-vendors, requester-only, debug, no-getenv, nuvoton/nations smallstack, nations-debug, nuvoton/nations autodisable) all build; SPDM unit tests pass with the same counts as master; 0 standard-requester symbols exported
fwTPM TCG e2e (spdm_test.sh fwtpm-tcg) 15/15
fwTPM PSK e2e (spdm_test.sh fwtpm-psk) 27/27
make check (full build) SPDM unit test and fwTPM unit test pass. tests/fwtpm_check.sh fails exactly as on master in the same lab, because that wolfSSL build lacks salted-session support; it is unrelated to SPDM.
make dist tarball contains the wolfSPDM sources and headers, and builds with --enable-spdm --enable-nuvoton --enable-nations
Nuvoton NPCT75x on a Raspberry Pi 5 (spdm_test.sh nuvoton, identity key pinned) 8/9: pinned connect, status, lock, unpinned-rejected-while-locked, status and caps in SPDM-only mode, unlock, and cleartext caps all pass. master on the same board gives the identical 8/9. The one failure, in both, is tests/unit_tests.c calling wolfTPM2_GetCapability_SPDMSessionInfo, which this firmware rejects with TPM_RC_VALUE.

Known issues seen on the bench (not changed here, same on master)

Tracked in wolfSSL/wolfSPDM #19, #20 and #21.

  • spdm_ctrl --get-pubkey fails on Nuvoton. It sends GET_PUBK without GET_VERSION first, and the firmware replies with ERROR UnexpectedRequest. It also prints only the first 32 bytes of the TPMT_PUBLIC. To pin the key for the bench, I read it with GET_VERSION and then GET_PUBK.
  • spdm_ctrl prints SPDM errors as "unknown error number". It formats wolfSPDM error codes with TPM2_GetRCString.

Before merge

Copilot AI balanced review requested due to automatic review settings September 29, 2026 18:16

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

Review effort: Lite
Findings: None

What changed in this PR

This PR migrates wolfTPM’s SPDM implementation to the lib/wolfSPDM git submodule, removing duplicated SPDM sources and building against the consolidated wolfSPDM library while preserving existing wolfTPM include paths via forwarding headers.

Changes:

  • Replaced in-tree SPDM sources with submodule sources in lib/wolfSPDM/src and updated Automake source lists accordingly.
  • Converted wolftpm/spdm/*.h to forwarding headers that include wolfSPDM headers when WOLFTPM_SPDM is enabled, while retaining Nations-specific TPM constants locally.
  • Updated configure + CI/workflows to require/checkout the submodule and validated installed-header consumption via consumer compile steps.
File Description
wolftpm/​spdm/​spdm.h Forwarding header to <wolfspdm/spdm.h> gated by WOLFTPM_SPDM.
wolftpm/​spdm/​spdm_types.h Forwarding header to <wolfspdm/spdm_types.h> gated by WOLFTPM_SPDM.
wolftpm/​spdm/​spdm_error.h Forwarding header to <wolfspdm/spdm_error.h> gated by WOLFTPM_SPDM.
wolftpm/​spdm/​spdm_tcg.h Forwarding header to <wolfspdm/spdm_tcg.h> gated by WOLFTPM_SPDM.
wolftpm/​spdm/​spdm_psk.h Forwarding header to <wolfspdm/spdm_psk.h> gated by WOLFTPM_SPDM.
wolftpm/​spdm/​spdm_responder.h Forwarding header to <wolfspdm/spdm_responder.h> gated by WOLFTPM_SPDM.
wolftpm/​spdm/​spdm_nuvoton.h Forwarding header to <wolfspdm/spdm_nuvoton.h> gated by WOLFTPM_SPDM.
wolftpm/​spdm/​spdm_nations.h Forwarding to <wolfspdm/spdm_nations.h> and retains Nations TPM constants under WOLFSPDM_NATIONS.
wolftpm/​include.am Installs wolfSPDM public headers and wolfspdm/options.h when BUILD_SPDM is enabled.
src/​spdm/​wolfspdm/​options.h Adds an installed wolfspdm/options.h that includes <wolftpm/options.h>.
src/​spdm/​include.am Builds SPDM from lib/wolfSPDM/src and ships needed submodule files in dist.
src/​fwtpm/​include.am Switches fwTPM SPDM build inputs to lib/wolfSPDM/src.
configure.ac Fails early if submodule isn’t checked out and adds wolfSPDM include paths.
.gitmodules Adds lib/wolfSPDM submodule configuration.
src/​spdm/​README.md Documents the submodule-based SPDM arrangement and clone/update instructions.
.github/​workflows/​*.yml Ensures CI checkouts include submodules; expands SPDM workflow triggers and adds consumer header compile checks.
.github/​semgrep-rules.yml Expands Semgrep scanning to cover lib/wolfSPDM/src appropriately.
.github/​copilot-instructions.md Updates vendored-tree exemptions to include lib/wolfSPDM/.

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

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot 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.

Fenrir Automated Review — PR #617

Scan targets checked: wolftpm-src, wolftpm-bugs
Coverage: 5 of 8 in-scope changed file(s) opened by the reviewer; not opened: wolftpm/spdm/spdm.h, wolftpm/spdm/spdm_error.h, wolftpm/spdm/spdm_nuvoton.h

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Lite

@aidangarske
aidangarske marked this pull request as ready for review September 30, 2026 00:10
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