Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f62070a
F-3503 - https://fenrir.wolfssl.com/finding/3503 - fwtpm: emit TPM_ST…
aidangarske Apr 28, 2026
4437bef
F-3493 - https://fenrir.wolfssl.com/finding/3493 - examples/managemen…
aidangarske Apr 28, 2026
1c2c809
F-3494 - https://fenrir.wolfssl.com/finding/3494 - examples/pkcs7: re…
aidangarske Apr 28, 2026
3b0147d
F-3496 - https://fenrir.wolfssl.com/finding/3496 - wolfTPM2_StartSess…
aidangarske Apr 28, 2026
1d7f460
F-3272 - https://fenrir.wolfssl.com/finding/3272 - fwtpm: FwParseAtte…
aidangarske Apr 28, 2026
aa19578
F-3273 - https://fenrir.wolfssl.com/finding/3273 - fwtpm: FwCmd_Sign …
aidangarske Apr 28, 2026
588455f
F-3274 - https://fenrir.wolfssl.com/finding/3274 - fwtpm: FwCmd_Certi…
aidangarske Apr 28, 2026
d04a78e
F-3502 - https://fenrir.wolfssl.com/finding/3502 - wolftpm: TPM2_Pack…
aidangarske Apr 28, 2026
cae955f
F-3504 - https://fenrir.wolfssl.com/finding/3504 - wolftpm: map wolfC…
aidangarske Apr 28, 2026
e7202aa
F-3495 - https://fenrir.wolfssl.com/finding/3495 - examples/keygen: g…
aidangarske Apr 28, 2026
b7d52b5
F-3497 - https://fenrir.wolfssl.com/finding/3497 - wolfTPM2_LoadEccPu…
aidangarske Apr 28, 2026
ae4ebe7
F-3498 - https://fenrir.wolfssl.com/finding/3498 - wolfTPM2_RsaEncryp…
aidangarske Apr 28, 2026
68bf667
F-3499 - https://fenrir.wolfssl.com/finding/3499 - wolfTPM2_SignHashS…
aidangarske Apr 28, 2026
3ec5485
F-3500 - https://fenrir.wolfssl.com/finding/3500 - wolfTPM2_NVCreateA…
aidangarske Apr 28, 2026
07bdb82
F-3508 - https://fenrir.wolfssl.com/finding/3508 - wolftpm: TPM2_Pack…
aidangarske Apr 28, 2026
2e00720
F-3509 - https://fenrir.wolfssl.com/finding/3509 - wolftpm: TPM2_Pack…
aidangarske Apr 28, 2026
d2dc2f7
F-3505 - https://fenrir.wolfssl.com/finding/3505 - examples/attestati…
aidangarske Apr 28, 2026
5e50cff
F-3506 - https://fenrir.wolfssl.com/finding/3506 - examples/keygen/ke…
aidangarske Apr 28, 2026
5f7a00e
F-3511 - https://fenrir.wolfssl.com/finding/3511 - wolfTPM2_RsaEncryp…
aidangarske Apr 28, 2026
9beaf2f
F-3501 - https://fenrir.wolfssl.com/finding/3501 - wolfTPM2_GetKeyTem…
aidangarske Apr 28, 2026
f66ca1e
F-3510 - https://fenrir.wolfssl.com/finding/3510 - wolftpm: TPM2_Pack…
aidangarske Apr 28, 2026
e2d1c34
F-3507 - https://fenrir.wolfssl.com/finding/3507 - examples/attestati…
aidangarske Apr 28, 2026
4817e79
Skoll review fixes
aidangarske Apr 28, 2026
2cc2089
F-3274 follow-up - tests/fwtpm_unit_tests: gate ECC sign helper for F…
aidangarske Apr 28, 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
4 changes: 3 additions & 1 deletion examples/attestation/activate_credential.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
XMEMSET(&endorse, 0, sizeof(endorse));
XMEMSET(&storage, 0, sizeof(storage));
XMEMSET(&akKey, 0, sizeof(akKey));
XMEMSET(&tpmSession, 0, sizeof(tpmSession));

printf("Demo how to create a credential blob for remote attestation\n");
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
Expand Down Expand Up @@ -230,7 +231,8 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])

exit:

wolfTPM2_UnloadHandle(&dev, &primary->handle);
if (primary != NULL)
wolfTPM2_UnloadHandle(&dev, &primary->handle);
wolfTPM2_UnloadHandle(&dev, &akKey.handle);
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
wolfTPM2_Cleanup(&dev);
Expand Down
3 changes: 2 additions & 1 deletion examples/keygen/keygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,8 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
}

/* Close handles */
wolfTPM2_UnloadHandle(&dev, &primary->handle);
if (primary != NULL)
wolfTPM2_UnloadHandle(&dev, &primary->handle);
wolfTPM2_UnloadHandle(&dev, &newKeyBlob.handle);
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);

Expand Down
3 changes: 2 additions & 1 deletion examples/keygen/keyload.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[])
}

/* Close key handles */
wolfTPM2_UnloadHandle(&dev, &primary->handle);
if (primary != NULL)
wolfTPM2_UnloadHandle(&dev, &primary->handle);
/* newKey.handle is already flushed by wolfTPM2_NVStoreKey */
if (!persistent) {
wolfTPM2_UnloadHandle(&dev, &newKey.handle);
Expand Down
2 changes: 1 addition & 1 deletion examples/management/flush.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ int TPM2_Flush_Tool(void* userCtx, int argc, char *argv[])
TPM2_FlushContext(&flushCtx);
}
/* Flush hmac sessions */
for (handle=0x3000000; handle < 0x3000004; handle++) {
for (handle=0x2000000; handle < 0x2000004; handle++) {
flushCtx.flushHandle = handle;
printf("Freeing %X object\n", handle);
TPM2_FlushContext(&flushCtx);
Expand Down
5 changes: 3 additions & 2 deletions examples/pkcs7/pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId,
}

/* Body - Data */
do {
offset = 0;
while (1) {
dataChunkSz = GetMyData(dataChunk, sizeof(dataChunk), offset);
if (dataChunkSz == 0)
break;
Expand All @@ -208,7 +209,7 @@ static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId,
}

offset += dataChunkSz;
} while (rc == 0);
}
Comment thread
aidangarske marked this conversation as resolved.
dataChunkSz = GetMyData(NULL, 0, 0); /* get total size */

/* Footer */
Expand Down
109 changes: 96 additions & 13 deletions src/fwtpm/fwtpm_command.c
Original file line number Diff line number Diff line change
Expand Up @@ -5724,6 +5724,17 @@ static TPM_RC FwCmd_Sign(FWTPM_CTX* ctx, TPM2_Packet* cmd,
if (rc == 0)
TPM2_Packet_ParseU16(cmd, &sigHashAlg);
}
/* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
* hashAlg per Part 2 Sec. 11.2.1.5. */
if (rc == 0 && sigScheme == TPM_ALG_ECDAA) {
UINT16 ecdaaCount;
if (cmd->pos + 2 > cmdSize)
rc = TPM_RC_COMMAND_SIZE;
if (rc == 0) {
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
(void)ecdaaCount;
}
}
}

if (rc == 0) {
Expand Down Expand Up @@ -11114,6 +11125,17 @@ static TPM_RC FwParseAttestParams(TPM2_Packet* cmd, int cmdSize,
*sigHashAlg = TPM_ALG_NULL;
if (*sigScheme != TPM_ALG_NULL)
TPM2_Packet_ParseU16(cmd, sigHashAlg);
/* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
* hashAlg per Part 2 Sec. 11.2.1.5. */
if (*sigScheme == TPM_ALG_ECDAA) {
UINT16 ecdaaCount;
if (cmd->pos + 2 > cmdSize)
rc = TPM_RC_COMMAND_SIZE;
if (rc == 0) {
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
(void)ecdaaCount;
}
}
}

return rc;
Expand Down Expand Up @@ -11419,6 +11441,17 @@ static TPM_RC FwCmd_CertifyCreation(FWTPM_CTX* ctx, TPM2_Packet* cmd,
sigHashAlg = TPM_ALG_NULL;
if (sigScheme != TPM_ALG_NULL)
TPM2_Packet_ParseU16(cmd, &sigHashAlg);
/* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
* hashAlg per Part 2 Sec. 11.2.1.5. */
if (sigScheme == TPM_ALG_ECDAA) {
UINT16 ecdaaCount;
if (cmd->pos + 2 > cmdSize)
rc = TPM_RC_COMMAND_SIZE;
if (rc == 0) {
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
(void)ecdaaCount;
}
}
}

/* creationTicket verification per TPM 2.0 Part 3 Section 18.3 */
Expand Down Expand Up @@ -11581,6 +11614,7 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
TPM2B_DATA qualifyingData;
UINT16 sigScheme, sigHashAlg;
UINT16 readSize, readOffset;
int digestMode = 0;
FWTPM_Object* sigObj;
FWTPM_NvIndex* nv;
FWTPM_DECLARE_BUF(attestBuf, FWTPM_MAX_ATTEST_BUF);
Expand Down Expand Up @@ -11639,12 +11673,20 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
}
}
if (rc == 0) {
if (readSize == 0)
/* Per Part 3 Sec. 31.16.1: when both size and offset are zero, the
* response must contain a TPMS_NV_DIGEST_CERTIFY_INFO with the
* digest of the entire NV index, instead of TPMS_NV_CERTIFY_INFO. */
if (readSize == 0 && readOffset == 0) {
digestMode = 1;
readSize = nv->nvPublic.dataSize;
}
else if (readSize == 0) {
readSize = nv->nvPublic.dataSize - readOffset;
}
if ((UINT32)(readOffset + readSize) > nv->nvPublic.dataSize) {
rc = TPM_RC_NV_RANGE;
}
if (rc == 0 && readSize > FWTPM_MAX_NV_DATA) {
if (rc == 0 && !digestMode && readSize > FWTPM_MAX_NV_DATA) {
rc = TPM_RC_SIZE;
}
}
Expand Down Expand Up @@ -11680,26 +11722,67 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,

/* Build TPMS_ATTEST for NV */
if (rc == 0) {
UINT16 attestType = digestMode ?
TPM_ST_ATTEST_NV_DIGEST : TPM_ST_ATTEST_NV;
XMEMSET(attestBuf, 0, FWTPM_MAX_ATTEST_BUF);
attestPkt.buf = attestBuf;
attestPkt.pos = 0;
attestPkt.size = (int)FWTPM_MAX_ATTEST_BUF;

FwAppendAttestCommonHeader(&attestPkt, TPM_ST_ATTEST_NV,
FwAppendAttestCommonHeader(&attestPkt, attestType,
&sigObj->name, &qualifyingData);

/* attested.nv: indexName + offset + nvContents */
TPM2_Packet_AppendU16(&attestPkt, nvName.size);
TPM2_Packet_AppendBytes(&attestPkt, (byte*)nvName.name,
nvName.size);
TPM2_Packet_AppendU16(&attestPkt, readOffset);
TPM2_Packet_AppendU16(&attestPkt, readSize);
TPM2_Packet_AppendBytes(&attestPkt, nv->data + readOffset,
readSize);
if (digestMode) {
/* attested.nvDigest: indexName + nvDigest
* nvDigest is hash of entire NV index using signing scheme hash */
UINT16 hashAlg = sigHashAlg;
byte nvDigest[TPM_MAX_DIGEST_SIZE];
int hashSz;
enum wc_HashType wcDigH;

/* Resolve hash from signing key when scheme/hash is NULL.
* keyScheme is filled in by the by-pointer interface but
* unused here - we only need the resolved hashAlg. */
if (hashAlg == TPM_ALG_NULL) {
UINT16 keyScheme = TPM_ALG_NULL;
FwResolveSignScheme(sigObj, &keyScheme, &hashAlg);
(void)keyScheme;
}
wcDigH = FwGetWcHashType(hashAlg);
hashSz = TPM2_GetHashDigestSize(hashAlg);
if (wcDigH == WC_HASH_TYPE_NONE || hashSz <= 0) {
rc = TPM_RC_HASH;
}
if (rc == 0) {
if (wc_Hash(wcDigH, nv->data, nv->nvPublic.dataSize,
nvDigest, hashSz) != 0) {
rc = TPM_RC_FAILURE;
}
}
if (rc == 0) {
TPM2_Packet_AppendU16(&attestPkt, nvName.size);
TPM2_Packet_AppendBytes(&attestPkt, (byte*)nvName.name,
nvName.size);
TPM2_Packet_AppendU16(&attestPkt, (UINT16)hashSz);
TPM2_Packet_AppendBytes(&attestPkt, nvDigest, hashSz);
}
}
else {
/* attested.nv: indexName + offset + nvContents */
TPM2_Packet_AppendU16(&attestPkt, nvName.size);
TPM2_Packet_AppendBytes(&attestPkt, (byte*)nvName.name,
nvName.size);
TPM2_Packet_AppendU16(&attestPkt, readOffset);
TPM2_Packet_AppendU16(&attestPkt, readSize);
TPM2_Packet_AppendBytes(&attestPkt, nv->data + readOffset,
readSize);
}

/* Build response */
rc = FwBuildAttestResponse(ctx, rsp, cmdTag, sigObj,
sigScheme, sigHashAlg, attestBuf, attestPkt.pos);
if (rc == 0) {
rc = FwBuildAttestResponse(ctx, rsp, cmdTag, sigObj,
sigScheme, sigHashAlg, attestBuf, attestPkt.pos);
}
}
FWTPM_FREE_BUF(attestBuf);
return rc;
Expand Down
21 changes: 19 additions & 2 deletions src/tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -6488,9 +6488,13 @@ int TPM2_GetCurveSize(TPM_ECC_CURVE curveID)
case TPM_ECC_NIST_P256:
case TPM_ECC_BN_P256:
case TPM_ECC_SM2_P256:
case TPM_ECC_BP_P256_R1:
return 32;
case TPM_ECC_NIST_P384:
case TPM_ECC_BP_P384_R1:
return 48;
case TPM_ECC_BP_P512_R1:
return 64;
case TPM_ECC_NIST_P521:
return 66;
case TPM_ECC_BN_P638:
Expand Down Expand Up @@ -6520,7 +6524,13 @@ int TPM2_GetTpmCurve(int curve_id)
ret = TPM_ECC_NIST_P521;
break;
case ECC_BRAINPOOLP256R1:
ret = TPM_ECC_BN_P256;
ret = TPM_ECC_BP_P256_R1;
break;
case ECC_BRAINPOOLP384R1:
ret = TPM_ECC_BP_P384_R1;
break;
case ECC_BRAINPOOLP512R1:
ret = TPM_ECC_BP_P512_R1;
break;
case TPM_ECC_BN_P638:
default:
Expand Down Expand Up @@ -6551,9 +6561,16 @@ int TPM2_GetWolfCurve(int curve_id)
case TPM_ECC_NIST_P521:
ret = ECC_SECP521R1;
break;
case TPM_ECC_BN_P256:
case TPM_ECC_BP_P256_R1:
ret = ECC_BRAINPOOLP256R1;
break;
case TPM_ECC_BP_P384_R1:
ret = ECC_BRAINPOOLP384R1;
break;
case TPM_ECC_BP_P512_R1:
ret = ECC_BRAINPOOLP512R1;
break;
case TPM_ECC_BN_P256:
case TPM_ECC_BN_P638:
default:
ret = ECC_CURVE_OID_E;
Expand Down
66 changes: 65 additions & 1 deletion src/tpm2_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,8 +782,33 @@ void TPM2_Packet_AppendPoint(TPM2_Packet* packet, TPM2B_ECC_POINT* point)
}
void TPM2_Packet_ParsePoint(TPM2_Packet* packet, TPM2B_ECC_POINT* point)
{
int pointStartPos;

TPM2_Packet_ParseU16(packet, &point->size);
TPM2_Packet_ParseEccPoint(packet, &point->point);
pointStartPos = (packet != NULL) ? packet->pos : 0;
/* Skip the inner ECC point parse when the outer size is zero. A
* malformed blob with size=0 but nonzero inner x.size/y.size would
* otherwise advance packet->pos and desync subsequent fields. */
if (point->size > 0) {
TPM2_Packet_ParseEccPoint(packet, &point->point);
}
else {
XMEMSET(&point->point, 0, sizeof(point->point));
}

/* Resync packet position to end of declared outer size so inner
* x.size / y.size disagreement can't desynchronize subsequent fields.
* If the declared outer size runs past the buffer, clamp to packet end
* so subsequent reads return an out-of-bounds sentinel rather than
* leaving the position wherever the inner parses landed. */
if (packet != NULL) {
if (pointStartPos + point->size <= packet->size) {
packet->pos = pointStartPos + point->size;
}
else {
packet->pos = packet->size;
}
}
}
Comment thread
aidangarske marked this conversation as resolved.

void TPM2_Packet_AppendSensitive(TPM2_Packet* packet, TPM2B_SENSITIVE* sensitive)
Expand Down Expand Up @@ -1095,7 +1120,10 @@ void TPM2_Packet_AppendPublic(TPM2_Packet* packet, TPM2B_PUBLIC* pub)
}
void TPM2_Packet_ParsePublic(TPM2_Packet* packet, TPM2B_PUBLIC* pub)
{
int pubStartPos;

TPM2_Packet_ParseU16(packet, &pub->size);
pubStartPos = (packet != NULL) ? packet->pos : 0;
if (pub->size > 0) {
TPM2_Packet_ParseU16(packet, &pub->publicArea.type);
TPM2_Packet_ParseU16(packet, &pub->publicArea.nameAlg);
Expand Down Expand Up @@ -1133,6 +1161,20 @@ void TPM2_Packet_ParsePublic(TPM2_Packet* packet, TPM2B_PUBLIC* pub)
/* TPMS_DERIVE derive; ? */
break;
}

/* Resync packet position to end of declared outer size so inner
* parses can't cause field drift if declared size and actual
* inner consumption disagree. If the declared outer size runs
* past the buffer, clamp to packet end so subsequent reads
* return an out-of-bounds sentinel. */
if (packet != NULL) {
if (pubStartPos + pub->size <= packet->size) {
packet->pos = pubStartPos + pub->size;
}
else {
packet->pos = packet->size;
}
}
}
}

Expand Down Expand Up @@ -1170,7 +1212,13 @@ void TPM2_Packet_AppendSignature(TPM2_Packet* packet, TPMT_SIGNATURE* sig)
digestSz = TPM2_GetHashDigestSize(sig->signature.hmac.hashAlg);
TPM2_Packet_AppendBytes(packet, sig->signature.hmac.digest.H, digestSz);
break;
case TPM_ALG_NULL:
/* Legitimate zero-payload signature - nothing to append. */
break;
default:
#ifdef DEBUG_WOLFTPM
printf("AppendSignature: unrecognized sigAlg 0x%x\n", sig->sigAlg);
#endif
break;
}
}
Expand Down Expand Up @@ -1242,7 +1290,13 @@ void TPM2_Packet_ParseSignature(TPM2_Packet* packet, TPMT_SIGNATURE* sig)
digestSz = TPM2_GetHashDigestSize(sig->signature.hmac.hashAlg);
TPM2_Packet_ParseBytes(packet, sig->signature.hmac.digest.H, digestSz);
break;
case TPM_ALG_NULL:
/* Legitimate zero-payload signature - nothing to consume. */
break;
default:
#ifdef DEBUG_WOLFTPM
printf("ParseSignature: unrecognized sigAlg 0x%x\n", sig->sigAlg);
#endif
break;
}
}
Expand Down Expand Up @@ -1342,6 +1396,16 @@ void TPM2_Packet_ParseAttest(TPM2_Packet* packet, TPMS_ATTEST* out)
out->attested.nv.nvContents.buffer,
(UINT16)sizeof(out->attested.nv.nvContents.buffer));
break;
case TPM_ST_ATTEST_NV_DIGEST:
TPM2_Packet_ParseU16Buf(packet,
&out->attested.nvDigest.indexName.size,
out->attested.nvDigest.indexName.name,
(UINT16)sizeof(out->attested.nvDigest.indexName.name));
TPM2_Packet_ParseU16Buf(packet,
&out->attested.nvDigest.nvDigest.size,
out->attested.nvDigest.nvDigest.buffer,
(UINT16)sizeof(out->attested.nvDigest.nvDigest.buffer));
break;
default:
/* unknown attestation type */
#ifdef DEBUG_WOLFTPM
Expand Down
Loading
Loading