Skip to content

Commit ddddacd

Browse files
committed
fwTPM: prevent SPDM-active failure from downgrading to cleartext and dedup transport dispatch
1 parent 13de985 commit ddddacd

1 file changed

Lines changed: 30 additions & 25 deletions

File tree

src/tpm2.c

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)