Skip to content

Commit 68ef2f6

Browse files
authored
Merge pull request #458 from aidangarske/add-full-spdm-support
wolfTPM SPDM support (Nuvoton NPCT75x and NSING NS350)
2 parents 82cb9f9 + 4d39d8b commit 68ef2f6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+10449
-22
lines changed

.github/workflows/make-test-swtpm.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,36 @@ jobs:
7575
# STMicro ST33KTPM2
7676
- name: st33ktpm2 firmware
7777
wolftpm_config: --enable-st33 --enable-firmware
78+
# SPDM + Nuvoton (compile-only, no hardware in CI)
79+
- name: spdm-nuvoton
80+
wolfssl_config: --enable-wolftpm --enable-ecc --enable-sha384 --enable-aesgcm --enable-hkdf --enable-sp
81+
wolftpm_config: --enable-spdm --enable-nuvoton
82+
needs_swtpm: false
83+
# SPDM small stack (heap-allocated SPDM context)
84+
- name: spdm-smallstack
85+
wolfssl_config: --enable-wolftpm --enable-ecc --enable-sha384 --enable-aesgcm --enable-hkdf --enable-sp
86+
wolftpm_config: --enable-spdm --enable-nuvoton --enable-smallstack
87+
needs_swtpm: false
88+
# SPDM debug
89+
- name: spdm-debug
90+
wolfssl_config: --enable-wolftpm --enable-ecc --enable-sha384 --enable-aesgcm --enable-hkdf --enable-sp
91+
wolftpm_config: --enable-spdm --enable-nuvoton --enable-debug
92+
needs_swtpm: false
93+
# SPDM + Nations (compile-only, no hardware in CI)
94+
- name: spdm-nations
95+
wolfssl_config: --enable-wolftpm --enable-ecc --enable-sha384 --enable-aesgcm --enable-hkdf --enable-sp
96+
wolftpm_config: --enable-spdm --enable-nations
97+
needs_swtpm: false
98+
# SPDM + Nations debug
99+
- name: spdm-nations-debug
100+
wolfssl_config: --enable-wolftpm --enable-ecc --enable-sha384 --enable-aesgcm --enable-hkdf --enable-sp
101+
wolftpm_config: --enable-spdm --enable-nations --enable-debug
102+
needs_swtpm: false
103+
# SPDM + Nations small stack (heap-allocated SPDM context)
104+
- name: spdm-nations-smallstack
105+
wolfssl_config: --enable-wolftpm --enable-ecc --enable-sha384 --enable-aesgcm --enable-hkdf --enable-sp
106+
wolftpm_config: --enable-spdm --enable-nations --enable-smallstack
107+
needs_swtpm: false
78108
# Microchip
79109
- name: microchip
80110
wolftpm_config: --enable-microchip

.gitignore

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ examples/firmware/ifx_fw_update
9292
examples/firmware/st33_fw_update
9393
examples/endorsement/get_ek_certs
9494
examples/endorsement/verify_ek_cert
95+
examples/spdm/spdm_ctrl
9596

9697
# Generated Cert Files
9798
certs/ca-*.pem
@@ -181,10 +182,18 @@ UpgradeLog.htm
181182
/IDE/Espressif/**/sdkconfig
182183
/IDE/Espressif/**/sdkconfig.old
183184

185+
# SPDM build artifacts
186+
spdm/wolfspdm/options.h
187+
spdm/config.h
188+
spdm/stamp-h1
189+
spdm/src/.libs/
190+
spdm/src/.deps/
191+
spdm/test/.libs/
192+
spdm/test/unit_test
193+
184194
# Firmware files
185195
examples/firmware/*.fi
186196
examples/firmware/*.BIN
187197
examples/firmware/*.DATA
188198
examples/firmware/*.MANIFEST
189199
examples/firmware/*.MANIFESTHASH
190-

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ include tests/include.am
4646
include docs/include.am
4747
include wrapper/include.am
4848
include hal/include.am
49+
include src/spdm/include.am
4950
include cmake/include.am
5051
include zephyr/include.am
5152

configure.ac

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ AC_CANONICAL_HOST
2222
AC_CANONICAL_TARGET
2323
AC_CONFIG_MACRO_DIR([m4])
2424

25+
2526
AM_INIT_AUTOMAKE([1.11 -Wall -Werror -Wno-portability foreign tar-ustar subdir-objects no-define color-tests])
2627

2728
AC_ARG_PROGRAM
@@ -332,6 +333,17 @@ then
332333
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_NUVOTON"
333334
fi
334335

336+
# Nations Technology NS350
337+
AC_ARG_ENABLE([nations],
338+
[AS_HELP_STRING([--enable-nations],[Enable Nations Technology NS350 TPM Support (default: disabled)])],
339+
[ ENABLED_NATIONS=$enableval ],
340+
[ ENABLED_NATIONS=no ]
341+
)
342+
if test "x$ENABLED_NATIONS" = "xyes"
343+
then
344+
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_NATIONS"
345+
fi
346+
335347
# Infineon SLB9670/SLB9672/SLB9673
336348
AC_ARG_ENABLE([infineon],
337349
[AS_HELP_STRING([--enable-infineon],[Enable Infineon SLB9670/SLB9672 TPM Support (default: disabled)])],
@@ -407,7 +419,8 @@ if test "x$ENABLED_AUTODETECT" = "xtest"
407419
then
408420
# If a module hasn't been selected then enable auto-detection
409421
if test "x$ENABLED_INFINEON" = "xno" && test "x$ENABLED_MCHP" = "xno" && test "x$ENABLED_MICROCHIP" = "xno" && \
410-
test "x$ENABLED_ST" = "xno" && test "x$ENABLED_ST33" = "xno" && test "x$ENABLED_NUVOTON" = "xno"
422+
test "x$ENABLED_ST" = "xno" && test "x$ENABLED_ST33" = "xno" && test "x$ENABLED_NUVOTON" = "xno" && \
423+
test "x$ENABLED_NATIONS" = "xno"
411424
then
412425
ENABLED_AUTODETECT=yes
413426
fi
@@ -462,6 +475,40 @@ then
462475
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_PROVISIONING"
463476
fi
464477

478+
# SPDM Support
479+
AC_ARG_ENABLE([spdm],
480+
[AS_HELP_STRING([--enable-spdm],[Enable SPDM support (default: disabled)])],
481+
[ ENABLED_SPDM=$enableval ],
482+
[ ENABLED_SPDM=no ]
483+
)
484+
485+
AC_ARG_WITH([wolfspdm],
486+
[AS_HELP_STRING([--with-wolfspdm=PATH],[DEPRECATED: Use --enable-spdm instead.])],
487+
[AC_MSG_ERROR([--with-wolfspdm is no longer needed. Use --enable-spdm instead.])])
488+
489+
if test "x$ENABLED_SPDM" = "xyes"
490+
then
491+
AC_DEFINE([WOLFTPM_SPDM], [1], [Enable SPDM support])
492+
493+
# Nuvoton SPDM support (required for SPDM in wolfTPM)
494+
if test "x$ENABLED_NUVOTON" = "xyes"
495+
then
496+
AC_DEFINE([WOLFSPDM_NUVOTON], [1], [Enable SPDM Nuvoton TPM support])
497+
AC_MSG_NOTICE([Nuvoton SPDM vendor commands enabled])
498+
fi
499+
500+
# Nations Technology SPDM support
501+
if test "x$ENABLED_NATIONS" = "xyes"
502+
then
503+
AC_DEFINE([WOLFSPDM_NATIONS], [1], [Enable SPDM Nations Technology support])
504+
AC_MSG_NOTICE([Nations Technology SPDM vendor commands enabled])
505+
fi
506+
507+
if test "x$ax_enable_debug" != "xno"
508+
then
509+
AC_DEFINE([WOLFSPDM_DEBUG], [1], [SPDM: Enable debug output])
510+
fi
511+
fi
465512

466513
# HARDEN FLAGS
467514
AX_HARDEN_CC_COMPILER_FLAGS
@@ -489,10 +536,12 @@ AM_CONDITIONAL([BUILD_DEVTPM], [test "x$ENABLED_DEVTPM" = "xyes"])
489536
AM_CONDITIONAL([BUILD_SWTPM], [test "x$ENABLED_SWTPM" = "xyes"])
490537
AM_CONDITIONAL([BUILD_WINAPI], [test "x$ENABLED_WINAPI" = "xyes"])
491538
AM_CONDITIONAL([BUILD_NUVOTON], [test "x$ENABLED_NUVOTON" = "xyes"])
539+
AM_CONDITIONAL([BUILD_NATIONS], [test "x$ENABLED_NATIONS" = "xyes"])
492540
AM_CONDITIONAL([BUILD_CHECKWAITSTATE], [test "x$ENABLED_CHECKWAITSTATE" = "xyes"])
493541
AM_CONDITIONAL([BUILD_AUTODETECT], [test "x$ENABLED_AUTODETECT" = "xyes"])
494542
AM_CONDITIONAL([BUILD_FIRMWARE], [test "x$ENABLED_FIRMWARE" = "xyes"])
495543
AM_CONDITIONAL([BUILD_HAL], [test "x$ENABLED_EXAMPLE_HAL" = "xyes" || test "x$ENABLED_MMIO" = "xyes"])
544+
AM_CONDITIONAL([BUILD_SPDM], [test "x$ENABLED_SPDM" = "xyes"])
496545

497546

498547
CREATE_HEX_VERSION
@@ -578,6 +627,10 @@ for option in $OPTION_FLAGS; do
578627
fi
579628
done
580629

630+
# Also capture SPDM defines from config.h (set via AC_DEFINE, not AM_CFLAGS)
631+
grep '^#define WOLFSPDM_' src/config.h >> $OPTION_FILE 2>/dev/null || true
632+
grep '^#define WOLFTPM_SPDM' src/config.h >> $OPTION_FILE 2>/dev/null || true
633+
581634
echo "" >> $OPTION_FILE
582635
echo "#ifdef __cplusplus" >> $OPTION_FILE
583636
echo "}" >> $OPTION_FILE
@@ -619,6 +672,8 @@ echo " * Infineon SLB967X $ENABLED_INFINEON"
619672
echo " * STM ST33: $ENABLED_ST"
620673
echo " * Microchip ATTPM20: $ENABLED_MICROCHIP"
621674
echo " * Nuvoton NPCT75x: $ENABLED_NUVOTON"
675+
echo " * Nations Tech NS350: $ENABLED_NATIONS"
622676

623677
echo " * Runtime Module Detection: $ENABLED_AUTODETECT"
624678
echo " * Firmware Upgrade Support: $ENABLED_FIRMWARE"
679+
echo " * SPDM Support: $ENABLED_SPDM"

examples/include.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ include examples/seal/include.am
1818
include examples/attestation/include.am
1919
include examples/firmware/include.am
2020
include examples/endorsement/include.am
21+
include examples/spdm/include.am
2122

2223
if BUILD_EXAMPLES
2324
EXTRA_DIST += examples/run_examples.sh

examples/spdm/README.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# TPM SPDM Setup/Control
2+
3+
This directory contains the SPDM setup and control tool for Nuvoton NPCT75x
4+
and Nations NS350 TPMs with wolfTPM.
5+
6+
## Overview
7+
8+
The `spdm_ctrl` tool establishes SPDM secure sessions between the host and a
9+
TPM over SPI, enabling AES-256-GCM encrypted bus communication. Once active,
10+
all TPM commands are automatically encrypted with no application changes.
11+
12+
Supported hardware:
13+
- **Nuvoton NPCT75x** — Identity key mode (ECDHE P-384)
14+
- **Nations NS350** — Identity key mode + PSK mode
15+
16+
For standard SPDM protocol support (spdm-emu, measurements, challenge, etc.),
17+
see the [wolfSPDM](https://github.com/aidangarske/wolfSPDM) standalone library.
18+
19+
## Building
20+
21+
### Prerequisites
22+
23+
wolfSSL with crypto algorithms required for SPDM Algorithm Set B:
24+
25+
```bash
26+
cd wolfssl
27+
./autogen.sh
28+
./configure --enable-wolftpm --enable-ecc --enable-sha384 --enable-aesgcm --enable-hkdf --enable-sp
29+
make && sudo make install && sudo ldconfig
30+
```
31+
32+
### wolfTPM with Nuvoton SPDM
33+
34+
```bash
35+
cd wolfTPM
36+
./autogen.sh
37+
./configure --enable-spdm --enable-nuvoton
38+
make
39+
```
40+
41+
### wolfTPM with Nations SPDM
42+
43+
```bash
44+
cd wolfTPM
45+
./autogen.sh
46+
./configure --enable-spdm --enable-nations
47+
make
48+
```
49+
50+
## Setup/Control Commands
51+
52+
| Option | Description |
53+
|--------|-------------|
54+
| `--enable` | Enable SPDM on TPM via NTC2_PreConfig (one-time, requires reset) |
55+
| `--disable` | Disable SPDM on TPM via NTC2_PreConfig (requires reset) |
56+
| `--status` | Query SPDM status from TPM |
57+
| `--get-pubkey` | Get TPM's SPDM-Identity P-384 public key |
58+
| `--connect` | Establish SPDM session (ECDH P-384 handshake) |
59+
| `--lock` | Lock SPDM-only mode (use with `--connect`) |
60+
| `--unlock` | Unlock SPDM-only mode (use with `--connect`) |
61+
62+
## Usage Examples
63+
64+
```bash
65+
# One-time setup: enable SPDM + reset TPM
66+
./examples/spdm/spdm_ctrl --enable
67+
# Reset the TPM (see "TPM Reset Pin Control" below)
68+
69+
# Query SPDM status
70+
./examples/spdm/spdm_ctrl --status
71+
72+
# Get TPM identity key
73+
./examples/spdm/spdm_ctrl --get-pubkey
74+
75+
# Establish SPDM session
76+
./examples/spdm/spdm_ctrl --connect
77+
78+
# Lock SPDM-only mode (connect + lock in one session)
79+
./examples/spdm/spdm_ctrl --connect --lock
80+
# Reset the TPM
81+
82+
# All commands now auto-encrypt:
83+
./examples/wrap/caps # auto-SPDM, AES-256-GCM encrypted
84+
./tests/unit.test # full test suite over encrypted bus
85+
86+
# Unlock SPDM-only mode
87+
# Reset the TPM
88+
./examples/spdm/spdm_ctrl --connect --unlock
89+
# Reset the TPM
90+
```
91+
92+
## TPM Reset Pin Control
93+
94+
SPDM enable/disable and SPDM-only mode changes require a TPM reset to take
95+
effect. The reset pin must be connected and controllable by the host.
96+
97+
**Important for custom hardware designs:** Ensure the TPM reset pin is routed
98+
to a host-controllable GPIO. Without reset pin control, SPDM mode changes
99+
cannot be applied and recovery from SPDM-only mode is not possible.
100+
101+
### Raspberry Pi Example (GPIO 4)
102+
103+
```bash
104+
# Assert reset low, wait, release high, wait for TPM startup
105+
gpioset gpiochip0 4=0 && sleep 0.1 && gpioset gpiochip0 4=1 && sleep 2
106+
```
107+
108+
Other platforms will use their own GPIO control mechanism. The key requirement
109+
is toggling the TPM reset line (active low) with sufficient hold time.
110+
111+
## Automated Test Suite
112+
113+
Runs the full SPDM setup lifecycle on hardware:
114+
115+
```bash
116+
./examples/spdm/spdm_test.sh ./examples/spdm/spdm_ctrl nuvoton
117+
./examples/spdm/spdm_test.sh ./examples/spdm/spdm_ctrl nations
118+
./examples/spdm/spdm_test.sh ./examples/spdm/spdm_ctrl nations-psk
119+
```
120+
121+
## Support
122+
123+
For production use with hardware TPMs and SPDM support, contact **support@wolfssl.com**.

examples/spdm/include.am

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# vim:ft=automake
2+
# All paths should be given relative to the root
3+
4+
if BUILD_EXAMPLES
5+
if BUILD_SPDM
6+
noinst_PROGRAMS += examples/spdm/spdm_ctrl
7+
8+
examples_spdm_spdm_ctrl_SOURCES = examples/spdm/spdm_ctrl.c
9+
examples_spdm_spdm_ctrl_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
10+
examples_spdm_spdm_ctrl_DEPENDENCIES = src/libwolftpm.la
11+
examples_spdm_spdm_ctrl_CFLAGS = $(AM_CFLAGS)
12+
endif
13+
endif
14+
15+
example_spdmdir = $(exampledir)/spdm
16+
dist_example_spdm_DATA = examples/spdm/spdm_ctrl.c
17+
18+
DISTCLEANFILES+= examples/spdm/.libs/spdm_ctrl

0 commit comments

Comments
 (0)