Merge pull request #389 from dgarske/nv_extend

Fix issue with session binding / add NV extend example
pull/392/head
Eric Blankenhorn 2024-12-17 17:00:58 -06:00 committed by GitHub
commit 80da56728c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 636 additions and 134 deletions

View File

@ -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;

View File

@ -0,0 +1,350 @@
/* 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 <config.h>
#endif
#include <wolftpm/tpm2_wrap.h>
#include <wolftpm/tpm2_packet.h>
#include <stdio.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT)
#include <examples/nvram/nvram.h>
#include <hal/tpm_io.h>
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>
/******************************************************************************/
/* --- 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");;
}
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 = hashListSz;
for (i=0; i<hashListSz; i++) {
policyOR.pHashList.digests[i].size = digestSz;
XMEMCPY(policyOR.pHashList.digests[i].buffer, hashList[i], digestSz);
}
(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;
byte* auth = (byte*)"cpusecret";
word32 authSz = (word32)XSTRLEN((const char*)auth);
TPMI_ALG_HASH hashAlg = WOLFTPM2_WRAP_DIGEST;
word32 nvSize = TPM2_GetHashDigestSize(hashAlg);
byte nvDigest[TPM_MAX_DIGEST_SIZE]; /* buffer for nv read */
byte policyDigest[3*TPM_MAX_DIGEST_SIZE]; /* Policy A/B/C */
word32 policyDigestSz = 0;
byte* policy[3]; /* pointers to policy A/B/C */
byte policyOr[TPM_MAX_DIGEST_SIZE];
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));
XMEMSET(nvDigest, 0, sizeof(nvDigest));
XMEMSET(policyDigest, 0, sizeof(policyDigest));
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_Init failed\n");
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
TPM_ALG_RSA
#else
TPM_ALG_ECC
#endif
);
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 */
policyOr, nvSize
);
}
/* 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, policy, 3, nvSize);
}
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, policy, 3, nvSize);
}
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, &nvSize, 0);
if (rc == 0) {
printf("NV Digest: %d\n", nvSize);
TPM2_PrintBin(nvDigest, nvSize);
/* 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 && !WOLFTPM2_NO_WOLFCRYPT */
#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
{
int rc = NOT_COMPILED_IN;
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT)
rc = TPM2_NVRAM_Extend_Example(NULL, argc, argv);
#else
printf("NVRAM extend code not compiled in\n");
(void)argc;
(void)argv;
#endif
return rc;
}
#endif

View File

@ -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

View File

@ -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" */

View File

@ -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;
rc = wolfTPM2_NVOpen(&dev, &nv, nvIndex, NULL, 0);
if (rc != 0) 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);
}
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;
}
#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;
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;
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;
}
#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;

View File

@ -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;

View File

@ -41,10 +41,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=$?
@ -61,10 +61,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=$?
@ -75,10 +75,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=$?
@ -98,10 +98,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=$?
@ -260,8 +260,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
@ -269,7 +269,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
@ -277,14 +277,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
@ -292,7 +292,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
@ -300,9 +300,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

View File

@ -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

View File

@ -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);

View File

@ -195,11 +195,12 @@ exit:
/* 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

View File

@ -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;
@ -4500,13 +4504,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;
@ -4543,29 +4550,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;
@ -4574,18 +4586,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 */
@ -4791,6 +4819,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;
}
@ -7476,6 +7505,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) */

View File

@ -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;

View File

@ -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