Skip to content

wolfTPM SPDM support (Nuvoton NPCT75x and NSING NS350)#458

Open
aidangarske wants to merge 5 commits intowolfSSL:masterfrom
aidangarske:add-full-spdm-support
Open

wolfTPM SPDM support (Nuvoton NPCT75x and NSING NS350)#458
aidangarske wants to merge 5 commits intowolfSSL:masterfrom
aidangarske:add-full-spdm-support

Conversation

@aidangarske
Copy link
Member

@aidangarske aidangarske commented Feb 20, 2026

Description

Migrates the standalone wolfSPDM library into wolfTPM as an in-tree spdm/
subdirectory and adds full SPDM support for both Nuvoton NPCT75x and
Nations NS350 TPMs. Eliminates the external dependency a single
--enable-spdm configure flag builds everything.

wolfSPDM Library (spdm/)

  • SPDM 1.3 (DSP0274) with Algorithm Set B (P-384, SHA-384, AES-256-GCM, HKDF)
  • Standard mode: works with libspdm spdm-emu responder for testing
  • TCG SPDM Binding: vendor-defined commands (GET_PUBK, GIVE_PUB, SPDMONLY,
    GET_STS_, TPM2_CMD, PSK_SET_, PSK_CLR_)
  • Identity key session: GET_VERSION, GET_CAPABILITIES, NEGOTIATE_ALGORITHMS,
    GET_PUBK, KEY_EXCHANGE, GIVE_PUB, FINISH
  • PSK session: GET_VERSION, GET_CAPABILITIES, NEGOTIATE_ALGORITHMS,
    PSK_EXCHANGE, PSK_FINISH
  • Secured messaging: AES-256-GCM AEAD with sequence number tracking
  • Static memory mode (zero-malloc) and dynamic mode (--enable-spdm-dynamic-mem)
  • Unit test suite (spdm/test/unit_test.c)

Nuvoton NPCT75x Support

  • NTC2_PreConfig vendor commands for SPDM enable/disable
  • SPDM-only mode: lock/unlock enforcement over identity key sessions
  • Auto-SPDM: transparent session establishment when TPM is in SPDM-only mode
  • Tested: 6/6 hardware tests (status, connect, lock, unit test, unlock, caps)

Nations NS350 Support

PSK Mode

  • PSK_SET/PSK_CLEAR vendor commands with 32-byte ClearAuth (TCG PC Client spec)
  • PSK_EXCHANGE/PSK_FINISH session establishment (Salt_0 = 0xFF for PSK mode)
  • GET_STATUS with response parsing (PSKSet, SPDMOnly, spec version)
  • SPDM_ONLY lock/unlock for PSK mode
  • Tested: 10/10 PSK lifecycle tests (provision, connect, clear, re-provision)

Identity Key Mode

  • Shared TCG SPDM binding protocol with Nuvoton
  • TPM2_VendorSpdmIdentityKeySet for identity key provisioning
  • TODO: Re-test on firmware 0.1.0.15 (digest changed to SHA-384(TPMT_PUBLIC))

wolfTPM Integration

  • 13+ new wolfTPM2_Spdm*() wrapper API functions in tpm2_wrap.h
  • Transparent SPDM transport in TPM2_SendCommand() — all TPM commands
    automatically encrypted when SPDM session is active
  • TIS I/O callback for routing SPDM through SPI/I2C TPM FIFO
  • Auto-generated ephemeral P-384 key pair for mutual authentication

SPDM Demo (examples/spdm/)

  • spdm_demo.c: Nuvoton and Nations hardware modes
  • spdm_test.sh: Automated tests for nuvoton, nations, and nations-psk modes

TCG SPDM Vendor Commands

VdCode Command Nuvoton Nations
GET_PUBK Get Public Key Yes Yes
GIVE_PUB Give Public Key Yes Yes
TPM2_CMD TPM Command Yes Yes
GET_STS_ Get Status Yes Yes
SPDMONLY SPDM-Only Mode Yes Yes
PSK_SET_ PSK Set N/A Yes
PSK_CLR_ PSK Clear N/A Yes

Test Plan

  • Build with --enable-spdm --enable-nuvoton
  • Build with --enable-spdm --enable-nations
  • Build without --enable-spdm (no breakage)
  • 26/26 unit tests PASS
  • 6/6 Nuvoton hardware tests PASS
  • 10/12 Nations PSK hardware tests PASS. (two still need testing)
  • Nations identity key mode on firmware 0.1.0.15
  • Copilot review
  • fenrir

This comment was marked as outdated.

This comment was marked as outdated.

This comment was marked as outdated.

@aidangarske aidangarske requested a review from dgarske February 20, 2026 21:58
@dgarske dgarske assigned dgarske and wolfSSL-Bot and unassigned aidangarske Feb 21, 2026
Copilot AI review requested due to automatic review settings February 24, 2026 16:26

This comment was marked as off-topic.

This comment was marked as outdated.

@dgarske dgarske removed their assignment Feb 24, 2026
Copilot AI review requested due to automatic review settings February 26, 2026 18:20

This comment was marked as outdated.

Copilot AI review requested due to automatic review settings March 13, 2026 01:05
@aidangarske aidangarske force-pushed the add-full-spdm-support branch from f43ecbb to 57c6e83 Compare March 13, 2026 01:05

This comment was marked as resolved.

@aidangarske aidangarske force-pushed the add-full-spdm-support branch from 57c6e83 to d58702e Compare March 13, 2026 17:50
@aidangarske aidangarske requested a review from dgarske March 13, 2026 18:08
@aidangarske aidangarske changed the title wolfSPDM migration to wolfTPM/spdm with Nuvoton and spdm-emu support wolfSPDM migration to wolfTPM/spdm with Nuvoton NPCT75x Mar 13, 2026
@dgarske dgarske removed their assignment Mar 17, 2026
@dgarske dgarske changed the title wolfSPDM migration to wolfTPM/spdm with Nuvoton NPCT75x wolfTPM SPDM support (tested with Nuvoton NPCT75x) Mar 18, 2026
wolfSSL-Fenrir-bot

This comment was marked as resolved.

This comment was marked as resolved.

@aidangarske aidangarske changed the title wolfTPM SPDM support (tested with Nuvoton NPCT75x) wolfTPM SPDM support (Nuvoton NPCT75x and NSING NS350) Mar 21, 2026
  - 18/18 emulator tests PASS (6 tests x 3 versions: 1.2, 1.3, 1.4)
  1. Removed OpaqueDataLength(2) from CHALLENGE request for SPDM 1.3+ — spec says only RequesterContext(8), no OpaqueDataLength in request
  2. Removed OpaqueDataLength(2) from signed GET_MEASUREMENTS request for SPDM 1.3+ — same issue
  - spdm/README.md: Added supported versions table (spdm-emu: 1.2/1.3/1.4, Nuvoton: 1.3), updated protocol flow diagram, added --ver flag to demo options,
  added wolfSPDM_SetMaxVersion() to API table, updated emulator section to mention 18-test multi-version coverage
  - Addressed PR review feedback
… lines)

  Security fixes:
  - Mandatory responder signature verification in KEY_EXCHANGE_RSP (was conditional skip)
  - Sensitive stack buffer zeroing (wc_ForceZero) in BuildFinish, ParseKeyExchangeRsp,
    wolfSPDM_Finish for keys, HMAC, and signature data
  - TCG integer underflow guard in ParseTcgClearMessage (msgSize < header check)
  - BuildIV: removed dead code duplicate branches, collapsed to single 8-byte XOR path

  Code quality:
  - Cascade error handling (rc == WOLFSPDM_SUCCESS pattern) across spdm_msg.c,
    spdm_session.c, spdm_secured.c for single-cleanup-path safety
  - wolfSPDM_BuildVendorDefined: added spdmVersion parameter (was hardcoded 0x13)
  - spdm_error.h: added spdm_types.h include for standalone WOLFSPDM_API definition
  - spdm.h: added stack usage documentation (~22KB context, ~20KB call chain)

  Codebase reduction (-4,301 net lines):
  - Condensed spdm_demo.c (382->256 lines), spdm_test.sh (143->70 lines)
  - Removed verbose banner comments and redundant section headers across all files
  - Consolidated unit tests with shared helpers, removed duplicate test patterns
  - Removed spdm-emu-test.yml CI workflow (moved to standalone wolfSPDM repo)
  - Streamlined README documentation

  Test results:
  - 26/26 unit tests PASS
  - 6/6 Nuvoton hardware tests PASS (spdm_test.sh)
  - Nations NS350 PSK mode: PSK_SET, PSK_CLEAR, PSK_EXCHANGE, PSK_FINISH,
    GET_STATUS, SPDM_ONLY with 32-byte ClearAuth per TCG PC Client spec
  - Salt_0 = 0xFF for PSK mode HKDF-Extract (vs 0x00 for identity key mode)
  - NATIONS_PSK mode checks in spdm_secured.c encrypt/decrypt paths
  - GET_STATUS response parsing fix (PSKSet byte was not being read)
  - Demo cleanup order: TPM2_Shutdown before SPDM disconnect
  - 32-byte ClearAuth enforcement on PSK_SET and PSK_CLEAR
  - spdm_test.sh nations-psk: 12-step PSK lifecycle test with NSING reference data
  - spdm/README.md: TCG commands section, Nations PSK docs, validation status
  - Removed unused inline PSK_SET, SetPskSetPayload, ConnectNationsPskProvision
  - SPDM 1.3+ OpaqueDataLength fix for CHALLENGE and GET_MEASUREMENTS requests

  Tested: 10/10 Nations PSK tests PASS, 6/6 Nuvoton tests PASS
@aidangarske aidangarske force-pushed the add-full-spdm-support branch from 59b592b to a5c2ffa Compare March 21, 2026 21:22
  - Ct hash changed from SHA-384(X||Y) to SHA-384(TPMT_PUBLIC) for both
    responder (KEY_EXCHANGE) and requester (FINISH mutual auth), matching
    Vision's updated firmware and Nuvoton's implementation
  - wolfSSL requires --enable-ecccustcurves=all for Nations (HAVE_ECC_CDH)
  - spdm_test.sh: use run_test_no_reset for Nations (GPIO 4 not wired to
    TPM_RST on NS350 daughter board, requires full power cycle)
  - spdm_test.sh nations: full lifecycle (unset, set, connect, status, caps)
  - spdm/README.md: separate wolfSSL build sections for Nuvoton vs Nations,
    removed status columns from command tables, updated troubleshooting for
    NS350 power cycle requirement
  - CLAUDE.md: updated build instructions with correct minimal flags

  Tested: 5/5 Nations identity key tests PASS, 12/12 Nations PSK tests PAS
wolfSSL-Fenrir-bot

This comment was marked as duplicate.

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.

5 participants