@@ -7154,6 +7154,9 @@ static TPM_RC FwCmd_SequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
71547154 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL;
71557155 int paramSzPos, paramStart;
71567156 int trc;
7157+ #ifdef WOLFTPM_V185
7158+ FWTPM_SignSeq* misRoutedSign = NULL;
7159+ #endif
71577160
71587161 FWTPM_ALLOC_BUF(dataBuf, FWTPM_MAX_DATA_BUF);
71597162
@@ -7167,6 +7170,11 @@ static TPM_RC FwCmd_SequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
71677170 seq = FwFindHashSeq(ctx, seqHandle);
71687171 if (seq == NULL) {
71697172 rc = TPM_RC_HANDLE;
7173+ #ifdef WOLFTPM_V185
7174+ /* Free a sign/verify slot mis-routed here so it doesn't leak. */
7175+ misRoutedSign = FwFindSignSeq(ctx, seqHandle);
7176+ if (misRoutedSign != NULL) FwFreeSignSeq(misRoutedSign);
7177+ #endif
71707178 }
71717179 else {
71727180 hashAlg = seq->hashAlg;
@@ -13054,9 +13062,10 @@ static TPM_RC FwCmd_Encapsulate(FWTPM_CTX* ctx, TPM2_Packet* cmd, int cmdSize,
1305413062 if (rc == 0 && cmdTag == TPM_ST_SESSIONS) {
1305513063 rc = FwSkipAuthArea(cmd, cmdSize);
1305613064 }
13057- /* Two KEM types per Part 2 Sec.10.3.13 Table 100: ML-KEM (FIPS 203) and
13058- * ECC DHKEM (RFC 9180 Sec.4.1). For ECC the kdf scheme MUST be HKDF
13059- * (Part 2 Sec.12.2.3.5) — TPM_RC_KEY for any other key type or unset kdf. */
13065+ /* KEM types per Part 2 Sec.10.3.13 Table 100: ML-KEM (FIPS 203) and ECC
13066+ * DHKEM (RFC 9180 Sec.4.1, ECC kdf MUST be HKDF). Part 3 Sec.14.10.1
13067+ * explicitly says the TPM does NOT verify objectAttributes here (only
13068+ * the public portion may be loaded), so no decrypt/restricted check. */
1306013069 if (rc == 0) {
1306113070 if (obj->pub.type == TPM_ALG_MLKEM) {
1306213071 ps = obj->pub.parameters.mlkemDetail.parameterSet;
@@ -13311,13 +13320,15 @@ static TPM_RC FwCmd_SignSequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1331113320 rc = TPM_RC_KEY;
1331213321 }
1331313322 /* Accept ML-DSA, Hash-ML-DSA, classical RSA/ECC, and KEYEDHASH
13314- * (HMAC) signing keys. Other types (SM2, ECSCHNORR) unsupported. */
13323+ * (HMAC) signing keys. Other types (SYMCIPHER, SM2, ECSCHNORR)
13324+ * map to TPM_RC_KEY ("not a signing key" — Part 3 Sec.17.5.1
13325+ * reserves TPM_RC_SCHEME for the NULL-scheme case below). */
1331513326 else if (obj->pub.type != TPM_ALG_MLDSA &&
1331613327 obj->pub.type != TPM_ALG_HASH_MLDSA &&
1331713328 obj->pub.type != TPM_ALG_RSA &&
1331813329 obj->pub.type != TPM_ALG_ECC &&
1331913330 obj->pub.type != TPM_ALG_KEYEDHASH) {
13320- rc = TPM_RC_SCHEME ;
13331+ rc = TPM_RC_KEY ;
1332113332 }
1332213333 }
1332313334
@@ -13336,6 +13347,9 @@ static TPM_RC FwCmd_SignSequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1333613347 if (authSz > sizeof(((TPM2B_AUTH*)0)->buffer)) {
1333713348 rc = TPM_RC_SIZE;
1333813349 }
13350+ else if (cmd->pos + authSz > cmdSize) {
13351+ rc = TPM_RC_COMMAND_SIZE;
13352+ }
1333913353 }
1334013354 /* Parse context (TPM2B_SIGNATURE_CTX) */
1334113355 if (rc == 0) {
@@ -13475,13 +13489,15 @@ static TPM_RC FwCmd_VerifySequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1347513489 rc = TPM_RC_KEY;
1347613490 }
1347713491 /* Accept ML-DSA, Hash-ML-DSA, classical RSA/ECC, and KEYEDHASH
13478- * (HMAC) signing keys. */
13492+ * (HMAC) signing keys. Other types map to TPM_RC_KEY per
13493+ * Part 3 Sec.17.6.1 (TPM_RC_SCHEME is reserved for the
13494+ * NULL-scheme case below). */
1347913495 else if (obj->pub.type != TPM_ALG_MLDSA &&
1348013496 obj->pub.type != TPM_ALG_HASH_MLDSA &&
1348113497 obj->pub.type != TPM_ALG_RSA &&
1348213498 obj->pub.type != TPM_ALG_ECC &&
1348313499 obj->pub.type != TPM_ALG_KEYEDHASH) {
13484- rc = TPM_RC_SCHEME ;
13500+ rc = TPM_RC_KEY ;
1348513501 }
1348613502 }
1348713503
@@ -13497,6 +13513,9 @@ static TPM_RC FwCmd_VerifySequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1349713513 if (authSz > sizeof(((TPM2B_AUTH*)0)->buffer)) {
1349813514 rc = TPM_RC_SIZE;
1349913515 }
13516+ else if (cmd->pos + authSz > cmdSize) {
13517+ rc = TPM_RC_COMMAND_SIZE;
13518+ }
1350013519 }
1350113520 if (rc == 0) {
1350213521 seq = FwAllocSignSeq(ctx, &seqHandle);
@@ -13509,8 +13528,11 @@ static TPM_RC FwCmd_VerifySequenceStart(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1350913528 TPM2_Packet_ParseBytes(cmd, seq->authValue.buffer, authSz);
1351013529
1351113530 TPM2_Packet_ParseU16(cmd, &hintSz);
13512- /* Part 2 Sec.11.3.9: hint MUST be zero-length for non-EdDSA schemes.
13513- * Reject any non-zero hint up front; nothing to consume on the wire. */
13531+ /* Part 3 Sec.17.6.1: hint carries the EdDSA R for EDDSA verify;
13532+ * MUST be zero-length for all other schemes. wolfTPM does not yet
13533+ * implement EDDSA verify-sequences (no TPM_ALG_EDDSA dispatch in
13534+ * VerifySequenceComplete), so reject any non-zero hint with
13535+ * TPM_RC_VALUE. Re-gate this on obj->pub.type when EDDSA is added. */
1351413536 if (hintSz > 0) {
1351513537 rc = TPM_RC_VALUE;
1351613538 }
@@ -13633,7 +13655,13 @@ static TPM_RC FwCmd_SignSequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1363313655 TPM2_Packet_ParseU32(cmd, &sequenceHandle);
1363413656 TPM2_Packet_ParseU32(cmd, &keyHandle);
1363513657 seq = FwFindSignSeq(ctx, sequenceHandle);
13636- if (seq == NULL || seq->isVerifySeq) {
13658+ /* NULL out seq for a peer's verify-sequence so cleanup
13659+ * doesn't free their slot. */
13660+ if (seq != NULL && seq->isVerifySeq) {
13661+ seq = NULL;
13662+ rc = TPM_RC_HANDLE;
13663+ }
13664+ else if (seq == NULL) {
1363713665 rc = TPM_RC_HANDLE;
1363813666 }
1363913667 }
@@ -13879,12 +13907,15 @@ static TPM_RC FwCmd_SignSequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1387913907 rc = TPM_RC_SCHEME;
1388013908 }
1388113909 else {
13882- paramStart = FwRspParamsBegin(rsp, cmdTag, ¶mSzPos);
13910+ paramStart = FwRspParamsBegin(rsp, cmdTag,
13911+ ¶mSzPos);
1388313912 rc = FwSignDigestAndAppend(ctx, keyObj,
1388413913 schemeAlg, hashAlg,
1388513914 digestOut, digestSz, rsp);
13915+ /* Always pair Begin with End so the param-size
13916+ * back-patch fires even on failure. */
13917+ FwRspParamsEnd(rsp, cmdTag, paramSzPos, paramStart);
1388613918 if (rc == 0) {
13887- FwRspParamsEnd(rsp, cmdTag, paramSzPos, paramStart);
1388813919 FwFreeSignSeq(seq);
1388913920 FWTPM_FREE_BUF(msgBuf);
1389013921 FWTPM_FREE_VAR(sigOut);
@@ -13983,7 +14014,13 @@ static TPM_RC FwCmd_VerifySequenceComplete(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1398314014 TPM2_Packet_ParseU32(cmd, &sequenceHandle);
1398414015 TPM2_Packet_ParseU32(cmd, &keyHandle);
1398514016 seq = FwFindSignSeq(ctx, sequenceHandle);
13986- if (seq == NULL || !seq->isVerifySeq) {
14017+ /* NULL out seq for a peer's sign-sequence so cleanup
14018+ * doesn't free their slot. */
14019+ if (seq != NULL && !seq->isVerifySeq) {
14020+ seq = NULL;
14021+ rc = TPM_RC_HANDLE;
14022+ }
14023+ else if (seq == NULL) {
1398714024 rc = TPM_RC_HANDLE;
1398814025 }
1398914026 }
@@ -14473,6 +14510,12 @@ static TPM_RC FwCmd_SignDigest(FWTPM_CTX* ctx, TPM2_Packet* cmd, int cmdSize,
1447314510 if (sigScheme == TPM_ALG_NULL || sigHashAlg == TPM_ALG_NULL) {
1447414511 rc = TPM_RC_SCHEME;
1447514512 }
14513+ else if (digest->size !=
14514+ (UINT16)TPM2_GetHashDigestSize(sigHashAlg)) {
14515+ /* Part 3 Sec.20.7.1: digest size MUST match the hashAlg
14516+ * digest size for ALL signing schemes. */
14517+ rc = TPM_RC_SIZE;
14518+ }
1447614519 else {
1447714520 rc = FwSignDigestAndAppend(ctx, obj, sigScheme, sigHashAlg,
1447814521 digest->buffer, digest->size, rsp);
@@ -14654,6 +14697,12 @@ static TPM_RC FwCmd_VerifyDigestSignature(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1465414697 keyHashAlg != classicalSig.signature.any.hashAlg) {
1465514698 rc = TPM_RC_SCHEME;
1465614699 }
14700+ else if (digest->size !=
14701+ (UINT16)TPM2_GetHashDigestSize(keyHashAlg)) {
14702+ /* Part 3 Sec.20.4.1: digest size MUST match the hashAlg
14703+ * digest size for ALL signing schemes. */
14704+ rc = TPM_RC_SIZE;
14705+ }
1465714706 else {
1465814707 rc = FwVerifySignatureCore(obj, digest->buffer, digest->size,
1465914708 &classicalSig);
0 commit comments