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.
- Renamed spdm_demo to spdm_ctrl: file, binary, internal demo_* functions to ctrl_*, all references in
include.am, spdm_test.sh, .gitignore, CLAUDE.md, both READMEs
- README mentions Nations: title updated to Nuvoton NPCT75x and Nations NS350 TPMs, added Nations build section
- README section header renamed from Demo Commands to Setup/Control Commands
- README added reset pin control section: documents GPIO reset requirement, Pi-specific example, custom hardware
design guidance
- Moved spdm_tcg.c to common build section, no longer conditional on Nuvoton/Nations in src/spdm/include.am
- Removed redundant wolfSSL options include from spdm_internal.h since tpm2_types.h handles this
- Added WOLFTPM_SPDM_TCG generic guard as auto-define in spdm_types.h, replaced ~30 occurrences of #if defined(WOLFSPDM_NUVOTON) || defined(WOLFSPDM_NATIONS) across all files
New examples:
- seal_pcr: PCR-only policy seal/unseal. Binds secrets to specific PCR
values without password or signing key. Supports split seal/unseal,
configurable PCR index, custom blob filenames, XOR/AES param encryption.
- seal_policy_auth: PolicyAuthorize with TPM-resident signing key (ECC/RSA).
Signing key can re-authorize PCR policy, allowing secrets to survive
authorized PCR changes (e.g., OS updates). Supports split seal/unseal,
XOR/AES param encryption.
- seal_nv: NV storage with PCR policy. Stores secrets directly in TPM
non-volatile memory with store/read/delete lifecycle and configurable
NV index. No external blob files needed.
Build system:
- Autotools: Updated include.am for seal and nvram with new build targets
- CMake: Added add_tpm_example() entries for all three examples
- Headers: Updated seal.h and nvram.h with new prototypes, removed old
TPM2_PCR_Seal_With_Policy_Auth_* declarations
- .gitignore: Added built binaries
Testing:
- run_examples.sh: Added ~110 lines of integration tests for seal_pcr,
seal_policy_auth (ECC + RSA), and seal_nv (store/read/delete lifecycle)
- seal_test.sh: Standalone test script with 28 tests across 3 groups
including positive, negative, param encryption, and custom path tests
- seal-test.yml: Dedicated CI workflow with SWTPM, path-filtered to
seal-related files, follows make-test-swtpm.yml pattern
Documentation:
- README.md: Usage examples and policy comparison table for all seal examples
* Added new build option for TPM provisioning (`--enable-provisioning` on by default).
* Added new `wolfTPM2_CreatePrimaryKey_ex` and `WOLFTPM2_PKEY` that supports returning creation ticket/hash.
* Added key templates for initial device (IDevID) and attestation keys (IAK).
* Extended `create_primary` example to support creation or IDevID and IAK.
* Added new policy hash helper API `wolfTPM2_PolicyHash`
* Switch handle/nvIndex string parsing to use `strtoul`.
ZD 18347
Added Infineon Modus Toolbox support. See `wolfssl/IDE/Infineon/README.md` for setup instructions.
Added support for Infineon CyHal I2C support.
Added Firmware extraction tool
Added Firmware update example application `examples/firmware/ifx_fw_update`.
Added support for vendor capabilities `TPM_CAP_VENDOR_PROPERTY`.
Added `XSLEEP_MS` macro for firmware update delay.
Added support for getting key group id, operational mode and update counts.
Added support for abandoning an update.
Added support for firmware update done, but not finalized
Fix auto-detect to not define SLB9672/SLB9673.
wolfTPM2_SealWithAuthSigNV needs to have PolicyPCR called as a part of its logic since it uses wolfTPM2_SetAuthPassword, which interferes with the policy digest
* Support for PCR with policy. Issue #109
* Progress on PCR policy. Work from John Bland.
* add wrapper functions to seal secrets the NVM with policy authorization
fix the seal and unseal with policy functions to work with non trial policies
update policy examples to allow multiple pcr indicies to be used, currently only 2 can be used because TPML_PCR_SELECTION only allows 2 pcr sellections, may need to be refactored but I didn't want to blow that part of the codebase up
* fix TPM2_SetupPCRSel to correctly use hash type banks
* update policy functions and examples based on pr comments
fixed rsa keys not working due to null default signing algorithm, seal_policy_auth can now be called with no arguments and will pick defaults
* update policy examples based on pcr comments
added error codes and htons macro for use when wolfcrypt is not available
* added policySigned logic to policy seal with nv functions
currently the policy seal with auth nv example is broken due to strange session issues
* Improvements to the session authentication for policy sessions.
* update the sealNV functions, add PolicyRestart and manual htnos
wolfTPM2_SealWithAuthSigNV allows for sealing secrets to NV with just the public part of the sealing key and a pre signed signature so that the private part of the key can be kept off the system. PolicyRestart was added to make reseting the policyDigest easy and a manual htnos function was added for use in wolfBoot
* update policy code based on pr comments
* reconfigure wolfTPM after setting up ibm simulator
* define XREWIND in wolfTPM since it is no longer in wolfssl
* fix scan-build warnings
* remove RSA_SIG_SZ
* use signed char in HexCharToByte for strict build options
* update based on pr comments
---------
Co-authored-by: David Garske <david@wolfssl.com>
* Added key generation example with parameter encryption
* Fixes and cleanups for KDFa
* Added KDFa unit test (passes)
* Added AES CFB support
* Fix for nonceTPM
* Added support for encrypted RSA salt and salted-unbounded session
* Removed unsalted-unbounded specific code for authValueKDF from KDFa
* Add innerWrap support
* Add missing wolfcrypt header for AES CFB
* Fixes for casting when calling KDFa for AES CFB parameter encryption
* Add outerWrap support
Signed-off-by: Dimitar Tomov <dimi@wolfssl.com>