A firmware TPM inside an AMD Spartan UltraScale+ FPGA

A TPM does not have to be a separate chip. wolfTPM‘s firmware-TPM (fwTPM) is the full TPM 2.0 command engine running as firmware, speaking the same protocol a discrete TPM would. On an FPGA that is a powerful idea: you can place a real root of trust inside the programmable logic you are already building, with no extra part on the board.

The target: Spartan UltraScale+

The AMD Spartan UltraScale+ SCU35 (xcsu35p) is a cost-optimized, pure-FPGA device with no hardened CPU. You compose the system you need in the fabric: for this example, a MicroBlaze V (RISC-V rv32imc) soft core, AXI UARTLite, AXI Timer, block RAM, and the device’s on-die SYSMONE4 System Monitor. The fwTPM runs on that soft core as just another block in your design, co-located with your application logic. A host drives it over UART with the same raw swtpm/mssim framing as our other ports, so the stock wolfTPM swtpm client works against it unmodified.

The problem it solves

Plenty of FPGA designs want a TPM’s services (device identity, attestation and measured boot, sealed keys, monotonic counters), but the board carries no TPM chip, and a pure FPGA has no hardened processor to run one. The fwTPM answers that by putting a standards-compliant TPM 2.0 directly in the fabric on a soft core: a root of trust you integrate into your own bitstream instead of sourcing, placing, and routing a discrete device.

The SCU35 even supplies its own entropy. Instead of a software jitter source, the example seeds the TPM’s DRBG from the on-die SYSMONE4 System Monitor, read as an AXI peripheral – real thermal and supply-rail noise from the silicon. It is hardware-validated: reading the monitor over JTAG shows the low bits jittering, and the TPM’s GetRandom returns different output on every cold boot.

What is in the example

A self-contained bare-metal MicroBlaze V HAL (UART, timer, RV32 startup, retarget), the fwTPM server with its clock / NV / TRNG HALs, and two small wolfSSL-authored Tcl scripts that add the System Monitor to AMD’s reference design without modifying any AMD source. TPM2_Startup and GetRandom pass on the board.

Size, algorithms, and speed

The SCU35 is memory-limited (192 KB of block RAM, no DDR), so this example is a minimal ECC-P256 TPM, about 190 KB, tuned to fit. Adding RSA or post-quantum (ML-DSA / ML-KEM) needs a larger Spartan UltraScale+ part, or one paired with DDR – the same firmware scales up unchanged. Measured on the soft core (MicroBlaze V, 225 MHz, portable-C math):

Operation Result
ECC P-256 keygen 9.0 ops/sec
ECDHE P-256 agree 9.0 ops/sec
ECDSA P-256 sign 8.1 ops/sec
ECDSA P-256 verify 4.4 ops/sec
SHA-256 2.0 MiB/s

Unhurried next to a hardened core, but well matched to a TPM’s occasional key, sign, and attestation work – with no chip and no CPU on the die. See the example (Xilinx/fwtpm-scu35-microblazev) and PR #6.

If you have questions about any of the above, please contact us at facts@wolfssl.com or call us at +1 425 245 8247.

Download wolfSSL Now