Skip to content

Commit 4817e79

Browse files
committed
Skoll review fixes
1 parent e2d1c34 commit 4817e79

6 files changed

Lines changed: 231 additions & 53 deletions

File tree

src/fwtpm/fwtpm_command.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11129,8 +11129,12 @@ static TPM_RC FwParseAttestParams(TPM2_Packet* cmd, int cmdSize,
1112911129
* hashAlg per Part 2 Sec. 11.2.1.5. */
1113011130
if (*sigScheme == TPM_ALG_ECDAA) {
1113111131
UINT16 ecdaaCount;
11132-
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
11133-
(void)ecdaaCount;
11132+
if (cmd->pos + 2 > cmdSize)
11133+
rc = TPM_RC_COMMAND_SIZE;
11134+
if (rc == 0) {
11135+
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
11136+
(void)ecdaaCount;
11137+
}
1113411138
}
1113511139
}
1113611140

@@ -11441,8 +11445,12 @@ static TPM_RC FwCmd_CertifyCreation(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1144111445
* hashAlg per Part 2 Sec. 11.2.1.5. */
1144211446
if (sigScheme == TPM_ALG_ECDAA) {
1144311447
UINT16 ecdaaCount;
11444-
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
11445-
(void)ecdaaCount;
11448+
if (cmd->pos + 2 > cmdSize)
11449+
rc = TPM_RC_COMMAND_SIZE;
11450+
if (rc == 0) {
11451+
TPM2_Packet_ParseU16(cmd, &ecdaaCount);
11452+
(void)ecdaaCount;
11453+
}
1144611454
}
1144711455
}
1144811456

@@ -11655,13 +11663,6 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1165511663
&qualifyingData, &sigScheme, &sigHashAlg);
1165611664
}
1165711665

11658-
/* Per Part 3 Sec. 31.16.1: TPM_RH_NULL signHandle requires non-NULL
11659-
* scheme and hash algorithm, otherwise return TPM_RC_SCHEME. */
11660-
if (rc == 0 && signHandle == TPM_RH_NULL &&
11661-
(sigScheme == TPM_ALG_NULL || sigHashAlg == TPM_ALG_NULL)) {
11662-
rc = TPM_RC_SCHEME;
11663-
}
11664-
1166511666
/* size, offset */
1166611667
if (rc == 0) {
1166711668
TPM2_Packet_ParseU16(cmd, &readSize);
@@ -11739,10 +11740,13 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1173911740
int hashSz;
1174011741
enum wc_HashType wcDigH;
1174111742

11742-
/* Resolve hash from signing key when scheme/hash is NULL */
11743+
/* Resolve hash from signing key when scheme/hash is NULL.
11744+
* keyScheme is filled in by the by-pointer interface but
11745+
* unused here - we only need the resolved hashAlg. */
1174311746
if (hashAlg == TPM_ALG_NULL) {
1174411747
UINT16 keyScheme = TPM_ALG_NULL;
1174511748
FwResolveSignScheme(sigObj, &keyScheme, &hashAlg);
11749+
(void)keyScheme;
1174611750
}
1174711751
wcDigH = FwGetWcHashType(hashAlg);
1174811752
hashSz = TPM2_GetHashDigestSize(hashAlg);

src/tpm2_packet.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -786,13 +786,28 @@ void TPM2_Packet_ParsePoint(TPM2_Packet* packet, TPM2B_ECC_POINT* point)
786786

787787
TPM2_Packet_ParseU16(packet, &point->size);
788788
pointStartPos = (packet != NULL) ? packet->pos : 0;
789-
TPM2_Packet_ParseEccPoint(packet, &point->point);
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+
}
790798

791799
/* Resync packet position to end of declared outer size so inner
792-
* x.size / y.size disagreement can't desynchronize subsequent fields */
793-
if (packet != NULL && point->size > 0 &&
794-
pointStartPos + point->size <= packet->size) {
795-
packet->pos = pointStartPos + point->size;
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+
}
796811
}
797812
}
798813

@@ -1149,10 +1164,16 @@ void TPM2_Packet_ParsePublic(TPM2_Packet* packet, TPM2B_PUBLIC* pub)
11491164

11501165
/* Resync packet position to end of declared outer size so inner
11511166
* parses can't cause field drift if declared size and actual
1152-
* inner consumption disagree */
1153-
if (packet != NULL &&
1154-
pubStartPos + pub->size <= packet->size) {
1155-
packet->pos = pubStartPos + pub->size;
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+
}
11561177
}
11571178
}
11581179
}

src/tpm2_wrap.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3550,6 +3550,11 @@ int wolfTPM2_LoadEccPublicKey_ex(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
35503550
return BUFFER_E;
35513551
if (eccPubYSz > sizeof(pub.publicArea.unique.ecc.y.buffer))
35523552
return BUFFER_E;
3553+
/* TPMS_SCHEME_ECDAA requires a 'count' field this helper cannot
3554+
* supply. Callers needing ECDAA must build TPM2B_PUBLIC manually and
3555+
* use wolfTPM2_LoadPublicKey directly. */
3556+
if (scheme == TPM_ALG_ECDAA)
3557+
return BAD_FUNC_ARG;
35533558

35543559
XMEMSET(&pub, 0, sizeof(pub));
35553560
pub.publicArea.type = TPM_ALG_ECC;
@@ -5521,8 +5526,10 @@ int wolfTPM2_RsaEncrypt(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
55215526
#endif
55225527
}
55235528

5524-
/* Plaintext copy lingers in the rsaEncIn stack frame after return -
5525-
* scrub it on every exit path. */
5529+
/* Plaintext copy lingers in rsaEncIn after the XMEMCPY above. Scrub
5530+
* before returning so the stack frame doesn't leak it. The early
5531+
* BUFFER_E returns above happen before the XMEMCPY so they don't
5532+
* need this path. */
55265533
TPM2_ForceZero(&rsaEncIn, sizeof(rsaEncIn));
55275534
return rc;
55285535
}
@@ -5725,9 +5732,14 @@ int wolfTPM2_UnloadHandle(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle)
57255732
/* nv is the populated handle and auth */
57265733
/* auth and authSz are optional NV authentication */
57275734
/* authPolicy and authPolicySz are optional policy digest */
5728-
int wolfTPM2_NVCreateAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
5735+
/* nameAlg is the index name hash algorithm; must match the hash that
5736+
* produced authPolicy when one is supplied, otherwise the policy can
5737+
* never be satisfied. Pass TPM_ALG_NULL to use WOLFTPM2_WRAP_DIGEST
5738+
* (default) or auto-infer from authPolicySz for SHA-only policies. */
5739+
int wolfTPM2_NVCreateAuthPolicy_ex(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
57295740
WOLFTPM2_NV* nv, word32 nvIndex, word32 nvAttributes, word32 maxSize,
5730-
const byte* auth, int authSz, const byte* authPolicy, int authPolicySz)
5741+
const byte* auth, int authSz, const byte* authPolicy, int authPolicySz,
5742+
TPMI_ALG_HASH nameAlg)
57315743
{
57325744
int rc, rctmp;
57335745
NV_DefineSpace_In in;
@@ -5758,30 +5770,36 @@ int wolfTPM2_NVCreateAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
57585770
XMEMCPY(in.auth.buffer, auth, in.auth.size);
57595771
}
57605772
in.publicInfo.nvPublic.nvIndex = nvIndex;
5761-
/* When a policy digest is supplied, nameAlg must match the hash that
5762-
* produced it - otherwise the policy can never be satisfied. Infer
5763-
* nameAlg from authPolicySz when possible, defaulting to
5764-
* WOLFTPM2_WRAP_DIGEST for the no-policy case. */
5765-
if (authPolicy != NULL && authPolicySz > 0) {
5773+
if (nameAlg != TPM_ALG_NULL) {
5774+
/* Caller supplied an explicit nameAlg; use it as-is and only
5775+
* sanity-check against the policy digest size. */
5776+
if (authPolicy != NULL && authPolicySz > 0) {
5777+
int expectSz = TPM2_GetHashDigestSize(nameAlg);
5778+
if (expectSz <= 0 || expectSz != authPolicySz)
5779+
return BAD_FUNC_ARG;
5780+
}
5781+
in.publicInfo.nvPublic.nameAlg = nameAlg;
5782+
}
5783+
else if (authPolicy != NULL && authPolicySz > 0) {
5784+
/* No explicit nameAlg supplied. Infer from policy digest size for
5785+
* SHA-only policies. The TPM stores the policy digest verbatim,
5786+
* so we don't need wolfCrypt to support the hash here - the
5787+
* caller has already computed the digest. SM3-256 / SHA3-256
5788+
* also produce 32 bytes; callers needing those must pass
5789+
* nameAlg explicitly via the _ex API. */
57665790
switch (authPolicySz) {
5767-
#ifndef NO_SHA
57685791
case TPM_SHA_DIGEST_SIZE:
57695792
in.publicInfo.nvPublic.nameAlg = TPM_ALG_SHA1;
57705793
break;
5771-
#endif
57725794
case TPM_SHA256_DIGEST_SIZE:
57735795
in.publicInfo.nvPublic.nameAlg = TPM_ALG_SHA256;
57745796
break;
5775-
#ifdef WOLFSSL_SHA384
57765797
case TPM_SHA384_DIGEST_SIZE:
57775798
in.publicInfo.nvPublic.nameAlg = TPM_ALG_SHA384;
57785799
break;
5779-
#endif
5780-
#ifdef WOLFSSL_SHA512
57815800
case TPM_SHA512_DIGEST_SIZE:
57825801
in.publicInfo.nvPublic.nameAlg = TPM_ALG_SHA512;
57835802
break;
5784-
#endif
57855803
default:
57865804
return BAD_FUNC_ARG;
57875805
}
@@ -5830,6 +5848,15 @@ int wolfTPM2_NVCreateAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
58305848
return rc;
58315849
}
58325850

5851+
int wolfTPM2_NVCreateAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
5852+
WOLFTPM2_NV* nv, word32 nvIndex, word32 nvAttributes, word32 maxSize,
5853+
const byte* auth, int authSz, const byte* authPolicy, int authPolicySz)
5854+
{
5855+
return wolfTPM2_NVCreateAuthPolicy_ex(dev, parent, nv, nvIndex,
5856+
nvAttributes, maxSize, auth, authSz, authPolicy, authPolicySz,
5857+
TPM_ALG_NULL);
5858+
}
5859+
58335860
int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent,
58345861
WOLFTPM2_NV* nv, word32 nvIndex, word32 nvAttributes, word32 maxSize,
58355862
const byte* auth, int authSz)

tests/fwtpm_unit_tests.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,9 +1096,11 @@ static UINT32 CreatePrimaryHelper(FWTPM_CTX* ctx, TPM_ALG_ID alg)
10961096
return GetU32BE(gRsp + TPM2_HEADER_SIZE);
10971097
}
10981098

1099-
#ifdef HAVE_ECC
1099+
#if defined(HAVE_ECC) && !defined(FWTPM_NO_ATTESTATION)
11001100
/* Build a non-restricted ECC-P256 sign-capable primary (for tests that
1101-
* require TPMA_OBJECT_sign and a key with no scheme bound at create time). */
1101+
* require TPMA_OBJECT_sign and a key with no scheme bound at create time).
1102+
* Only consumed by the attestation tests, so gated to avoid
1103+
* -Werror=unused-function in FWTPM_NO_ATTESTATION builds. */
11021104
static int BuildCreatePrimaryEccSignCmd(byte* buf)
11031105
{
11041106
int pos = 0;
@@ -1155,7 +1157,7 @@ static UINT32 CreatePrimaryEccSignHelper(FWTPM_CTX* ctx)
11551157
if (GetRspRC(gRsp) != TPM_RC_SUCCESS) return 0;
11561158
return GetU32BE(gRsp + TPM2_HEADER_SIZE);
11571159
}
1158-
#endif
1160+
#endif /* HAVE_ECC && !FWTPM_NO_ATTESTATION */
11591161

11601162
/* Helper: flush a handle */
11611163
static void FlushHandle(FWTPM_CTX* ctx, UINT32 handle)
@@ -1578,13 +1580,15 @@ static void test_fwtpm_nv_counter(void)
15781580
}
15791581

15801582
#ifndef FWTPM_NO_ATTESTATION
1583+
#ifdef HAVE_ECC
15811584
/* TPMT_SIG_SCHEME parser must consume the extra UINT16 count field for
15821585
* TPMS_SCHEME_ECDAA per Part 2 Sec. 11.2.1.5. Sending a Quote with
15831586
* inScheme.scheme = TPM_ALG_ECDAA followed by hashAlg + count + a single
15841587
* PCR selection (count=1) verifies that subsequent PCRselect parsing
15851588
* is not desynchronized. With the bug, pcrSelectionsCount reads as 0
15861589
* because the count field is interpreted as the high 16 bits of the
1587-
* PCR-selection count. */
1590+
* PCR-selection count. ECC-only because the RSA sign path rejects
1591+
* TPM_ALG_ECDAA with TPM_RC_SCHEME. */
15881592
static void test_fwtpm_quote_ecdaa_scheme(void)
15891593
{
15901594
FWTPM_CTX ctx;
@@ -1598,11 +1602,7 @@ static void test_fwtpm_quote_ecdaa_scheme(void)
15981602
memset(&ctx, 0, sizeof(ctx));
15991603
AssertIntEQ(fwtpm_test_startup(&ctx), 0);
16001604

1601-
#ifdef HAVE_ECC
16021605
keyH = CreatePrimaryHelper(&ctx, TPM_ALG_ECC);
1603-
#else
1604-
keyH = CreatePrimaryHelper(&ctx, TPM_ALG_RSA);
1605-
#endif
16061606
AssertIntNE(keyH, 0);
16071607

16081608
/* Build TPM2_Quote with ECDAA inScheme. */
@@ -1650,6 +1650,7 @@ static void test_fwtpm_quote_ecdaa_scheme(void)
16501650
FWTPM_Cleanup(&ctx);
16511651
printf("Test fwTPM:\tQuote(ECDAA scheme):\t\tPassed\n");
16521652
}
1653+
#endif /* HAVE_ECC */
16531654

16541655
#ifdef HAVE_ECC
16551656
/* TPM2_CertifyCreation inScheme parser must consume the extra UINT16
@@ -2540,8 +2541,8 @@ int fwtpm_unit_tests(int argc, char *argv[])
25402541
test_fwtpm_nv_counter();
25412542
#ifndef FWTPM_NO_ATTESTATION
25422543
test_fwtpm_nv_certify_digest_mode();
2543-
test_fwtpm_quote_ecdaa_scheme();
25442544
#ifdef HAVE_ECC
2545+
test_fwtpm_quote_ecdaa_scheme();
25452546
test_fwtpm_sign_ecdaa_scheme();
25462547
test_fwtpm_certify_creation_ecdaa_scheme();
25472548
#endif

0 commit comments

Comments
 (0)