Build / portability:
- Drop #pragma message in fwtpm_crypto.c (MSVC-incompatible)
- Replace non-ASCII section sign with Sec. across all sources/docs
Configure:
- Add --enable-pqc alias for --enable-v185 (same WOLFTPM_V185 macro)
- Auto-detect: when --enable-fwtpm + wolfCrypt has dilithium.h+mlkem.h
and neither flag is set, configure auto-enables PQC; --disable-pqc
opts out
- Both flags probe the wolfSSL PQC headers and fail at configure time
with a clear hint when missing
Spec / security hardening:
- VerifySequenceComplete now emits TPM_ST_DIGEST_VERIFIED (with hashAlg
metadata) for Hash-ML-DSA tickets, MESSAGE_VERIFIED for Pure ML-DSA
(was mis-tagging digests as messages, breaking PolicyTicket consumers)
- Sign/VerifySequenceComplete: free the slot on TPM_RC_SIGN_CONTEXT_KEY
too, so wrong-key Complete cannot exhaust FWTPM_MAX_SIGN_SEQ slots
(CWE-772 DoS)
- TestParms PQC arms return TPM_RC_PARMS (spec-correct) instead of
TPM_RC_VALUE; reject MLDSA/MLKEM parameter sets not actually compiled
in; parse TPMS_MLKEM_PARMS.symmetric via TPM2_Packet_ParseSymmetric
- GetCapability TPMA_ML_PARAMETER_SETS gates each MLDSA/MLKEM bit on the
per-set wolfCrypt availability macro (subset builds advertise truth)
- TPM2_VerifySignature client parser now defensive: only consume the
v1.85 metaAlg when tag==DIGEST_VERIFIED && hierarchy!=RH_NULL
- VerifyDigestSignature: hard-fail on keyName overflow instead of
silently emitting a ticket missing the name binding
- TPM_GENERATED_VALUE prefix check guarded with rc==0
- Drop dead (void)cmdSize casts in Sign/VerifySequenceStart
- wolfTPM2_EncryptSecret_MLKEM: track wc_InitRng_ex/wc_MlKemKey_Init
success flags so Free is only called on initialized state
- UBSan-v185 sanitizer cflags: explicitly disable signed-integer-overflow
and shift checks (matches the comment about wolfSSL Hash_df 440<<24)
Embedded RAM:
- FWTPM_NV_PUBAREA_EST derives from FWTPM_MAX_MLDSA_PUB_SIZE /
FWTPM_MAX_MLKEM_PUB_SIZE auto-shrink macros (subset builds save NV)
- tpm2_types.h MAX_MLDSA_*/MAX_MLKEM_* stay at worst-case (ABI floor
for TPM2B wire buffers) with comment
Tests:
- Negative test for Hash-MLDSA VerifySeqComplete ticket tag
- Negative test exposing sign-seq slot leak on TPM_RC_SIGN_CONTEXT_KEY
- Roundtrip test for wolfTPM2_SignDigest + VerifyDigestSignature
Documentation:
- README, FWTPM.md, fwtpm/README.md, examples/pqc/README.md mention
both --enable-pqc and --enable-v185 + auto-detect
- README wolfSSL line: --enable-pkcallbacks + WC_RSA_NO_PADDING
- fwtpm/README.md: drop FWTPM_SPEC_* labels (macros never existed),
remove v1.85 Additions table (all 8 commands implemented), update
coverage table to 137/113/24 (82%); note remaining gaps are
inherited v1.59/v1.84 commands, not PQC
- fwtpm_nv.h:52: clarify 2592 vs 2720 math (PQC pub key + header slack)
Closes 13 spec-conformance findings flagged by two TCG compliance reviews
of the v1.85 PQC handlers. Each fix maps to a specific Part 2 / Part 3
section; all are exercised by negative test fixtures in
tests/fwtpm_unit_tests.c that bite-verify each fix in isolation.
Spec-RC corrections (one-line each):
- Drop TPMA_ML_PARAMETER_SET_extMu from TPM_PT_ML_PARAMETER_SETS — Part 2
§12.2.3.6 (no μ-direct sign API in wolfCrypt yet).
- Sign* handlers return TPM_RC_SCHEME (not TPM_RC_KEY) for valid keys
with unsupported scheme — Part 3 §17.5.1 / §20.7.1.
- SignDigest / VerifyDigestSignature return TPM_RC_ATTRIBUTES (not
TPM_RC_EXT_MU) when key's allowExternalMu=NO — EXT_MU is reserved for
capability errors, ATTRIBUTES for key-attribute errors.
Validation additions:
- SignDigest rejects restricted and x509sign keys at entry
(TPM_RC_ATTRIBUTES, Part 3 §20.7.1).
- VerifyDigestSignature enforces sigHashAlg == key.hashAlg
(TPM_RC_SCHEME, Part 3 §20.4.1) and digest size == hashAlg digest size
(TPM_RC_SIZE).
- CreatePrimary / Create / CreateLoaded / TestParms reject MLDSA with
allowExternalMu=YES at object-creation time (TPM_RC_EXT_MU, Part 2
§12.2.3.6) instead of letting the request succeed and fail later.
- TestParms validates ML-DSA / Hash-ML-DSA / ML-KEM parameterSet ranges.
- SignSequenceComplete rejects restricted keys signing messages whose
first 4 bytes are TPM_GENERATED_VALUE (0xFF544347) (TPM_RC_VALUE,
Part 3 §20.6.1).
- SignSequenceComplete rejects x509sign keys (TPM_RC_ATTRIBUTES).
- TPM_RC_ONE_SHOT_SIGNATURE moved from SequenceUpdate to
SignSequenceComplete (Part 3 §20.6.1: it's a Complete-time RC about
non-empty sequence, not an Update-time RC).
Structural fixes:
- TPMA_OBJECT_x509sign (bit 19, Part 2 §8.3.3 v1.85) added to the enum
in wolftpm/tpm2.h and enforced in the two sign-side handlers.
- TPM_PT_ML_PARAMETER_SETS bits gated on wolfCrypt build symbols
(WOLFSSL_HAVE_MLKEM / KYBER_*, WOLFSSL_WC_DILITHIUM / HAVE_DILITHIUM)
so the capability matches what the build actually delivers.
- wolfTPM2_EncryptSecret_MLKEM applies KDFa(SECRET, ct, pub) over the
ML-KEM shared secret per Part 1 §47.4 Eq 66 (Labeled-KEM); previous
code emitted raw K as the salt.
- VerifySequenceComplete and VerifyDigestSignature emit hierarchy-bound
TPMT_TK_VERIFIED tickets (Part 2 §10.6.5) instead of the
TPM_RH_NULL + empty-HMAC stub.
Tests (tests/fwtpm_unit_tests.c, 8 new + 4 updated, all under fwtpm_unit):
- 8 new spec-bite negatives, one per finding where a single-RC test is
meaningful. Each was bite-verified by reverting its source fix and
confirming the test fails with a different RC.
- 4 existing negatives updated to assert the new spec-mandated RCs and
reshaped where the rejection point moved (SequenceUpdate → Complete).
CI:
- New .github/workflows/pqc-examples.yml: builds + smoke-runs the v1.85
examples + invokes tests/check_doc_constants.sh on each PR.
- tests/check_doc_constants.sh greps every FWTPM_* size/seed/digest
constant from wolftpm/fwtpm/fwtpm.h and asserts each is mentioned in
docs/FWTPM.md (catches doc drift like the v1.85
FWTPM_MAX_COMMAND_SIZE 4096→8192 bump). docs/FWTPM.md gains 6 missing
entries (CMD_AUTHS, SENSITIVE_SIZE, SIGN_SEQ, SYM_KEY_SIZE,
HMAC_KEY_SIZE, HMAC_DIGEST_SIZE) so the check passes clean.
- fuzz.yml / fwtpm-test.yml / make-test-swtpm.yml / sanitizer.yml each
gain a v1.85 matrix entry running the same checks under
--enable-v185 + wolfSSL --enable-dilithium --enable-mlkem
--enable-experimental.
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.