@@ -7172,6 +7172,9 @@ static TPM_RC FwCmd_SequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
71727172 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL;
71737173 int paramSzPos, paramStart;
71747174 int trc;
7175+ #ifdef WOLFTPM_V185
7176+ FWTPM_SignSeq* misRoutedSign = NULL;
7177+ #endif
71757178
71767179 FWTPM_ALLOC_BUF(dataBuf, FWTPM_MAX_DATA_BUF);
71777180
@@ -7185,6 +7188,11 @@ static TPM_RC FwCmd_SequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
71857188 seq = FwFindHashSeq(ctx, seqHandle);
71867189 if (seq == NULL) {
71877190 rc = TPM_RC_HANDLE;
7191+ #ifdef WOLFTPM_V185
7192+ /* Free a sign/verify slot mis-routed here so it doesn't leak. */
7193+ misRoutedSign = FwFindSignSeq(ctx, seqHandle);
7194+ if (misRoutedSign != NULL) FwFreeSignSeq(misRoutedSign);
7195+ #endif
71887196 }
71897197 else {
71907198 hashAlg = seq->hashAlg;
@@ -13144,9 +13152,10 @@ static TPM_RC FwCmd_Encapsulate(FWTPM_CTX* ctx, TPM2_Packet* cmd, int cmdSize,
1314413152 if (rc == 0 && cmdTag == TPM_ST_SESSIONS) {
1314513153 rc = FwSkipAuthArea(cmd, cmdSize);
1314613154 }
13147- /* Two KEM types per Part 2 Sec.10.3.13 Table 100: ML-KEM (FIPS 203) and
13148- * ECC DHKEM (RFC 9180 Sec.4.1). For ECC the kdf scheme MUST be HKDF
13149- * (Part 2 Sec.12.2.3.5) — TPM_RC_KEY for any other key type or unset kdf. */
13155+ /* KEM types per Part 2 Sec.10.3.13 Table 100: ML-KEM (FIPS 203) and ECC
13156+ * DHKEM (RFC 9180 Sec.4.1, ECC kdf MUST be HKDF). Part 3 Sec.14.10.1
13157+ * explicitly says the TPM does NOT verify objectAttributes here (only
13158+ * the public portion may be loaded), so no decrypt/restricted check. */
1315013159 if (rc == 0) {
1315113160 if (obj->pub.type == TPM_ALG_MLKEM) {
1315213161 ps = obj->pub.parameters.mlkemDetail.parameterSet;
@@ -13401,13 +13410,15 @@ static TPM_RC FwCmd_SignSequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1340113410 rc = TPM_RC_KEY;
1340213411 }
1340313412 /* Accept ML-DSA, Hash-ML-DSA, classical RSA/ECC, and KEYEDHASH
13404- * (HMAC) signing keys. Other types (SM2, ECSCHNORR) unsupported. */
13413+ * (HMAC) signing keys. Other types (SYMCIPHER, SM2, ECSCHNORR)
13414+ * map to TPM_RC_KEY ("not a signing key" — Part 3 Sec.17.5.1
13415+ * reserves TPM_RC_SCHEME for the NULL-scheme case below). */
1340513416 else if (obj->pub.type != TPM_ALG_MLDSA &&
1340613417 obj->pub.type != TPM_ALG_HASH_MLDSA &&
1340713418 obj->pub.type != TPM_ALG_RSA &&
1340813419 obj->pub.type != TPM_ALG_ECC &&
1340913420 obj->pub.type != TPM_ALG_KEYEDHASH) {
13410- rc = TPM_RC_SCHEME ;
13421+ rc = TPM_RC_KEY ;
1341113422 }
1341213423 }
1341313424
@@ -13426,6 +13437,9 @@ static TPM_RC FwCmd_SignSequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1342613437 if (authSz > sizeof(((TPM2B_AUTH*)0)->buffer)) {
1342713438 rc = TPM_RC_SIZE;
1342813439 }
13440+ else if (cmd->pos + authSz > cmdSize) {
13441+ rc = TPM_RC_COMMAND_SIZE;
13442+ }
1342913443 }
1343013444 /* Parse context (TPM2B_SIGNATURE_CTX) */
1343113445 if (rc == 0) {
@@ -13565,13 +13579,15 @@ static TPM_RC FwCmd_VerifySequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1356513579 rc = TPM_RC_KEY;
1356613580 }
1356713581 /* Accept ML-DSA, Hash-ML-DSA, classical RSA/ECC, and KEYEDHASH
13568- * (HMAC) signing keys. */
13582+ * (HMAC) signing keys. Other types map to TPM_RC_KEY per
13583+ * Part 3 Sec.17.6.1 (TPM_RC_SCHEME is reserved for the
13584+ * NULL-scheme case below). */
1356913585 else if (obj->pub.type != TPM_ALG_MLDSA &&
1357013586 obj->pub.type != TPM_ALG_HASH_MLDSA &&
1357113587 obj->pub.type != TPM_ALG_RSA &&
1357213588 obj->pub.type != TPM_ALG_ECC &&
1357313589 obj->pub.type != TPM_ALG_KEYEDHASH) {
13574- rc = TPM_RC_SCHEME ;
13590+ rc = TPM_RC_KEY ;
1357513591 }
1357613592 }
1357713593
@@ -13587,6 +13603,9 @@ static TPM_RC FwCmd_VerifySequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1358713603 if (authSz > sizeof(((TPM2B_AUTH*)0)->buffer)) {
1358813604 rc = TPM_RC_SIZE;
1358913605 }
13606+ else if (cmd->pos + authSz > cmdSize) {
13607+ rc = TPM_RC_COMMAND_SIZE;
13608+ }
1359013609 }
1359113610 if (rc == 0) {
1359213611 seq = FwAllocSignSeq(ctx, &seqHandle);
@@ -13599,8 +13618,11 @@ static TPM_RC FwCmd_VerifySequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1359913618 TPM2_Packet_ParseBytes(cmd, seq->authValue.buffer, authSz);
1360013619
1360113620 TPM2_Packet_ParseU16(cmd, &hintSz);
13602- /* Part 2 Sec.11.3.9: hint MUST be zero-length for non-EdDSA schemes.
13603- * Reject any non-zero hint up front; nothing to consume on the wire. */
13621+ /* Part 3 Sec.17.6.1: hint carries the EdDSA R for EDDSA verify;
13622+ * MUST be zero-length for all other schemes. wolfTPM does not yet
13623+ * implement EDDSA verify-sequences (no TPM_ALG_EDDSA dispatch in
13624+ * VerifySequenceComplete), so reject any non-zero hint with
13625+ * TPM_RC_VALUE. Re-gate this on obj->pub.type when EDDSA is added. */
1360413626 if (hintSz > 0) {
1360513627 rc = TPM_RC_VALUE;
1360613628 }
@@ -13723,7 +13745,13 @@ static TPM_RC FwCmd_SignSequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1372313745 TPM2_Packet_ParseU32(cmd, &sequenceHandle);
1372413746 TPM2_Packet_ParseU32(cmd, &keyHandle);
1372513747 seq = FwFindSignSeq(ctx, sequenceHandle);
13726- if (seq == NULL || seq->isVerifySeq) {
13748+ /* NULL out seq for a peer's verify-sequence so cleanup
13749+ * doesn't free their slot. */
13750+ if (seq != NULL && seq->isVerifySeq) {
13751+ seq = NULL;
13752+ rc = TPM_RC_HANDLE;
13753+ }
13754+ else if (seq == NULL) {
1372713755 rc = TPM_RC_HANDLE;
1372813756 }
1372913757 }
@@ -13969,12 +13997,15 @@ static TPM_RC FwCmd_SignSequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1396913997 rc = TPM_RC_SCHEME;
1397013998 }
1397113999 else {
13972- paramStart = FwRspParamsBegin(rsp, cmdTag, ¶mSzPos);
14000+ paramStart = FwRspParamsBegin(rsp, cmdTag,
14001+ ¶mSzPos);
1397314002 rc = FwSignDigestAndAppend(ctx, keyObj,
1397414003 schemeAlg, hashAlg,
1397514004 digestOut, digestSz, rsp);
14005+ /* Always pair Begin with End so the param-size
14006+ * back-patch fires even on failure. */
14007+ FwRspParamsEnd(rsp, cmdTag, paramSzPos, paramStart);
1397614008 if (rc == 0) {
13977- FwRspParamsEnd(rsp, cmdTag, paramSzPos, paramStart);
1397814009 FwFreeSignSeq(seq);
1397914010 FWTPM_FREE_BUF(msgBuf);
1398014011 FWTPM_FREE_VAR(sigOut);
@@ -14073,7 +14104,13 @@ static TPM_RC FwCmd_VerifySequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1407314104 TPM2_Packet_ParseU32(cmd, &sequenceHandle);
1407414105 TPM2_Packet_ParseU32(cmd, &keyHandle);
1407514106 seq = FwFindSignSeq(ctx, sequenceHandle);
14076- if (seq == NULL || !seq->isVerifySeq) {
14107+ /* NULL out seq for a peer's sign-sequence so cleanup
14108+ * doesn't free their slot. */
14109+ if (seq != NULL && !seq->isVerifySeq) {
14110+ seq = NULL;
14111+ rc = TPM_RC_HANDLE;
14112+ }
14113+ else if (seq == NULL) {
1407714114 rc = TPM_RC_HANDLE;
1407814115 }
1407914116 }
@@ -14563,6 +14600,12 @@ static TPM_RC FwCmd_SignDigest(FWTPM_CTX* ctx, TPM2_Packet* cmd, int cmdSize,
1456314600 if (sigScheme == TPM_ALG_NULL || sigHashAlg == TPM_ALG_NULL) {
1456414601 rc = TPM_RC_SCHEME;
1456514602 }
14603+ else if (digest->size !=
14604+ (UINT16)TPM2_GetHashDigestSize(sigHashAlg)) {
14605+ /* Part 3 Sec.20.7.1: digest size MUST match the hashAlg
14606+ * digest size for ALL signing schemes. */
14607+ rc = TPM_RC_SIZE;
14608+ }
1456614609 else {
1456714610 rc = FwSignDigestAndAppend(ctx, obj, sigScheme, sigHashAlg,
1456814611 digest->buffer, digest->size, rsp);
@@ -14744,6 +14787,12 @@ static TPM_RC FwCmd_VerifyDigestSignature(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1474414787 keyHashAlg != classicalSig.signature.any.hashAlg) {
1474514788 rc = TPM_RC_SCHEME;
1474614789 }
14790+ else if (digest->size !=
14791+ (UINT16)TPM2_GetHashDigestSize(keyHashAlg)) {
14792+ /* Part 3 Sec.20.4.1: digest size MUST match the hashAlg
14793+ * digest size for ALL signing schemes. */
14794+ rc = TPM_RC_SIZE;
14795+ }
1474714796 else {
1474814797 rc = FwVerifySignatureCore(obj, digest->buffer, digest->size,
1474914798 &classicalSig);
0 commit comments