Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
dc655b6
F-7585 - Parse policy_sign -pcrdigest= hex result in a signed temporary
aidangarske Aug 6, 2026
6c3c356
F-7596 - Compare pcrDigestSz against remaining buffer capacity
aidangarske Aug 6, 2026
394dce3
F-7586 - Keep EK cert verify result out of the example return code
aidangarske Aug 6, 2026
2e32fca
F-7587 - Define TPM_SPI_PIN in the Microchip chip select fallback
aidangarske Aug 6, 2026
db418eb
F-7602 - Zeroize HAL I2C write staging buffers
aidangarske Aug 6, 2026
6833067
F-7589 - Check I2C busy timeout in Microchip read data and write loops
aidangarske Aug 6, 2026
e514706
F-7594 - Compare PolicyNV operands in constant time
aidangarske Aug 6, 2026
790a288
F-7595 - Compare PolicyCounterTimer operands in constant time
aidangarske Aug 6, 2026
3ab9027
F-7588 - Reject transcript growth without 32-bit addition wraparound
aidangarske Aug 6, 2026
cc7cb89
F-7590 - Reserve the NUL terminator when clamping -secrethex= input
aidangarske Aug 6, 2026
3f8c84d
F-7591 - Cap PCR selection count to the entries actually parsed
aidangarske Aug 6, 2026
62427d8
F-7592 - Check BuildPolicyCommandCode status for each policy digest
aidangarske Aug 6, 2026
d17fb78
F-7597 - Clamp shared memory rsp_len to the TIS response FIFO size
aidangarske Aug 6, 2026
d3a61f2
F-7598 - Validate manifest hash size before staging FieldUpgradeStart
aidangarske Aug 6, 2026
28626aa
F-7601 - Zeroize ML-DSA sign and verify sequence input structs
aidangarske Aug 6, 2026
edcb845
F-7603 - Zeroize crypto callback hash cache before freeing
aidangarske Aug 6, 2026
395dc2b
F-7604 - Zeroize response authentication temporaries in TPM2_Response…
aidangarske Aug 6, 2026
099de0e
F-7593 - Check GetNvAttributesTemplate status before modifying attrib…
aidangarske Aug 6, 2026
f86b78d
F-7599 - Reject authenticated SPDM records shorter than the length field
aidangarske Aug 6, 2026
954cd33
F-7600 - Terminate CSR subject components and clear stale bytes
aidangarske Aug 6, 2026
1401945
F-7605 - Zeroize hash context in PCRGetDigest and PolicyHash
aidangarske Aug 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/boot/secret_seal.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ int TPM2_Boot_SecretSeal_Example(void* userCtx, int argc, char *argv[])
const char* secretStr = argv[argc-1] + XSTRLEN("-secrethex=");
word32 secretStrSz = (word32)XSTRLEN(secretStr);
int secretHexSz;
if (secretStrSz > (word32)(sizeof(secret)*2-1))
secretStrSz = (word32)(sizeof(secret)*2-1);
if (secretStrSz > (word32)((sizeof(secret)-1)*2))
secretStrSz = (word32)((sizeof(secret)-1)*2);
secretHexSz = hexToByte(secretStr, secret, secretStrSz);
if (secretHexSz < 0) {
printf("Invalid secret hex string\n");
Expand Down
4 changes: 2 additions & 2 deletions examples/endorsement/get_ek_certs.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,10 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
#ifndef WOLFCRYPT_ONLY
if (rc == 0) {
/* Validate EK certificate against trusted certificates */
rc = wolfSSL_CertManagerVerifyBuffer(cm, certBuf, certSz,
int vfyRc = wolfSSL_CertManagerVerifyBuffer(cm, certBuf, certSz,
WOLFSSL_FILETYPE_ASN1);
printf("EK Certificate is %s\n",
(rc == WOLFSSL_SUCCESS) ? "VALID" : "INVALID");
(vfyRc == WOLFSSL_SUCCESS) ? "VALID" : "INVALID");
}
#endif

Expand Down
6 changes: 3 additions & 3 deletions examples/gpio/gpio_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,13 +404,13 @@ int TPM2_GPIO_Config_Example(void* userCtx, int argc, char *argv[])
/* Initial NV attributes */
parent.hndl = TPM_RH_PLATFORM;
rc = wolfTPM2_GetNvAttributesTemplate(parent.hndl, &nvAttributes);
/* Add NV attributes required by Nuvoton specification */
nvAttributes |= (TPMA_NV_PLATFORMCREATE | TPMA_NV_POLICY_DELETE);
nvAttributes |= (TPMA_NV_TPM_NT & (TPM_NT_ORDINARY << 4));
if (rc != TPM_RC_SUCCESS) {
printf("Setting NV attributes failed\n");
goto exit;
}
/* Add NV attributes required by Nuvoton specification */
nvAttributes |= (TPMA_NV_PLATFORMCREATE | TPMA_NV_POLICY_DELETE);
nvAttributes |= (TPMA_NV_TPM_NT & (TPM_NT_ORDINARY << 4));
#ifdef DEBUG_WOLFTPM
printf("nvAttributes = 0x%8.8X\n", nvAttributes);
#endif
Expand Down
18 changes: 15 additions & 3 deletions examples/nvram/extend.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,35 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[])
/* Policy A: TPM2_PolicyCommandCode -> TPM_CC_NV_Read */
/* 47ce3032d8bad1f3089cb0c09088de43501491d460402b90cd1b7fc0b68ca92f */
policy[0] = &policyDigest[policyDigestSz];
BuildPolicyCommandCode(hashAlg, policy[0], &nvSize, TPM_CC_NV_Read);
rc = BuildPolicyCommandCode(hashAlg, policy[0], &nvSize, TPM_CC_NV_Read);
if (rc != TPM_RC_SUCCESS) {
printf("Building PolicyA failed!\n");
goto exit;
}
printf("PolicyA: %d\n", nvSize);
TPM2_PrintBin(policy[0], nvSize);
policyDigestSz += nvSize;

/* Policy B: TPM2_PolicyCommandCode -> TPM_CC_NV_Extend */
/* b6a2e7142ee56fd978047488483daa5b42b8dc4cc7ddcceddfb91793cf1ff1b7 */
policy[1] = &policyDigest[policyDigestSz];
BuildPolicyCommandCode(hashAlg, policy[1], &nvSize, TPM_CC_NV_Extend);
rc = BuildPolicyCommandCode(hashAlg, policy[1], &nvSize, TPM_CC_NV_Extend);
if (rc != TPM_RC_SUCCESS) {
printf("Building PolicyB failed!\n");
goto exit;
}
printf("PolicyB: %d\n", nvSize);
TPM2_PrintBin(policy[1], nvSize);
policyDigestSz += nvSize;

/* Policy C: TPM2_PolicyCommandCode -> TPM_CC_PolicyNV */
/* 203e4bd5d0448c9615cc13fa18e8d39222441cc40204d99a77262068dbd55a43 */
policy[2] = &policyDigest[policyDigestSz];
BuildPolicyCommandCode(hashAlg, policy[2], &nvSize, TPM_CC_PolicyNV);
rc = BuildPolicyCommandCode(hashAlg, policy[2], &nvSize, TPM_CC_PolicyNV);
if (rc != TPM_RC_SUCCESS) {
printf("Building PolicyC failed!\n");
goto exit;
}
printf("PolicyC: %d\n", nvSize);
TPM2_PrintBin(policy[2], nvSize);
policyDigestSz += nvSize;
Expand Down
10 changes: 6 additions & 4 deletions examples/pcr/policy_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,15 +292,17 @@ int TPM2_PCR_PolicySign_Example(void* userCtx, int argc, char *argv[])
else if (XSTRNCMP(argv[argc-1], "-pcrdigest=", XSTRLEN("-pcrdigest=")) == 0) {
const char* hashHexStr = argv[argc-1] + XSTRLEN("-pcrdigest=");
int hashHexStrLen = (int)XSTRLEN(hashHexStr);
if (hashHexStrLen > (int)sizeof(pcrDigest)*2+1)
pcrDigestSz = -1;
int hexRet;
if (hashHexStrLen > (int)sizeof(pcrDigest)*2)
hexRet = -1;
else
pcrDigestSz = hexToByte(hashHexStr, pcrDigest, hashHexStrLen);
if (pcrDigestSz <= 0) {
hexRet = hexToByte(hashHexStr, pcrDigest, hashHexStrLen);
if (hexRet <= 0) {
fprintf(stderr, "Invalid PCR hash length\n");
usage();
return -1;
}
pcrDigestSz = (word32)hexRet;
}
else if (XSTRNCMP(argv[argc-1], "-password=",
XSTRLEN("-password=")) == 0) {
Expand Down
2 changes: 2 additions & 0 deletions hal/tpm_io_espressif.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ static esp_err_t esp_tpm_register_write(uint32_t reg,
}
}

TPM2_ForceZero(buf, sizeof(buf));

return result;
}

Expand Down
1 change: 1 addition & 0 deletions hal/tpm_io_infineon.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
else {
printf("CyHAL I2C Write failure %d\n", (int)result);
}
TPM2_ForceZero(buf, sizeof(buf));
return ret;
}

Expand Down
2 changes: 2 additions & 0 deletions hal/tpm_io_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@
break;
} while (--timeout > 0);

TPM2_ForceZero(buf, sizeof(buf));

return (rc == -1) ? TPM_RC_FAILURE : TPM_RC_SUCCESS;
}

Expand Down
60 changes: 54 additions & 6 deletions hal/tpm_io_microchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,29 @@

static uintptr_t dummy_context;

/* Staging buffers stay at file scope: a busy-timeout bail-out returns
* while the bit-bang engine is still clocking data in or out of them, so
* they must outlive the call that queued the transfer. Reads stage here
* too, so a timeout cannot leave the engine writing into the caller's
* (often stack-local) buffer. */
static byte i2cRegBuf[1];
static byte i2cXferBuf[MAX_SPI_FRAMESIZE+1];
static byte i2cRdBuf[MAX_SPI_FRAMESIZE];
/* Set when a busy timeout leaves plaintext in a staging buffer that could
* not be scrubbed; cleared by the next call that finds the engine idle. */
static int i2cXferDirty = 0;

/* Scrub staging left dirty by a previous busy timeout. Only safe once the
* engine is idle, so callers must check I2C_BB_IsBusy() first. */
static void i2c_scrub_stale(void)
{
if (i2cXferDirty) {
TPM2_ForceZero(i2cXferBuf, sizeof(i2cXferBuf));
TPM2_ForceZero(i2cRdBuf, sizeof(i2cRdBuf));
i2cXferDirty = 0;
}
}

static void dummy_callback(uintptr_t context)
{
(void) context;
Expand Down Expand Up @@ -101,12 +124,13 @@
bool queued = false;
int timeout = TPM_I2C_TRIES;
int busy_retry = TPM_I2C_TRIES;
byte buf[1];
byte* buf = i2cRegBuf;

if (I2C_BB_IsBusy()) {
printf("error: i2c_read: already busy\n");
return -1;
}
i2c_scrub_stale();

/* TIS layer should never provide a buffer larger than this,
but double check for good coding practice */
Expand All @@ -119,7 +143,7 @@

do {
/* Queue the write with I2C_BB. */
queued = I2C_BB_Write(TPM2_I2C_ADDR, buf, sizeof(buf));
queued = I2C_BB_Write(TPM2_I2C_ADDR, buf, sizeof(i2cRegBuf));

if (!queued) {
printf("error: i2c_read: I2C_BB_Write failed\n");
Expand Down Expand Up @@ -159,7 +183,7 @@

do {
/* Queue the read with I2C_BB. */
queued = I2C_BB_Read(TPM2_I2C_ADDR, data, len);
queued = I2C_BB_Read(TPM2_I2C_ADDR, i2cRdBuf, len);

if (!queued) {
printf("error: i2c_read: I2C_BB_Read failed\n");
Expand All @@ -172,20 +196,30 @@
microchip_wait(250);
}

if (I2C_BB_IsBusy()) {
/* Engine still owns i2cRdBuf; it cannot be scrubbed here, so
* flag it for the next call that finds the engine idle */
i2cXferDirty = 1;
printf("error: i2c_read: busy wait timed out\n");
return -1;
}

status = I2C_BB_ErrorGet();
if (status == I2CBB_ERROR_NAK) {
microchip_wait(250);
}
} while (status == I2CBB_ERROR_NAK && --timeout > 0);

if (status == I2CBB_ERROR_NONE) {
XMEMCPY(data, i2cRdBuf, len);
ret = TPM_RC_SUCCESS;
}
else {
printf("error: I2C Read failure %d (tries %d)\n",
status, TPM_I2C_TRIES - timeout);
}

TPM2_ForceZero(i2cRdBuf, sizeof(i2cRdBuf));
return ret;
}

Expand All @@ -196,7 +230,7 @@
bool queued = false;
int timeout = TPM_I2C_TRIES;
int busy_retry = TPM_I2C_TRIES;
byte buf[MAX_SPI_FRAMESIZE+1];
byte* buf = i2cXferBuf;

/* TIS layer should never provide a buffer larger than this,
but double check for good coding practice */
Expand All @@ -209,8 +243,11 @@
printf("error: i2c_write: already busy\n");
return -1;
}
i2c_scrub_stale();

/* Build packet with TPM register and data */
/* Build packet with TPM register and data. The engine is idle here,
* so clear any residue a previous busy-timeout bail-out left */
TPM2_ForceZero(buf, sizeof(i2cXferBuf));
buf[0] = (reg & 0xFF); /* convert to simple 8-bit address for I2C */
XMEMCPY(buf + 1, data, len);

Expand All @@ -220,6 +257,7 @@

if (!queued) {
printf("error: i2c_write: I2C_BB_Write failed: %d\n", status);
TPM2_ForceZero(buf, sizeof(i2cXferBuf));
return -1;
}

Expand All @@ -229,6 +267,15 @@
microchip_wait(250);
}

if (I2C_BB_IsBusy()) {
/* Engine is still clocking out i2cXferBuf, so it cannot be
* scrubbed here; flag it for the next call that finds the
* engine idle */
i2cXferDirty = 1;
printf("error: i2c_write: busy wait timed out\n");
return -1;
}

status = I2C_BB_ErrorGet();

if (status == I2CBB_ERROR_NAK) {
Expand All @@ -242,6 +289,7 @@
else {
printf("I2C Write failure %d\n", status);
}
TPM2_ForceZero(buf, sizeof(i2cXferBuf));
return ret;
}

Expand Down Expand Up @@ -279,7 +327,7 @@

/* TPM Chip Select Pin (default PC5) */
#ifndef TPM_SPI_PIN
#define SYS_PORT_PIN_PC5
#define TPM_SPI_PIN SYS_PORT_PIN_PC5
#endif

int TPM2_IoCb_Microchip_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
Expand Down
1 change: 1 addition & 0 deletions hal/tpm_io_st.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
else {
printf("I2C Write failure %d\n", status);
}
TPM2_ForceZero(buf, sizeof(buf));
return ret;
}

Expand Down
1 change: 1 addition & 0 deletions hal/tpm_io_zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ int TPM2_IoCb_Zephyr_I2C(TPM2_CTX* ctx, int isRead, word32 addr,
printf("Failed to write to TPM at register 0x%02X! Error: %d\n", addr, ret);
}

TPM2_ForceZero(tempBuf, size + 1);
XFREE(tempBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}

Expand Down
Loading
Loading