Skip to content

Add firmware TPM 2.0 (fwTPM) implementation#474

Merged
aidangarske merged 1 commit intowolfSSL:masterfrom
dgarske:fwtpm
Apr 17, 2026
Merged

Add firmware TPM 2.0 (fwTPM) implementation#474
aidangarske merged 1 commit intowolfSSL:masterfrom
dgarske:fwtpm

Conversation

@dgarske
Copy link
Copy Markdown
Contributor

@dgarske dgarske commented Mar 21, 2026

Summary

Add fwtpm_server: a portable, standards-compliant firmware TPM 2.0 command
processor built entirely on wolfCrypt. The fwTPM can replace a hardware TPM on
embedded platforms without a discrete TPM chip, or serve as a drop-in
development/CI replacement for external simulators (swtpm, MS TPM simulator).

71 files changed, ~32,000 lines added, ~2,000 lines removed.

Features

TPM 2.0 Command Processor (105 commands, 93% of v1.38 spec)

104 command handler functions in fwtpm_command.c (~13,300 lines) covering:

  • Startup/Lifecycle (5): Startup, Shutdown, SelfTest, IncrementalSelfTest, GetTestResult
  • Random (2): GetRandom, StirRandom
  • Key Management (18): CreatePrimary, Create, CreateLoaded, Load, LoadExternal, Import, Duplicate, Rewrap, FlushContext, ContextSave, ContextLoad, ReadPublic, ObjectChangeAuth, EvictControl, HierarchyControl, HierarchyChangeAuth, Clear, ClearControl
  • Hierarchy (4): ChangeEPS, ChangePPS, SetPrimaryPolicy, GetCapability
  • Cryptographic Operations (12): Sign, VerifySignature, RSA_Encrypt, RSA_Decrypt, EncryptDecrypt, EncryptDecrypt2, Hash, HMAC, ECDH_KeyGen, ECDH_ZGen, ECC_Parameters, EC_Ephemeral, ZGen_2Phase, TestParms
  • Hash Sequences (5): HashSequenceStart, HMAC_Start, SequenceUpdate, SequenceComplete, EventSequenceComplete
  • PCR (7): PCR_Read, PCR_Extend, PCR_Reset, PCR_Event, PCR_Allocate, PCR_SetAuthPolicy, PCR_SetAuthValue
  • Clock (3): ReadClock, ClockSet, ClockRateAdjust
  • Sessions (1): StartAuthSession (HMAC, policy, trial)
  • Sealing (1): Unseal
  • Policy (21): PolicyGetDigest, PolicyRestart, PolicyPCR, PolicyPassword, PolicyAuthValue, PolicyCommandCode, PolicyOR, PolicySecret, PolicyAuthorize, PolicyLocality, PolicySigned, PolicyNV, PolicyPhysicalPresence, PolicyNvWritten, PolicyTemplate, PolicyCpHash, PolicyNameHash, PolicyDuplicationSelect, PolicyCounterTimer, PolicyTicket, PolicyAuthorizeNV
  • NV RAM (13): NV_DefineSpace, NV_UndefineSpace, NV_UndefineSpaceSpecial, NV_ReadPublic, NV_Write, NV_Read, NV_Extend, NV_Increment, NV_WriteLock, NV_ReadLock, NV_SetBits, NV_ChangeAuth, NV_GlobalWriteLock
  • Attestation (5): Quote, Certify, CertifyCreation, GetTime, NV_Certify
  • Credentials (2): MakeCredential, ActivateCredential
  • Dictionary Attack (2): DictionaryAttackLockReset, DictionaryAttackParameters
  • Vendor (1): Vendor_TCG_Test

Cryptographic Engine (fwtpm_crypto.c, ~3,000 lines)

39 helper functions built on wolfCrypt providing:

  • RSA key generation (deterministic primary derivation via KDFa, CRT computation)
  • ECC key generation (P-256, P-384, P-521 deterministic derivation)
  • RSA sign/verify (PSS, PKCS#1 v1.5), ECC sign/verify (ECDSA)
  • RSA encrypt/decrypt (OAEP, PKCS#1, raw/no-pad)
  • ECDH key agreement (KeyGen, ZGen, ZGen_2Phase)
  • AES-CFB encrypt/decrypt (symmetric objects + parameter encryption)
  • Seed encryption/decryption (RSA OAEP, ECC ECDH+KDFe) for Import/Duplicate/StartAuthSession/ActivateCredential
  • Import key verification (HMAC integrity + AES-CFB decryption) and reconstruction
  • Sensitive area marshaling (internal format and standard TPM 2.0 wire format)

Transport Layers

Socket/SWTPM Protocol (fwtpm_io.c, 669 lines):

  • TCP server on command port (2321) and platform port (2322)
  • Compatible with both mssim and swtpm TCTI protocols (auto-detected)
  • Platform signals: power on/off, physical presence, NV on, cancel, reset, session end, stop
  • Works with tpm2-tools, wolfTPM examples, and any SWTPM-aware client

TIS Register-Level Transport (fwtpm_tis.c + fwtpm_tis_shm.c, 688 lines):

  • Full TIS (TPM Interface Specification) register state machine
  • POSIX shared memory + semaphore transport for inter-process communication
  • Emulates SPI-attached TPM for bare-metal integration testing
  • Client-side HAL (hal/tpm_io_fwtpm.c, 262 lines) translates wolfTPM TIS register ops to shared memory

UART Transport (client-side, in tpm2_swtpm.c):

  • SWTPM protocol over serial UART via termios (--enable-swtpm=uart)
  • For connecting wolfTPM client to fwTPM on embedded targets (e.g., STM32H5)

NV Persistent Storage (fwtpm_nv.c, ~1,800 lines)

  • TLV (Tag-Length-Value) journal format designed for flash compatibility
  • Append-only write semantics with compaction on save
  • Stores: hierarchy seeds/auth, PCR state/allocation, NV indices (data, counters, bits, extend), persistent objects, primary key cache, DA lockout state, hierarchy policies
  • File-based backend (default) or custom HAL callbacks for embedded flash/EEPROM
  • NV state versioning with automatic v1->v2 migration

Session and Authorization

  • HMAC sessions (salted, unbound, bound) with response HMAC validation
  • Policy sessions with 21 policy commands
  • Trial sessions for policy digest computation
  • Parameter encryption: AES-CFB and XOR modes (both command and response)
  • Auth area parsing with cpHash/rpHash computation per TPM 2.0 spec
  • PolicyPassword/PolicyAuthValue HMAC integration (authValue included in HMAC key)

Primary Key Derivation and Caching

  • Deterministic key derivation from hierarchy seeds per TPM 2.0 Part 1 Section 26
  • RSA: iterative KDFa with "RSA p"/"RSA q" labels, primality testing, CRT computation
  • ECC: KDFa-derived private scalar, public point Q = d*G
  • Primary key cache (SHA-256 of template, configurable slots) avoids re-derivation
  • Persistent object storage via EvictControl (survives power cycles)

Compile-Time Feature Selection

All features independently gateable for size optimization on constrained targets:

Macro Effect
FWTPM_NO_ATTESTATION Removes Quote, Certify, CertifyCreation, GetTime, NV_Certify
FWTPM_NO_NV Removes all 13 NV commands + NV-dependent policy
FWTPM_NO_POLICY Removes all 21 policy commands
FWTPM_NO_CREDENTIAL Removes MakeCredential, ActivateCredential
FWTPM_NO_DA Removes DictionaryAttackLockReset/Parameters
FWTPM_NO_PARAM_ENC Removes AES-CFB/XOR parameter encryption
NO_RSA / NO_AES Removes RSA/AES commands at compile time
WOLFTPM_SMALL_STACK Heap-allocates large crypto objects for constrained stacks

HAL Abstraction for Embedded Porting

  • IO HAL: 5 callbacks (send, recv, wait, accept, close_conn) + context pointer
  • NV HAL: 2 callbacks (read, write at offset) + context pointer
  • Clock HAL: get/set time abstraction (TODO placeholder)
  • Porting guide with bare-metal SPI+flash example in docs/FWTPM.md

Library Refactoring

Extracted shared code from existing library files into new reusable modules:

  • tpm2_crypto.c (515 lines): TPM2_KDFa_ex, TPM2_KDFe, AES-CFB encrypt/decrypt, HMAC helpers, hash wrappers -- moved from tpm2_param_enc.c
  • tpm2_util.c (168 lines): TPM2_GetHashType, TPM2_GetHashDigestSize, ConstantCompare, ForceZero, PrintBin -- moved from tpm2.c
  • tpm2_packet.c: Added byte-array endian conversion helpers (U16/U32/U64 ToByteArray/FromByteArray, both BE and LE), shared by fwTPM wire format and NV serialization
  • tpm2_swtpm.c: Added UART serial transport option (WOLFTPM_SWTPM_UART), SWTPM protocol auto-detection (mssim vs swtpm TCTI)
  • Net reduction of ~690 lines in existing files (tpm2.c, tpm2_param_enc.c, tpm2_wrap.c)

Testing

Unit Tests (fwtpm_unit_tests.c, 2,223 lines)

56 test functions calling FWTPM_ProcessCommand() directly with crafted packets:

  • Startup/shutdown lifecycle, self-test
  • Error handling: undersized commands, bad tags, size mismatches, unknown commands, no-startup, oversize auth
  • GetRandom, StirRandom, GetCapability (algorithms, commands, properties, PCRs)
  • PCR read/extend/reset/event, ReadClock
  • CreatePrimary (RSA + ECC), Hash, ReadPublic
  • Auth sessions (HMAC, policy, trial), policy commands
  • NV define/write/read/counter/read-public
  • Hierarchy auth, Clear, ChangeEPS/ChangePPS
  • DA parameters/reset, ECC_Parameters
  • ContextSave/ContextLoad, EvictControl
  • ClockSet, hash sequences, NV/Clock HAL callbacks

tpm2-tools Integration Tests (tpm2_tools_test.sh, 2,127 lines)

318 tests across 63 test groups using standard tpm2-tools commands:

  • Startup, GetCapability, GetRandom
  • CreatePrimary, Create/Load (RSA + ECC), Sign/Verify
  • NV RAM (define, write, read, extend, counter, locks, setbits, changeauth)
  • Policy engine (PCR, password, authvalue, commandcode, OR, secret, authorize, locality, NV, countertimer)
  • Attestation (quote, certify, certify creation, gettime, NV certify)
  • RSA/AES encrypt/decrypt
  • EvictControl (persistent handles)
  • Import/Duplicate, MakeCredential/ActivateCredential
  • Hierarchy control, Clear, ClearControl, ChangePPS/ChangeEPS
  • Dictionary attack lockout
  • ContextSave/ContextLoad, LoadExternal, HMAC
  • Hash + Sign with TK_HASHCHECK ticket
  • ECC operations (ECDH_KeyGen, ECDH_ZGen, ECC_Parameters)
  • Primary key determinism across server restart
  • 14 negative test groups (auth failures, handle errors, PCR locality, NV errors, key type mismatches, policy failures, state violations, unsupported algorithms, disabled hierarchy, NV read lock)

Fuzz Testing (tests/fuzz/, libFuzzer)

  • fwtpm_fuzz.c: Feeds raw byte streams to FWTPM_ProcessCommand() with ASan
  • gen_corpus.py: Generates 29 seed corpus entries (valid TPM command packets)
  • tpm2.dict: Fuzzer dictionary with TPM tags, command codes, algorithm IDs
  • CI: weekly 10-minute full fuzz + 60-second PR smoke test

CI Workflows

New: fwtpm-test.yml (11 matrix entries)

Runtime tests (build + examples + make check):

  • fwtpm-socket: Primary socket transport test
  • fwtpm-tis: TIS/shared-memory transport test
  • fwtpm-asan: AddressSanitizer
  • fwtpm-ubsan: UndefinedBehaviorSanitizer

Build-only tests (compilation + pedantic warnings):

  • fwtpm-no-rsa, fwtpm-no-ecc, fwtpm-no-sha384, fwtpm-no-sha1
  • fwtpm-only (server-only, no client library)
  • fwtpm-minimal (all feature macros disabled)
  • Individual FWTPM_NO_* macro tests (policy, nv, attestation, credential, da, param-enc)
  • Cross-combinations (no-rsa + no-policy, no-ecc + no-nv)
  • WOLFTPM_SMALL_STACK
  • Pedantic: gcc -Werror, clang -Werror, fwtpm-only -Werror

Separate job: tpm2-tools (311 tests via scripts/tpm2_tools_test.sh)

New: fuzz.yml

  • Weekly Monday 4am UTC: 10-minute full fuzz run with ASan + leak detection
  • Per-PR: 60-second smoke test
  • Crash artifact upload on failure

Updated Existing Workflows

  • cmake-build.yml: Added fwTPM matrix entries (socket, TIS, fwtpm-only) + CTest step
  • coverity-scan-fixes.yml: Updated wolfSSL build flags
  • make-test-swtpm.yml: Enhanced for fwTPM server lifecycle management
  • sanitizer.yml: Added fwTPM sanitizer configurations
  • seal-test.yml: Updated for fwTPM compatibility
  • codespell.yml: Added new word exceptions (daa, pris, hsi)
  • multi-compiler.yml: Updated wolfSSL flags

Build System

  • configure.ac: New --enable-fwtpm, --enable-fwtpm-only, --enable-fuzz options; WOLFTPM_FWTPM_HAL/WOLFTPM_FWTPM_TIS auto-configuration when swtpm is not enabled
  • CMakeLists.txt: Full CMake support with WOLFTPM_FWTPM, WOLFTPM_FWTPM_ONLY options, fwtpm_server target, fuzz target, CTest integration
  • Makefile.am: Updated for new source files and scripts
  • src/fwtpm/include.am: Build rules for fwtpm_server and fwtpm_fuzz targets
  • IDE/VisualStudio/wolftpm.vcxproj: Added new shared source files

Documentation

  • docs/FWTPM.md (688 lines): Architecture, build instructions, all 105 commands documented, HAL porting guide with examples, configuration macro reference, transport mode details, API reference, lifecycle documentation, primary key derivation explanation
  • src/fwtpm/README.md (248 lines): Full CI test matrix, spec coverage gap analysis (v1.38/v1.59/v1.84/v1.85 roadmap), build/test quick reference
  • docs/SWTPM.md: Added fwTPM as alternative to external swtpm
  • README.md: Added fwTPM feature section with summary and link to docs
  • src/fwtpm/ports/README.md: Porting placeholder for embedded targets

Other Changes

  • examples/run_examples.sh: Updated to manage fwtpm_server lifecycle, stale cert/blob cleanup on NV wipe
  • examples/native/native_test.c: Conditional compilation for fwTPM compatibility
  • tests/unit_tests.c: Updated for shared utility refactoring
  • .gitignore: Added fwtpm_server binary, NV file, fuzz artifacts
  • pre-commit.sh: Removed (superseded by CI workflows)
  • zephyr/user_settings.h: Added WOLFTPM_FWTPM support

Remaining Known Gaps

  • 8 missing v1.38 commands (audit digests, DAA/Commit, field upgrade, SetAlgorithmSet, PP_Commands, SetCommandCodeAuditStatus)
  • NV encryption with device-unique key (TODO)
  • Clock HAL portable abstraction (TODO placeholder)
  • tpm2_import -i key.pem (direct import without tpm2_duplicate wrapping) returns TPM_RC_INTEGRITY due to tpm2-tools internal format difference; workaround via tpm2_duplicate --tcti none works correctly

wolfSSL-Fenrir-bot

This comment was marked as resolved.

@dgarske dgarske force-pushed the fwtpm branch 3 times, most recently from 9c0208f to eae465e Compare March 21, 2026 23:51
@dgarske dgarske changed the title Add fwTPM firmware TPM 2.0 server with STM32 port Add fwTPM firmware TPM 2.0 server Mar 21, 2026
@dgarske dgarske changed the title Add fwTPM firmware TPM 2.0 server Add new Firmware TPM (fwTPM) Mar 22, 2026
@dgarske dgarske force-pushed the fwtpm branch 2 times, most recently from b186ecc to f529484 Compare March 23, 2026 21:28
@dgarske dgarske assigned wolfSSL-Bot and unassigned dgarske and aidangarske Mar 24, 2026
@dgarske dgarske assigned dgarske and unassigned wolfSSL-Bot Mar 25, 2026
wolfSSL-Fenrir-bot

This comment was marked as resolved.

wolfSSL-Fenrir-bot

This comment was marked as resolved.

This comment was marked as resolved.

@aidangarske aidangarske requested a review from danielinux March 25, 2026 20:51
Comment thread src/fwtpm/fwtpm_nv.c Outdated
Comment thread src/fwtpm/fwtpm_nv.c
Comment thread src/fwtpm/fwtpm_command.c Outdated
Copilot AI review requested due to automatic review settings April 3, 2026 17:42

This comment was marked as resolved.

aidangarske

This comment was marked as resolved.

aidangarske

This comment was marked as resolved.

aidangarske

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 13, 2026 18:52

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 13, 2026 21:56

This comment was marked as resolved.

aidangarske

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 14, 2026 21:46

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 15, 2026 16:50

This comment was marked as resolved.

wolfSSL-Fenrir-bot

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 15, 2026 20:27

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 16, 2026 00:41

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 16, 2026 19:49

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 16, 2026 23:20

This comment was marked as resolved.

Add portable firmware TPM 2.0 implementation (fwTPM) built on wolfCrypt.
Implements 105/113 TPM 2.0 v1.38 commands (93%) as a standalone server
with socket and TIS transports, NV storage, and full CI/fuzz coverage.
@dgarske dgarske changed the title Add new Firmware TPM (fwTPM) Add firmware TPM 2.0 (fwTPM) implementation Apr 16, 2026
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.

6 participants