Address review: guard retry code with WOLFTPM_NO_RETRY, drop wrappers, document option

pull/537/head
aidan garske 2026-06-23 15:48:26 -07:00
parent 550cea93ab
commit 720d90285a
9 changed files with 31 additions and 59 deletions

View File

@ -31,9 +31,9 @@
resubmitted when the TPM reports it is momentarily busy (for example
persisting the daUsed flag on first auth use of a non-noDA AIK/SUDI key),
matching the TCG ESYS behavior. Resubmit count defaults to `WOLFTPM_MAX_RETRIES`
(3) and is configurable at runtime via `wolfTPM2_SetCommandRetries` /
`TPM2_SetCommandRetries`; define `WOLFTPM_NO_RETRY` or set the count to 0 to
disable and return `TPM_RC_RETRY` to the caller.
(3) and is configurable at runtime via `TPM2_SetCommandRetries`; define
`WOLFTPM_NO_RETRY` or set the count to 0 to disable and return `TPM_RC_RETRY`
to the caller.
## wolfTPM Release 4.0.0 (Apr 22, 2026)

View File

@ -363,6 +363,8 @@ WOLFTPM2_USE_SW_ECDHE Disables use of TPM for ECC ephemeral key generation and
WOLFTPM2_ECC_DEFAULT_CURVE Default ECC curve for wrapper key templates that request P256 (SRK/AIK/general ECC). Defaults to TPM_ECC_NIST_P256, or the smallest enabled curve meeting ECC_MIN_KEY_SZ. Override e.g. -DWOLFTPM2_ECC_DEFAULT_CURVE=TPM_ECC_NIST_P384.
TLS_BENCH_MODE Enables TLS benchmarking mode.
NO_TPM_BENCH Disables the TPM benchmarking example.
WOLFTPM_MAX_RETRIES Number of times a command is transparently resubmitted when the TPM returns TPM_RC_RETRY (momentarily busy, e.g. persisting the daUsed flag on first auth use of a non-noDA AIK/SUDI key). Defaults to 3. Adjust at runtime with TPM2_SetCommandRetries().
WOLFTPM_NO_RETRY Compiles out the TPM_RC_RETRY auto-resubmit handling; TPM_RC_RETRY is returned to the caller for manual handling.
```
Note: For the I2C support on Raspberry Pi you may need to enable I2C. Here are the steps:

View File

@ -735,6 +735,7 @@ TPM_RC TPM2_SetHalIoCb(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCtx)
return rc;
}
#ifndef WOLFTPM_NO_RETRY
TPM_RC TPM2_SetCommandRetries(TPM2_CTX* ctx, int retries)
{
TPM_RC rc;
@ -761,6 +762,7 @@ int TPM2_GetCommandRetries(TPM2_CTX* ctx)
/* atomic int read, no lock needed; the setter takes the lock */
return ctx->retries;
}
#endif /* !WOLFTPM_NO_RETRY */
/* If timeoutTries <= 0 then it will not try and startup chip and will
* use existing default locality */
@ -775,7 +777,9 @@ TPM_RC TPM2_Init_ex(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCtx,
XMEMSET(ctx, 0, sizeof(TPM2_CTX));
#ifndef WOLFTPM_NO_RETRY
ctx->retries = WOLFTPM_MAX_RETRIES;
#endif
#ifndef WOLFTPM2_NO_WOLFCRYPT
rc = TPM2_WolfCrypt_Init();

View File

@ -1625,6 +1625,7 @@ TPM_RC TPM2_Packet_Parse(TPM_RC rc, TPM2_Packet* packet)
return rc;
}
#ifndef WOLFTPM_NO_RETRY
int TPM2_Packet_RetryRestore(TPM_RC rc, int* retries, TPM2_Packet* packet,
const byte* cmdHdr, int origSize)
{
@ -1639,6 +1640,7 @@ int TPM2_Packet_RetryRestore(TPM_RC rc, int* retries, TPM2_Packet* packet,
packet->size = origSize;
return 1;
}
#endif /* !WOLFTPM_NO_RETRY */
int TPM2_Packet_Finalize(TPM2_Packet* packet, TPM_ST tag, TPM_CC cc)
{

View File

@ -750,22 +750,6 @@ int wolfTPM2_GetTpmDevId(WOLFTPM2_DEV* dev)
return (int)dev->ctx.did_vid; /* return something besides INVALID_DEVID */
}
int wolfTPM2_SetCommandRetries(WOLFTPM2_DEV* dev, int retries)
{
if (dev == NULL) {
return BAD_FUNC_ARG;
}
return TPM2_SetCommandRetries(&dev->ctx, retries);
}
int wolfTPM2_GetCommandRetries(WOLFTPM2_DEV* dev)
{
if (dev == NULL) {
return BAD_FUNC_ARG;
}
return TPM2_GetCommandRetries(&dev->ctx);
}
int wolfTPM2_SelfTest(WOLFTPM2_DEV* dev)
{
int rc;

View File

@ -2515,34 +2515,35 @@ static void test_wolfTPM2_VerifyHashTicket_DigestSize(void)
#endif
}
#ifndef WOLFTPM_NO_RETRY
/* Transparent TPM_RC_RETRY resubmit is configurable. Verify the default seeded
* by init, the setter/getter round-trip, and rejection of bad arguments. */
static void test_wolfTPM2_CommandRetries(void)
static void test_TPM2_CommandRetries(void)
{
int rc;
WOLFTPM2_DEV dev;
XMEMSET(&dev, 0, sizeof(dev));
rc = wolfTPM2_SetCommandRetries(NULL, 1);
rc = TPM2_SetCommandRetries(NULL, 1);
AssertIntEQ(rc, BAD_FUNC_ARG);
rc = wolfTPM2_GetCommandRetries(NULL);
rc = TPM2_GetCommandRetries(NULL);
AssertIntEQ(rc, BAD_FUNC_ARG);
rc = wolfTPM2_SetCommandRetries(&dev, -1);
rc = TPM2_SetCommandRetries(&dev.ctx, -1);
AssertIntEQ(rc, BAD_FUNC_ARG);
/* retries is seeded before any HAL IO setup, so the default holds even on
* builds without a default IO callback where init returns an error */
(void)TPM2_Init_minimal(&dev.ctx);
AssertIntEQ(wolfTPM2_GetCommandRetries(&dev), WOLFTPM_MAX_RETRIES);
AssertIntEQ(TPM2_GetCommandRetries(&dev.ctx), WOLFTPM_MAX_RETRIES);
rc = wolfTPM2_SetCommandRetries(&dev, 0);
rc = TPM2_SetCommandRetries(&dev.ctx, 0);
AssertIntEQ(rc, TPM_RC_SUCCESS);
AssertIntEQ(wolfTPM2_GetCommandRetries(&dev), 0);
AssertIntEQ(TPM2_GetCommandRetries(&dev.ctx), 0);
rc = wolfTPM2_SetCommandRetries(&dev, 7);
rc = TPM2_SetCommandRetries(&dev.ctx, 7);
AssertIntEQ(rc, TPM_RC_SUCCESS);
AssertIntEQ(wolfTPM2_GetCommandRetries(&dev), 7);
AssertIntEQ(TPM2_GetCommandRetries(&dev.ctx), 7);
TPM2_Cleanup(&dev.ctx);
@ -2600,6 +2601,7 @@ static void test_TPM2_Packet_RetryRestore(void)
printf("Test TPM Wrapper:\tRetryRestore logic:\t\tPassed\n");
}
#endif /* !WOLFTPM_NO_RETRY */
/* wolfTPM2_NVCreateAuthPolicy must derive nameAlg from authPolicySz so
* the policy digest hash matches the index's nameAlg. Bug-mode hardcoded
@ -5785,8 +5787,10 @@ int unit_tests(int argc, char *argv[])
test_wolfTPM2_GetKeyTemplate_ex_nameAlg();
test_wolfTPM2_SignHashScheme_DigestSize();
test_wolfTPM2_VerifyHashTicket_DigestSize();
test_wolfTPM2_CommandRetries();
#ifndef WOLFTPM_NO_RETRY
test_TPM2_CommandRetries();
test_TPM2_Packet_RetryRestore();
#endif
test_wolfTPM2_NVCreateAuthPolicy_NameAlg();
test_wolfTPM2_GetKeyTemplate_KeyedHash_Scheme();
test_wolfTPM2_LoadEccPublicKey_Ex();

View File

@ -2230,8 +2230,10 @@ typedef struct TPM2_CTX {
unsigned int spdmOnlyDetected:1; /* TPM_RC_DISABLED from Startup */
#endif
#ifndef WOLFTPM_NO_RETRY
/* Additional resubmit attempts on TPM_RC_RETRY (0 disables) */
int retries;
#endif
} TPM2_CTX;
@ -3776,6 +3778,7 @@ WOLFTPM_API TPM_RC TPM2_ChipStartup(TPM2_CTX* ctx, int timeoutTries);
*/
WOLFTPM_API TPM_RC TPM2_SetHalIoCb(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCtx);
#ifndef WOLFTPM_NO_RETRY
/*!
\ingroup TPM2_Proprietary
\brief Sets the number of times a command is transparently resubmitted on TPM_RC_RETRY
@ -3788,7 +3791,6 @@ WOLFTPM_API TPM_RC TPM2_SetHalIoCb(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCt
\param retries number of additional resubmit attempts on TPM_RC_RETRY (0 disables)
\sa TPM2_GetCommandRetries
\sa wolfTPM2_SetCommandRetries
*/
WOLFTPM_API TPM_RC TPM2_SetCommandRetries(TPM2_CTX* ctx, int retries);
@ -3802,9 +3804,9 @@ WOLFTPM_API TPM_RC TPM2_SetCommandRetries(TPM2_CTX* ctx, int retries);
\param ctx pointer to a TPM2_CTX struct
\sa TPM2_SetCommandRetries
\sa wolfTPM2_SetCommandRetries
*/
WOLFTPM_API int TPM2_GetCommandRetries(TPM2_CTX* ctx);
#endif /* !WOLFTPM_NO_RETRY */
/*!
\ingroup TPM2_Proprietary

View File

@ -241,8 +241,10 @@ WOLFTPM_LOCAL void TPM2_Packet_ParseAttest(TPM2_Packet* packet, TPMS_ATTEST* out
WOLFTPM_LOCAL TPM_RC TPM2_Packet_Parse(TPM_RC rc, TPM2_Packet* packet);
WOLFTPM_LOCAL int TPM2_Packet_Finalize(TPM2_Packet* packet, TPM_ST tag, TPM_CC cc);
#ifndef WOLFTPM_NO_RETRY
WOLFTPM_TEST_API int TPM2_Packet_RetryRestore(TPM_RC rc, int* retries,
TPM2_Packet* packet, const byte* cmdHdr, int origSize);
#endif
WOLFTPM_LOCAL int TPM2_GetCmdAuthCount(TPM2_CTX* ctx, const CmdInfo_t* info);

View File

@ -341,34 +341,6 @@ WOLFTPM_API int wolfTPM2_Cleanup_ex(WOLFTPM2_DEV* dev, int doShutdown);
*/
WOLFTPM_API int wolfTPM2_GetTpmDevId(WOLFTPM2_DEV* dev);
/*!
\ingroup wolfTPM2_Wrappers
\brief Sets the number of times a command is transparently resubmitted on TPM_RC_RETRY
\brief The TPM returns TPM_RC_RETRY when momentarily busy (for example persisting the daUsed flag on first auth use of a non-noDA key such as an AIK or SUDI key). wolfTPM resends the identical command up to this many times. Defaults to WOLFTPM_MAX_RETRIES; set to 0 to disable and have TPM_RC_RETRY returned to the caller.
\return TPM_RC_SUCCESS: successful
\return BAD_FUNC_ARG: dev is NULL or retries is negative
\param dev pointer to a populated structure of WOLFTPM2_DEV type
\param retries number of additional resubmit attempts on TPM_RC_RETRY (0 disables)
\sa wolfTPM2_GetCommandRetries
*/
WOLFTPM_API int wolfTPM2_SetCommandRetries(WOLFTPM2_DEV* dev, int retries);
/*!
\ingroup wolfTPM2_Wrappers
\brief Returns the number of times a command is transparently resubmitted on TPM_RC_RETRY
\return the configured retry count on success
\return BAD_FUNC_ARG: dev is a NULL pointer
\param dev pointer to a populated structure of WOLFTPM2_DEV type
\sa wolfTPM2_SetCommandRetries
*/
WOLFTPM_API int wolfTPM2_GetCommandRetries(WOLFTPM2_DEV* dev);
/*!
\ingroup wolfTPM2_Wrappers
\brief Asks the TPM to perform its self test