From 96cd17af1d94ea4c05dbf6421be4fa7cfa97e255 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 15 Sep 2023 12:19:17 -0700 Subject: [PATCH] Improvements/fixes to NV auth and session auth set/unset: * Fix bug with NV name after first write (only appears when using HMAC session). * Add new API `wolfTPM2_UnsetAuthSession` to unset auth index for a session and save off the nonce from the TPM. This allows auth to be unset/set again with the same session. * Cleanup in the NV API's for unsetting of the auth to be handled by caller, not in API. --- examples/boot/secure_rot.c | 1 + examples/gpio/gpio_config.c | 4 +++- examples/nvram/counter.c | 2 ++ examples/nvram/policy_nv.c | 2 ++ examples/nvram/read.c | 4 ++++ examples/nvram/store.c | 2 ++ examples/wrap/wrap_test.c | 2 ++ src/tpm2_wrap.c | 45 ++++++++++++++++++++++++++----------- wolftpm/tpm2_wrap.h | 19 ++++++++++++++++ 9 files changed, 67 insertions(+), 14 deletions(-) diff --git a/examples/boot/secure_rot.c b/examples/boot/secure_rot.c index 2c200c26..5f013253 100644 --- a/examples/boot/secure_rot.c +++ b/examples/boot/secure_rot.c @@ -228,6 +228,7 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[]) printf("Warning: NV Index 0x%x already exists!\n", nvIndex); rc = 0; } + wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle); } if (rc == 0) { /* Write digest to NV */ diff --git a/examples/gpio/gpio_config.c b/examples/gpio/gpio_config.c index 8e5b88fd..ebd5cac1 100644 --- a/examples/gpio/gpio_config.c +++ b/examples/gpio/gpio_config.c @@ -240,6 +240,7 @@ int TPM2_GPIO_Config_Example(void* userCtx, int argc, char *argv[]) printf("Creating NV Index for GPIO acccess failed\n"); goto exit; } + wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle); printf("NV Index for GPIO access created\n"); /* GPIO configured as an input, requires an extra configuration step */ @@ -413,9 +414,10 @@ int TPM2_GPIO_Config_Example(void* userCtx, int argc, char *argv[]) rc = wolfTPM2_NVCreateAuth(&dev, &parent, &nv, nvIndex, nvAttributes, sizeof(BYTE), (byte*)gNvAuth, sizeof(gNvAuth)-1); if (rc != 0 && rc != TPM_RC_NV_DEFINED) { - printf("Creating NV Index for GPIO acccess failed\n"); + printf("Creating NV Index for GPIO access failed\n"); goto exit; } + wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle); printf("NV Index for GPIO access created\n"); (void)gpioInput; /* not used */ diff --git a/examples/nvram/counter.c b/examples/nvram/counter.c index 4fca5cec..75e9e80b 100644 --- a/examples/nvram/counter.c +++ b/examples/nvram/counter.c @@ -156,6 +156,8 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[]) nvAttributes, 8, (byte*)gNvAuth, sizeof(gNvAuth)-1); if (rc != 0) goto exit; + wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle); + rc = wolfTPM2_NVReadPublic(&dev, nvIndex, &nvPublic); } if (rc != TPM_RC_SUCCESS) { diff --git a/examples/nvram/policy_nv.c b/examples/nvram/policy_nv.c index a7c25ded..d8e575db 100644 --- a/examples/nvram/policy_nv.c +++ b/examples/nvram/policy_nv.c @@ -186,6 +186,8 @@ int TPM2_NVRAM_PolicyNV_Example(void* userCtx, int argc, char *argv[]) nvAttributes, (word32)bufLen, auth.buffer, auth.size); if (rc != 0 && rc != TPM_RC_NV_DEFINED) goto exit; + wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle); + printf("Storing data at TPM NV index 0x%x with password protection\n\n", nvIndex); diff --git a/examples/nvram/read.c b/examples/nvram/read.c index c787ef81..869cbb8a 100644 --- a/examples/nvram/read.c +++ b/examples/nvram/read.c @@ -216,6 +216,10 @@ int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[]) printf("Successfully read private key part from NV\n\n"); } + /* auth 0 is owner, no auth */ + wolfTPM2_SetAuthPassword(&dev, 0, NULL); + wolfTPM2_UnsetAuth(&dev, 1); + parent.hndl = authHandle; rc = wolfTPM2_NVDeleteAuth(&dev, &parent, nvIndex); if (rc != 0) goto exit; diff --git a/examples/nvram/store.c b/examples/nvram/store.c index 9fbd488d..b439b9cd 100644 --- a/examples/nvram/store.c +++ b/examples/nvram/store.c @@ -169,6 +169,8 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[]) nvAttributes, TPM2_DEMO_NV_TEST_SIZE, (byte*)gNvAuth, sizeof(gNvAuth)-1); if (rc != 0 && rc != TPM_RC_NV_DEFINED) goto exit; + wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle); + printf("Storing key at TPM NV index 0x%x with password protection\n\n", nvIndex); diff --git a/examples/wrap/wrap_test.c b/examples/wrap/wrap_test.c index d0b7f0f4..ea2b0b78 100644 --- a/examples/wrap/wrap_test.c +++ b/examples/wrap/wrap_test.c @@ -710,6 +710,8 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[]) nvAttributes, TPM2_DEMO_NV_TEST_SIZE, (byte*)gNvAuth, sizeof(gNvAuth)-1); if (rc != 0 && rc != TPM_RC_NV_DEFINED) goto exit; + wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle); + message.size = TPM2_DEMO_NV_TEST_SIZE; /* test message 0x11,0x11,etc */ XMEMSET(message.buffer, 0x11, message.size); rc = wolfTPM2_NVWriteAuth(&dev, &nv, TPM2_DEMO_NV_TEST_AUTH_INDEX, diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index db818708..c65bf07f 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -752,6 +752,26 @@ int wolfTPM2_UnsetAuth(WOLFTPM2_DEV* dev, int index) return TPM2_SetSessionAuth(dev->session); } +int wolfTPM2_UnsetAuthSession(WOLFTPM2_DEV* dev, int index, + WOLFTPM2_SESSION* tpmSession) +{ + TPM2_AUTH_SESSION* devSession; + + if (dev == NULL || tpmSession == NULL || + index >= MAX_SESSION_NUM || index < 0) { + return BAD_FUNC_ARG; + } + + devSession = &dev->session[index]; + + /* save off nonce from TPM to support continued use of session */ + XMEMCPY(&tpmSession->nonceTPM, &devSession->nonceTPM, sizeof(TPM2B_NONCE)); + + XMEMSET(devSession, 0, sizeof(TPM2_AUTH_SESSION)); + + return TPM2_SetSessionAuth(dev->session); +} + int wolfTPM2_SetAuth(WOLFTPM2_DEV* dev, int index, TPM_HANDLE sessionHandle, const TPM2B_AUTH* auth, TPMA_SESSION sessionAttributes, const TPM2B_NAME* name) @@ -4056,9 +4076,6 @@ int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, if (rctmp != TPM_RC_SUCCESS) rc = rctmp; - /* make sure auth not set */ - wolfTPM2_UnsetAuth(dev, 1); - #ifdef DEBUG_WOLFTPM printf("TPM2_NV_DefineSpace: Auth 0x%x, Idx 0x%x, Attribs 0x%d, Size %d\n", (word32)in.authHandle, @@ -4137,6 +4154,14 @@ int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, return rc; } + /* if this is the first write to NV then the NV_WRITTEN bit will get set + * and name needs re-computed */ + if (pos == 0) { + /* read public and re-compute name */ + rc = wolfTPM2_NVOpen(dev, nv, nv->handle.hndl, NULL, 0); + if (rc != 0) break; + } + #ifdef DEBUG_WOLFTPM printf("TPM2_NV_Write: Auth 0x%x, Idx 0x%x, Offset %d, Size %d\n", (word32)in.authHandle, (word32)in.nvIndex, @@ -4341,10 +4366,9 @@ int wolfTPM2_NVIncrement(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv) if (rc != TPM_RC_SUCCESS) { return rc; } } - /* make sure auth not set */ - wolfTPM2_UnsetAuth(dev, 1); - + /* Necessary, because NVRead has two handles, second is NV Index */ rc = wolfTPM2_SetAuthHandleName(dev, 0, &nv->handle); + rc |= wolfTPM2_SetAuthHandleName(dev, 1, &nv->handle); if (rc != TPM_RC_SUCCESS) { #ifdef DEBUG_WOLFTPM printf("Setting NV index name failed\n"); @@ -4390,10 +4414,9 @@ int wolfTPM2_NVWriteLock(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv) } } - /* make sure auth not set */ - wolfTPM2_UnsetAuth(dev, 1); - + /* Necessary, because NVRead has two handles, second is NV Index */ rc = wolfTPM2_SetAuthHandleName(dev, 0, &nv->handle); + rc |= wolfTPM2_SetAuthHandleName(dev, 1, &nv->handle); if (rc != TPM_RC_SUCCESS) { #ifdef DEBUG_WOLFTPM printf("Setting NV index name failed\n"); @@ -4421,10 +4444,6 @@ int wolfTPM2_NVDeleteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, if (dev->ctx.session) { rc = wolfTPM2_SetAuthHandle(dev, 0, parent); if (rc != TPM_RC_SUCCESS) { return rc; } - - /* Make sure no other auth sessions exist */ - (void)wolfTPM2_UnsetAuth(dev, 1); - (void)wolfTPM2_UnsetAuth(dev, 2); } XMEMSET(&in, 0, sizeof(in)); diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index 2104f7de..b291a157 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -367,6 +367,25 @@ WOLFTPM_API int wolfTPM2_GetCapabilities(WOLFTPM2_DEV* dev, WOLFTPM2_CAPS* caps) */ WOLFTPM_API int wolfTPM2_UnsetAuth(WOLFTPM2_DEV* dev, int index); +/*! + \ingroup wolfTPM2_Wrappers + \brief Clears one of the TPM Authorization session slots, pointed by its index + number and saves the nonce from the TPM so the session can continue to be used + again with wolfTPM2_SetAuthSession + + \return TPM_RC_SUCCESS: successful + \return TPM_RC_FAILURE: unable to get lock on the TPM2 Context + \return BAD_FUNC_ARG: check the provided arguments + + \param dev pointer to a TPM2_DEV struct + \param index integer value, specifying the TPM Authorization slot, between zero and three + \param session pointer to a WOLFTPM2_SESSION struct used with wolfTPM2_StartSession and wolfTPM2_SetAuthSession + + \sa wolfTPM2_StartSession + \sa wolfTPM2_SetAuthSession +*/ +WOLFTPM_API int wolfTPM2_UnsetAuthSession(WOLFTPM2_DEV* dev, int index, WOLFTPM2_SESSION* session); + /*! \ingroup wolfTPM2_Wrappers \brief Sets a TPM Authorization slot using the provided index, session handle, attributes and auth