Skip to content

Fixes for Firmware TPM issues and related session, clock and signature defects - #656

Open
dgarske wants to merge 13 commits into
wolfSSL:masterfrom
dgarske:fwtpm_fixes
Open

dgarske wants to merge 13 commits into
wolfSSL:masterfrom
dgarske:fwtpm_fixes

Conversation

@dgarske

@dgarske dgarske commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

This PR fixes the fwTPM issues #648-#654, plus related defects in the same code paths. Each fix is its own commit with a regression test:

Related fixes:

  • Apply command HMAC verification consistently to every session in the authorization area.
  • Hash and StirRandom parse their parameters after the authorization area and return session-framed responses.
  • TPM_CAP_HANDLES includes hash, HMAC, event, sign and verify sequence handles.
  • wolfTPM2_SignDigest and wolfTPM2_SignSequenceComplete normalize ECDSA scalars to the curve width, as wolfTPM2_SignHashScheme already does.
  • TPM2_Sign reports a digest size mismatch on parameter 1.

Notes:

  • New FWTPM_Clock_PowerOn() for hosts that power cycle within one FWTPM_CTX. Embedded hosts must call FWTPM_Clock_Update() at least every FWTPM_CLOCK_POLL_MS.
  • Older fwTPM firmware cannot read the extended orderly-shutdown NV marker, so a downgrade needs journal conversion.
  • MAX_CONTEXT_SIZE defaults to 4096 when MAX_RSA_KEY_BITS exceeds 2048 and to 8192 with PQC, since an object context now carries the private key. Define it to keep a fixed size.
  • New CI job runs tpm2-pkcs11 (tpm2_ptool and OpenSC pkcs11-tool) against fwtpm_server, directly and through tpm2-abrmd, for the classic and v1.85 builds.

Fixes #648, Fixes #649, Fixes #650, Fixes #651, Fixes #652, Fixes #653, Fixes #654

@AlexLaroche

Copy link
Copy Markdown

Thanks @dgarske, I tested #656 (0d35f1d) against master (d7f73b5) and it resolves #648–#653. #654 is mostly resolved: see the note below.

Reproductions. Both servers were built with --enable-fwtpm-only --enable-swtpm on wolfSSL v5.9.4-stable, with AddressSanitizer. Each case uses the ESYS program from its issue.

Issue master d7f73b5 #656
#648 Unseal through an encrypting session (plain, and salted+bound) 64 bytes, wrong 64 bytes, correct
#649 ECDSA r/s of 200 signatures each (P-256 child, P-521 child, P-256 primary) 1/0, 95/107, 2/1 short none short
#650 RSA_Decrypt OAEP-SHA1 (MGF1-SHA1) of an OpenSSL ciphertext TPM_RC_FAILURE decrypts, plaintext matches
#650 TPM_CAP_ALGS no SHA-1 SHA-1 and SHA3-256/384/512 listed
#651 TPM_CAP_TPM_PROPERTIES from TPM_PT_FIXED 19 properties 46, including TPM_PT_CONTEXT_HASH/_SYM/_SYM_SIZE (SHA-256, AES, 256)
#652 ContextSave, FlushContext, ContextLoad of a loaded key TPM_RC_HANDLE on load loads
#653 TestParms RSA keyBits 1000 0x087 0x1c4, the same as libtpms
#654 ECDSA of an all-zero digest TPM_RC_FAILURE TPM_RC_VALUE on parameter 1

End to end. I also ran the tpm2-pkcs11 stack you mention in the PR's notes. That was released tpm2-pkcs11 1.10.1 on tpm2-tss 4.2.0, driven by a C# PKCS#11 suite of 642 cases. It ran on both tpm2-pkcs11 store backends (esysdb and FAPI), and on both the classic and --enable-v185 fwTPM builds:

These results are without any of the local patches I had been applying to fwTPM for #648–#652, so I can drop them.

One note on #654. A clear TPM_RC_VALUE on the digest parameter is a real improvement, because a client no longer sees the TPM as failed. libtpms and the TCG reference implementation still sign e = 0, so a PKCS#11 C_Sign of an empty message with CKM_ECDSA works on those and fails on fwTPM. I'm fine with closing #654 on this. If wolfCrypt later accepts a zero hash, signing it would match the other TPMs.

@dgarske

dgarske commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

Hi @AlexLaroche thank you for that feedback! I've pushed updates. Can you take another look? Thanks, David Garske, wolfSSL

@embhorn embhorn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skoll Multi-Scan Review

Modes: review + review-security

Overall recommendation: REQUEST_CHANGES
Findings: 6 total — 6 posted, 0 skipped
6 finding(s) posted as inline comments (see file-level comments below)

Posted findings

  • [High] [review] Legacy persistent-object children can no longer be context-saved — src/fwtpm/fwtpm_command.c:5844-5848
  • [High] [review] Any signing failure on a zero digest becomes a parameter error — src/fwtpm/fwtpm_crypto.c:3990-3995
  • [High] [review] RSA SHA-3 schemes silently use MGF1-SHA256 — src/fwtpm/fwtpm_crypto.c:94-107
  • [Medium] [review-security] Fresh TPM reports Clock as unsafe for its first update interval — src/fwtpm/fwtpm.c:41-47
  • [Medium] [review-security] OAEP now selects MGF1 from the scheme hash — src/fwtpm/fwtpm_crypto.c:85-88
  • [Medium] [review-security] SHA-3 RSA falls back to MGF1-SHA256 when its selector is unavailable — src/fwtpm/fwtpm_crypto.c:94-108

Review generated by Skoll

Comment thread src/fwtpm/fwtpm_command.c Resolved
Comment thread src/fwtpm/fwtpm_crypto.c Resolved
Comment thread src/fwtpm/fwtpm_crypto.c Resolved
Comment thread src/fwtpm/fwtpm.c Resolved
Comment thread src/fwtpm/fwtpm_crypto.c Resolved
Comment thread src/fwtpm/fwtpm_crypto.c Resolved
@embhorn embhorn assigned dgarske and unassigned embhorn Oct 29, 2026
@AlexLaroche

Copy link
Copy Markdown

Hi @AlexLaroche thank you for that feedback! I've pushed updates. Can you take another look? Thanks, David Garske, wolfSSL

Thanks @dgarske! I retested #656 at ad2e978, again with no local patches. Everything still holds, and #654 is now fully resolved.

Reproductions. As before: fwtpm_server built with --enable-fwtpm-only --enable-swtpm on wolfSSL v5.9.4-stable, with AddressSanitizer, and each issue's ESYS program. No sanitizer reports.

Issue ad2e978
#648 Unseal through an encrypting session (plain, and salted+bound) 64 bytes, correct
#649 ECDSA r/s of 200 signatures each (P-256 child, P-521 child, P-256 primary) none short
#650 RSA_Decrypt OAEP-SHA1 (MGF1-SHA1) of an OpenSSL ciphertext decrypts, plaintext matches
#650 TPM_CAP_ALGS SHA-1 and SHA3-256/384/512 listed
#651 TPM_CAP_TPM_PROPERTIES from TPM_PT_FIXED 46 properties
#652 ContextSave, FlushContext, ContextLoad of a loaded key loads
#653 TestParms RSA keyBits 1000 0x1c4, the same as libtpms
#654 ECDSA of an all-zero digest, wolfSSL defaults TPM_RC_VALUE on parameter 1
#654 ECDSA of an all-zero digest, wolfSSL with -DWC_ALLOW_ECC_ZERO_HASH signs; OpenSSL verifies the signature against the key's public point

Thanks for the WC_ALLOW_ECC_ZERO_HASH path. With it, a PKCS#11 C_Sign of an empty message with CKM_ECDSA works on fwTPM as it does on libtpms and the TCG reference implementation.

End to end. The C# PKCS#11 suite (642 cases) ran through tpm2-pkcs11, now at master a5156c5, on tpm2-tss 4.2.0. It covered both store backends (esysdb and FAPI) and both the classic and --enable-v185 builds, connected directly and behind tpm2-abrmd. All 8 configurations pass, with 0 failures. That includes the --enable-v185 build behind tpm2-abrmd, which I hadn't run last time.

One small note on the new digest-size check in TPM2_Sign (fwtpm_command.c, "Part 3 Sec.20.2.1"). It returns a bare TPM_RC_SIZE, while the TCG reference implementation returns TPM_RCS_SIZE + RC_Sign_digest, which names parameter 1 (Sign.c). The reference also checks the size only when no validation ticket is supplied. I found this by reading the code, not by running it. It doesn't affect anything above.

@AlexLaroche

Copy link
Copy Markdown

One more finding on ad2e978, in the same area as #653: object creation with a key size or curve the build doesn't support.

TPM2_CreatePrimary with an RSA key size the build doesn't support returns TPM_RC_FAILURE, so a client reads it as a TPM failure. TestParms already gives the right code for the same template since #653. The TPM keeps working afterwards (GetRandom succeeds). This comes from an ESYS program run against both servers, with a signing key in the null hierarchy:

fwTPM ad2e978 libtpms
RSA 3072, TestParms 0x1c4 success
RSA 3072, CreatePrimary 0x101 (TPM_RC_FAILURE) success
RSA 4096, TestParms 0x1c4 0x1c4
RSA 4096, CreatePrimary 0x101 (TPM_RC_FAILURE) 0x2c4 (TPM_RC_VALUE, parameter 2)
P-224, TestParms 0x1e6 success
P-224, CreatePrimary 0x0a6 (TPM_RC_CURVE, no parameter number) success

From the code, CreatePrimary and Create don't check keyBits before wc_MakeRsaKey, and FwGenerateRsaKey maps the wolfCrypt error to TPM_RC_FAILURE. Running the same check TestParms does would give 0x2c4 for the RSA sizes and 0x2e6 (TPM_RC_CURVE on inPublic) for P-224. I only ran CreatePrimary; Create goes through the same FwGenerateRsaKey.

@dgarske
dgarske requested a review from embhorn October 29, 2026 17:35
@dgarske dgarske assigned embhorn and unassigned dgarske Oct 29, 2026
@dgarske

dgarske commented Oct 29, 2026

Copy link
Copy Markdown
Member Author

Hi @AlexLaroche , thanks for the feedback! Can you review the latest work? Thanks, David Garske, wolfSSL

@embhorn embhorn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skoll Code Review

Scan type: review

Overall recommendation: REQUEST_CHANGES
Findings: 3 total — 3 posted, 0 skipped
3 finding(s) posted as inline comments (see file-level comments below)

Posted findings

  • [High] No-NV power cycle reports a rolled-back Clock as safe — src/fwtpm/fwtpm.c:265-268
  • [High] RSA seed operations accept a parent with no usable MGF1 — src/fwtpm/fwtpm_crypto.c:105-108
  • [High] Clock compaction can replace the durable checkpoint with a different RAM value — src/fwtpm/fwtpm_nv.c:2968-2976

Review generated by Skoll

Comment thread src/fwtpm/fwtpm.c Resolved
Comment thread src/fwtpm/fwtpm_crypto.c Resolved
Comment thread src/fwtpm/fwtpm_nv.c Resolved

@embhorn embhorn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skoll Code Review

Scan type: review

Overall recommendation: REQUEST_CHANGES
Findings: 2 total — 2 posted, 0 skipped
2 finding(s) posted as inline comments (see file-level comments below)

Posted findings

  • [High] Socket polling timeout disconnects valid slow clients — src/fwtpm/fwtpm_io.c:100-103
  • [Medium] HMAC sweep accepts unrelated command errors as proof — tests/fwtpm_unit_tests.c:17308-17312

Review generated by Skoll

Comment thread src/fwtpm/fwtpm_io.c Resolved
Comment thread tests/fwtpm_unit_tests.c Resolved

@embhorn embhorn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skoll Code Review

Scan type: review

Overall recommendation: REQUEST_CHANGES
Findings: 2 total — 2 posted, 0 skipped
2 finding(s) posted as inline comments (see file-level comments below)

Posted findings

  • [High] Reset the server Time epoch on platform power-on — src/fwtpm/fwtpm_main.c:340-341
  • [Medium] Correct the Clock rollback claim in the new API documentation — wolftpm/fwtpm/fwtpm.h:1094-1096

Review generated by Skoll

Comment thread src/fwtpm/fwtpm_main.c Resolved
Comment thread wolftpm/fwtpm/fwtpm.h Resolved

@embhorn embhorn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skoll Code Review

Scan type: review

Overall recommendation: REQUEST_CHANGES
Findings: 1 total — 1 posted, 0 skipped
1 finding(s) posted as inline comments (see file-level comments below)

Posted findings

  • [High] Fresh initialization discards the committed Clock checkpoint — src/fwtpm/fwtpm.c:181

Review generated by Skoll

Comment thread src/fwtpm/fwtpm.c Resolved
Copilot AI balanced review requested due to automatic review settings November 2, 2026 19:18
@dgarske
dgarske requested a review from embhorn November 2, 2026 19:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new CI job installs system packages at runtime rather than baking them into the versioned CI image as required, introducing a dependency on live package repositories.

1 open issue
What changed in this PR

This PR addresses fwTPM compatibility issues #648–#654 and related session, clock, and signature defects, improving interoperability with tpm2-pkcs11 and resource managers.

Changes:

  • Corrects authorization-session handling, signature encoding, RSA hash selection, capability reporting, and parameter validation.
  • Adds restorable object snapshots and durable Clock and orderly-counter recovery.
  • Adds signature and socket regression tests, PKCS#11 integration coverage, and updated configuration documentation.
File Description
wolftpm/​tpm2_wrap.h Documents fixed-width ECC signatures.
wolftpm/​tpm2_types.h Increases context capacity for larger keys.
wolftpm/​fwtpm/​fwtpm.h Adds Clock persistence state and APIs.
wolftpm/​fwtpm/​fwtpm_tis.h Documents bounded transport waits.
tests/​signature_padding_tests.c Tests ECC padding and output bounds.
tests/​include.am Adds the signature test target.
tests/​fwtpm_hal_unit_tests.c Stubs Clock updates for transport tests.
tests/​fwtpm_check.sh Tests clients pausing mid-command.
src/​tpm2_wrap.c Shares fixed-width ECC signature extraction.
src/​fwtpm/​README.md Documents Clock recovery and journal compatibility.
src/​fwtpm/​include.am Applies server-specific build flags.
src/​fwtpm/​fwtpm.c Implements Clock power-on recovery and checkpoint scheduling.
src/​fwtpm/​fwtpm_tis.c Checkpoints Clock in the TIS loop.
src/​fwtpm/​fwtpm_tis_shm.c Bounds shared-memory semaphore waits.
src/​fwtpm/​fwtpm_nv.c Persists Clock checkpoints and orderly safety state.
src/​fwtpm/​fwtpm_main.c Registers a monotonic host clock.
src/​fwtpm/​fwtpm_io.c Polls Clock during socket waits and handles power-on recovery.
src/​fwtpm/​fwtpm_crypto.c Corrects RSA hash mappings and ECDSA output handling.
src/​fwtpm/​fwtpm_command.c Updates sessions, contexts, capabilities, validation, and orderly counters.
scripts/​tpm2_pkcs11_test.sh Adds PKCS#11 interoperability tests.
docs/​ja/​fwtpm/​building.md Documents the server object-slot default in Japanese.
docs/​fwtpm/​building.md Documents the server object-slot default.
configure.ac Defaults the server to seven object slots.
.gitignore Ignores signature-test artifacts.
.github/​workflows/​fwtpm-test.yml Adds direct and resource-managed PKCS#11 CI coverage.

Review effort: Balanced

Comment thread .github/workflows/fwtpm-test.yml Outdated
Comment on lines +594 to +597
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y \
libtpm2-pkcs11-1 libtpm2-pkcs11-tools tpm2-abrmd \
libtss2-tcti-tabrmd0 opensc dbus

@embhorn embhorn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skoll Multi-Scan Review

Modes: review + review-security

Overall recommendation: APPROVE
Findings: 0 total — 0 posted, 0 skipped

No issues found.

Review generated by Skoll

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

6 participants