Skip to content

Commit 0011737

Browse files
authored
Merge pull request #496 from aidangarske/fenrir-fixes-10
Security Hardening and TCG v185 compliance
2 parents 570acb1 + 2cc2089 commit 0011737

14 files changed

Lines changed: 1359 additions & 75 deletions

File tree

examples/attestation/activate_credential.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
9999
XMEMSET(&endorse, 0, sizeof(endorse));
100100
XMEMSET(&storage, 0, sizeof(storage));
101101
XMEMSET(&akKey, 0, sizeof(akKey));
102+
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
102103

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

231232
exit:
232233

233-
wolfTPM2_UnloadHandle(&dev, &primary->handle);
234+
if (primary != NULL)
235+
wolfTPM2_UnloadHandle(&dev, &primary->handle);
234236
wolfTPM2_UnloadHandle(&dev, &akKey.handle);
235237
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
236238
wolfTPM2_Cleanup(&dev);

examples/keygen/keygen.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,8 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
481481
}
482482

483483
/* Close handles */
484-
wolfTPM2_UnloadHandle(&dev, &primary->handle);
484+
if (primary != NULL)
485+
wolfTPM2_UnloadHandle(&dev, &primary->handle);
485486
wolfTPM2_UnloadHandle(&dev, &newKeyBlob.handle);
486487
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
487488

examples/keygen/keyload.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[])
224224
}
225225

226226
/* Close key handles */
227-
wolfTPM2_UnloadHandle(&dev, &primary->handle);
227+
if (primary != NULL)
228+
wolfTPM2_UnloadHandle(&dev, &primary->handle);
228229
/* newKey.handle is already flushed by wolfTPM2_NVStoreKey */
229230
if (!persistent) {
230231
wolfTPM2_UnloadHandle(&dev, &newKey.handle);

examples/management/flush.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ int TPM2_Flush_Tool(void* userCtx, int argc, char *argv[])
9292
TPM2_FlushContext(&flushCtx);
9393
}
9494
/* Flush hmac sessions */
95-
for (handle=0x3000000; handle < 0x3000004; handle++) {
95+
for (handle=0x2000000; handle < 0x2000004; handle++) {
9696
flushCtx.flushHandle = handle;
9797
printf("Freeing %X object\n", handle);
9898
TPM2_FlushContext(&flushCtx);

examples/pkcs7/pkcs7.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId,
196196
}
197197

198198
/* Body - Data */
199-
do {
199+
offset = 0;
200+
while (1) {
200201
dataChunkSz = GetMyData(dataChunk, sizeof(dataChunk), offset);
201202
if (dataChunkSz == 0)
202203
break;
@@ -208,7 +209,7 @@ static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId,
208209
}
209210

210211
offset += dataChunkSz;
211-
} while (rc == 0);
212+
}
212213
dataChunkSz = GetMyData(NULL, 0, 0); /* get total size */
213214

214215
/* Footer */

src/fwtpm/fwtpm_command.c

Lines changed: 96 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5731,6 +5731,17 @@ static TPM_RC FwCmd_Sign(FWTPM_CTX* ctx, TPM2_Packet* cmd,
57315731
if (rc == 0)
57325732
TPM2_Packet_ParseU16(cmd, &sigHashAlg);
57335733
}
5734+
/* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
5735+
* hashAlg per Part 2 Sec. 11.2.1.5. */
5736+
if (rc == 0 && sigScheme == TPM_ALG_ECDAA) {
5737+
UINT16 ecdaaCount;
5738+
if (cmd->pos + 2 > cmdSize)
5739+
rc = TPM_RC_COMMAND_SIZE;
5740+
if (rc == 0) {
5741+
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
5742+
(void)ecdaaCount;
5743+
}
5744+
}
57345745
}
57355746

57365747
if (rc == 0) {
@@ -11121,6 +11132,17 @@ static TPM_RC FwParseAttestParams(TPM2_Packet* cmd, int cmdSize,
1112111132
*sigHashAlg = TPM_ALG_NULL;
1112211133
if (*sigScheme != TPM_ALG_NULL)
1112311134
TPM2_Packet_ParseU16(cmd, sigHashAlg);
11135+
/* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
11136+
* hashAlg per Part 2 Sec. 11.2.1.5. */
11137+
if (*sigScheme == TPM_ALG_ECDAA) {
11138+
UINT16 ecdaaCount;
11139+
if (cmd->pos + 2 > cmdSize)
11140+
rc = TPM_RC_COMMAND_SIZE;
11141+
if (rc == 0) {
11142+
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
11143+
(void)ecdaaCount;
11144+
}
11145+
}
1112411146
}
1112511147

1112611148
return rc;
@@ -11426,6 +11448,17 @@ static TPM_RC FwCmd_CertifyCreation(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1142611448
sigHashAlg = TPM_ALG_NULL;
1142711449
if (sigScheme != TPM_ALG_NULL)
1142811450
TPM2_Packet_ParseU16(cmd, &sigHashAlg);
11451+
/* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
11452+
* hashAlg per Part 2 Sec. 11.2.1.5. */
11453+
if (sigScheme == TPM_ALG_ECDAA) {
11454+
UINT16 ecdaaCount;
11455+
if (cmd->pos + 2 > cmdSize)
11456+
rc = TPM_RC_COMMAND_SIZE;
11457+
if (rc == 0) {
11458+
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
11459+
(void)ecdaaCount;
11460+
}
11461+
}
1142911462
}
1143011463

1143111464
/* creationTicket verification per TPM 2.0 Part 3 Section 18.3 */
@@ -11588,6 +11621,7 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1158811621
TPM2B_DATA qualifyingData;
1158911622
UINT16 sigScheme, sigHashAlg;
1159011623
UINT16 readSize, readOffset;
11624+
int digestMode = 0;
1159111625
FWTPM_Object* sigObj;
1159211626
FWTPM_NvIndex* nv;
1159311627
FWTPM_DECLARE_BUF(attestBuf, FWTPM_MAX_ATTEST_BUF);
@@ -11646,12 +11680,20 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1164611680
}
1164711681
}
1164811682
if (rc == 0) {
11649-
if (readSize == 0)
11683+
/* Per Part 3 Sec. 31.16.1: when both size and offset are zero, the
11684+
* response must contain a TPMS_NV_DIGEST_CERTIFY_INFO with the
11685+
* digest of the entire NV index, instead of TPMS_NV_CERTIFY_INFO. */
11686+
if (readSize == 0 && readOffset == 0) {
11687+
digestMode = 1;
11688+
readSize = nv->nvPublic.dataSize;
11689+
}
11690+
else if (readSize == 0) {
1165011691
readSize = nv->nvPublic.dataSize - readOffset;
11692+
}
1165111693
if ((UINT32)(readOffset + readSize) > nv->nvPublic.dataSize) {
1165211694
rc = TPM_RC_NV_RANGE;
1165311695
}
11654-
if (rc == 0 && readSize > FWTPM_MAX_NV_DATA) {
11696+
if (rc == 0 && !digestMode && readSize > FWTPM_MAX_NV_DATA) {
1165511697
rc = TPM_RC_SIZE;
1165611698
}
1165711699
}
@@ -11687,26 +11729,67 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1168711729

1168811730
/* Build TPMS_ATTEST for NV */
1168911731
if (rc == 0) {
11732+
UINT16 attestType = digestMode ?
11733+
TPM_ST_ATTEST_NV_DIGEST : TPM_ST_ATTEST_NV;
1169011734
XMEMSET(attestBuf, 0, FWTPM_MAX_ATTEST_BUF);
1169111735
attestPkt.buf = attestBuf;
1169211736
attestPkt.pos = 0;
1169311737
attestPkt.size = (int)FWTPM_MAX_ATTEST_BUF;
1169411738

11695-
FwAppendAttestCommonHeader(&attestPkt, TPM_ST_ATTEST_NV,
11739+
FwAppendAttestCommonHeader(&attestPkt, attestType,
1169611740
&sigObj->name, &qualifyingData);
1169711741

11698-
/* attested.nv: indexName + offset + nvContents */
11699-
TPM2_Packet_AppendU16(&attestPkt, nvName.size);
11700-
TPM2_Packet_AppendBytes(&attestPkt, (byte*)nvName.name,
11701-
nvName.size);
11702-
TPM2_Packet_AppendU16(&attestPkt, readOffset);
11703-
TPM2_Packet_AppendU16(&attestPkt, readSize);
11704-
TPM2_Packet_AppendBytes(&attestPkt, nv->data + readOffset,
11705-
readSize);
11742+
if (digestMode) {
11743+
/* attested.nvDigest: indexName + nvDigest
11744+
* nvDigest is hash of entire NV index using signing scheme hash */
11745+
UINT16 hashAlg = sigHashAlg;
11746+
byte nvDigest[TPM_MAX_DIGEST_SIZE];
11747+
int hashSz;
11748+
enum wc_HashType wcDigH;
11749+
11750+
/* Resolve hash from signing key when scheme/hash is NULL.
11751+
* keyScheme is filled in by the by-pointer interface but
11752+
* unused here - we only need the resolved hashAlg. */
11753+
if (hashAlg == TPM_ALG_NULL) {
11754+
UINT16 keyScheme = TPM_ALG_NULL;
11755+
FwResolveSignScheme(sigObj, &keyScheme, &hashAlg);
11756+
(void)keyScheme;
11757+
}
11758+
wcDigH = FwGetWcHashType(hashAlg);
11759+
hashSz = TPM2_GetHashDigestSize(hashAlg);
11760+
if (wcDigH == WC_HASH_TYPE_NONE || hashSz <= 0) {
11761+
rc = TPM_RC_HASH;
11762+
}
11763+
if (rc == 0) {
11764+
if (wc_Hash(wcDigH, nv->data, nv->nvPublic.dataSize,
11765+
nvDigest, hashSz) != 0) {
11766+
rc = TPM_RC_FAILURE;
11767+
}
11768+
}
11769+
if (rc == 0) {
11770+
TPM2_Packet_AppendU16(&attestPkt, nvName.size);
11771+
TPM2_Packet_AppendBytes(&attestPkt, (byte*)nvName.name,
11772+
nvName.size);
11773+
TPM2_Packet_AppendU16(&attestPkt, (UINT16)hashSz);
11774+
TPM2_Packet_AppendBytes(&attestPkt, nvDigest, hashSz);
11775+
}
11776+
}
11777+
else {
11778+
/* attested.nv: indexName + offset + nvContents */
11779+
TPM2_Packet_AppendU16(&attestPkt, nvName.size);
11780+
TPM2_Packet_AppendBytes(&attestPkt, (byte*)nvName.name,
11781+
nvName.size);
11782+
TPM2_Packet_AppendU16(&attestPkt, readOffset);
11783+
TPM2_Packet_AppendU16(&attestPkt, readSize);
11784+
TPM2_Packet_AppendBytes(&attestPkt, nv->data + readOffset,
11785+
readSize);
11786+
}
1170611787

1170711788
/* Build response */
11708-
rc = FwBuildAttestResponse(ctx, rsp, cmdTag, sigObj,
11709-
sigScheme, sigHashAlg, attestBuf, attestPkt.pos);
11789+
if (rc == 0) {
11790+
rc = FwBuildAttestResponse(ctx, rsp, cmdTag, sigObj,
11791+
sigScheme, sigHashAlg, attestBuf, attestPkt.pos);
11792+
}
1171011793
}
1171111794
FWTPM_FREE_BUF(attestBuf);
1171211795
return rc;

src/tpm2.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6488,9 +6488,13 @@ int TPM2_GetCurveSize(TPM_ECC_CURVE curveID)
64886488
case TPM_ECC_NIST_P256:
64896489
case TPM_ECC_BN_P256:
64906490
case TPM_ECC_SM2_P256:
6491+
case TPM_ECC_BP_P256_R1:
64916492
return 32;
64926493
case TPM_ECC_NIST_P384:
6494+
case TPM_ECC_BP_P384_R1:
64936495
return 48;
6496+
case TPM_ECC_BP_P512_R1:
6497+
return 64;
64946498
case TPM_ECC_NIST_P521:
64956499
return 66;
64966500
case TPM_ECC_BN_P638:
@@ -6520,7 +6524,13 @@ int TPM2_GetTpmCurve(int curve_id)
65206524
ret = TPM_ECC_NIST_P521;
65216525
break;
65226526
case ECC_BRAINPOOLP256R1:
6523-
ret = TPM_ECC_BN_P256;
6527+
ret = TPM_ECC_BP_P256_R1;
6528+
break;
6529+
case ECC_BRAINPOOLP384R1:
6530+
ret = TPM_ECC_BP_P384_R1;
6531+
break;
6532+
case ECC_BRAINPOOLP512R1:
6533+
ret = TPM_ECC_BP_P512_R1;
65246534
break;
65256535
case TPM_ECC_BN_P638:
65266536
default:
@@ -6551,9 +6561,16 @@ int TPM2_GetWolfCurve(int curve_id)
65516561
case TPM_ECC_NIST_P521:
65526562
ret = ECC_SECP521R1;
65536563
break;
6554-
case TPM_ECC_BN_P256:
6564+
case TPM_ECC_BP_P256_R1:
65556565
ret = ECC_BRAINPOOLP256R1;
65566566
break;
6567+
case TPM_ECC_BP_P384_R1:
6568+
ret = ECC_BRAINPOOLP384R1;
6569+
break;
6570+
case TPM_ECC_BP_P512_R1:
6571+
ret = ECC_BRAINPOOLP512R1;
6572+
break;
6573+
case TPM_ECC_BN_P256:
65576574
case TPM_ECC_BN_P638:
65586575
default:
65596576
ret = ECC_CURVE_OID_E;

src/tpm2_packet.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,8 +782,33 @@ void TPM2_Packet_AppendPoint(TPM2_Packet* packet, TPM2B_ECC_POINT* point)
782782
}
783783
void TPM2_Packet_ParsePoint(TPM2_Packet* packet, TPM2B_ECC_POINT* point)
784784
{
785+
int pointStartPos;
786+
785787
TPM2_Packet_ParseU16(packet, &point->size);
786-
TPM2_Packet_ParseEccPoint(packet, &point->point);
788+
pointStartPos = (packet != NULL) ? packet->pos : 0;
789+
/* Skip the inner ECC point parse when the outer size is zero. A
790+
* malformed blob with size=0 but nonzero inner x.size/y.size would
791+
* otherwise advance packet->pos and desync subsequent fields. */
792+
if (point->size > 0) {
793+
TPM2_Packet_ParseEccPoint(packet, &point->point);
794+
}
795+
else {
796+
XMEMSET(&point->point, 0, sizeof(point->point));
797+
}
798+
799+
/* Resync packet position to end of declared outer size so inner
800+
* x.size / y.size disagreement can't desynchronize subsequent fields.
801+
* If the declared outer size runs past the buffer, clamp to packet end
802+
* so subsequent reads return an out-of-bounds sentinel rather than
803+
* leaving the position wherever the inner parses landed. */
804+
if (packet != NULL) {
805+
if (pointStartPos + point->size <= packet->size) {
806+
packet->pos = pointStartPos + point->size;
807+
}
808+
else {
809+
packet->pos = packet->size;
810+
}
811+
}
787812
}
788813

789814
void TPM2_Packet_AppendSensitive(TPM2_Packet* packet, TPM2B_SENSITIVE* sensitive)
@@ -1095,7 +1120,10 @@ void TPM2_Packet_AppendPublic(TPM2_Packet* packet, TPM2B_PUBLIC* pub)
10951120
}
10961121
void TPM2_Packet_ParsePublic(TPM2_Packet* packet, TPM2B_PUBLIC* pub)
10971122
{
1123+
int pubStartPos;
1124+
10981125
TPM2_Packet_ParseU16(packet, &pub->size);
1126+
pubStartPos = (packet != NULL) ? packet->pos : 0;
10991127
if (pub->size > 0) {
11001128
TPM2_Packet_ParseU16(packet, &pub->publicArea.type);
11011129
TPM2_Packet_ParseU16(packet, &pub->publicArea.nameAlg);
@@ -1133,6 +1161,20 @@ void TPM2_Packet_ParsePublic(TPM2_Packet* packet, TPM2B_PUBLIC* pub)
11331161
/* TPMS_DERIVE derive; ? */
11341162
break;
11351163
}
1164+
1165+
/* Resync packet position to end of declared outer size so inner
1166+
* parses can't cause field drift if declared size and actual
1167+
* inner consumption disagree. If the declared outer size runs
1168+
* past the buffer, clamp to packet end so subsequent reads
1169+
* return an out-of-bounds sentinel. */
1170+
if (packet != NULL) {
1171+
if (pubStartPos + pub->size <= packet->size) {
1172+
packet->pos = pubStartPos + pub->size;
1173+
}
1174+
else {
1175+
packet->pos = packet->size;
1176+
}
1177+
}
11361178
}
11371179
}
11381180

@@ -1170,7 +1212,13 @@ void TPM2_Packet_AppendSignature(TPM2_Packet* packet, TPMT_SIGNATURE* sig)
11701212
digestSz = TPM2_GetHashDigestSize(sig->signature.hmac.hashAlg);
11711213
TPM2_Packet_AppendBytes(packet, sig->signature.hmac.digest.H, digestSz);
11721214
break;
1215+
case TPM_ALG_NULL:
1216+
/* Legitimate zero-payload signature - nothing to append. */
1217+
break;
11731218
default:
1219+
#ifdef DEBUG_WOLFTPM
1220+
printf("AppendSignature: unrecognized sigAlg 0x%x\n", sig->sigAlg);
1221+
#endif
11741222
break;
11751223
}
11761224
}
@@ -1242,7 +1290,13 @@ void TPM2_Packet_ParseSignature(TPM2_Packet* packet, TPMT_SIGNATURE* sig)
12421290
digestSz = TPM2_GetHashDigestSize(sig->signature.hmac.hashAlg);
12431291
TPM2_Packet_ParseBytes(packet, sig->signature.hmac.digest.H, digestSz);
12441292
break;
1293+
case TPM_ALG_NULL:
1294+
/* Legitimate zero-payload signature - nothing to consume. */
1295+
break;
12451296
default:
1297+
#ifdef DEBUG_WOLFTPM
1298+
printf("ParseSignature: unrecognized sigAlg 0x%x\n", sig->sigAlg);
1299+
#endif
12461300
break;
12471301
}
12481302
}
@@ -1342,6 +1396,16 @@ void TPM2_Packet_ParseAttest(TPM2_Packet* packet, TPMS_ATTEST* out)
13421396
out->attested.nv.nvContents.buffer,
13431397
(UINT16)sizeof(out->attested.nv.nvContents.buffer));
13441398
break;
1399+
case TPM_ST_ATTEST_NV_DIGEST:
1400+
TPM2_Packet_ParseU16Buf(packet,
1401+
&out->attested.nvDigest.indexName.size,
1402+
out->attested.nvDigest.indexName.name,
1403+
(UINT16)sizeof(out->attested.nvDigest.indexName.name));
1404+
TPM2_Packet_ParseU16Buf(packet,
1405+
&out->attested.nvDigest.nvDigest.size,
1406+
out->attested.nvDigest.nvDigest.buffer,
1407+
(UINT16)sizeof(out->attested.nvDigest.nvDigest.buffer));
1408+
break;
13451409
default:
13461410
/* unknown attestation type */
13471411
#ifdef DEBUG_WOLFTPM

0 commit comments

Comments
 (0)