diff --git a/src/fwtpm/fwtpm_command.c b/src/fwtpm/fwtpm_command.c index d70b05cf..92608398 100644 --- a/src/fwtpm/fwtpm_command.c +++ b/src/fwtpm/fwtpm_command.c @@ -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", diff --git a/src/tpm2.c b/src/tpm2.c index 9bde0856..95e70a4f 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -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; diff --git a/src/tpm2_tis.c b/src/tpm2_tis.c index 6de86be5..0a02df57 100644 --- a/src/tpm2_tis.c +++ b/src/tpm2_tis.c @@ -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)