@@ -452,7 +452,13 @@ static TPM_RC TPM2_SPDM_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet)
452452 packet -> buf , packet -> pos , tpmResp , & tpmRespSz );
453453 if (rc != 0 ) {
454454 TPM2_ForceZero (tpmResp , sizeof (tpmResp ));
455- return rc ;
455+ #ifdef DEBUG_WOLFTPM
456+ printf ("SPDM secured exchange failed: %d\n" , rc );
457+ #endif
458+ /* SPDM is active: never downgrade to cleartext. Map the (negative)
459+ * transport error to a positive TPM RC so the caller treats it as a
460+ * hard failure instead of "SPDM not active". */
461+ return TPM_RC_FAILURE ;
456462 }
457463
458464 if (tpmRespSz > MAX_RESPONSE_SIZE ) {
@@ -467,6 +473,25 @@ static TPM_RC TPM2_SPDM_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet)
467473}
468474#endif /* WOLFTPM_SPDM */
469475
476+ /* Send the finalized command in packet over the SPDM secured channel when a
477+ * session is active, otherwise over the raw transport. Once SPDM is active an
478+ * exchange failure is returned as-is and never falls back to a cleartext send,
479+ * so a forced SPDM failure cannot downgrade the link. */
480+ static TPM_RC TPM2_DispatchCommand (TPM2_CTX * ctx , TPM2_Packet * packet )
481+ {
482+ TPM_RC rc ;
483+
484+ #ifdef WOLFTPM_SPDM
485+ rc = TPM2_SPDM_SendCommand (ctx , packet );
486+ if (rc >= 0 )
487+ return rc ; /* SPDM active: success or hard failure, no cleartext */
488+ /* rc < 0: SPDM not active, use normal transport */
489+ #endif
490+ rc = (TPM_RC )INTERNAL_SEND_COMMAND (ctx , packet );
491+
492+ return rc ;
493+ }
494+
470495#ifdef WOLFTPM_NO_RETRY
471496/* Submit the finalized command in packet (length cmdSz) and parse the
472497 * response, returning the TPM response code. */
@@ -478,19 +503,9 @@ static TPM_RC TPM2_TransmitCommand(TPM2_CTX* ctx, TPM2_Packet* packet,
478503 /* send command requires packet->pos to be the total command length */
479504 packet -> pos = cmdSz ;
480505
481- #ifdef WOLFTPM_SPDM
482- rc = TPM2_SPDM_SendCommand (ctx , packet );
483- if (rc >= 0 ) {
484- if (rc != TPM_RC_SUCCESS )
485- return rc ; /* SPDM active but failed, do not retry cleartext */
486- }
487- else /* rc < 0: SPDM not active, use normal transport */
488- #endif
489- {
490- rc = (TPM_RC )INTERNAL_SEND_COMMAND (ctx , packet );
491- }
506+ rc = TPM2_DispatchCommand (ctx , packet );
492507 if (rc != 0 )
493- return rc ; /* transport error */
508+ return rc ; /* transport or SPDM error */
494509
495510 /* parse response header and extract the TPM response code */
496511 rc = TPM2_Packet_Parse (rc , packet );
@@ -518,19 +533,9 @@ static TPM_RC TPM2_TransmitCommand(TPM2_CTX* ctx, TPM2_Packet* packet,
518533 /* send command requires packet->pos to be the total command length */
519534 packet -> pos = cmdSz ;
520535
521- #ifdef WOLFTPM_SPDM
522- rc = TPM2_SPDM_SendCommand (ctx , packet );
523- if (rc >= 0 ) {
524- if (rc != TPM_RC_SUCCESS )
525- return rc ; /* SPDM active but failed, do not retry cleartext */
526- }
527- else /* rc < 0: SPDM not active, use normal transport */
528- #endif
529- {
530- rc = (TPM_RC )INTERNAL_SEND_COMMAND (ctx , packet );
531- }
536+ rc = TPM2_DispatchCommand (ctx , packet );
532537 if (rc != 0 )
533- return rc ; /* transport error */
538+ return rc ; /* transport or SPDM error */
534539
535540 /* parse response header and extract the TPM response code */
536541 rc = TPM2_Packet_Parse (rc , packet );
0 commit comments