Merge pull request #608 from aidangarske/fenrir-fixes-14014-14015-14068-14072-14073-14074-14087

Fix fwTPM SPDM and TPM transport security findings
pull/590/head
David Garske 2026-09-14 10:19:12 -07:00 committed by GitHub
commit 2a726188ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 8 deletions

View File

@ -6375,7 +6375,7 @@ static TPM_RC FwCmd_Create(FWTPM_CTX* ctx, TPM2_Packet* cmd,
if (rc == 0) {
inPublic->publicArea.unique.keyedHash.size = (UINT16)
FwComputeUniqueHash(inPublic->publicArea.nameAlg,
privKeyDer, keySz,
privKeyDer, privKeyDerSz,
inPublic->publicArea.unique.keyedHash.buffer);
}
break;
@ -7995,6 +7995,10 @@ static TPM_RC FwCmd_Rewrap(FWTPM_CTX* ctx, TPM2_Packet* cmd,
FWTPM_ALLOC_BUF(plainSens, FWTPM_MAX_SENSITIVE_SIZE);
FWTPM_ALLOC_BUF(encSeedBuf, FWTPM_MAX_PUB_BUF);
/* The dispatcher leaves the command packet overflow flag as-is, so clear it
* before parsing to measure only this command's reads. */
cmd->overflow = 0;
/* Parse handles */
TPM2_Packet_ParseU32(cmd, &oldParentH);
TPM2_Packet_ParseU32(cmd, &newParentH);
@ -8031,6 +8035,12 @@ static TPM_RC FwCmd_Rewrap(FWTPM_CTX* ctx, TPM2_Packet* cmd,
TPM2_Packet_ParseBytes(cmd, symSeedBuf, symSeedSz);
}
/* Reject a command that declared more bytes than it carried; the missing
* duplicate suffix would otherwise be re-wrapped and disclosed. */
if (rc == 0 && cmd->overflow) {
rc = TPM_RC_SIZE;
}
/* Look up oldParent (TPM_RH_NULL means no outer protection) */
if (rc == 0 && oldParentH != TPM_RH_NULL) {
oldParent = FwFindObject(ctx, oldParentH);
@ -19539,12 +19549,11 @@ int FWTPM_ProcessCommand(FWTPM_CTX* ctx,
}
}
else if (authPolicy != NULL && authPolicy->size == 0 &&
cmdAuths[pj].cmdHmacSize == 0) {
/* Per TPM 2.0 Part 1 Sec.19.7, a policy session can only
* authorize an entity whose authPolicy is non-empty.
* When the entity has no authPolicy AND the session
* supplied no HMAC, every downstream auth check would
* be skipped reject up front. */
(cmdAuths[pj].cmdHmacSize == 0 ||
(!pSess->isPasswordPolicy && !pSess->isAuthValuePolicy))) {
/* A policy session authorizes an empty-authPolicy entity only
* via PolicyPassword or PolicyAuthValue; otherwise the entity
* auth is excluded and an unbound/empty HMAC would authorize. */
#ifdef DEBUG_WOLFTPM
printf("fwTPM: Policy session empty-HMAC rejected for "
"handle 0x%x without authPolicy (CC=0x%x)\n",

View File

@ -590,6 +590,15 @@ static TPM_RC TPM2_TransmitCommand(TPM2_CTX* ctx, TPM2_Packet* packet,
/* parse response header and extract the TPM response code */
rc = TPM2_Packet_Parse(rc, packet);
/* Wipe request-tail bytes a shorter response did not overwrite, so
* plaintext auth values do not linger in the shared command buffer. Only
* on success: the command must survive a transport error for inspection. */
if (rc == TPM_RC_SUCCESS && packet->size >= 0 &&
(UINT32)packet->size < cmdSz) {
TPM2_ForceZero(packet->buf + packet->size,
cmdSz - (UINT32)packet->size);
}
return rc;
}
#else
@ -630,6 +639,16 @@ static TPM_RC TPM2_TransmitCommand(TPM2_CTX* ctx, TPM2_Packet* packet,
break;
}
/* Wipe request-tail bytes a shorter response did not overwrite, so
* plaintext auth values do not linger in the shared command buffer. Only
* after the final attempt, and only on success so the command survives a
* transport error for retry and inspection. */
if (rc == TPM_RC_SUCCESS && packet->size >= 0 &&
(UINT32)packet->size < cmdSz) {
TPM2_ForceZero(packet->buf + packet->size,
cmdSz - (UINT32)packet->size);
}
return rc;
}
#endif /* WOLFTPM_NO_RETRY */
@ -7648,8 +7667,14 @@ int TPM2_ParsePublic(TPM2B_PUBLIC* pub, byte* buf, word32 size, int* sizeUsed)
packet.buf = buf;
packet.pos = 0;
packet.size = (int)size;
packet.overflow = 0;
TPM2_Packet_ParsePublic(&packet, pub);
if (packet.overflow) {
*sizeUsed = 0;
return TPM_RC_SIZE;
}
*sizeUsed = packet.pos;
return TPM_RC_SUCCESS;

View File

@ -335,6 +335,7 @@ int TPM2_TIS_RequestLocalityEx(TPM2_CTX* ctx, int locality, int timeout)
int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout)
{
int rc;
int locality = WOLFTPM_LOCALITY_DEFAULT;
#ifdef WOLFTPM_TIS_RESET_STALE_LOCALITY
int l;
@ -359,7 +360,12 @@ int TPM2_TIS_RequestLocality(TPM2_CTX* ctx, int timeout)
}
#endif /* WOLFTPM_TIS_RESET_STALE_LOCALITY */
return TPM2_TIS_RequestLocalityEx(ctx, locality, timeout);
rc = TPM2_TIS_RequestLocalityEx(ctx, locality, timeout);
/* RequestLocalityEx returns the granted locality (0-4) on success; status
* callers expect TPM_RC_SUCCESS, so map any granted locality onto it. */
if (rc >= 0 && rc <= WOLFTPM_LOCALITY_MAX)
rc = TPM_RC_SUCCESS;
return rc;
}
int TPM2_TIS_ReleaseLocality(TPM2_CTX* ctx, int locality)