Merge pull request #600 from aidangarske/tpm2-core-fixes-12758

Improve TPM2 core zeroization and robustness and comments correctness
pull/603/head
David Garske 2026-09-09 15:07:38 -07:00 committed by GitHub
commit b0e882da46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 180 additions and 71 deletions

View File

@ -235,6 +235,7 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
#ifdef DEBUG_WOLFTPM
printf("Command parameter encryption failed\n");
#endif
TPM2_ForceZero(&authCmd, sizeof(authCmd));
return rc;
}
}
@ -249,6 +250,7 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
#ifdef DEBUG_WOLFTPM
printf("Error getting names for cpHash!\n");
#endif
TPM2_ForceZero(&authCmd, sizeof(authCmd));
return BAD_FUNC_ARG;
}
@ -259,6 +261,8 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
#ifdef DEBUG_WOLFTPM
printf("Error calculating cpHash!\n");
#endif
TPM2_ForceZero(&hash, sizeof(hash));
TPM2_ForceZero(&authCmd, sizeof(authCmd));
return rc;
}
/* Calculate HMAC for policy, hmac or salted sessions */
@ -270,6 +274,8 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
#ifdef DEBUG_WOLFTPM
printf("Error calculating command HMAC!\n");
#endif
TPM2_ForceZero(&hash, sizeof(hash));
TPM2_ForceZero(&authCmd, sizeof(authCmd));
return rc;
}
#endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_HMAC */
@ -388,14 +394,21 @@ int TPM2_ResponseProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
XMEMSET(&hash, 0, sizeof(hash));
XMEMSET(&hmac, 0, sizeof(hmac));
if (expectedHmacSz == 0 || authRsp.hmac.size != expectedHmacSz) {
if (expectedHmacSz == 0) {
#ifdef DEBUG_WOLFTPM
printf("Response HMAC size mismatch! expected=%u got=%u\n",
expectedHmacSz, authRsp.hmac.size);
printf("Response HMAC size invalid! expected=%u\n",
expectedHmacSz);
#endif
TPM2_ForceZero(&authRsp, sizeof(authRsp));
return TPM_RC_HMAC;
}
sizeMismatch = (authRsp.hmac.size != expectedHmacSz);
#ifdef DEBUG_WOLFTPM
if (sizeMismatch) {
printf("Response HMAC size mismatch! expected=%u got=%u\n",
expectedHmacSz, authRsp.hmac.size);
}
#endif
/* calculate "rpHash" hash for command code and parameters */
rc = TPM2_CalcRpHash(session->authHash, cmdCode, param, paramSz,
@ -423,11 +436,11 @@ int TPM2_ResponseProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
return rc;
}
/* Verify HMAC using constant-time comparison. Wire-format
* size is validated above; this is a branch-free tail check
* (hmac.size and authRsp.hmac.size are both algorithm-derived
* and equal to expectedHmacSz at this point). */
sizeMismatch = (hmac.size != authRsp.hmac.size);
/* Verify HMAC using constant-time comparison. A wire-size
* mismatch captured above is combined here rather than
* rejected early, so this always reads expectedHmacSz
* bytes regardless of the attacker-supplied wire size. */
sizeMismatch |= (hmac.size != authRsp.hmac.size);
diff = TPM2_ConstantCompare(hmac.buffer, authRsp.hmac.buffer,
expectedHmacSz);
if (sizeMismatch | diff) {
@ -467,6 +480,15 @@ int TPM2_ResponseProcess(TPM2_CTX* ctx, TPM2_Packet* packet,
return rc;
}
}
/* Retire a one-shot session: when the TPM clears
* continueSession the session is consumed, so clear the local
* slot to prevent reuse of a stale handle. */
if ((authRsp.sessionAttributes & TPMA_SESSION_continueSession)
== 0) {
TPM2_ForceZero(session, sizeof(TPM2_AUTH_SESSION));
session->sessionHandle = TPM_RS_PW;
}
}
TPM2_ForceZero(&authRsp, sizeof(authRsp));
@ -6826,6 +6848,10 @@ int TPM2_GetNonceNoLock(byte* nonceBuf, int nonceSz)
}
/* response buffer held freshly generated random; wipe before return */
TPM2_ForceZero(buffer, sizeof(buffer));
if (rc != TPM_RC_SUCCESS && randSz > 0) {
/* wipe partial nonce bytes already written from earlier chunks */
TPM2_ForceZero(nonceBuf, (word32)randSz);
}
#endif
return rc;
@ -7516,6 +7542,7 @@ int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size)
#ifndef WOLFTPM2_NO_WOLFCRYPT
int rc;
int hashSize, nameAlgSize;
int hashInitialized = 0;
UINT16 nameAlgValue;
wc_HashAlg hash;
enum wc_HashType hashType;
@ -7551,6 +7578,7 @@ int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size)
rc = wc_HashInit(&hash, hashType);
if (rc == 0) {
hashInitialized = 1;
rc = wc_HashUpdate(&hash, hashType, packet.buf, packet.pos);
}
if (rc == 0) {
@ -7567,7 +7595,11 @@ int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size)
rc = TPM_RC_SUCCESS;
}
wc_HashFree(&hash, hashType);
if (hashInitialized) {
wc_HashFree(&hash, hashType);
}
TPM2_ForceZero(&hash, sizeof(hash));
TPM2_ForceZero(appending, sizeof(appending));
return rc;
#else
@ -7585,19 +7617,21 @@ int TPM2_AppendPublic(byte* buf, word32 size, int* sizeUsed, TPM2B_PUBLIC* pub)
if (buf == NULL || pub == NULL || sizeUsed == NULL)
return BAD_FUNC_ARG;
if (size < sizeof(TPM2B_PUBLIC)) {
/* Prepare temporary buffer. The append helpers bounds-check against
* packet.size and set packet.overflow, so an exact-fit buffer is
* accepted and only an actually-too-small buffer is rejected. */
packet.buf = buf;
packet.pos = 0;
packet.size = (int)size;
packet.overflow = 0;
TPM2_Packet_AppendPublic(&packet, pub);
if (packet.overflow) {
#ifdef DEBUG_WOLFTPM
printf("Insufficient buffer size for TPM2B_PUBLIC operations\n");
#endif
return TPM_RC_FAILURE;
}
/* Prepare temporary buffer */
packet.buf = buf;
packet.pos = 0;
packet.size = (int)size;
TPM2_Packet_AppendPublic(&packet, pub);
*sizeUsed = packet.pos;
return TPM_RC_SUCCESS;

View File

@ -420,7 +420,8 @@ int TPM2_HmacCompute(
int dSz;
if (digest == NULL || (key == NULL && keySz > 0) ||
(data == NULL && dataSz > 0)) {
(data == NULL && dataSz > 0) ||
(data2 == NULL && data2Sz > 0)) {
return BAD_FUNC_ARG;
}

View File

@ -382,7 +382,7 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
sigRS, keySz*2,
info->pk.eccverify.hash, info->pk.eccverify.hashlen);
if (info->pk.eccverify.res) {
if ((rc & TPM_RC_SIGNATURE) == TPM_RC_SIGNATURE) {
if ((rc & RC_MAX_FMT1) == TPM_RC_SIGNATURE) {
/* mark invalid signature */
*info->pk.eccverify.res = 0;
rc = 0;
@ -1110,6 +1110,10 @@ static int RsaPadPss(const byte* input, word32 inputLen, byte* pkcsBlock,
if ((int)pkcsBlockLen - hLen < saltLen + 2) {
return PSS_SALTLEN_E;
}
/* Ensure M' (padding || hLen || saltLen) fits the scratch buffer */
if ((int)pkcsBlockLen < RSA_PSS_PAD_SZ + hLen + saltLen) {
return PSS_SALTLEN_E;
}
ret = wc_HashInit_ex(&hashCtx, hType, NULL, INVALID_DEVID);
if (ret != 0) {

View File

@ -573,8 +573,8 @@ void TPM2_Packet_AppendPCR(TPM2_Packet* packet, TPML_PCR_SELECTION* pcr)
TPM2_Packet_AppendU32(packet, count);
for (i=0; i<(int)count; i++) {
UINT8 selectSz = pcr->pcrSelections[i].sizeofSelect;
if (selectSz > PCR_SELECT_MIN)
selectSz = PCR_SELECT_MIN;
if (selectSz > PCR_SELECT_MAX)
selectSz = PCR_SELECT_MAX;
TPM2_Packet_AppendU16(packet, pcr->pcrSelections[i].hash);
TPM2_Packet_AppendU8(packet, selectSz);
TPM2_Packet_AppendBytes(packet,
@ -621,8 +621,8 @@ void TPM2_Packet_ParsePCR(TPM2_Packet* packet, TPML_PCR_SELECTION* pcr)
if (i < (int)pcr->count) {
pcr->pcrSelections[i].hash = hash;
pcr->pcrSelections[i].sizeofSelect = wireSizeofSelect;
if (pcr->pcrSelections[i].sizeofSelect > PCR_SELECT_MIN)
pcr->pcrSelections[i].sizeofSelect = PCR_SELECT_MIN;
if (pcr->pcrSelections[i].sizeofSelect > PCR_SELECT_MAX)
pcr->pcrSelections[i].sizeofSelect = PCR_SELECT_MAX;
TPM2_Packet_ParseBytes(packet,
pcr->pcrSelections[i].pcrSelect,
pcr->pcrSelections[i].sizeofSelect);
@ -871,6 +871,7 @@ void TPM2_Packet_ParsePoint(TPM2_Packet* packet, TPM2B_ECC_POINT* point)
}
else {
packet->pos = packet->size;
packet->overflow = 1;
}
}
}
@ -946,6 +947,7 @@ void TPM2_Packet_ParseSensitive(TPM2_Packet* packet, TPM2B_SENSITIVE* sensitive)
TPM2_Packet_ParseU16(packet, &sensitive->size);
if (sensitive->size == 0) {
XMEMSET(&sensitive->sensitiveArea, 0, sizeof(sensitive->sensitiveArea));
return;
}
/* Clamp outer size to remaining packet bytes so inner parses are bounded */

View File

@ -111,30 +111,31 @@ static int wolfTPM2_SPDM_TisIoCb(
/* Ensure we have TPM locality */
rc = TPM2_TIS_RequestLocality(tpmCtx, TPM_TIMEOUT_TRIES);
if (rc != TPM_RC_SUCCESS) {
return rc;
if (rc == TPM_RC_SUCCESS) {
/* Send through TIS FIFO and receive response */
rc = TPM2_TIS_SendCommand(tpmCtx, &packet);
}
/* Send through TIS FIFO and receive response */
rc = TPM2_TIS_SendCommand(tpmCtx, &packet);
if (rc != TPM_RC_SUCCESS) {
return rc;
if (rc == TPM_RC_SUCCESS) {
/* Extract response size from header bytes [2..5] (big-endian).
* Both TPM headers and TCG SPDM binding headers store the total
* message size at this offset in the same format. */
XMEMCPY(&rspSz, &ioBuf[2], sizeof(UINT32));
rspSz = TPM2_Packet_SwapU32(rspSz);
if (wolfTPM2_SPDM_ValidateRspSz(rspSz, *rxSz, sizeof(ioBuf)) != 0) {
rc = -1;
}
}
/* Extract response size from header bytes [2..5] (big-endian).
* Both TPM headers and TCG SPDM binding headers store the total
* message size at this offset in the same format. */
XMEMCPY(&rspSz, &ioBuf[2], sizeof(UINT32));
rspSz = TPM2_Packet_SwapU32(rspSz);
if (wolfTPM2_SPDM_ValidateRspSz(rspSz, *rxSz, sizeof(ioBuf)) != 0) {
return -1;
if (rc == TPM_RC_SUCCESS) {
XMEMCPY(rxBuf, ioBuf, rspSz);
*rxSz = rspSz;
}
XMEMCPY(rxBuf, ioBuf, rspSz);
*rxSz = rspSz;
TPM2_ForceZero(ioBuf, sizeof(ioBuf));
return 0;
return rc;
}
#endif /* WOLFTPM_SPDM_TIS_IO */
@ -166,28 +167,33 @@ static int wolfTPM2_SPDM_SwtpmIoCb(
packet.size = (int)sizeof(ioBuf);
rc = TPM2_SWTPM_SendCommand(tpmCtx, &packet);
if (rc != TPM_RC_SUCCESS) {
return rc;
if (rc == TPM_RC_SUCCESS) {
/* TPM2_SWTPM_SendCommand validated the received length against
* TPM2_HEADER_SIZE, so the size field below is present. */
/* TCG SPDM Binding header and TPM2 header both carry total size at
* bytes [2..5] big-endian. */
XMEMCPY(&rspSz, &ioBuf[2], sizeof(word32));
rspSz = TPM2_Packet_SwapU32(rspSz);
if (rspSz < TPM2_HEADER_SIZE) {
rc = -1;
}
else if (wolfTPM2_SPDM_ValidateRspSz(rspSz, *rxSz,
sizeof(ioBuf)) != 0) {
rc = -1;
}
}
/* TPM2_SWTPM_SendCommand validated the received length against
* TPM2_HEADER_SIZE, so the size field below is present. */
/* TCG SPDM Binding header and TPM2 header both carry total size at
* bytes [2..5] big-endian. */
XMEMCPY(&rspSz, &ioBuf[2], sizeof(word32));
rspSz = TPM2_Packet_SwapU32(rspSz);
if (rspSz < TPM2_HEADER_SIZE) {
return -1;
}
if (wolfTPM2_SPDM_ValidateRspSz(rspSz, *rxSz, sizeof(ioBuf)) != 0) {
return -1;
if (rc == TPM_RC_SUCCESS) {
XMEMCPY(rxBuf, ioBuf, rspSz);
*rxSz = rspSz;
}
XMEMCPY(rxBuf, ioBuf, rspSz);
*rxSz = rspSz;
return 0;
TPM2_ForceZero(ioBuf, sizeof(ioBuf));
return rc;
}
#endif /* WOLFTPM_SPDM_SWTPM_IO */

View File

@ -611,11 +611,12 @@ int TPM2_SWTPM_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet)
if (rc == TPM_RC_SUCCESS) {
rc = SwTpmReceive(ctx, &tss_word, sizeof(uint32_t));
tss_word = TPM2_Packet_SwapU32(tss_word);
#ifdef WOLFTPM_DEBUG
if (tss_word != 0) {
if (rc == TPM_RC_SUCCESS && tss_word != 0) {
#ifdef WOLFTPM_DEBUG
printf("SWTPM ack %d\n", tss_word);
#endif
rc = TPM_RC_FAILURE;
}
#endif
}

View File

@ -528,7 +528,7 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet)
pos = 0;
while (pos < packet->pos) {
rc = TPM2_TIS_GetBurstCount(ctx, &burstCount);
if (rc < 0)
if (rc != TPM_RC_SUCCESS)
goto exit;
xferSz = packet->pos - pos;
@ -591,7 +591,7 @@ int TPM2_TIS_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet)
}
rc = TPM2_TIS_GetBurstCount(ctx, &burstCount);
if (rc < 0)
if (rc != TPM_RC_SUCCESS)
goto exit;
xferSz = rspSz - pos;

View File

@ -140,6 +140,9 @@ int TPM2_ConstantCompare(const byte* a, const byte* b, word32 len)
void TPM2_ForceZero(void* mem, word32 len)
{
volatile byte* z = (volatile byte*)mem;
if (mem == NULL) {
return;
}
while (len--) {
*z++ = 0;
}

View File

@ -903,6 +903,7 @@ int wolfTPM2_SetKeyBlobFromBuffer(WOLFTPM2_KEYBLOB* key, byte *buffer,
printf("Extra data left in buffer (%d!=%d)\n",
bufferSz, (word32)done_reading);
#endif
TPM2_ForceZero(key, sizeof(*key));
return BUFFER_E;
}
@ -1622,6 +1623,8 @@ int wolfTPM2_SpdmConnectNuvoton(WOLFTPM2_DEV* dev,
pubKeyY, &ySz);
wc_ecc_free(&hostKey);
wc_FreeRng(&rng);
TPM2_ForceZero(&hostKey, sizeof(hostKey));
TPM2_ForceZero(&rng, sizeof(rng));
if (rc != 0) {
wc_ForceZero(privKey, sizeof(privKey));
return rc;
@ -1814,6 +1817,8 @@ int wolfTPM2_SpdmConnectNations(WOLFTPM2_DEV* dev,
pubKeyY, &ySz);
wc_ecc_free(&hostKey);
wc_FreeRng(&rng);
TPM2_ForceZero(&hostKey, sizeof(hostKey));
TPM2_ForceZero(&rng, sizeof(rng));
if (rc != 0) {
wc_ForceZero(privKey, sizeof(privKey));
return rc;
@ -2518,6 +2523,9 @@ static int wolfTPM2_EncryptSecret_ECC(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* tpm
wc_ecc_free(&eccKeyPub);
wc_ecc_free(&eccKeyPriv);
wc_FreeRng(&rng);
TPM2_ForceZero(&eccKeyPub, sizeof(eccKeyPub));
TPM2_ForceZero(&eccKeyPriv, sizeof(eccKeyPriv));
TPM2_ForceZero(&rng, sizeof(rng));
TPM2_ForceZero(&secretPoint, sizeof(secretPoint));
if (rc >= 0) {
@ -2614,6 +2622,12 @@ static int wolfTPM2_EncryptSecret_RSA(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* tpm
rc = (rc == secret->size) ? 0 /* success */ : BUFFER_E /* fail */;
}
if (rc != 0) {
/* Do not leave the plaintext salt or seed in the caller buffer */
TPM2_ForceZero(data->buffer, sizeof(data->buffer));
data->size = 0;
}
return rc;
}
#endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_RSA && !WC_NO_RNG */
@ -2922,6 +2936,8 @@ int wolfTPM2_StartSession_ex(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
wolfTPM2_GetRCString(rc));
#endif
TPM2_ForceZero(&session->salt, sizeof(session->salt));
TPM2_ForceZero(&authSesIn, sizeof(authSesIn));
TPM2_ForceZero(&authSesOut, sizeof(authSesOut));
return rc;
}
@ -3027,6 +3043,8 @@ int wolfTPM2_StartSession_ex(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
}
TPM2_ForceZero(keyIn, sizeof(keyIn));
TPM2_ForceZero(&authSesIn, sizeof(authSesIn));
TPM2_ForceZero(&authSesOut, sizeof(authSesOut));
return rc;
}
@ -3367,14 +3385,19 @@ int wolfTPM2_CreateAndLoadKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
if (dev == NULL || key == NULL)
return BAD_FUNC_ARG;
XMEMSET(key, 0, sizeof(WOLFTPM2_KEY));
XMEMSET(&keyBlob, 0, sizeof(keyBlob));
rc = wolfTPM2_CreateKey(dev, &keyBlob, parent, publicTemplate,
auth, authSz);
if (rc == TPM_RC_SUCCESS) {
rc = wolfTPM2_LoadKey(dev, &keyBlob, parent);
}
/* return loaded key */
XMEMCPY(key, &keyBlob, sizeof(WOLFTPM2_KEY));
if (rc == TPM_RC_SUCCESS) {
/* return loaded key */
XMEMCPY(key, &keyBlob, sizeof(WOLFTPM2_KEY));
}
TPM2_ForceZero(&keyBlob, sizeof(keyBlob));
return rc;
@ -3533,6 +3556,11 @@ int wolfTPM2_ComputeName(const TPM2B_PUBLIC* pub, TPM2B_NAME* out)
packet.buf = data.buffer;
packet.size = sizeof(data.buffer);
TPM2_Packet_AppendPublicArea(&packet, (TPMT_PUBLIC*)&pub->publicArea);
if (packet.overflow) {
/* A truncated public area would produce a wrong Name and corrupt
* authorization binding, so reject rather than hash a partial area */
return BUFFER_E;
}
data.size = packet.pos;
hashSz = TPM2_GetHashDigestSize(nameAlg);
@ -4434,6 +4462,7 @@ int wolfTPM2_DecodeRsaDer(const byte* der, word32 derSz,
}
}
wc_FreeRsaKey(key);
TPM2_ForceZero(key, sizeof(RsaKey));
}
TPM2_ForceZero(d, sizeof(d));
@ -4559,6 +4588,7 @@ int wolfTPM2_DecodeEccDer(const byte* der, word32 derSz, TPM2B_PUBLIC* pub,
}
wc_ecc_free(key);
TPM2_ForceZero(key, sizeof(ecc_key));
}
TPM2_ForceZero(d, sizeof(d));
@ -4689,6 +4719,10 @@ int wolfTPM2_ImportPublicKeyBuffer(WOLFTPM2_DEV* dev, int keyType,
return BAD_FUNC_ARG;
}
if (keyType != TPM_ALG_RSA && keyType != TPM_ALG_ECC) {
return BAD_FUNC_ARG;
}
if (encodingType == ENCODING_TYPE_PEM) {
#ifdef WOLFTPM2_PEM_DECODE
/* der size is base 64 decode length */
@ -4755,6 +4789,10 @@ int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev,
return BAD_FUNC_ARG;
}
if (keyType != TPM_ALG_RSA && keyType != TPM_ALG_ECC) {
return BAD_FUNC_ARG;
}
pub = &keyBlob->pub;
XMEMSET(pub, 0, sizeof(*pub));
XMEMSET(&sens, 0, sizeof(sens));
@ -4907,8 +4945,10 @@ int wolfTPM2_RsaPrivateKeyImportDer(WOLFTPM2_DEV* dev,
qSz, scheme, hashAlg);
}
if (initRc == 0)
if (initRc == 0) {
wc_FreeRsaKey(key);
TPM2_ForceZero(key, sizeof(RsaKey));
}
TPM2_ForceZero(d, sizeof(d));
TPM2_ForceZero(p, sizeof(p));
@ -5233,6 +5273,7 @@ static int wolfTPM2_EccMakePubBlinded(ecc_key* key, ecc_point* point)
wc_FreeRng(&rng);
}
TPM2_ForceZero(&rng, sizeof(rng));
return rc;
#else
(void)key;
@ -5558,6 +5599,11 @@ int wolfTPM2_SignHashScheme(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
return BAD_FUNC_ARG;
}
if (key->pub.publicArea.type != TPM_ALG_ECC &&
key->pub.publicArea.type != TPM_ALG_RSA) {
return BAD_FUNC_ARG;
}
if (key->pub.publicArea.type == TPM_ALG_ECC) {
/* get curve size */
curveSize = wolfTPM2_GetCurveSize(
@ -5894,6 +5940,8 @@ int wolfTPM2_SignSequenceStart(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
*sequenceHandle = signSeqStartOut.sequenceHandle;
}
TPM2_ForceZero(&signSeqStartIn, sizeof(signSeqStartIn));
return rc;
}
@ -6084,6 +6132,8 @@ int wolfTPM2_VerifySequenceStart(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
*sequenceHandle = verifySeqStartOut.sequenceHandle;
}
TPM2_ForceZero(&verifySeqStartIn, sizeof(verifySeqStartIn));
return rc;
}
@ -8079,6 +8129,10 @@ int wolfTPM2_GetRandom(WOLFTPM2_DEV* dev, byte* buf, word32 len)
TPM2_ForceZero(&out, sizeof(out));
}
TPM2_ForceZero(&out, sizeof(out));
if (rc != TPM_RC_SUCCESS) {
/* Scrub any partial random material already written to the caller */
TPM2_ForceZero(buf, len);
}
return rc;
}
@ -8760,7 +8814,9 @@ int wolfTPM2_HmacStart(WOLFTPM2_DEV* dev, WOLFTPM2_HMAC* hmac,
}
if (usageAuth != NULL) {
/* Capture usage auth */
/* Capture usage auth, clearing any longer prior value first */
TPM2_ForceZero(hmac->hash.handle.auth.buffer,
sizeof(hmac->hash.handle.auth.buffer));
hmac->hash.handle.auth.size = usageAuthSz;
XMEMCPY(hmac->hash.handle.auth.buffer, usageAuth, usageAuthSz);
}
@ -10254,6 +10310,8 @@ static void wolfTPM2_CopyPub(TPM2B_PUBLIC* out, const TPM2B_PUBLIC* in)
static void wolfTPM2_CopyPriv(TPM2B_PRIVATE* out, const TPM2B_PRIVATE* in)
{
if (out != NULL && in != NULL) {
/* Clear any longer prior blob so its tail does not remain resident */
TPM2_ForceZero(out->buffer, sizeof(out->buffer));
out->size = in->size;
if (out->size > (UINT16)sizeof(out->buffer))
out->size = (UINT16)sizeof(out->buffer);

View File

@ -979,11 +979,11 @@ WOLFTPM_API const char* FWTPM_GetVersionString(void);
FWTPM_Clock_GetMs returns ctx->clockOffset only.
\return 0 on success
\return BAD_FUNC_ARG if ctx is NULL
\return BAD_FUNC_ARG if ctx or get_ms is NULL
\param ctx pointer to an initialized FWTPM_CTX
\param get_ms callback returning milliseconds-since-boot; may be NULL
to clear a previously registered HAL
\param get_ms callback returning milliseconds-since-boot; must be
non-NULL, or the call returns BAD_FUNC_ARG
\param halCtx opaque context passed back to get_ms
\sa FWTPM_Clock_GetMs

View File

@ -1169,7 +1169,7 @@ typedef struct TPMS_PCR_SELECT {
typedef struct TPMS_PCR_SELECTION {
TPMI_ALG_HASH hash;
BYTE sizeofSelect;
BYTE pcrSelect[PCR_SELECT_MIN];
BYTE pcrSelect[PCR_SELECT_MAX];
} TPMS_PCR_SELECTION;