From 580b3a779ea203f217ea65ea6cbed2bd23cb5701 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 10 Dec 2024 15:32:18 -0800 Subject: [PATCH 1/3] Fix issue with session binding. Add example for NV extend based on the TCG "bus protection guidance". --- examples/gpio/gpio_config.c | 2 +- examples/nvram/extend.c | 327 ++++++++++++++++++++++++++++++++++++ examples/nvram/include.am | 18 +- examples/nvram/nvram.h | 1 + examples/nvram/read.c | 126 ++++++++------ examples/nvram/store.c | 28 +-- examples/run_examples.sh | 41 +++-- examples/tpm_test.h | 1 + src/tpm2.c | 3 + src/tpm2_param_enc.c | 92 +++++++--- src/tpm2_wrap.c | 75 ++++++--- wolftpm/tpm2.h | 3 +- wolftpm/tpm2_wrap.h | 25 +++ 13 files changed, 609 insertions(+), 133 deletions(-) create mode 100644 examples/nvram/extend.c diff --git a/examples/gpio/gpio_config.c b/examples/gpio/gpio_config.c index 189d3d73..4be4d4b1 100644 --- a/examples/gpio/gpio_config.c +++ b/examples/gpio/gpio_config.c @@ -406,7 +406,7 @@ int TPM2_GPIO_Config_Example(void* userCtx, int argc, char *argv[]) rc = wolfTPM2_GetNvAttributesTemplate(parent.hndl, &nvAttributes); /* Add NV attributes required by Nuvoton specification */ nvAttributes |= (TPMA_NV_PLATFORMCREATE | TPMA_NV_POLICY_DELETE); - nvAttributes |= (TPM_NT_ORDINARY & TPMA_NV_TPM_NT); + nvAttributes |= (TPMA_NV_TPM_NT & (TPM_NT_ORDINARY << 4)); if (rc != TPM_RC_SUCCESS) { printf("Setting NV attributes failed\n"); goto exit; diff --git a/examples/nvram/extend.c b/examples/nvram/extend.c new file mode 100644 index 00000000..1b147b42 --- /dev/null +++ b/examples/nvram/extend.c @@ -0,0 +1,327 @@ +/* extend.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfTPM. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Example for showing NV extend usage for bus protection: +* See "TCG_-CPU_-TPM_Bus_Protection_Guidance_Active_Attack_Mitigations-V1-R30_PUB-1.pdf" */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#ifndef WOLFTPM2_NO_WRAPPER + +#include +#include +#include +#include + +/******************************************************************************/ +/* --- BEGIN TPM NVRAM Extend Example -- */ +/******************************************************************************/ +static void usage(void) +{ + printf("Expected usage:\n"); + printf("./examples/nvram/extend [-nvindex=handle] [-aes/-xor]\n"); + printf("* -nvindex=[handle] (default 0x%x)\n", + TPM2_DEMO_NVRAM_EXTEND_INDEX); + printf("* -aes/xor: Use Parameter Encryption\n");; +} + +/* Policy A: TPM2_PolicyCommandCode -> TPM_CC_NV_Read */ +static const byte policyA[] = { + 0x47, 0xCE, 0x30, 0x32, 0xD8, 0xBA, 0xD1, 0xF3, + 0x08, 0x9C, 0xB0, 0xC0, 0x90, 0x88, 0xDE, 0x43, + 0x50, 0x14, 0x91, 0xD4, 0x60, 0x40, 0x2B, 0x90, + 0xCD, 0x1B, 0x7F, 0xC0, 0xB6, 0x8C, 0xA9, 0x2F +}; +/* Policy B: TPM2_PolicyCommandCode -> TPM_CC_NV_Extend */ +static const byte policyB[] = { + 0xB6, 0xA2, 0xE7, 0x14, 0x2E, 0xE5, 0x6F, 0xD9, + 0x78, 0x04, 0x74, 0x88, 0x48, 0x3D, 0xAA, 0x5B, + 0x42, 0xB8, 0xDC, 0x4C, 0xC7, 0xDD, 0xCC, 0xED, + 0xDF, 0xB9, 0x17, 0x93, 0xCF, 0x1F, 0xF1, 0xB7 +}; +/* Policy C: TPM2_PolicyCommandCode -> TPM_CC_PolicyNV */ +static const byte policyC[] = { + 0x20, 0x3E, 0x4B, 0xD5, 0xD0, 0x44, 0x8C, 0x96, + 0x15, 0xCC, 0x13, 0xFA, 0x18, 0xE8, 0xD3, 0x92, + 0x22, 0x44, 0x1C, 0xC4, 0x02, 0x04, 0xD9, 0x9A, + 0x77, 0x26, 0x20, 0x68, 0xDB, 0xD5, 0x5A, 0x43 +}; + +/* pre-computed policy: + * NV Read (A), NV Extend (B), PolicyNV (C), then policy OR (A/B/C) */ +static const byte policyNv[] = { + 0x7F, 0x17, 0x93, 0x7E, 0x20, 0x62, 0x79, 0xA3, + 0xF7, 0x55, 0xFB, 0x60, 0xF4, 0x0C, 0xF1, 0x26, + 0xB7, 0x0E, 0x5B, 0x1D, 0x9B, 0xF2, 0x02, 0x86, + 0x6D, 0x52, 0x76, 0x13, 0x87, 0x4A, 0x64, 0xAC +}; + + +static int PolicyOrApply(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* policySession) +{ + PolicyOR_In policyOR; + XMEMSET(&policyOR, 0, sizeof(policyOR)); + policyOR.policySession = policySession->handle.hndl; + policyOR.pHashList.count = 3; + policyOR.pHashList.digests[0].size = sizeof(policyA); + XMEMCPY(policyOR.pHashList.digests[0].buffer, policyA, sizeof(policyA)); + policyOR.pHashList.digests[1].size = sizeof(policyB); + XMEMCPY(policyOR.pHashList.digests[1].buffer, policyB, sizeof(policyB)); + policyOR.pHashList.digests[2].size = sizeof(policyC); + XMEMCPY(policyOR.pHashList.digests[2].buffer, policyC, sizeof(policyC)); + (void)dev; + return TPM2_PolicyOR(&policyOR); +} + +int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) +{ + int rc; + WOLFTPM2_DEV dev; + WOLFTPM2_KEY endorse; + WOLFTPM2_SESSION tpmSession; + WOLFTPM2_HANDLE nvAuth; + WOLFTPM2_HANDLE bind; + WOLFTPM2_NV nv; + word32 nvAttributes; + int paramEncAlg = TPM_ALG_CFB; + TPMI_RH_NV_AUTH authHandle = TPM_RH_PLATFORM; + word32 nvIndex = TPM2_DEMO_NVRAM_EXTEND_INDEX; + word32 nvSize; /* 32 for SHA2-256 */ + byte* auth = (byte*)"cpusecret"; + word32 authSz = (word32)XSTRLEN((const char*)auth); + byte nvDigest[32]; + word32 nvDigestSz = (word32)sizeof(nvDigest); + + if (argc >= 2) { + if (XSTRCMP(argv[1], "-?") == 0 || + XSTRCMP(argv[1], "-h") == 0 || + XSTRCMP(argv[1], "--help") == 0) { + usage(); + return 0; + } + } + while (argc > 1) { + if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) { + const char* nvIndexStr = argv[argc-1] + XSTRLEN("-nvindex="); + nvIndex = (word32)XSTRTOUL(nvIndexStr, NULL, 0); + if (nvIndex >= TPM_20_PLATFORM_MFG_NV_SPACE && + nvIndex < TPM_20_OWNER_NV_SPACE) { + authHandle = TPM_RH_PLATFORM; + } + else if (nvIndex >= TPM_20_OWNER_NV_SPACE && + nvIndex < TPM_20_TCG_NV_SPACE) { + authHandle = TPM_RH_OWNER; + } + else { + fprintf(stderr, "Invalid NV Index %s\n", nvIndexStr); + fprintf(stderr, "\tPlatform Range: 0x%x -> 0x%x\n", + TPM_20_PLATFORM_MFG_NV_SPACE, TPM_20_OWNER_NV_SPACE); + fprintf(stderr, "\tOwner Range: 0x%x -> 0x%x\n", + TPM_20_OWNER_NV_SPACE, TPM_20_TCG_NV_SPACE); + usage(); + return -1; + } + } + else if (XSTRCMP(argv[argc-1], "-aes") == 0) { + paramEncAlg = TPM_ALG_CFB; + } + else if (XSTRCMP(argv[argc-1], "-xor") == 0) { + paramEncAlg = TPM_ALG_XOR; + } + else { + printf("Warning: Unrecognized option: %s\n", argv[argc-1]); + } + argc--; + }; + + printf("NVRAM Extend (bus protection example)\n"); + printf("Parameter Encryption: %s\n", + (paramEncAlg == TPM_ALG_CFB) ? "AES CFB" : "XOR"); + + XMEMSET(&tpmSession, 0, sizeof(tpmSession)); + XMEMSET(&endorse, 0, sizeof(endorse)); + XMEMSET(&bind, 0, sizeof(bind)); + XMEMSET(&nv, 0, sizeof(nv)); + XMEMSET(&nvAuth, 0, sizeof(nvAuth)); + + rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); + if (rc != TPM_RC_SUCCESS) { + printf("wolfTPM2_Init failed\n"); + goto exit; + } + + /* 1: Create EK RSA 2048-bit */ + rc = wolfTPM2_CreateEK(&dev, &endorse, TPM_ALG_RSA); + if (rc != 0) { + printf("Create EK RSA failed!\n"); + goto exit; + } + endorse.handle.policyAuth = 1; /* EK requires policy auth */ + printf("EK Handle: 0x%x\n", (word32)endorse.handle.hndl); + + /* 2: Create a salted session with the TPM using the EK */ + rc = wolfTPM2_StartSession(&dev, &tpmSession, &endorse, NULL, + TPM_SE_HMAC, paramEncAlg); + if (rc == 0) { + rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession, + (TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | + TPMA_SESSION_continueSession)); + } + if (rc != 0) { + printf("Start HMAC session failed!\n"); + goto exit; + } + printf("Encrypted HMAC Session Handle 0x%x\n", + (word32)tpmSession.handle.hndl); + + /* 3. Create the NV Index with extend attribute. + * Use "host secret" as password so it is used with the bind session later */ + + /* See TPM_Bus_Protection_Guidance_Active_Attack_Mitigations: + * Section 3.4 Provisioning the NV Index */ + nvAttributes = ( + (TPMA_NV_TPM_NT & (TPM_NT_EXTEND << 4)) | + TPMA_NV_ORDERLY | + TPMA_NV_CLEAR_STCLEAR | + TPMA_NV_PLATFORMCREATE | + TPMA_NV_POLICYWRITE | + TPMA_NV_POLICYREAD | + TPMA_NV_NO_DA); + nvSize = TPM2_GetHashDigestSize(WOLFTPM2_WRAP_DIGEST); + + /* Try and open existing NV */ + rc = wolfTPM2_NVOpen(&dev, &nv, nvIndex, auth, authSz); + if (rc != 0) { + nvAuth.hndl = authHandle; + + rc = wolfTPM2_NVCreateAuthPolicy(&dev, &nvAuth, &nv, nvIndex, + nvAttributes, /* needs TPM_NT_EXTEND set */ + nvSize, /* must match nameAlg digest size */ + auth, authSz, /* the password to bind session with */ + policyNv, (word32)sizeof(policyNv) + ); + } + + /* Close session and unload endorsement */ + wolfTPM2_UnsetAuth(&dev, 0); + wolfTPM2_UnloadHandle(&dev, &tpmSession.handle); + wolfTPM2_UnloadHandle(&dev, &endorse.handle); + + + /* 4. Start a policy session and bind to NV handle */ + rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, &nv.handle, + TPM_SE_POLICY, TPM_ALG_CFB); + if (rc == 0) { + rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession, + (TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | + TPMA_SESSION_continueSession)); + } + if (rc != 0) { + printf("Start Policy session failed!\n"); + goto exit; + } + printf("Encrypted Policy Session Handle 0x%x\n", + (word32)tpmSession.handle.hndl); + + /* 5. Satisfy policy for NV Extend (policy B) */ + rc = wolfTPM2_PolicyCommandCode(&dev, &tpmSession, TPM_CC_NV_Extend); + if (rc == 0) { + rc = PolicyOrApply(&dev, &tpmSession); + } + if (rc != 0) { + printf("Failed to apply policy B\n"); + goto exit; + } + + /* 6. Perform NV extend */ + rc = wolfTPM2_NVExtend(&dev, &nv, nvIndex, auth, (word32)authSz); + if (rc != 0) { + printf("NV Extend failed!\n"); + goto exit; + } + printf("NV 0x%08x extended\n", (word32)nvIndex); + + /* 7. Restart session policy */ + rc = wolfTPM2_PolicyRestart(&dev, tpmSession.handle.hndl); + if (rc != 0) { + printf("Policy restart failed!\n"); + goto exit; + } + + /* 8. Satisfy policy for NV Read (policy A) */ + rc = wolfTPM2_PolicyCommandCode(&dev, &tpmSession, TPM_CC_NV_Read); + if (rc == 0) { + rc = PolicyOrApply(&dev, &tpmSession); + } + if (rc != 0) { + printf("Failed to apply policy A\n"); + goto exit; + } + + /* 9. Read NV extend digest */ + rc = wolfTPM2_NVRead(&dev, authHandle, nv.handle.hndl, + nvDigest, &nvDigestSz, 0); + if (rc == 0) { + printf("NV Digest: %d\n", nvDigestSz); + TPM2_PrintBin(nvDigest, nvDigestSz); + + /* Should be: + * 0ad80f8e4450587760d9137df41c9374f657bafa621fe37d4d5c8cecf0bcce5e */ + } + +exit: + + if (rc != 0) { + printf("\nFailure 0x%x: %s\n\n", rc, wolfTPM2_GetRCString(rc)); + } + + wolfTPM2_UnloadHandle(&dev, &tpmSession.handle); + wolfTPM2_Cleanup(&dev); + + return rc; +} + +/******************************************************************************/ +/* --- END TPM NVRAM Extend Example -- */ +/******************************************************************************/ +#endif /* !WOLFTPM2_NO_WRAPPER */ + +#ifndef NO_MAIN_DRIVER +int main(int argc, char *argv[]) +{ + int rc = NOT_COMPILED_IN; + +#ifndef WOLFTPM2_NO_WRAPPER + rc = TPM2_NVRAM_Extend_Example(NULL, argc, argv); +#else + printf("NVRAM code not compiled in\n"); + (void)argc; + (void)argv; +#endif + + return rc; +} +#endif diff --git a/examples/nvram/include.am b/examples/nvram/include.am index 4e8146aa..4e1d5e0f 100644 --- a/examples/nvram/include.am +++ b/examples/nvram/include.am @@ -27,6 +27,12 @@ examples_nvram_policy_nv_SOURCES = examples/nvram/policy_nv.c \ examples/tpm_test_keys.c examples_nvram_policy_nv_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) examples_nvram_policy_nv_DEPENDENCIES = src/libwolftpm.la + +noinst_PROGRAMS += examples/nvram/extend +examples_nvram_extend_SOURCES = examples/nvram/extend.c \ + examples/tpm_test_keys.c +examples_nvram_extend_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD) +examples_nvram_extend_DEPENDENCIES = src/libwolftpm.la endif example_nvramdir = $(exampledir)/nvram @@ -34,9 +40,11 @@ dist_example_nvram_DATA = \ examples/nvram/store.c \ examples/nvram/read.c \ examples/nvram/counter.c \ - examples/nvram/policy_nv.c + examples/nvram/policy_nv.c \ + examples/nvram/extend.c -DISTCLEANFILES+= examples/nvram/.libs/store -DISTCLEANFILES+= examples/nvram/.libs/read -DISTCLEANFILES+= examples/nvram/.libs/counter -DISTCLEANFILES+= examples/nvram/.libs/policy_nv +DISTCLEANFILES+= examples/nvram/.libs/store \ + examples/nvram/.libs/read \ + examples/nvram/.libs/counter \ + examples/nvram/.libs/policy_nv \ + examples/nvram/.libs/extend diff --git a/examples/nvram/nvram.h b/examples/nvram/nvram.h index d5ab9491..97b4f297 100644 --- a/examples/nvram/nvram.h +++ b/examples/nvram/nvram.h @@ -32,6 +32,7 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[]); int TPM2_PCR_Seal_With_Policy_Auth_NV_Test(void* userCtx, int argc, char *argv[]); int TPM2_PCR_Seal_With_Policy_Auth_NV_External_Test(void* userCtx, int argc, char *argv[]); int TPM2_NVRAM_PolicyNV_Example(void* userCtx, int argc, char *argv[]); +int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]); #ifdef __cplusplus } /* extern "C" */ diff --git a/examples/nvram/read.c b/examples/nvram/read.c index 7dce5993..3399e4cb 100644 --- a/examples/nvram/read.c +++ b/examples/nvram/read.c @@ -50,12 +50,13 @@ static void usage(void) { printf("Expected usage:\n"); - printf("./examples/nvram/read [-nvindex] [-priv] [-pub] [-aes/-xor]\n"); + printf("./examples/nvram/read [-nvindex] [-priv] [-pub] [-aes/-xor] [-delete]\n"); printf("* -nvindex=[handle] (default 0x%x)\n", TPM2_DEMO_NVRAM_STORE_INDEX); printf("* -priv: Read ony the private part\n"); printf("* -pub: Read only the public part\n"); printf("* -aes/xor: Use Parameter Encryption\n"); printf("* -endorsement/platform/owner: Auth hierarchy\n"); + printf("* -delete: Remove NV\n"); } int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[]) @@ -77,6 +78,8 @@ int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[]) byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)]; int pubAreaSize; word32 nvIndex = TPM2_DEMO_NVRAM_STORE_INDEX; + int deleteKey = 0; + int nvExtend = 0; if (argc >= 2) { if (XSTRCMP(argv[1], "-?") == 0 || @@ -121,6 +124,9 @@ int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[]) else if (XSTRCMP(argv[argc-1], "-pub") == 0) { partialRead = PUBLIC_PART_ONLY; } + else if (XSTRCMP(argv[argc-1], "-delete") == 0) { + deleteKey = 1; + } else { printf("Warning: Unrecognized option: %s\n", argv[argc-1]); } @@ -176,71 +182,91 @@ int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[]) nv.handle.auth.size = auth.size; XMEMCPY(nv.handle.auth.buffer, auth.buffer, auth.size); - if (partialRead != PRIVATE_PART_ONLY) { - readSize = sizeof(keyBlob.pub.size); - printf("Trying to read %d bytes of public key size marker\n", readSize); - rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, - (byte*)&keyBlob.pub.size, &readSize, 0); - if (rc != 0) { - printf("Was a public key part written? (see nvram/store)\n"); - goto exit; - } - printf("Successfully read public key part from NV\n\n"); - offset += readSize; - - readSize = sizeof(UINT16) + keyBlob.pub.size; /* account for TPM2B size marker */ - printf("Trying to read %d bytes of public key part from NV\n", keyBlob.pub.size); - rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, - pubAreaBuffer, &readSize, offset); - if (rc != 0) goto exit; - printf("Successfully read public key part from NV\n\n"); - offset += readSize; + rc = wolfTPM2_NVOpen(&dev, &nv, nvIndex, NULL, 0); + if (rc != 0) goto exit; - /* Necessary for storing the publicArea with the correct encoding */ - rc = TPM2_ParsePublic(&keyBlob.pub, pubAreaBuffer, - (word32)sizeof(pubAreaBuffer), &pubAreaSize); - if (rc != TPM_RC_SUCCESS) { - printf("Decoding of PublicArea failed. Unable to extract correctly.\n"); - goto exit; + printf("NV Read: Attributes 0x%08x\n", nv.attributes); + + if (((nv.attributes & TPMA_NV_TPM_NT) >> 4) & TPM_NT_EXTEND) { + byte digest[TPM_SHA256_DIGEST_SIZE]; + word32 digestLen = (word32)sizeof(digest); + printf("NV Read Extend\n"); + nvExtend = 1; + rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, digest, &digestLen, 0); + if (rc == 0) { + printf("\tDigest: %d\n", digestLen); + TPM2_PrintBin(digest, digestLen); } - -#ifdef WOLFTPM_DEBUG_VERBOSE - TPM2_PrintPublicArea(&keyBlob.pub); -#endif } + else { + if (partialRead != PRIVATE_PART_ONLY) { + readSize = sizeof(keyBlob.pub.size); + printf("Trying to read %d bytes of public key size marker\n", readSize); + rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, + (byte*)&keyBlob.pub.size, &readSize, 0); + if (rc != 0) { + printf("Was a public key part written? (see nvram/store)\n"); + goto exit; + } + printf("Successfully read public key part from NV\n\n"); + offset += readSize; + + readSize = sizeof(UINT16) + keyBlob.pub.size; /* account for TPM2B size marker */ + printf("Trying to read %d bytes of public key part from NV\n", keyBlob.pub.size); + rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, + pubAreaBuffer, &readSize, offset); + if (rc != 0) goto exit; + printf("Successfully read public key part from NV\n\n"); + offset += readSize; + + /* Necessary for storing the publicArea with the correct encoding */ + rc = TPM2_ParsePublic(&keyBlob.pub, pubAreaBuffer, + (word32)sizeof(pubAreaBuffer), &pubAreaSize); + if (rc != TPM_RC_SUCCESS) { + printf("Decoding of PublicArea failed. Unable to extract correctly.\n"); + goto exit; + } - if (partialRead != PUBLIC_PART_ONLY) { - printf("Trying to read size marker of the private key part from NV\n"); - readSize = sizeof(keyBlob.priv.size); - rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, - (byte*)&keyBlob.priv.size, &readSize, offset); - if (rc != 0) { - printf("Was a private key part written? (see nvram/store)\n"); - goto exit; + #ifdef WOLFTPM_DEBUG_VERBOSE + TPM2_PrintPublicArea(&keyBlob.pub); + #endif } - printf("Successfully read size marker from NV\n\n"); - offset += readSize; - readSize = keyBlob.priv.size; - printf("Trying to read %d bytes of private key part from NV\n", readSize); - rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, - (byte*)&keyBlob.priv.buffer, &readSize, offset); - if (rc != 0) goto exit; - printf("Successfully read private key part from NV\n\n"); + if (partialRead != PUBLIC_PART_ONLY) { + printf("Trying to read size marker of the private key part from NV\n"); + readSize = sizeof(keyBlob.priv.size); + rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, + (byte*)&keyBlob.priv.size, &readSize, offset); + if (rc != 0) { + printf("Was a private key part written? (see nvram/store)\n"); + goto exit; + } + printf("Successfully read size marker from NV\n\n"); + offset += readSize; + + readSize = keyBlob.priv.size; + printf("Trying to read %d bytes of private key part from NV\n", readSize); + rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, + (byte*)&keyBlob.priv.buffer, &readSize, offset); + if (rc != 0) goto exit; + 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; + if (deleteKey) { + parent.hndl = authHandle; + rc = wolfTPM2_NVDeleteAuth(&dev, &parent, nvIndex); + if (rc != 0) goto exit; + } printf("Extraction of key from NVRAM at index 0x%x succeeded\n", nvIndex); - if (!partialRead) { + if (!nvExtend && !partialRead) { /* get SRK */ rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA); if (rc != 0) goto exit; diff --git a/examples/nvram/store.c b/examples/nvram/store.c index 7ef611d7..584ba453 100644 --- a/examples/nvram/store.c +++ b/examples/nvram/store.c @@ -51,7 +51,7 @@ static void usage(void) { printf("Expected usage:\n"); printf("./examples/nvram/store [filename] [-nvindex] [-priv] [-pub] [-aes/-xor]\n"); - printf("* filename: point to a file containing a TPM key\n"); + printf("* filename: point to a file containing a TPM key (default keyblob.bin\n"); printf("\tDefault filename is \"keyblob.bin\"\n"); printf("* -nvindex=[handle] (default 0x%x)\n", TPM2_DEMO_NVRAM_STORE_INDEX); printf("* -priv: Store only the private part of the key\n"); @@ -88,9 +88,6 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[]) usage(); return 0; } - if (argv[1][0] != '-') { - filename = argv[1]; - } } while (argc > 1) { if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) { @@ -124,7 +121,10 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[]) else if (XSTRCMP(argv[argc-1], "-pub") == 0) { partialStore = PUBLIC_PART_ONLY; } - else if (argv[argc-1][0] == '-') { + else if (argv[argc-1][0] != '-') { + filename = argv[argc-1]; + } + else { printf("Warning: Unrecognized option: %s\n", argv[argc-1]); } argc--; @@ -164,15 +164,15 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[]) if (rc != 0) goto exit; } - rc = readKeyBlob(filename, &keyBlob); - if (rc != 0) goto exit; - /* Prepare NV_AUTHWRITE and NV_AUTHREAD attributes necessary for password */ parent.hndl = authHandle; rc = wolfTPM2_GetNvAttributesTemplate(parent.hndl, &nvAttributes); if (rc != 0) goto exit; - /* Estimate size of NV */ + rc = readKeyBlob(filename, &keyBlob); + if (rc != 0) goto exit; + + /* Get maximum size of NV */ nvSize = keyBlob.pub.size + sizeof(keyBlob.pub.size) + sizeof(UINT16) + keyBlob.priv.size + sizeof(keyBlob.priv.size) + sizeof(UINT16); @@ -191,7 +191,7 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[]) wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle); printf("Storing key at TPM NV index 0x%x with password protection\n\n", - nvIndex); + nvIndex); if (partialStore != PRIVATE_PART_ONLY) { printf("Public part = %hu bytes\n", keyBlob.pub.size); @@ -205,10 +205,10 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[]) rc = TPM2_AppendPublic(pubAreaBuffer, (word32)sizeof(pubAreaBuffer), &pubAreaSize, &keyBlob.pub); /* Note: - * Public Area is the only part of a TPM key that can be stored encoded - * Private Area is stored as-is, because TPM2B_PRIVATE is byte buffer - * and UINT16 size field, while Public Area is a complex TCG structure. - */ + * Public Area is the only part of a TPM key that can be stored encoded + * Private Area is stored as-is, because TPM2B_PRIVATE is byte buffer + * and UINT16 size field, while Public Area is a complex TCG structure. + */ if (rc != TPM_RC_SUCCESS) { printf("Encoding of the publicArea failed. Unable to store.\n"); goto exit; diff --git a/examples/run_examples.sh b/examples/run_examples.sh index 3f706a91..0612ea5b 100755 --- a/examples/run_examples.sh +++ b/examples/run_examples.sh @@ -38,10 +38,10 @@ RESULT=$? ./examples/keygen/create_primary -rsa -eh >> run.out 2>&1 RESULT=$? -[ $RESULT -ne 0 ] && echo -e "create primary endosement rsa key failed! $RESULT" && exit 1 +[ $RESULT -ne 0 ] && echo -e "create primary endorsement rsa key failed! $RESULT" && exit 1 ./examples/keygen/create_primary -ecc -eh >> run.out 2>&1 RESULT=$? -[ $RESULT -ne 0 ] && echo -e "create primary endosement ecc key failed! $RESULT" && exit 1 +[ $RESULT -ne 0 ] && echo -e "create primary endorsement ecc key failed! $RESULT" && exit 1 ./examples/keygen/create_primary -rsa -ph >> run.out 2>&1 RESULT=$? @@ -58,10 +58,10 @@ if [ $WOLFCRYPT_ENABLE -eq 1 ]; then # Provisioning examples (required --enable-provisioning) ./examples/keygen/create_primary -rsa -eh -iak -keep >> run.out 2>&1 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "create primary endosement rsa IAK key failed! $RESULT" && exit 1 + [ $RESULT -ne 0 ] && echo -e "create primary endorsement rsa IAK key failed! $RESULT" && exit 1 ./examples/keygen/create_primary -rsa -eh -idevid -keep >> run.out 2>&1 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "create primary endosement rsa IDevID key failed! $RESULT" && exit 1 + [ $RESULT -ne 0 ] && echo -e "create primary endorsement rsa IDevID key failed! $RESULT" && exit 1 ./examples/attestation/certify -rsa -certify=0x80000001 -signer=0x80000000 >> run.out 2>&1 RESULT=$? @@ -72,10 +72,10 @@ if [ $WOLFCRYPT_ENABLE -eq 1 ]; then ./examples/keygen/create_primary -ecc -eh -iak -keep >> run.out 2>&1 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "create primary endosement ecc IAK key failed! $RESULT" && exit 1 + [ $RESULT -ne 0 ] && echo -e "create primary endorsement ecc IAK key failed! $RESULT" && exit 1 ./examples/keygen/create_primary -ecc -eh -idevid -keep >> run.out 2>&1 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "create primary endosement ecc IDevID key failed! $RESULT" && exit 1 + [ $RESULT -ne 0 ] && echo -e "create primary endorsement ecc IDevID key failed! $RESULT" && exit 1 ./examples/attestation/certify -ecc -certify=0x80000001 -signer=0x80000000 >> run.out 2>&1 RESULT=$? @@ -95,10 +95,10 @@ if [ $WOLFCRYPT_ENABLE -eq 1 ]; then ./examples/keygen/create_primary -rsa -eh -aes >> run.out 2>&1 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "create primary endosement rsa key param enc failed! $RESULT" && exit 1 + [ $RESULT -ne 0 ] && echo -e "create primary endorsement rsa key param enc failed! $RESULT" && exit 1 ./examples/keygen/create_primary -ecc -eh -aes >> run.out 2>&1 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "create primary endosement ecc key param enc failed! $RESULT" && exit 1 + [ $RESULT -ne 0 ] && echo -e "create primary endorsement ecc key param enc failed! $RESULT" && exit 1 ./examples/keygen/create_primary -rsa -ph -aes >> run.out 2>&1 RESULT=$? @@ -257,8 +257,8 @@ if [ $NO_FILESYSTEM -eq 0 ]; then if [ $WOLFCRYPT_ENABLE -eq 1 ]; then ./examples/nvram/store -xor >> run.out 2>&1 RESULT=$? - [ $RESULT -ne 0 ] && echo -e "nv store param enc xorfailed! $RESULT" && exit 1 - ./examples/nvram/read -xor >> run.out 2>&1 + [ $RESULT -ne 0 ] && echo -e "nv store param enc xor failed! $RESULT" && exit 1 + ./examples/nvram/read -xor -delete >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv read param enc xor failed! $RESULT" && exit 1 @@ -266,7 +266,7 @@ if [ $NO_FILESYSTEM -eq 0 ]; then ./examples/nvram/store -aes >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv store param enc aes failed! $RESULT" && exit 1 - ./examples/nvram/read -aes >> run.out 2>&1 + ./examples/nvram/read -aes -delete >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv read param enc aes failed! $RESULT" && exit 1 fi @@ -274,14 +274,14 @@ if [ $NO_FILESYSTEM -eq 0 ]; then ./examples/nvram/store -priv >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv store priv only failed! $RESULT" && exit 1 - ./examples/nvram/read -priv >> run.out 2>&1 + ./examples/nvram/read -priv -delete >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv read priv only failed! $RESULT" && exit 1 if [ $WOLFCRYPT_ENABLE -eq 1 ]; then ./examples/nvram/store -priv -xor >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv store priv only param enc xor failed! $RESULT" && exit 1 - ./examples/nvram/read -priv -xor >> run.out 2>&1 + ./examples/nvram/read -priv -xor -delete >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv read priv only param enc xor failed! $RESULT" && exit 1 @@ -289,7 +289,7 @@ if [ $NO_FILESYSTEM -eq 0 ]; then ./examples/nvram/store -priv -aes >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv store priv only param enc aes failed! $RESULT" && exit 1 - ./examples/nvram/read -priv -aes >> run.out 2>&1 + ./examples/nvram/read -priv -aes -delete >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv read priv only param enc aes failed! $RESULT" && exit 1 fi @@ -297,9 +297,20 @@ if [ $NO_FILESYSTEM -eq 0 ]; then ./examples/nvram/store -pub >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv store pub only failed! $RESULT" && exit 1 - ./examples/nvram/read -pub >> run.out 2>&1 + ./examples/nvram/read -pub -delete >> run.out 2>&1 RESULT=$? [ $RESULT -ne 0 ] && echo -e "nv read pub only failed! $RESULT" && exit 1 + + if [ $WOLFCRYPT_ENABLE -eq 1 ] && [ $WOLFCRYPT_DEFAULT -eq 0 ]; then + # extend test + ./examples/nvram/extend -aes + RESULT=$? + [ $RESULT -ne 0 ] && echo -e "nv extend aes failed! $RESULT" && exit 1 + + ./examples/nvram/extend -xor + RESULT=$? + [ $RESULT -ne 0 ] && echo -e "nv extend xor failed! $RESULT" && exit 1 + fi fi ./examples/nvram/policy_nv >> run.out 2>&1 diff --git a/examples/tpm_test.h b/examples/tpm_test.h index 32526865..ef474789 100644 --- a/examples/tpm_test.h +++ b/examples/tpm_test.h @@ -44,6 +44,7 @@ #define TPM2_DEMO_NV_TEST_INDEX 0x01800200 #define TPM2_DEMO_NV_TEST_AUTH_INDEX 0x01800201 #define TPM2_DEMO_NVRAM_STORE_INDEX 0x01800202 +#define TPM2_DEMO_NVRAM_EXTEND_INDEX 0x01000200 #define TPM2_DEMO_NV_TEST_SIZE MAX_DIGEST_BUFFER /* max size on Infineon SLB9670 is 1664 */ #define TPM2_DEMO_NV_COUNTER_INDEX 0x01800300 diff --git a/src/tpm2.c b/src/tpm2.c index 955cdfe0..9984ee70 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -5056,6 +5056,9 @@ TPM_RC TPM2_NV_Extend(NV_Extend_In* in) TPM2_Packet_Init(ctx, &packet); TPM2_Packet_AppendU32(&packet, in->authHandle); + /* When using an HMAC or Policy session make sure the NV "name" is + * populated in the TPM2_AUTH_SESSION name.name. This is a computed + * hash (see TPM2_HashNvPublic) */ TPM2_Packet_AppendU32(&packet, in->nvIndex); TPM2_Packet_AppendAuth(&packet, ctx, &info); diff --git a/src/tpm2_param_enc.c b/src/tpm2_param_enc.c index 8690c1cc..dc84539a 100644 --- a/src/tpm2_param_enc.c +++ b/src/tpm2_param_enc.c @@ -195,11 +195,12 @@ int TPM2_KDFa( /* Perform XOR encryption over the first parameter of a TPM packet */ -static int TPM2_ParamEnc_XOR(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, - TPM2B_NONCE* nonceCaller, TPM2B_NONCE* nonceTPM, BYTE *paramData, - UINT32 paramSz) +static int TPM2_ParamEnc_XOR(TPM2_AUTH_SESSION *session, TPM2B_AUTH* sessKey, + TPM2B_AUTH* bindKey, TPM2B_NONCE* nonceCaller, TPM2B_NONCE* nonceTPM, + BYTE *paramData, UINT32 paramSz) { int rc = TPM_RC_FAILURE; + TPM2B_DATA keyIn; TPM2B_MAX_BUFFER mask; UINT32 i; @@ -207,9 +208,17 @@ static int TPM2_ParamEnc_XOR(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, return BUFFER_E; } + /* Build HMAC key input */ + XMEMCPY(keyIn.buffer, sessKey->buffer, sessKey->size); + keyIn.size = sessKey->size; + if (bindKey != NULL) { + XMEMCPY(&keyIn.buffer[keyIn.size], bindKey->buffer, bindKey->size); + keyIn.size += bindKey->size; + } + /* Generate XOR Mask stream matching paramater size */ XMEMSET(mask.buffer, 0, sizeof(mask.buffer)); - rc = TPM2_KDFa(session->authHash, (TPM2B_DATA*)keyIn, "XOR", + rc = TPM2_KDFa(session->authHash, &keyIn, "XOR", nonceCaller, nonceTPM, mask.buffer, paramSz); if ((UINT32)rc != paramSz) { #ifdef DEBUG_WOLFTPM @@ -230,11 +239,12 @@ static int TPM2_ParamEnc_XOR(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, } /* Perform XOR decryption over the first parameter of a TPM packet */ -static int TPM2_ParamDec_XOR(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, - TPM2B_NONCE* nonceCaller, TPM2B_NONCE* nonceTPM, BYTE *paramData, - UINT32 paramSz) +static int TPM2_ParamDec_XOR(TPM2_AUTH_SESSION *session, TPM2B_AUTH* sessKey, + TPM2B_AUTH* bindKey, TPM2B_NONCE* nonceCaller, TPM2B_NONCE* nonceTPM, + BYTE *paramData, UINT32 paramSz) { int rc = TPM_RC_FAILURE; + TPM2B_DATA keyIn; TPM2B_MAX_BUFFER mask; UINT32 i; @@ -242,9 +252,17 @@ static int TPM2_ParamDec_XOR(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, return BUFFER_E; } + /* Build HMAC key input */ + XMEMCPY(keyIn.buffer, sessKey->buffer, sessKey->size); + keyIn.size = sessKey->size; + if (bindKey != NULL) { + XMEMCPY(&keyIn.buffer[keyIn.size], bindKey->buffer, bindKey->size); + keyIn.size += bindKey->size; + } + /* Generate XOR Mask stream matching paramater size */ XMEMSET(mask.buffer, 0, sizeof(mask.buffer)); - rc = TPM2_KDFa(session->authHash, (TPM2B_DATA*)keyIn, "XOR", + rc = TPM2_KDFa(session->authHash, &keyIn, "XOR", nonceTPM, nonceCaller, mask.buffer, paramSz); if ((UINT32)rc != paramSz) { #ifdef DEBUG_WOLFTPM @@ -265,11 +283,12 @@ static int TPM2_ParamDec_XOR(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, #if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_AES_CFB) /* Perform AES CFB encryption over the first parameter of a TPM packet */ -static int TPM2_ParamEnc_AESCFB(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, - TPM2B_NONCE* nonceCaller, TPM2B_NONCE* nonceTPM, BYTE *paramData, - UINT32 paramSz) +static int TPM2_ParamEnc_AESCFB(TPM2_AUTH_SESSION *session, TPM2B_AUTH* sessKey, + TPM2B_AUTH* bindKey, TPM2B_NONCE* nonceCaller, TPM2B_NONCE* nonceTPM, + BYTE *paramData, UINT32 paramSz) { int rc = TPM_RC_FAILURE; + TPM2B_DATA keyIn; BYTE symKey[32 + 16]; /* AES key (max) + IV (block size) */ int symKeySz = session->symmetric.keyBits.aes / 8; const int symKeyIvSz = 16; @@ -279,9 +298,17 @@ static int TPM2_ParamEnc_AESCFB(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, return BUFFER_E; } + /* Build HMAC key input */ + XMEMCPY(keyIn.buffer, sessKey->buffer, sessKey->size); + keyIn.size = sessKey->size; + if (bindKey != NULL) { + XMEMCPY(&keyIn.buffer[keyIn.size], bindKey->buffer, bindKey->size); + keyIn.size += bindKey->size; + } + /* Generate AES Key and IV */ XMEMSET(symKey, 0, sizeof(symKey)); - rc = TPM2_KDFa(session->authHash, (TPM2B_DATA*)keyIn, "CFB", + rc = TPM2_KDFa(session->authHash, &keyIn, "CFB", nonceCaller, nonceTPM, symKey, symKeySz + symKeyIvSz); if (rc != symKeySz + symKeyIvSz) { #ifdef DEBUG_WOLFTPM @@ -311,11 +338,12 @@ static int TPM2_ParamEnc_AESCFB(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, } /* Perform AES CFB decryption over the first parameter of a TPM packet */ -static int TPM2_ParamDec_AESCFB(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, - TPM2B_NONCE* nonceCaller, TPM2B_NONCE* nonceTPM, BYTE *paramData, - UINT32 paramSz) +static int TPM2_ParamDec_AESCFB(TPM2_AUTH_SESSION *session, TPM2B_AUTH* sessKey, + TPM2B_AUTH* bindKey, TPM2B_NONCE* nonceCaller, TPM2B_NONCE* nonceTPM, + BYTE *paramData, UINT32 paramSz) { int rc = TPM_RC_FAILURE; + TPM2B_DATA keyIn; BYTE symKey[32 + 16]; /* AES key 128-bit + IV (block size) */ int symKeySz = session->symmetric.keyBits.aes / 8; const int symKeyIvSz = 16; @@ -325,9 +353,17 @@ static int TPM2_ParamDec_AESCFB(TPM2_AUTH_SESSION *session, TPM2B_AUTH* keyIn, return BUFFER_E; } + /* Build HMAC key input */ + XMEMCPY(keyIn.buffer, sessKey->buffer, sessKey->size); + keyIn.size = sessKey->size; + if (bindKey != NULL) { + XMEMCPY(&keyIn.buffer[keyIn.size], bindKey->buffer, bindKey->size); + keyIn.size += bindKey->size; + } + /* Generate AES Key and IV */ XMEMSET(symKey, 0, sizeof(symKey)); - rc = TPM2_KDFa(session->authHash, (TPM2B_DATA*)keyIn, "CFB", + rc = TPM2_KDFa(session->authHash, &keyIn, "CFB", nonceTPM, nonceCaller, symKey, symKeySz + symKeyIvSz); if (rc != symKeySz + symKeyIvSz) { #ifdef DEBUG_WOLFTPM @@ -558,6 +594,10 @@ TPM_RC TPM2_ParamEnc_CmdRequest(TPM2_AUTH_SESSION *session, #ifdef WOLFTPM_DEBUG_VERBOSE printf("CmdEnc Session Key %d\n", session->auth.size); TPM2_PrintBin(session->auth.buffer, session->auth.size); + if (session->bind != NULL) { + printf("CmdEnc Extra Key %d\n", session->bind->size); + TPM2_PrintBin(session->bind->buffer, session->bind->size); + } printf("CmdEnc Nonce caller %d\n", session->nonceCaller.size); TPM2_PrintBin(session->nonceCaller.buffer, session->nonceCaller.size); printf("CmdEnc Nonce TPM %d\n", session->nonceTPM.size); @@ -566,14 +606,14 @@ TPM_RC TPM2_ParamEnc_CmdRequest(TPM2_AUTH_SESSION *session, if (session->symmetric.algorithm == TPM_ALG_XOR) { - rc = TPM2_ParamEnc_XOR(session, &session->auth, &session->nonceCaller, - &session->nonceTPM, paramData, paramSz); + rc = TPM2_ParamEnc_XOR(session, &session->auth, session->bind, + &session->nonceCaller, &session->nonceTPM, paramData, paramSz); } else if (session->symmetric.algorithm == TPM_ALG_AES && session->symmetric.mode.aes == TPM_ALG_CFB) { #if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_AES_CFB) - rc = TPM2_ParamEnc_AESCFB(session, &session->auth, &session->nonceCaller, - &session->nonceTPM, paramData, paramSz); + rc = TPM2_ParamEnc_AESCFB(session, &session->auth, session->bind, + &session->nonceCaller, &session->nonceTPM, paramData, paramSz); #else rc = NOT_COMPILED_IN; #endif @@ -590,6 +630,10 @@ TPM_RC TPM2_ParamDec_CmdResponse(TPM2_AUTH_SESSION *session, #ifdef WOLFTPM_DEBUG_VERBOSE printf("RspDec Session Key %d\n", session->auth.size); TPM2_PrintBin(session->auth.buffer, session->auth.size); + if (session->bind != NULL) { + printf("RspDec Extra Key %d\n", session->bind->size); + TPM2_PrintBin(session->bind->buffer, session->bind->size); + } printf("RspDec Nonce caller %d\n", session->nonceCaller.size); TPM2_PrintBin(session->nonceCaller.buffer, session->nonceCaller.size); printf("RspDec Nonce TPM %d\n", session->nonceTPM.size); @@ -597,14 +641,14 @@ TPM_RC TPM2_ParamDec_CmdResponse(TPM2_AUTH_SESSION *session, #endif if (session->symmetric.algorithm == TPM_ALG_XOR) { - rc = TPM2_ParamDec_XOR(session, &session->auth, &session->nonceCaller, - &session->nonceTPM, paramData, paramSz); + rc = TPM2_ParamDec_XOR(session, &session->auth, session->bind, + &session->nonceCaller, &session->nonceTPM, paramData, paramSz); } else if (session->symmetric.algorithm == TPM_ALG_AES && session->symmetric.mode.aes == TPM_ALG_CFB) { #if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_AES_CFB) - rc = TPM2_ParamDec_AESCFB(session, &session->auth, &session->nonceCaller, - &session->nonceTPM, paramData, paramSz); + rc = TPM2_ParamDec_AESCFB(session, &session->auth, session->bind, + &session->nonceCaller, &session->nonceTPM, paramData, paramSz); #else rc = NOT_COMPILED_IN; #endif diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 969e1973..a0eb6dd2 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -1066,6 +1066,9 @@ int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index, session->policyAuth = tpmSession->handle.policyAuth; session->policyPass = tpmSession->handle.policyPass; + /* Capture pointer to bind */ + session->bind = tpmSession->bind; + /* define the symmetric algorithm */ session->authHash = tpmSession->authHash; XMEMCPY(&session->symmetric, &tpmSession->handle.symmetric, @@ -1536,7 +1539,6 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session, int rc; StartAuthSession_In authSesIn; StartAuthSession_Out authSesOut; - TPM2B_AUTH* bindAuth = NULL; TPM2B_DATA keyIn; TPMI_ALG_HASH authHash = WOLFTPM2_WRAP_DIGEST; int hashDigestSz; @@ -1556,7 +1558,8 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session, /* set session auth for key */ if (tpmKey) { TPMA_SESSION sessionAttributes = 0; - if (encDecAlg == TPM_ALG_CFB || encDecAlg == TPM_ALG_XOR) { + if (bind != NULL && + (encDecAlg == TPM_ALG_CFB || encDecAlg == TPM_ALG_XOR)) { /* if parameter encryption is enabled and key bind set, enable * encrypt/decrypt by default */ sessionAttributes |= (TPMA_SESSION_decrypt | TPMA_SESSION_encrypt); @@ -1573,7 +1576,6 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session, authSesIn.bind = (TPMI_DH_ENTITY)TPM_RH_NULL; if (bind) { authSesIn.bind = bind->hndl; - bindAuth = &bind->auth; } authSesIn.sessionType = sesType; @@ -1632,9 +1634,10 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session, /* Calculate "key" and store into auth */ /* key is bindAuthValue || salt */ XMEMSET(&keyIn, 0, sizeof(keyIn)); - if (bindAuth && bindAuth->size > 0) { - XMEMCPY(&keyIn.buffer[keyIn.size], bindAuth->buffer, bindAuth->size); - keyIn.size += bindAuth->size; + if (bind && bind->auth.size > 0) { + XMEMCPY(&keyIn.buffer[keyIn.size], bind->auth.buffer, + bind->auth.size); + keyIn.size += bind->auth.size; } if (session->salt.size > 0) { XMEMCPY(&keyIn.buffer[keyIn.size], session->salt.buffer, @@ -1667,6 +1670,7 @@ int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session, session->handle.hndl = authSesOut.sessionHandle; wolfTPM2_CopySymmetric(&session->handle.symmetric, &authSesIn.symmetric); if (bind) { + session->bind = &bind->auth; /* pointer to bind key auth */ wolfTPM2_CopyName(&session->handle.name, &bind->name); } session->nonceCaller.size = authSesIn.nonceCaller.size; @@ -4498,13 +4502,16 @@ int wolfTPM2_NVCreate(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, maxSize, auth, authSz); } -int wolfTPM2_NVWriteAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, +static int wolfTPM2_NVWriteData(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, WOLFTPM2_NV* nv, - word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset) + word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset, int extend) { int rc = TPM_RC_SUCCESS; word32 pos = 0, towrite; - NV_Write_In in; + union { + NV_Write_In write; + NV_Extend_In extend; + } in; if (dev == NULL || nv == NULL || dataBuf == NULL) { return BAD_FUNC_ARG; @@ -4541,29 +4548,34 @@ int wolfTPM2_NVWriteAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, rc |= wolfTPM2_SetAuthHandleName(dev, 1, &nv->handle); if (rc != TPM_RC_SUCCESS) { #ifdef DEBUG_WOLFTPM - printf("Setting NV index name failed\n"); + printf("wolfTPM2_NVWriteData: Setting NV index name failed\n"); #endif rc = TPM_RC_FAILURE; break; } XMEMSET(&in, 0, sizeof(in)); - in.authHandle = nv->handle.hndl; - in.nvIndex = nvIndex; - in.offset = offset+pos; - in.data.size = towrite; + in.write.authHandle = nv->handle.hndl; + in.write.nvIndex = nvIndex; + in.write.data.size = towrite; if (dataBuf) - XMEMCPY(in.data.buffer, &dataBuf[pos], towrite); - - rc = TPM2_NV_Write(&in); + XMEMCPY(in.write.data.buffer, &dataBuf[pos], towrite); + if (!extend) { + in.write.offset = offset+pos; + rc = TPM2_NV_Write(&in.write); + } + else { + rc = TPM2_NV_Extend(&in.extend); + } if (rc != TPM_RC_SUCCESS) { 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, - in.offset, in.data.size); + printf("wolfTPM2_NVWriteData: Auth 0x%x, Idx 0x%x, Offset %d, Size %d, " + "Extend %d\n", + (word32)in.write.authHandle, (word32)in.write.nvIndex, + in.write.offset, in.write.data.size, extend); #endif pos += towrite; @@ -4572,18 +4584,34 @@ int wolfTPM2_NVWriteAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, #ifdef DEBUG_WOLFTPM if (rc != TPM_RC_SUCCESS) { - printf("TPM2_NV_Write failed %d: %s\n", rc, wolfTPM2_GetRCString(rc)); + printf("wolfTPM2_NVWriteData failed %d: %s\n", + rc, wolfTPM2_GetRCString(rc)); } #endif return rc; } +int wolfTPM2_NVExtend(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, + word32 nvIndex, byte* dataBuf, word32 dataSz) +{ + return wolfTPM2_NVWriteData(dev, NULL, TPM_ALG_NULL, NULL, 0, + nv, nvIndex, dataBuf, dataSz, 0, 1); +} + +int wolfTPM2_NVWriteAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* tpmSession, + TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, WOLFTPM2_NV* nv, + word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset) +{ + return wolfTPM2_NVWriteData(dev, tpmSession, pcrAlg, pcrArray, pcrArraySz, + nv, nvIndex, dataBuf, dataSz, offset, 0); +} + int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset) { - return wolfTPM2_NVWriteAuthPolicy(dev, NULL, TPM_ALG_NULL, NULL, 0, - nv, nvIndex, dataBuf, dataSz, offset); + return wolfTPM2_NVWriteData(dev, NULL, TPM_ALG_NULL, NULL, 0, + nv, nvIndex, dataBuf, dataSz, offset, 0); } /* older API kept for compatibility, recommend using wolfTPM2_NVWriteAuth */ @@ -4789,6 +4817,7 @@ int wolfTPM2_NVOpen(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, word32 nvIndex, /* flag that the NV was "opened" and name was loaded */ nv->handle.nameLoaded = 1; + nv->attributes = nvPublic.attributes; return rc; } diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index d72e8c44..38e8f358 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -1552,7 +1552,7 @@ typedef UINT32 TPMA_NV; #define TPMA_NV_OWNERWRITE 0x00000002UL #define TPMA_NV_AUTHWRITE 0x00000004UL #define TPMA_NV_POLICYWRITE 0x00000008UL -#define TPMA_NV_TPM_NT 0x000000F0UL +#define TPMA_NV_TPM_NT 0x000000F0UL /* index type see TPM_NT_ */ #define TPMA_NV_POLICY_DELETE 0x00000400UL #define TPMA_NV_WRITELOCKED 0x00000800UL #define TPMA_NV_WRITEALL 0x00001000UL @@ -1654,6 +1654,7 @@ typedef struct TPM2_AUTH_SESSION { TPMI_ALG_HASH authHash; TPM2B_NAME name; TPM2B_AUTH auth; + TPM2B_AUTH* bind; unsigned int policyAuth : 1; /* if policy auth should be used */ unsigned int policyPass : 1; diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index 4932b58f..8fc26d74 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -51,6 +51,7 @@ typedef struct WOLFTPM2_SESSION { TPM2B_DIGEST salt; /* User defined */ TPMI_ALG_HASH authHash; TPMA_SESSION sessionAttributes; + TPM2B_AUTH* bind; /* pointer to bind auth password */ } WOLFTPM2_SESSION; typedef struct WOLFTPM2_DEV { @@ -92,6 +93,7 @@ typedef struct WOLFTPM2_HASH { typedef struct WOLFTPM2_NV { WOLFTPM2_HANDLE handle; + TPMA_NV attributes; } WOLFTPM2_NV; typedef struct WOLFTPM2_HMAC { @@ -2014,6 +2016,29 @@ WOLFTPM_API int wolfTPM2_NVWriteAuthPolicy(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* TPM_ALG_ID pcrAlg, byte* pcrArray, word32 pcrArraySz, WOLFTPM2_NV* nv, word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset); +/*! + \ingroup wolfTPM2_Wrappers + \brief Extend data to an NV index + \note When NV index is read it will return the digest + + \return TPM_RC_SUCCESS: successful + \return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code) + \return BAD_FUNC_ARG: check the provided arguments + + \param dev pointer to a TPM2_DEV struct + \param nv pointer to a populated structure of WOLFTPM2_NV type + \param nvIndex integer value, holding an existing NV Index Handle value + \param dataBuf pointer to a byte buffer, containing the user data to be written to the TPM's NVRAM + \param dataSz integer value, specifying the size of the user data buffer, in bytes + + \sa wolfTPM2_NVReadAuth + \sa wolfTPM2_NVCreateAuth + \sa wolfTPM2_NVOpen + \sa wolfTPM2_NVDeleteAuth +*/ +WOLFTPM_API int wolfTPM2_NVExtend(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, + word32 nvIndex, byte* dataBuf, word32 dataSz); + /*! \ingroup wolfTPM2_Wrappers \brief Reads user data from a NV Index, starting at the given offset From 671b702786cba4f89adce41e5705fd4ec7dd5171 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 16 Dec 2024 14:17:15 -0800 Subject: [PATCH 2/3] Allow extend with RSA or ECC. --- examples/nvram/extend.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/nvram/extend.c b/examples/nvram/extend.c index 1b147b42..2cbc4bbc 100644 --- a/examples/nvram/extend.c +++ b/examples/nvram/extend.c @@ -173,8 +173,14 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) goto exit; } - /* 1: Create EK RSA 2048-bit */ - rc = wolfTPM2_CreateEK(&dev, &endorse, TPM_ALG_RSA); + /* 1: Create EK (RSA or ECC) */ + rc = wolfTPM2_CreateEK(&dev, &endorse, + #ifndef NO_RSA + TPM_ALG_RSA + #else + TPM_ALG_ECC + #endif + ); if (rc != 0) { printf("Create EK RSA failed!\n"); goto exit; From 15add23dcfed4e587939f7f35ab6d90afa3bec4c Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 17 Dec 2024 11:13:10 -0800 Subject: [PATCH 3/3] Add code for calculating NV extend policies. Fixed issue with `wolfTPM2_PolicyHash` where input digest could be too large. --- examples/nvram/extend.c | 123 +++++++++++++++++++++++----------------- src/tpm2_wrap.c | 3 + 2 files changed, 73 insertions(+), 53 deletions(-) diff --git a/examples/nvram/extend.c b/examples/nvram/extend.c index 2cbc4bbc..a0adb8da 100644 --- a/examples/nvram/extend.c +++ b/examples/nvram/extend.c @@ -27,15 +27,17 @@ #endif #include +#include #include -#ifndef WOLFTPM2_NO_WRAPPER +#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) #include #include #include #include + /******************************************************************************/ /* --- BEGIN TPM NVRAM Extend Example -- */ /******************************************************************************/ @@ -48,50 +50,26 @@ static void usage(void) printf("* -aes/xor: Use Parameter Encryption\n");; } -/* Policy A: TPM2_PolicyCommandCode -> TPM_CC_NV_Read */ -static const byte policyA[] = { - 0x47, 0xCE, 0x30, 0x32, 0xD8, 0xBA, 0xD1, 0xF3, - 0x08, 0x9C, 0xB0, 0xC0, 0x90, 0x88, 0xDE, 0x43, - 0x50, 0x14, 0x91, 0xD4, 0x60, 0x40, 0x2B, 0x90, - 0xCD, 0x1B, 0x7F, 0xC0, 0xB6, 0x8C, 0xA9, 0x2F -}; -/* Policy B: TPM2_PolicyCommandCode -> TPM_CC_NV_Extend */ -static const byte policyB[] = { - 0xB6, 0xA2, 0xE7, 0x14, 0x2E, 0xE5, 0x6F, 0xD9, - 0x78, 0x04, 0x74, 0x88, 0x48, 0x3D, 0xAA, 0x5B, - 0x42, 0xB8, 0xDC, 0x4C, 0xC7, 0xDD, 0xCC, 0xED, - 0xDF, 0xB9, 0x17, 0x93, 0xCF, 0x1F, 0xF1, 0xB7 -}; -/* Policy C: TPM2_PolicyCommandCode -> TPM_CC_PolicyNV */ -static const byte policyC[] = { - 0x20, 0x3E, 0x4B, 0xD5, 0xD0, 0x44, 0x8C, 0x96, - 0x15, 0xCC, 0x13, 0xFA, 0x18, 0xE8, 0xD3, 0x92, - 0x22, 0x44, 0x1C, 0xC4, 0x02, 0x04, 0xD9, 0x9A, - 0x77, 0x26, 0x20, 0x68, 0xDB, 0xD5, 0x5A, 0x43 -}; - -/* pre-computed policy: - * NV Read (A), NV Extend (B), PolicyNV (C), then policy OR (A/B/C) */ -static const byte policyNv[] = { - 0x7F, 0x17, 0x93, 0x7E, 0x20, 0x62, 0x79, 0xA3, - 0xF7, 0x55, 0xFB, 0x60, 0xF4, 0x0C, 0xF1, 0x26, - 0xB7, 0x0E, 0x5B, 0x1D, 0x9B, 0xF2, 0x02, 0x86, - 0x6D, 0x52, 0x76, 0x13, 0x87, 0x4A, 0x64, 0xAC -}; - - -static int PolicyOrApply(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* policySession) +static int BuildPolicyCommandCode(TPMI_ALG_HASH hashAlg, + byte* digest, word32* digestSz, TPM_CC cc) +{ + word32 val = cpu_to_be32(cc); + return wolfTPM2_PolicyHash(hashAlg, digest, digestSz, + TPM_CC_PolicyCommandCode, (byte*)&val, sizeof(val)); +} + +static int PolicyOrApply(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* policySession, + byte** hashList, word32 hashListSz, word32 digestSz) { + word32 i; PolicyOR_In policyOR; XMEMSET(&policyOR, 0, sizeof(policyOR)); policyOR.policySession = policySession->handle.hndl; - policyOR.pHashList.count = 3; - policyOR.pHashList.digests[0].size = sizeof(policyA); - XMEMCPY(policyOR.pHashList.digests[0].buffer, policyA, sizeof(policyA)); - policyOR.pHashList.digests[1].size = sizeof(policyB); - XMEMCPY(policyOR.pHashList.digests[1].buffer, policyB, sizeof(policyB)); - policyOR.pHashList.digests[2].size = sizeof(policyC); - XMEMCPY(policyOR.pHashList.digests[2].buffer, policyC, sizeof(policyC)); + policyOR.pHashList.count = hashListSz; + for (i=0; i= 2) { if (XSTRCMP(argv[1], "-?") == 0 || @@ -166,6 +148,8 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) XMEMSET(&bind, 0, sizeof(bind)); XMEMSET(&nv, 0, sizeof(nv)); XMEMSET(&nvAuth, 0, sizeof(nvAuth)); + XMEMSET(nvDigest, 0, sizeof(nvDigest)); + XMEMSET(policyDigest, 0, sizeof(policyDigest)); rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); if (rc != TPM_RC_SUCCESS) { @@ -173,6 +157,39 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) goto exit; } + /* Build Policies A/B/C */ + /* Policy A: TPM2_PolicyCommandCode -> TPM_CC_NV_Read */ + /* 47ce3032d8bad1f3089cb0c09088de43501491d460402b90cd1b7fc0b68ca92f */ + policy[0] = &policyDigest[policyDigestSz]; + BuildPolicyCommandCode(hashAlg, policy[0], &nvSize, TPM_CC_NV_Read); + 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); + 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); + printf("PolicyC: %d\n", nvSize); + TPM2_PrintBin(policy[2], nvSize); + policyDigestSz += nvSize; + + /* Policy OR A/B/C */ + /* 7f17937e206279a3f755fb60f40cf126b70e5b1d9bf202866d527613874a64ac */ + XMEMSET(policyOr, 0, sizeof(policyOr)); + rc = wolfTPM2_PolicyHash(hashAlg, policyOr, &nvSize, + TPM_CC_PolicyOR, policyDigest, policyDigestSz); + printf("PolicyOR A/B/C: %d\n", nvSize); + TPM2_PrintBin(policyOr, nvSize); + /* 1: Create EK (RSA or ECC) */ rc = wolfTPM2_CreateEK(&dev, &endorse, #ifndef NO_RSA @@ -227,7 +244,7 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) nvAttributes, /* needs TPM_NT_EXTEND set */ nvSize, /* must match nameAlg digest size */ auth, authSz, /* the password to bind session with */ - policyNv, (word32)sizeof(policyNv) + policyOr, nvSize ); } @@ -255,7 +272,7 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) /* 5. Satisfy policy for NV Extend (policy B) */ rc = wolfTPM2_PolicyCommandCode(&dev, &tpmSession, TPM_CC_NV_Extend); if (rc == 0) { - rc = PolicyOrApply(&dev, &tpmSession); + rc = PolicyOrApply(&dev, &tpmSession, policy, 3, nvSize); } if (rc != 0) { printf("Failed to apply policy B\n"); @@ -280,7 +297,7 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) /* 8. Satisfy policy for NV Read (policy A) */ rc = wolfTPM2_PolicyCommandCode(&dev, &tpmSession, TPM_CC_NV_Read); if (rc == 0) { - rc = PolicyOrApply(&dev, &tpmSession); + rc = PolicyOrApply(&dev, &tpmSession, policy, 3, nvSize); } if (rc != 0) { printf("Failed to apply policy A\n"); @@ -289,10 +306,10 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) /* 9. Read NV extend digest */ rc = wolfTPM2_NVRead(&dev, authHandle, nv.handle.hndl, - nvDigest, &nvDigestSz, 0); + nvDigest, &nvSize, 0); if (rc == 0) { - printf("NV Digest: %d\n", nvDigestSz); - TPM2_PrintBin(nvDigest, nvDigestSz); + printf("NV Digest: %d\n", nvSize); + TPM2_PrintBin(nvDigest, nvSize); /* Should be: * 0ad80f8e4450587760d9137df41c9374f657bafa621fe37d4d5c8cecf0bcce5e */ @@ -313,17 +330,17 @@ int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]) /******************************************************************************/ /* --- END TPM NVRAM Extend Example -- */ /******************************************************************************/ -#endif /* !WOLFTPM2_NO_WRAPPER */ +#endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT */ #ifndef NO_MAIN_DRIVER int main(int argc, char *argv[]) { int rc = NOT_COMPILED_IN; -#ifndef WOLFTPM2_NO_WRAPPER +#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) rc = TPM2_NVRAM_Extend_Example(NULL, argc, argv); #else - printf("NVRAM code not compiled in\n"); + printf("NVRAM extend code not compiled in\n"); (void)argc; (void)argv; #endif diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index a0eb6dd2..0aa7564b 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -7499,6 +7499,9 @@ int wolfTPM2_PolicyHash(TPM_ALG_ID hashAlg, /* policyDigestOld */ if (rc == 0 && inSz > 0) { + /* old digest cannot be larger than digest size */ + if (inSz > *digestSz) + inSz = *digestSz; rc = wc_HashUpdate(&hash_ctx, hashType, digest, inSz); } /* Command Code (optional) */