We just opened a PR adding a wolfTPM Firmware TPM (fTPM) example for the Microchip PolarFire SoC, validated end-to-end on the MPFS250T Video Kit. It runs a full TPM 2.0 service on a dedicated RISC-V hart, isolated from Linux, with no discrete TPM chip and no third-party TEE.
Why this matters
Most TPM integrations need either a discrete SPI/I2C chip or a firmware TPM buried in someone else’s TEE. This is a different option: a TPM 2.0 service you own end-to-end, on a hard RISC-V core, isolated by AMP partitioning, small enough to live in M-mode. The result is ~200 KB of code giving Linux TPM-grade key storage, sealing, and attestation with no security chip and no vendor blob owning the boundary.
Why wolfTPM’s fTPM
It is the same fwtpm library across every target. The TPM 2.0 command dispatch, TIS protocol, NV journal, and the FWTPM_NV_HAL / FWTPM_CLOCK_HAL / FWTPM_TIS_HAL interfaces are identical to the desktop and STM32H5 builds. Porting to a new part means three small HAL shims (storage, clock, transport) plus a startup file – not re-architecting a TPM.
That portability is real: the same core runs on ARM TrustZone (STM32H5), a RISC-V hart in AMP (this port), and Cortex-R5 lock-step (Xilinx ZCU102). Being wolfTPM, you also get SPDM-protected sessions (v1.84) and post-quantum ML-DSA / ML-KEM (v1.85), from a single vendor with auditable source.
How it is wired
PolarFire SoC has four U54 application cores plus an E51 monitor. Microchip’s HSS launches an AMP payload:
- E51: HSS monitor.
- U54 harts 1-3: Linux (S-mode under OpenSBI), Yocto rootfs.
- U54 hart 4: the fwTPM server – M-mode, bare-metal, loaded at 0x91C00000.
Linux reaches hart 4 through a shared-memory mailbox, console ring, and TIS register block in L2 LIM at 0x08000000:
0x08000000 mailbox (64 B - cmd/rsp + boot/trap debug) 0x08000040 console ring (4 KB - server stdout via /dev/mem) 0x08001040 TIS regs (~8 KB - regs + cmd/rsp FIFOs)
Because LIM is not in Linux’s System RAM map, the mailbox is readable from /dev/mem even under a stock CONFIG_STRICT_DEVMEM=y kernel – no kernel rebuild. The one device-tree change is a small overlay releasing hart 4.
The transport is build-selectable (FWTPM_XPORT): the default cacheable L2-LIM mailbox is coherent under HSS AMP and just works, and a fully-uncached DDR-alias path ships as a verified alternative for designs that want the mailbox outside cache entirely.
Smoke test
Two root scripts ship with the example. fwtpm_mbox_dump.py decodes the mailbox, boot-progress marker, M-mode trap fields (mcause/mepc/mtval), and the captured console ring – so you can see exactly where the server is even with no routed UART. fwtpm_smoke.py confirms the server is alive (Phase 1), then drives a TIS transaction through the mailbox (Phase 2) with a rolling nonce the server echoes back – proving hart 4 saw the new write, not a stale cache line.
It works end-to-end
The full Linux <-> hart 4 round-trip works on real hardware: both phases pass reproducibly on the default build, no special configuration.
Entropy is secure by default: a plain make seeds the DRBG from the System Controller hardware TRNG (FWTPM_RNG=SCB_NONCE) as the sole entropy source – validated on the Video Kit. A development-only MTIME-jitter seed exists for early bring-up but is gated behind an explicit opt-in, so it can never ship silently and a default build is never weakly seeded.
Where this is going
Today the fwTPM runs on a hard U54 application core. The headline next step makes it a true fabric root of trust: instantiate a Microchip Mi-V RISC-V soft core in the MPFS250T’s FPGA fabric and host the fwTPM there. The hard U54 cluster keeps running Linux untouched; the Mi-V core becomes a dedicated security processor in programmable logic, with its own bus mastering and no application code sharing its silicon.
Because the fwtpm library is portable, that move is mostly a new transport HAL and startup file – the TPM 2.0 core is unchanged. The payoff is the tie-in to PolarFire’s hardware security blocks: seed entropy from the System Controller TRNG (already wired), bind a device-unique root key to the SRAM-PUF, offload crypto to the User Crypto (Athena TeraFire) processor, and persist NV state in sNVM secure storage. That turns the soft-core fwTPM into a self-contained, tamper-resistant root of trust living in fabric – not borrowed from the application complex.
Also on the roadmap:
- Persistent NV behind FWTPM_NV_HAL (sNVM integrity key + QSPI bulk) so keys survive a power cycle.
- PQC: enable ML-KEM / ML-DSA and benchmark on the target.
- An interrupt-driven doorbell so the TPM core sleeps between requests.
- A wolfBoot-hosted variant (wolfBoot replaces HSS and owns the SBI on E51), opening an SBI doorbell and measured boot.
If you have a design that wants TPM 2.0 key storage, sealing, or attestation but no room for a discrete chip or closed TEE, this is the shape of the answer – and it runs end-to-end on a shipping RISC-V SoC today, with a soft-core fabric root of trust next. The full example is on GitHub; reach out if you want a hand bringing it up on your part.
Reference
- wolfTPM: https://github.com/wolfSSL/wolfTPM
- This example (PR): https://github.com/wolfSSL/wolftpm-examples/pull/2
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

