From 2485b2d5b26e203cee3b32d930a2c90a28fa3bfc Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 6 Mar 2026 14:22:31 -0800 Subject: [PATCH] Fix 335, 340, 347, 348, 349, 336, 418, 338, 337, 339, 423, 424 --- hal/tpm_io_espressif.c | 19 ++++++++++++++++--- hal/tpm_io_microchip.c | 2 +- hal/tpm_io_mmio.c | 21 +++++++++++++++++---- hal/tpm_io_xilinx.c | 2 +- src/tpm2.c | 18 +++++++++++++++--- src/tpm2_cryptocb.c | 22 +++++++++++++++++----- src/tpm2_param_enc.c | 1 + src/tpm2_swtpm.c | 1 + wolftpm/tpm2.h | 3 +++ 9 files changed, 72 insertions(+), 17 deletions(-) diff --git a/hal/tpm_io_espressif.c b/hal/tpm_io_espressif.c index f162cd12..4d7b0d5b 100644 --- a/hal/tpm_io_espressif.c +++ b/hal/tpm_io_espressif.c @@ -170,14 +170,21 @@ static int _is_initialized_i2c = 0; #ifdef DEBUG_WOLFSSL_VERBOSE +/* Fixed buffer size for hex output (MAX_SPI_FRAMESIZE * 2 + 2) */ +#define SHOW_BINARY_HEX_BUF_SZ ((MAX_SPI_FRAMESIZE * 2) + 2) static esp_err_t show_binary(byte* theVar, size_t dataSz) { - char hex_buffer[(dataSz * 2) + 2]; + char hex_buffer[SHOW_BINARY_HEX_BUF_SZ]; word32 i; + size_t maxSz; + + /* Limit output to buffer capacity */ + maxSz = (dataSz > MAX_SPI_FRAMESIZE) ? MAX_SPI_FRAMESIZE : dataSz; ESP_LOGI(TAG, "*********************************************************"); - for (i = 0; i < dataSz; i++) { + for (i = 0; i < maxSz; i++) { snprintf(&hex_buffer[i * 2], 3, "%02X", (unsigned char)theVar[i]); } + hex_buffer[maxSz * 2] = '\0'; ESP_LOGI("TAG", "%s", hex_buffer); ESP_LOGI(TAG, "*********************************************************"); return ESP_OK; @@ -557,7 +564,13 @@ static int esp_spi_master_init(void) ret = spi_bus_add_device(SPI2_HOST, &dev_cfg, &spi); ESP_ERROR_CHECK(ret); - tpm_data = malloc(sizeof(struct TPM_DATA)); + tpm_data = (struct TPM_DATA*)XMALLOC(sizeof(struct TPM_DATA), + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tpm_data == NULL) { + spi_bus_remove_device(spi); + spi_bus_free(SPI2_HOST); + return TPM_RC_FAILURE; + } tpm_data->spi = spi; tpm_data->cs_pin = PIN_NUM_CS; tpm_data->timeout_expiry = 0; diff --git a/hal/tpm_io_microchip.c b/hal/tpm_io_microchip.c index b431a4bc..461e4f6a 100644 --- a/hal/tpm_io_microchip.c +++ b/hal/tpm_io_microchip.c @@ -305,7 +305,7 @@ int TPM2_IoCb_Microchip_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, /* Send Entire Message blocking - no wait states */ if (DRV_SPI_WriteReadTransfer(handle, (byte*)txBuf, xferSz, rxBuf, xferSz) == true) { - ret = TPM_RC_SUCCESS + ret = TPM_RC_SUCCESS; } (void)ctx; diff --git a/hal/tpm_io_mmio.c b/hal/tpm_io_mmio.c index 22483d1e..4985abf3 100644 --- a/hal/tpm_io_mmio.c +++ b/hal/tpm_io_mmio.c @@ -90,25 +90,38 @@ static void TPM2_Mmio_Write8(word32 addr, byte *buf) sw_barrier(); } +/* Maximum valid TPM register offset to prevent address wrap-around */ +#ifndef TPM_MMIO_MAX_OFFSET +#define TPM_MMIO_MAX_OFFSET 0x1000000u /* 16MB - well above any valid TPM offset */ +#endif + int TPM2_IoCb_Mmio(TPM2_CTX *ctx, int isRead, word32 addr, byte* buf, word16 size, void* userCtx) { size_t i; + word32 effectiveAddr; + + /* Bounds check to prevent address wrap-around */ + if (addr >= TPM_MMIO_MAX_OFFSET) { + return TPM_RC_FAILURE; + } + + effectiveAddr = MIMO_BASE_ADDRESS + addr; /* IO for 32-bit aligned */ for (i = 0; ((size_t)size - i) >= sizeof(word32); i += sizeof(word32)) { if (isRead) - TPM2_Mmio_Read32(MIMO_BASE_ADDRESS + addr, buf + i); + TPM2_Mmio_Read32(effectiveAddr, buf + i); else - TPM2_Mmio_Write32(MIMO_BASE_ADDRESS + addr, buf + i); + TPM2_Mmio_Write32(effectiveAddr, buf + i); } /* IO for unaligned remainder */ for (; i < (size_t)size; i++) { if (isRead) - TPM2_Mmio_Read8(MIMO_BASE_ADDRESS + addr, buf + i); + TPM2_Mmio_Read8(effectiveAddr, buf + i); else - TPM2_Mmio_Write8(MIMO_BASE_ADDRESS + addr, buf + i); + TPM2_Mmio_Write8(effectiveAddr, buf + i); } (void)ctx; diff --git a/hal/tpm_io_xilinx.c b/hal/tpm_io_xilinx.c index ff6c4511..4e6204e4 100644 --- a/hal/tpm_io_xilinx.c +++ b/hal/tpm_io_xilinx.c @@ -196,7 +196,7 @@ (byte*)txBuf, rxBuf, 1); if (status == XST_SUCCESS && rxBuf[0] & TPM_TIS_READY_MASK) break; - } while (ret == TPM_RC_SUCCESS && --timeout > 0); + } while (status == XST_SUCCESS && --timeout > 0); #ifdef WOLFTPM_DEBUG_TIMEOUT printf("SPI Ready Wait %d\n", TPM_SPI_WAIT_RETRY - timeout); #endif diff --git a/src/tpm2.c b/src/tpm2.c index 92ab4407..84258c31 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -377,9 +377,10 @@ static int TPM2_ResponseProcess(TPM2_CTX* ctx, TPM2_Packet* packet, return rc; } - /* Verify HMAC */ + /* Verify HMAC using constant-time comparison */ if (hmac.size != authRsp.hmac.size || - XMEMCMP(hmac.buffer, authRsp.hmac.buffer, hmac.size) != 0) { + TPM2_ConstantCompare(hmac.buffer, authRsp.hmac.buffer, + hmac.size) != 0) { #ifdef DEBUG_WOLFTPM printf("Response HMAC verification failed!\n"); #endif @@ -5537,7 +5538,7 @@ TPM_RC TPM2_GetProductInfo(uint8_t* info, uint16_t size) if (payloadSz > (size_t)size) { payloadSz = (size_t)size; } - XMEMCPY(info, &packet.buf[25], payloadSz); + XMEMCPY(info, &packet.buf[26], payloadSz); } } TPM2_ReleaseLock(ctx); @@ -6620,6 +6621,17 @@ void TPM2_ForceZero(void* mem, word32 len) while (len--) *z++ = 0; } +/* Constant time memory comparison. Returns 0 if equal, non-zero if different. */ +int TPM2_ConstantCompare(const byte* a, const byte* b, word32 len) +{ + word32 i; + byte result = 0; + for (i = 0; i < len; i++) { + result |= a[i] ^ b[i]; + } + return (int)result; +} + #ifdef DEBUG_WOLFTPM #define LINE_LEN 16 void TPM2_PrintBin(const byte* buffer, word32 length) diff --git a/src/tpm2_cryptocb.c b/src/tpm2_cryptocb.c index 99a9db65..0bb3b549 100644 --- a/src/tpm2_cryptocb.c +++ b/src/tpm2_cryptocb.c @@ -647,10 +647,12 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) /* clean hmac context */ if (rc != 0 || info->hmac.digest != NULL) { - wolfTPM2_UnloadHandle(tlsCtx->dev, &hmacCtx->hash.handle); - wolfTPM2_UnloadHandle(tlsCtx->dev, &hmacCtx->key.handle); - XFREE(hmacCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); - hmacCtx = NULL; + if (hmacCtx != NULL) { + wolfTPM2_UnloadHandle(tlsCtx->dev, &hmacCtx->hash.handle); + wolfTPM2_UnloadHandle(tlsCtx->dev, &hmacCtx->key.handle); + XFREE(hmacCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + hmacCtx = NULL; + } } info->hmac.hmac->devCtx = hmacCtx; #endif /* WOLFTPM_USE_SYMMETRIC */ @@ -739,11 +741,19 @@ static int wolfTPM2_HashUpdateCache(WOLFTPM2_HASHCTX* hashCtx, /* determine if we need to grow buffer */ else if ((hashCtx->cacheSz + inSz) > hashCtx->cacheBufSz) { byte* oldIn = hashCtx->cacheBuf; + word32 oldBufSz = hashCtx->cacheBufSz; + /* check for overflow */ + if (hashCtx->cacheSz + inSz < hashCtx->cacheSz) { + return BUFFER_E; + } hashCtx->cacheBufSz = (hashCtx->cacheSz + inSz + WOLFTPM2_HASH_BLOCK_SZ - 1) & ~(WOLFTPM2_HASH_BLOCK_SZ - 1); - hashCtx->cacheBuf = (byte*)XMALLOC(hashCtx->cacheBufSz, + hashCtx->cacheBuf = (byte*)XMALLOC(hashCtx->cacheBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (hashCtx->cacheBuf == NULL) { + /* restore old buffer on allocation failure */ + hashCtx->cacheBuf = oldIn; + hashCtx->cacheBufSz = oldBufSz; return MEMORY_E; } XMEMCPY(hashCtx->cacheBuf, oldIn, hashCtx->cacheSz); @@ -919,6 +929,7 @@ static int RsaMGF1(wc_HashAlg* hash, enum wc_HashType hType, counter++; } while (ret == 0 && idx < outSz); + TPM2_ForceZero(tmp, sizeof(tmp)); return ret; } @@ -1057,6 +1068,7 @@ static int RsaPadPss(const byte* input, word32 inputLen, byte* pkcsBlock, xorbuf(m, salt + o, (word32)saltLen); } wc_HashFree(&hashCtx, hType); + TPM2_ForceZero(salt, sizeof(salt)); return ret; } diff --git a/src/tpm2_param_enc.c b/src/tpm2_param_enc.c index 571052c9..7a91d84c 100644 --- a/src/tpm2_param_enc.c +++ b/src/tpm2_param_enc.c @@ -177,6 +177,7 @@ int TPM2_KDFa( exit: wc_HmacFree(&hmac_ctx); + TPM2_ForceZero(hash, sizeof(hash)); /* return length rounded up to nearest 8 multiple */ return ret; diff --git a/src/tpm2_swtpm.c b/src/tpm2_swtpm.c index 8c8ed122..98f038b5 100644 --- a/src/tpm2_swtpm.c +++ b/src/tpm2_swtpm.c @@ -191,6 +191,7 @@ static TPM_RC SwTpmConnect(TPM2_CTX* ctx, const char* host, const char* port) s = getaddrinfo(host, port, &hints, &result); if (s != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + return rc; } for (rp = result; rp != NULL; rp = rp->ai_next) { diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 6f2ca10d..a01eacf2 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -3880,6 +3880,9 @@ WOLFTPM_API UINT16 TPM2_GetVendorID(void); /* Internal helper API for ensuring memory is forcefully zero'd */ WOLFTPM_LOCAL void TPM2_ForceZero(void* mem, word32 len); +/* Constant time memory comparison */ +WOLFTPM_LOCAL int TPM2_ConstantCompare(const byte* a, const byte* b, word32 len); + #ifdef DEBUG_WOLFTPM /*!