From 4f1fb41d7e2250273ed86fc2b7324a4d74803561 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 14 Aug 2019 11:32:45 -0700 Subject: [PATCH] Added support for using authentication with NV. Adds new wrapper API's: `wolfTPM2_NVWriteAuth`, `wolfTPM2_NVReadAuth` and `wolfTPM2_NVDeleteAuth`. --- examples/tpm_test.h | 5 ++ examples/wrap/wrap_test.c | 47 +++++++++++++++++-- src/tpm2_wrap.c | 97 +++++++++++++++++++++++++++++---------- wolftpm/tpm2_wrap.h | 22 ++++++++- 4 files changed, 143 insertions(+), 28 deletions(-) diff --git a/examples/tpm_test.h b/examples/tpm_test.h index 697fa542..89b796b0 100755 --- a/examples/tpm_test.h +++ b/examples/tpm_test.h @@ -38,9 +38,14 @@ #define TPM2_DEMO_ECC_KEY_HANDLE (0x81000000 + TPM2_DEMO_ECC_IDX) /* Persistent Key Handle */ #define TPM2_DEMO_ECC_CERT_HANDLE (0x01800000 + TPM2_DEMO_ECC_IDX) /* NV Handle */ +#define TPM2_DEMO_NV_TEST_INDEX 0x01800200 +#define TPM2_DEMO_NV_TEST_AUTH_INDEX 0x01800201 +#define TPM2_DEMO_NV_TEST_SIZE 1024 /* max size on Infineon SLB9670 is 1664 */ + static const char gStorageKeyAuth[] = "ThisIsMyStorageKeyAuth"; static const char gKeyAuth[] = "ThisIsMyKeyAuth"; static const char gUsageAuth[] = "ThisIsASecretUsageAuth"; +static const char gNvAuth[] = "ThisIsMyNvAuth"; #ifndef WOLFTPM_ST33 #define TEST_AES_MODE TPM_ALG_CFB diff --git a/examples/wrap/wrap_test.c b/examples/wrap/wrap_test.c index 48bc74c5..8da21853 100644 --- a/examples/wrap/wrap_test.c +++ b/examples/wrap/wrap_test.c @@ -33,8 +33,6 @@ #include /* Configuration */ -#define TPM2_DEMO_NV_TEST_INDEX 0x01800200 -#define TPM2_DEMO_NV_TEST_SIZE 1024 /* max size on Infineon SLB9670 is 1664 */ #if 0 #define ENABLE_LARGE_HASH_TEST /* optional large hash test */ #endif @@ -495,8 +493,47 @@ int TPM2_Wrapper_Test(void* userCtx) /*------------------------------------------------------------------------*/ /* NV TESTS */ /*------------------------------------------------------------------------*/ + /* NV with Auth (preferred API's) */ + { + WOLFTPM2_HANDLE parent; + WOLFTPM2_NV nv; - /* NV Tests */ + XMEMSET(&parent, 0, sizeof(parent)); + parent.hndl = TPM_RH_OWNER; + + rc = wolfTPM2_GetNvAttributesTemplate(parent.hndl, &nvAttributes); + if (rc != 0) goto exit; + rc = wolfTPM2_NVCreateAuth(&dev, &parent, &nv, TPM2_DEMO_NV_TEST_AUTH_INDEX, + nvAttributes, TPM2_DEMO_NV_TEST_SIZE, (byte*)gNvAuth, sizeof(gNvAuth)-1); + if (rc != 0 && rc != TPM_RC_NV_DEFINED) goto exit; + + message.size = TPM2_DEMO_NV_TEST_SIZE; /* test message 0x11,0x11,etc */ + XMEMSET(message.buffer, 0x11, message.size); + rc = wolfTPM2_NVWriteAuth(&dev, &nv, TPM2_DEMO_NV_TEST_AUTH_INDEX, + message.buffer, message.size, 0); + if (rc != 0) goto exit; + + plain.size = TPM2_DEMO_NV_TEST_SIZE; + rc = wolfTPM2_NVReadAuth(&dev, &nv, TPM2_DEMO_NV_TEST_AUTH_INDEX, + plain.buffer, (word32*)&plain.size, 0); + if (rc != 0) goto exit; + + rc = wolfTPM2_NVReadPublic(&dev, TPM2_DEMO_NV_TEST_AUTH_INDEX, NULL); + if (rc != 0) goto exit; + + rc = wolfTPM2_NVDeleteAuth(&dev, &parent, TPM2_DEMO_NV_TEST_AUTH_INDEX); + if (rc != 0) goto exit; + + if (message.size != plain.size || + XMEMCMP(message.buffer, plain.buffer, message.size) != 0) { + rc = TPM_RC_TESTING; goto exit; + } + + printf("NV Test (with auth) on index 0x%x with %d bytes passed\n", + TPM2_DEMO_NV_TEST_AUTH_INDEX, TPM2_DEMO_NV_TEST_SIZE); + } + + /* NV Tests (older API's without auth) */ rc = wolfTPM2_GetNvAttributesTemplate(TPM_RH_OWNER, &nvAttributes); if (rc != 0) goto exit; rc = wolfTPM2_NVCreate(&dev, TPM_RH_OWNER, TPM2_DEMO_NV_TEST_INDEX, @@ -528,6 +565,10 @@ int TPM2_Wrapper_Test(void* userCtx) printf("NV Test on index 0x%x with %d bytes passed\n", TPM2_DEMO_NV_TEST_INDEX, TPM2_DEMO_NV_TEST_SIZE); + + /*------------------------------------------------------------------------*/ + /* RANDOM TESTS */ + /*------------------------------------------------------------------------*/ /* Random Test */ XMEMSET(message.buffer, 0, sizeof(message.buffer)); rc = wolfTPM2_GetRandom(&dev, message.buffer, sizeof(message.buffer)); diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index a74c18d6..041d3e48 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -1877,27 +1877,29 @@ int wolfTPM2_UnloadHandle(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle) return TPM_RC_SUCCESS; } - -int wolfTPM2_NVCreate(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, - word32 nvIndex, word32 nvAttributes, word32 maxSize, +/* nv is the populated handle and auth */ +/* auth and authSz are optional NV authentication */ +int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, + WOLFTPM2_NV* nv, word32 nvIndex, word32 nvAttributes, word32 maxSize, const byte* auth, int authSz) { int rc; NV_DefineSpace_In in; - if (dev == NULL) + if (dev == NULL || nv == NULL) return BAD_FUNC_ARG; - /* clear auth */ - XMEMSET(&dev->session[0].auth, 0, sizeof(dev->session[0].auth)); + /* set session auth for key */ + dev->session[0].auth = parent->auth; XMEMSET(&in, 0, sizeof(in)); - in.authHandle = authHandle; + in.authHandle = parent->hndl; if (auth && authSz > 0) { + if (authSz > (int)sizeof(in.auth.buffer)) + authSz = (int)sizeof(in.auth.buffer); in.auth.size = authSz; XMEMCPY(in.auth.buffer, auth, in.auth.size); } - in.publicInfo.nvPublic.nvIndex = nvIndex; in.publicInfo.nvPublic.nameAlg = TPM_ALG_SHA256; in.publicInfo.nvPublic.attributes = nvAttributes; @@ -1912,6 +1914,10 @@ int wolfTPM2_NVCreate(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, return rc; } + /* return new NV handle */ + nv->handle.hndl = (TPM_HANDLE)nvIndex; + nv->handle.auth = in.auth; + #ifdef DEBUG_WOLFTPM printf("TPM2_NV_DefineSpace: Auth 0x%x, Idx 0x%x, Attribs 0x%d, Size %d\n", (word32)in.authHandle, @@ -1923,18 +1929,33 @@ int wolfTPM2_NVCreate(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, return rc; } -int wolfTPM2_NVWrite(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, +/* older API kept for compatibility, recommend using wolfTPM2_NVCreateAuth */ +int wolfTPM2_NVCreate(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, + word32 nvIndex, word32 nvAttributes, word32 maxSize, + const byte* auth, int authSz) +{ + WOLFTPM2_NV nv; + WOLFTPM2_HANDLE parent; + + XMEMSET(&nv, 0, sizeof(nv)); + XMEMSET(&parent, 0, sizeof(parent)); + parent.hndl = authHandle; + return wolfTPM2_NVCreateAuth(dev, &parent, &nv, nvIndex, nvAttributes, + maxSize, auth, authSz); +} + +int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset) { int rc = TPM_RC_SUCCESS; word32 pos = 0, towrite; NV_Write_In in; - if (dev == NULL) + if (dev == NULL || nv == NULL) return BAD_FUNC_ARG; - /* clear auth */ - XMEMSET(&dev->session[0].auth, 0, sizeof(dev->session[0].auth)); + /* set auth */ + dev->session[0].auth = nv->handle.auth; while (dataSz > 0) { towrite = dataSz; @@ -1942,7 +1963,7 @@ int wolfTPM2_NVWrite(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, towrite = MAX_NV_BUFFER_SIZE; XMEMSET(&in, 0, sizeof(in)); - in.authHandle = authHandle; + in.authHandle = nv->handle.hndl; in.nvIndex = nvIndex; in.offset = offset+pos; in.data.size = towrite; @@ -1970,7 +1991,17 @@ int wolfTPM2_NVWrite(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, return rc; } -int wolfTPM2_NVRead(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, +/* older API kept for compatibility, recommend using wolfTPM2_NVWriteAuth */ +int wolfTPM2_NVWrite(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, + word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset) +{ + WOLFTPM2_NV nv; + XMEMSET(&nv, 0, sizeof(nv)); + nv.handle.hndl = authHandle; + return wolfTPM2_NVWriteAuth(dev, &nv, nvIndex, dataBuf, dataSz, offset); +} + +int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, word32 nvIndex, byte* dataBuf, word32* pDataSz, word32 offset) { int rc = TPM_RC_SUCCESS; @@ -1978,13 +2009,13 @@ int wolfTPM2_NVRead(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, NV_Read_In in; NV_Read_Out out; - if (dev == NULL || pDataSz == NULL) + if (dev == NULL || nv == NULL || pDataSz == NULL) return BAD_FUNC_ARG; dataSz = *pDataSz; - /* clear auth */ - XMEMSET(&dev->session[0].auth, 0, sizeof(dev->session[0].auth)); + /* set auth */ + dev->session[0].auth = nv->handle.auth; while (dataSz > 0) { toread = dataSz; @@ -1992,7 +2023,7 @@ int wolfTPM2_NVRead(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, toread = MAX_NV_BUFFER_SIZE; XMEMSET(&in, 0, sizeof(in)); - in.authHandle = authHandle; + in.authHandle = nv->handle.hndl; in.nvIndex = nvIndex; in.offset = offset+pos; in.size = toread; @@ -2029,6 +2060,16 @@ int wolfTPM2_NVRead(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, return rc; } +/* older API kept for compatibility, recommend using wolfTPM2_NVReadAuth */ +int wolfTPM2_NVRead(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, + word32 nvIndex, byte* dataBuf, word32* pDataSz, word32 offset) +{ + WOLFTPM2_NV nv; + XMEMSET(&nv, 0, sizeof(nv)); + nv.handle.hndl = authHandle; + return wolfTPM2_NVReadAuth(dev, &nv, nvIndex, dataBuf, pDataSz, offset); +} + int wolfTPM2_NVReadPublic(WOLFTPM2_DEV* dev, word32 nvIndex, TPMS_NV_PUBLIC* nvPublic) { @@ -2069,20 +2110,20 @@ int wolfTPM2_NVReadPublic(WOLFTPM2_DEV* dev, word32 nvIndex, return rc; } -int wolfTPM2_NVDelete(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, +int wolfTPM2_NVDeleteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, word32 nvIndex) { int rc; NV_UndefineSpace_In in; - if (dev == NULL) + if (dev == NULL || parent == NULL) return BAD_FUNC_ARG; - /* clear auth */ - XMEMSET(&dev->session[0].auth, 0, sizeof(dev->session[0].auth)); + /* set auth */ + dev->session[0].auth = parent->auth; XMEMSET(&in, 0, sizeof(in)); - in.authHandle = authHandle; + in.authHandle = parent->hndl; in.nvIndex = nvIndex; rc = TPM2_NV_UndefineSpace(&in); @@ -2102,6 +2143,16 @@ int wolfTPM2_NVDelete(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, return rc; } +/* older API kept for compatibility, recommend using wolfTPM2_NVDeleteAuth */ +int wolfTPM2_NVDelete(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, + word32 nvIndex) +{ + WOLFTPM2_HANDLE parent; + XMEMSET(&parent, 0, sizeof(parent)); + parent.hndl = authHandle; + return wolfTPM2_NVDeleteAuth(dev, &parent, nvIndex); +} + #ifndef WOLFTPM2_NO_WOLFCRYPT struct WC_RNG* wolfTPM2_GetRng(WOLFTPM2_DEV* dev) { diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index b9398093..6eb9ba09 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -54,6 +54,10 @@ typedef struct WOLFTPM2_HASH { WOLFTPM2_HANDLE handle; } WOLFTPM2_HASH; +typedef struct WOLFTPM2_NV { + WOLFTPM2_HANDLE handle; +} WOLFTPM2_NV; + typedef struct WOLFTPM2_HMAC { WOLFTPM2_HASH hash; WOLFTPM2_KEY key; @@ -201,17 +205,31 @@ WOLFTPM_API int wolfTPM2_ReadPCR(WOLFTPM2_DEV* dev, WOLFTPM_API int wolfTPM2_ExtendPCR(WOLFTPM2_DEV* dev, int pcrIndex, int hashAlg, const byte* digest, int digestLen); +/* Newer API's that use WOLFTPM2_NV context and support auth */ +WOLFTPM_API int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, + WOLFTPM2_NV* nv, word32 nvIndex, word32 nvAttributes, word32 maxSize, + const byte* auth, int authSz); +WOLFTPM_API int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, + word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset); +WOLFTPM_API int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, + word32 nvIndex, byte* dataBuf, word32* pDataSz, word32 offset); +WOLFTPM_API int wolfTPM2_NVDeleteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, + word32 nvIndex); + +/* older API's with improper auth support, kept only for backwards compatibility */ WOLFTPM_API int wolfTPM2_NVCreate(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, word32 nvIndex, word32 nvAttributes, word32 maxSize, const byte* auth, int authSz); WOLFTPM_API int wolfTPM2_NVWrite(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, word32 nvIndex, byte* dataBuf, word32 dataSz, word32 offset); WOLFTPM_API int wolfTPM2_NVRead(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, word32 nvIndex, byte* dataBuf, word32* dataSz, word32 offset); -WOLFTPM_API int wolfTPM2_NVReadPublic(WOLFTPM2_DEV* dev, word32 nvIndex, - TPMS_NV_PUBLIC* nvPublic); WOLFTPM_API int wolfTPM2_NVDelete(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle, word32 nvIndex); +WOLFTPM_API int wolfTPM2_NVReadPublic(WOLFTPM2_DEV* dev, word32 nvIndex, + TPMS_NV_PUBLIC* nvPublic); + + WOLFTPM_API int wolfTPM2_NVStoreKey(WOLFTPM2_DEV* dev, TPM_HANDLE primaryHandle, WOLFTPM2_KEY* key, TPM_HANDLE persistentHandle); WOLFTPM_API int wolfTPM2_NVDeleteKey(WOLFTPM2_DEV* dev, TPM_HANDLE primaryHandle,