Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7e8aec5
6748 - Gate fwTPM TestParms PQC arms on WOLFTPM_MLDSA/WOLFTPM_MLKEM
aidangarske Jul 7, 2026
cd46447
6749 - Bound ECDH response x-coordinate against caller buffer capacity
aidangarske Jul 7, 2026
e41d2c9
6738 - Require explicit master password in wolfTPM2_SetIdentityAuth
aidangarske Jul 7, 2026
a634687
6739 - Propagate readKeyBlob failure in activate_credential example
aidangarske Jul 7, 2026
b47aa22
6740 - Propagate readKeyBlob failure in external_import example
aidangarske Jul 7, 2026
32ef758
6741 - Use rsaDec label size for RSA Decrypt label copy in native_test
aidangarske Jul 7, 2026
7b85356
6742 - Add KDFe known-answer vector to pin hash-input construction
aidangarske Jul 7, 2026
c29d5ec
6743 - Add CalcHmac KAT and cpHash/attributes binding checks
aidangarske Jul 7, 2026
9a56a46
6745 - Fix RSA exponent byte order in wolfTPM2_RsaKey_TpmToWolf
aidangarske Jul 7, 2026
ee00c70
6746 - Right-align short ECC coordinates in wolfTPM2_EccKey_TpmToWolf
aidangarske Jul 7, 2026
78096c1
6750 - Scrub hash context in wolfTPM2_SetIdentityAuth after use
aidangarske Jul 7, 2026
67feae3
6744 - Exercise crypto-callback ECDSA invalid-signature branch in test
aidangarske Jul 7, 2026
fe88c6a
6738 - Allow sample password on autodetect Infineon builds and check …
aidangarske Jul 7, 2026
a79760c
6746 - Use deterministic P-256 vector in short-coordinate test
aidangarske Jul 7, 2026
d91adb6
6738 - Match SetIdentityAuth test guard to production autodetect gating
aidangarske Jul 7, 2026
ea50fa5
6746 - Drop redundant WOLFTPM2_NO_WRAPPER guard on TpmToWolf tests
aidangarske Jul 7, 2026
c42c6f6
6749 - Collapse wolfTPM2_EccZToBuffer header comment to one line
aidangarske Jul 7, 2026
ebfdcf3
6738 - Update TLS example comment for Infineon-gated sample password
aidangarske Jul 7, 2026
eef373d
6738 - Document Infineon-gated master password precondition in Doxygen
aidangarske Jul 7, 2026
41ba3bb
6749 - Bound EccZToBuffer source size against z->buffer to prevent OO…
aidangarske Jul 7, 2026
3d2f217
6743 - Assert HMAC size before comparing against fixed KAT length
aidangarske Jul 7, 2026
732e4c8
6738 - Gate identity sample password on ST33/autodetect not Infineon
aidangarske Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/attestation/activate_credential.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
rc = readKeyBlob(keyblob, &akKey);
if (rc != TPM_RC_SUCCESS) {
printf("Failure to read keyblob.\n");
goto exit;
}
rc = wolfTPM2_LoadKey(&dev, &akKey, &primary->handle);
if (rc != TPM_RC_SUCCESS) {
Expand Down
1 change: 1 addition & 0 deletions examples/keygen/external_import.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ int TPM2_ExternalImport_Example(void* userCtx, int argc, char *argv[])
rc = readKeyBlob(keyblobFile, rsaKey3);
if (rc != TPM_RC_SUCCESS) {
printf("Error reading keyblob.bin: %d\n", rc);
goto exit;
}
}
else { /* create key and save as keyblob.bin */
Expand Down
2 changes: 1 addition & 1 deletion examples/native/native_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,7 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
cmdIn.rsaDec.inScheme.scheme = TPM_ALG_OAEP;
cmdIn.rsaDec.inScheme.details.oaep.hashAlg = TPM_ALG_SHA256;
cmdIn.rsaDec.label.size = sizeof(label); /* Null term required */
XMEMCPY(cmdIn.rsaDec.label.buffer, label, cmdIn.rsaEnc.label.size);
XMEMCPY(cmdIn.rsaDec.label.buffer, label, cmdIn.rsaDec.label.size);
rc = TPM2_RSA_Decrypt(&cmdIn.rsaDec, &cmdOut.rsaDec);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_RSA_Decrypt failed 0x%x: %s\n", rc,
Expand Down
9 changes: 4 additions & 5 deletions examples/tls/tls_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,11 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
/* Attempt to use pre-provisioned identity key */
rc = wolfTPM2_ReadPublicKey(&dev, &eccKey, TPM2_IDEVID_KEY_HANDLE);
if (rc == 0) {
/* Custom should supply their own custom master password used during
* device provisioning. If using a sample TPM supply NULL to use the
* default password. */
wolfTPM2_SetIdentityAuth(&dev, &eccKey.handle, NULL, 0);
/* NULL uses the sample password on ST33 builds; else supply your
* own provisioning password (or this falls back to a key) */
rc = wolfTPM2_SetIdentityAuth(&dev, &eccKey.handle, NULL, 0);
}
else
if (rc != 0)
#endif
{
/* Create/Load ECC key for TLS authentication */
Expand Down
9 changes: 4 additions & 5 deletions examples/tls/tls_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,11 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
/* Attempt to use pre-provisioned identity key */
rc = wolfTPM2_ReadPublicKey(&dev, &eccKey, TPM2_IDEVID_KEY_HANDLE);
if (rc == 0) {
/* Custom should supply their own custom master password used during
* device provisioning. If using a sample TPM supply NULL to use the
* default password. */
wolfTPM2_SetIdentityAuth(&dev, &eccKey.handle, NULL, 0);
/* NULL uses the sample password on ST33 builds; else supply your
* own provisioning password (or this falls back to a key) */
rc = wolfTPM2_SetIdentityAuth(&dev, &eccKey.handle, NULL, 0);
}
else
if (rc != 0)
#endif
{
/* Create/Load ECC key for TLS authentication */
Expand Down
6 changes: 4 additions & 2 deletions src/fwtpm/fwtpm_command.c
Original file line number Diff line number Diff line change
Expand Up @@ -1554,7 +1554,7 @@ static TPM_RC FwCmd_TestParms(FWTPM_CTX* ctx, TPM2_Packet* cmd, int cmdSize,
case TPM_ALG_NULL:
/* Supported - skip remaining type-specific params */
break;
#ifdef WOLFTPM_V185
#ifdef WOLFTPM_MLDSA
/* Part 2 Sec.12.2.3.6: TestParms for ML-DSA / Hash-ML-DSA / ML-KEM
* MUST validate the parameterSet range, and for ML-DSA MUST
* return TPM_RC_EXT_MU when allowExternalMu=YES on a TPM that
Expand Down Expand Up @@ -1611,6 +1611,8 @@ static TPM_RC FwCmd_TestParms(FWTPM_CTX* ctx, TPM2_Packet* cmd, int cmdSize,
}
break;
}
#endif /* WOLFTPM_MLDSA */
#ifdef WOLFTPM_MLKEM
case TPM_ALG_MLKEM: {
/* TPMS_MLKEM_PARMS = symmetric (TPMT_SYM_DEF_OBJECT+) +
* parameterSet. Use the existing TPMT symmetric parser so
Expand Down Expand Up @@ -1640,7 +1642,7 @@ static TPM_RC FwCmd_TestParms(FWTPM_CTX* ctx, TPM2_Packet* cmd, int cmdSize,
}
break;
}
#endif /* WOLFTPM_V185 */
#endif /* WOLFTPM_MLKEM */
default:
/* Unrecognized algorithm type. TPM_RC_PARMS only exists
* under WOLFTPM_V185; fall back to TPM_RC_TYPE otherwise. */
Expand Down
109 changes: 72 additions & 37 deletions src/tpm2_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -4615,11 +4615,12 @@ int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
exponent = tpmKey->pub.publicArea.parameters.rsaDetail.exponent;
if (exponent == 0)
exponent = RSA_DEFAULT_PUBLIC_EXPONENT;
e[3] = (exponent >> 24) & 0xFF;
e[2] = (exponent >> 16) & 0xFF;
e[1] = (exponent >> 8) & 0xFF;
e[0] = exponent & 0xFF;
eSz = e[3] ? 4 : e[2] ? 3 : e[1] ? 2 : e[0] ? 1 : 0; /* calc size */
/* big-endian, matching wc_RsaPublicKeyDecodeRaw and RsaKey_Exponent */
e[0] = (exponent >> 24) & 0xFF;
e[1] = (exponent >> 16) & 0xFF;
e[2] = (exponent >> 8) & 0xFF;
e[3] = exponent & 0xFF;
eSz = e[0] ? 4 : e[1] ? 3 : e[2] ? 2 : e[3] ? 1 : 0; /* significant bytes */

/* load public key */
nSz = tpmKey->pub.publicArea.unique.rsa.size;
Expand All @@ -4628,8 +4629,8 @@ int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
}
XMEMCPY(n, tpmKey->pub.publicArea.unique.rsa.buffer, nSz);

/* load public key portion into wolf RsaKey */
rc = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, wolfKey);
/* load public key portion into wolf RsaKey (pass trailing significant e) */
rc = wc_RsaPublicKeyDecodeRaw(n, nSz, e + (sizeof(e) - eSz), eSz, wolfKey);

return rc;
}
Expand Down Expand Up @@ -4798,7 +4799,7 @@ int wolfTPM2_RsaKey_PubPemToTpm(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
int wolfTPM2_EccKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
ecc_key* wolfKey)
{
int rc, curve_id;
int rc, curve_id, keySz;
byte qx[WOLFTPM2_WRAP_ECC_KEY_BITS / 8];
byte qy[WOLFTPM2_WRAP_ECC_KEY_BITS / 8];
word32 qxSz;
Expand All @@ -4812,24 +4813,32 @@ int wolfTPM2_EccKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,

/* load curve type */
curve_id = tpmKey->pub.publicArea.parameters.eccDetail.curveID;
keySz = wolfTPM2_GetCurveSize(curve_id); /* field size for right-align */
rc = TPM2_GetWolfCurve(curve_id);
if (rc < 0)
return rc;
curve_id = rc;
if (keySz <= 0 || keySz > (int)sizeof(qx)) {
return BUFFER_E;
}

/* load public key */
/* load public key; right-align each coordinate into the field-size buffer
* so wc_ecc_import_unsigned reads the correct big-endian value even when
* the TPM stripped leading zero bytes */
qxSz = tpmKey->pub.publicArea.unique.ecc.x.size;
if (qxSz > sizeof(qx) ||
if (qxSz > (word32)keySz ||
qxSz > sizeof(tpmKey->pub.publicArea.unique.ecc.x.buffer)) {
return BUFFER_E;
}
XMEMCPY(qx, tpmKey->pub.publicArea.unique.ecc.x.buffer, qxSz);
XMEMCPY(qx + (keySz - (int)qxSz),
tpmKey->pub.publicArea.unique.ecc.x.buffer, qxSz);
qySz = tpmKey->pub.publicArea.unique.ecc.y.size;
if (qySz > sizeof(qy) ||
if (qySz > (word32)keySz ||
qySz > sizeof(tpmKey->pub.publicArea.unique.ecc.y.buffer)) {
return BUFFER_E;
}
XMEMCPY(qy, tpmKey->pub.publicArea.unique.ecc.y.buffer, qySz);
XMEMCPY(qy + (keySz - (int)qySz),
tpmKey->pub.publicArea.unique.ecc.y.buffer, qySz);

/* load public key portion into wolf ecc_key */
rc = wc_ecc_import_unsigned(wolfKey, qx, qy, NULL, curve_id);
Expand Down Expand Up @@ -6320,6 +6329,20 @@ int wolfTPM2_ECDHGenKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* ecdhKey, int curve_id,
return rc;
}

/* Copy the ECDH shared secret to the caller buffer, reject if larger */
int wolfTPM2_EccZToBuffer(byte* out, int* outSz, const TPM2B_ECC_PARAMETER* z)
{
if (out == NULL || outSz == NULL || z == NULL) {
return BAD_FUNC_ARG;
}
if (z->size > (UINT16)sizeof(z->buffer) || (int)z->size > *outSz) {
return BUFFER_E;
}
*outSz = (int)z->size;
XMEMCPY(out, z->buffer, z->size);
return TPM_RC_SUCCESS;
}

/* Generate ephemeral key and compute Z (shared secret) */
/* One shot API using private key handle to generate key-pair and return
pub-point and shared secret */
Expand Down Expand Up @@ -6360,16 +6383,14 @@ int wolfTPM2_ECDHGen(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* privKey,
pubPoint->size = ecdhOut.pubPoint.size;
wolfTPM2_CopyEccParam(&pubPoint->point.x, &ecdhOut.pubPoint.point.x);
wolfTPM2_CopyEccParam(&pubPoint->point.y, &ecdhOut.pubPoint.point.y);
*outSz = ecdhOut.zPoint.point.x.size;
if (*outSz > (int)sizeof(ecdhOut.zPoint.point.x.buffer)) {
*outSz = (int)sizeof(ecdhOut.zPoint.point.x.buffer); /* truncate */
}
XMEMCPY(out, ecdhOut.zPoint.point.x.buffer, *outSz);
rc = wolfTPM2_EccZToBuffer(out, outSz, &ecdhOut.zPoint.point.x);

#ifdef DEBUG_WOLFTPM
printf("TPM2_ECDH_KeyGen: zPt %d, pubPt %d\n",
ecdhOut.zPoint.size,
ecdhOut.pubPoint.size);
if (rc == TPM_RC_SUCCESS) {
printf("TPM2_ECDH_KeyGen: zPt %d, pubPt %d\n",
ecdhOut.zPoint.size,
ecdhOut.pubPoint.size);
}
#endif

TPM2_ForceZero(&ecdhOut, sizeof(ecdhOut));
Expand Down Expand Up @@ -6412,14 +6433,12 @@ int wolfTPM2_ECDHGenZ(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* privKey,
return rc;
}

*outSz = ecdhZOut.outPoint.point.x.size;
if (*outSz > (int)sizeof(ecdhZOut.outPoint.point.x.buffer)) {
*outSz = (int)sizeof(ecdhZOut.outPoint.point.x.buffer); /* truncate */
}
XMEMCPY(out, ecdhZOut.outPoint.point.x.buffer, *outSz);
rc = wolfTPM2_EccZToBuffer(out, outSz, &ecdhZOut.outPoint.point.x);

#ifdef DEBUG_WOLFTPM
printf("TPM2_ECDH_ZGen: zPt %d\n", ecdhZOut.outPoint.size);
if (rc == TPM_RC_SUCCESS) {
printf("TPM2_ECDH_ZGen: zPt %d\n", ecdhZOut.outPoint.size);
}
#endif

TPM2_ForceZero(&ecdhZOut, sizeof(ecdhZOut));
Expand Down Expand Up @@ -6504,14 +6523,12 @@ int wolfTPM2_ECDHEGenZ(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey,
return rc;
}

*outSz = outZGen2Ph.outZ2.point.x.size;
if (*outSz > (int)sizeof(outZGen2Ph.outZ2.point.x.buffer)) {
*outSz = (int)sizeof(outZGen2Ph.outZ2.point.x.buffer); /* truncate */
}
XMEMCPY(out, outZGen2Ph.outZ2.point.x.buffer, *outSz);
rc = wolfTPM2_EccZToBuffer(out, outSz, &outZGen2Ph.outZ2.point.x);

#ifdef DEBUG_WOLFTPM
printf("TPM2_ZGen_2Phase: zPt %d\n", outZGen2Ph.outZ2.size);
if (rc == TPM_RC_SUCCESS) {
printf("TPM2_ZGen_2Phase: zPt %d\n", outZGen2Ph.outZ2.size);
}
#endif

TPM2_ForceZero(&outZGen2Ph, sizeof(outZGen2Ph));
Expand Down Expand Up @@ -10820,10 +10837,12 @@ int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg,
/* pre-provisioned IAK and IDevID key/cert from TPM vendor */
#ifdef WOLFTPM_MFG_IDENTITY

#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
static const uint8_t TPM2_IAK_SAMPLE_MASTER_PASSWORD[] = {
0xFE, 0xEF, 0x8C, 0xDF, 0x1B, 0x77, 0xBD, 0x00,
0x30, 0x58, 0x5E, 0x47, 0xB8, 0x21, 0x46, 0x0B
};
#endif

int wolfTPM2_SetIdentityAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle,
uint8_t* masterPassword, uint16_t masterPasswordSz)
Expand All @@ -10834,6 +10853,18 @@ int wolfTPM2_SetIdentityAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle,
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
uint8_t digest[TPM_SHA256_DIGEST_SIZE];

if (handle == NULL) {
return BAD_FUNC_ARG;
}

#if !defined(WOLFTPM_ST33) && !defined(WOLFTPM_AUTODETECT)
/* The sample master password only provisions ST33 sample parts; require an
* explicit secret on other targets rather than deriving from a public value */
if (masterPassword == NULL || masterPasswordSz == 0) {
return BAD_FUNC_ARG;
}
#endif

/* Get TPM serial number */
rc = TPM2_GetProductInfo(serialNum, (uint16_t)sizeof(serialNum));
if (rc != 0) {
Expand All @@ -10853,21 +10884,25 @@ int wolfTPM2_SetIdentityAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle,
if (rc == 0) {
rc = wc_HashUpdate(&hash_ctx, hashType, serialNum, sizeof(serialNum));
if (rc == 0) {
if (masterPassword == NULL || masterPasswordSz == 0) {
if (masterPassword != NULL && masterPasswordSz > 0) {
rc = wc_HashUpdate(&hash_ctx, hashType,
TPM2_IAK_SAMPLE_MASTER_PASSWORD,
sizeof(TPM2_IAK_SAMPLE_MASTER_PASSWORD));
masterPassword, masterPasswordSz);
}
#if defined(WOLFTPM_ST33) || defined(WOLFTPM_AUTODETECT)
else {
rc = wc_HashUpdate(&hash_ctx, hashType,
masterPassword, masterPasswordSz);
TPM2_IAK_SAMPLE_MASTER_PASSWORD,
sizeof(TPM2_IAK_SAMPLE_MASTER_PASSWORD));
}
#endif
}
if (rc == 0) {
rc = wc_HashFinal(&hash_ctx, hashType, digest);
}

wc_HashFree(&hash_ctx, hashType);
/* scrub the hash state: it retains trailing plaintext of the input */
TPM2_ForceZero(&hash_ctx, sizeof(hash_ctx));
}

/* Only copy digest to handle auth when hashing succeeded — otherwise
Expand Down
33 changes: 33 additions & 0 deletions tests/fwtpm_unit_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -6482,6 +6482,34 @@ static void test_fwtpm_mlkem_primary_determinism(void)
}
#endif /* WOLFTPM_V185 */

#ifdef WOLFTPM_MLDSA
/* TestParms for a supported ML-DSA parameter set with allowExternalMu=NO must
* report TPM_RC_SUCCESS. Guarded on WOLFTPM_MLDSA so it also runs in the lean
* WOLFTPM_PQC build where the PQC arms were previously gated out. */
static void test_fwtpm_testparms_mldsa_supported_returns_success(void)
{
FWTPM_CTX ctx;
int rc, rspSize, pos;

memset(&ctx, 0, sizeof(ctx));
AssertIntEQ(fwtpm_test_startup(&ctx), 0);

pos = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, TPM_CC_TestParms);
PutU16BE(gCmd + pos, TPM_ALG_MLDSA); pos += 2;
PutU16BE(gCmd + pos, TPM_MLDSA_65); pos += 2;
gCmd[pos++] = NO; /* allowExternalMu */
PutU32BE(gCmd + 2, (UINT32)pos);

rspSize = 0;
rc = FWTPM_ProcessCommand(&ctx, gCmd, pos, gRsp, &rspSize, 0);
AssertIntEQ(rc, TPM_RC_SUCCESS);
AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS);

FWTPM_Cleanup(&ctx);
fwtpm_pass("TestParms MLDSA supported ps (SUCCESS):", 1);
}
#endif /* WOLFTPM_MLDSA */

/* ================================================================== */
/* 9. Hash Sequence */
/* ================================================================== */
Expand Down Expand Up @@ -10515,6 +10543,11 @@ int fwtpm_unit_tests(int argc, char *argv[])
test_fwtpm_create_primary_mldsa_extmu_returns_ext_mu();
test_fwtpm_testparms_mldsa_extmu_returns_ext_mu();
test_fwtpm_signdigest_wrong_digest_size_returns_size();
#endif /* WOLFTPM_V185 */
#ifdef WOLFTPM_MLDSA
test_fwtpm_testparms_mldsa_supported_returns_success();
#endif
#ifdef WOLFTPM_V185
test_fwtpm_signseqcomplete_x509sign_returns_attributes();
test_fwtpm_sign_x509sign_returns_attributes();
test_fwtpm_signseqcomplete_restricted_generated_value_returns_value();
Expand Down
Loading
Loading