diff --git a/src/tpm2.c b/src/tpm2.c index 13c392b..9b7218d 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -108,7 +108,8 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet, int rc = TPM_RC_SUCCESS; UINT32 authSz; BYTE *param, *encParam = NULL; - int paramSz, encParamSz = 0, authPos, i; + int paramSz, encParamSz = 0; + int i, authPos, handlePos; /* Skip the header and handles area */ packet->pos = TPM2_HEADER_SIZE + (info->inHandleCnt * sizeof(TPM_HANDLE)); @@ -187,9 +188,16 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet, } #ifndef WOLFTPM2_NO_WOLFCRYPT - rc = TPM2_GetName(ctx, info->inHandleCnt, 0, &name1); - rc |= TPM2_GetName(ctx, info->inHandleCnt, 1, &name2); - rc |= TPM2_GetName(ctx, info->inHandleCnt, 2, &name3); + UINT32 handleValue; + + handlePos = packet->pos; + packet->pos = TPM2_HEADER_SIZE; /* Handles are right after header */ + TPM2_Packet_ParseU32(packet, &handleValue); + packet->pos = handlePos; + + rc = TPM2_GetName(ctx, handleValue, info->inHandleCnt, 0, &name1); + rc |= TPM2_GetName(ctx, handleValue, info->inHandleCnt, 1, &name2); + rc |= TPM2_GetName(ctx, handleValue, info->inHandleCnt, 2, &name3); if (rc != TPM_RC_SUCCESS) { #ifdef DEBUG_WOLFTPM printf("Error getting names for cpHash!\n"); @@ -5269,7 +5277,7 @@ int TPM2_GetNonce(byte* nonceBuf, int nonceSz) } /* Get name for object/handle */ -int TPM2_GetName(TPM2_CTX* ctx, int handleCnt, int idx, TPM2B_NAME* name) +int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2B_NAME* name) { TPM2_AUTH_SESSION* session; @@ -5279,10 +5287,28 @@ int TPM2_GetName(TPM2_CTX* ctx, int handleCnt, int idx, TPM2B_NAME* name) return TPM_RC_SUCCESS; session = &ctx->session[idx]; + +#if 0 if (session->name.size > 0) { name->size = session->name.size; XMEMCPY(name->name, session->name.name, name->size); } + (void)handleValue; +#else + if ((handleValue >= TRANSIENT_FIRST) || + (handleValue >= NV_INDEX_FIRST && handleValue <= NV_INDEX_LAST)) { + if (session->name.size > 0) { + name->size = session->name.size; + XMEMCPY(name->name, session->name.name, name->size); + } + } + else { + handleValue = TPM2_Packet_SwapU32(handleValue); + name->size = sizeof(handleValue); + XMEMCPY(name->name, (byte*)&handleValue, name->size); + } +#endif + #ifdef WOLFTPM_DEBUG_VERBOSE printf("Name %d: %d\n", idx, name->size); TPM2_PrintBin(name->name, name->size); @@ -5649,6 +5675,67 @@ UINT16 TPM2_GetVendorID(void) return vid; } +/* Stores nameAlg + the digest of nvPublic in buffer, total size in size */ +int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size) +{ + int rc; +#ifndef WOLFTPM2_NO_WOLFCRYPT + int hashSize, nameAlgValue, nameAlgSize; + wc_HashAlg hash; + enum wc_HashType hashType; + byte appending[sizeof(TPMS_NV_PUBLIC)]; + TPM2B_DIGEST digest; + TPM2_Packet packet; + + /* Prepare temporary buffer */ + packet.buf = appending; + packet.pos = 0; + packet.size = sizeof(appending); + + /* nvPublic must be in Marshaled state for hashing */ + TPM2_Packet_AppendU32(&packet, nvPublic->nvIndex); + TPM2_Packet_AppendU16(&packet, nvPublic->nameAlg); + TPM2_Packet_AppendU32(&packet, nvPublic->attributes); + TPM2_Packet_AppendU16(&packet, nvPublic->authPolicy.size); + TPM2_Packet_AppendBytes(&packet, nvPublic->authPolicy.buffer, + nvPublic->authPolicy.size); + TPM2_Packet_AppendU16(&packet, nvPublic->dataSize); + + /* Hashing nvPublic */ + rc = TPM2_GetHashType(nvPublic->nameAlg); + hashType = (enum wc_HashType)rc; + rc = wc_HashGetDigestSize(hashType); + if (rc < 0) { + return rc; + } + hashSize = rc; + + rc = wc_HashInit(&hash, hashType); + if(rc == 0) { + rc = wc_HashUpdate(&hash, hashType, packet.buf, packet.pos); + } + + if (rc == 0) { + rc = wc_HashFinal(&hash, hashType, digest.buffer); + } + + if (rc == 0) { + nameAlgValue = TPM2_Packet_SwapU16(nvPublic->nameAlg); + nameAlgSize = sizeof(nvPublic->nameAlg); + XMEMCPY(buffer, (byte*)&nameAlgValue, nameAlgSize); + XMEMCPY(&buffer[2], digest.buffer, hashSize); + /* account for nameAlg concatenation */ + *size = hashSize + nameAlgSize; + } + + wc_HashFree(&hash, hashType); + + return TPM_RC_SUCCESS; +#else + return TPM_RC_FAILURE; +#endif +} + #ifdef DEBUG_WOLFTPM #define LINE_LEN 16 void TPM2_PrintBin(const byte* buffer, word32 length) diff --git a/src/tpm2_packet.c b/src/tpm2_packet.c index 03c2936..1260f52 100644 --- a/src/tpm2_packet.c +++ b/src/tpm2_packet.c @@ -320,7 +320,9 @@ void TPM2_Packet_AppendAuthCmd(TPM2_Packet* packet, TPMS_AUTH_COMMAND* authCmd) if (packet == NULL || authCmd == NULL) return; +#ifdef WOLFTPM_DEBUG_VERBOSE TPM2_PrintAuth(authCmd); +#endif /* make sure continueSession is set for TPM_RS_PW */ if (authCmd->sessionHandle == TPM_RS_PW && diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 493f0a5..e21df7e 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -26,6 +26,11 @@ /* For some struct to buffer conversions */ #include +#ifndef WOLFTPM2_NO_WOLFCRYPT +/* Required in wolfTPM2_CreateAuth() for name computation of NV handles */ +#include +#endif + /* Local Functions */ static int wolfTPM2_GetCapabilities_NoDev(WOLFTPM2_CAPS* cap); @@ -369,6 +374,20 @@ int wolfTPM2_GetCapabilities(WOLFTPM2_DEV* dev, WOLFTPM2_CAPS* cap) return wolfTPM2_GetCapabilities_NoDev(cap); } +int wolfTPM2_UnsetAuth(WOLFTPM2_DEV* dev, int index) +{ + TPM2_AUTH_SESSION* session; + + if (dev == NULL || index >= MAX_SESSION_NUM) { + return BAD_FUNC_ARG; + } + + session = &dev->session[index]; + XMEMSET(session, 0, sizeof(TPM2_AUTH_SESSION)); + + return TPM2_SetSessionAuth(dev->session); +} + int wolfTPM2_SetAuth(WOLFTPM2_DEV* dev, int index, TPM_HANDLE sessionHandle, const TPM2B_AUTH* auth, TPMA_SESSION sessionAttributes, const TPM2B_NAME* name) @@ -415,6 +434,24 @@ int wolfTPM2_SetAuthHandle(WOLFTPM2_DEV* dev, int index, return wolfTPM2_SetAuth(dev, index, TPM_RS_PW, auth, 0, name); } +int wolfTPM2_SetNameHandle(WOLFTPM2_DEV* dev, int index, + const WOLFTPM2_HANDLE* handle) +{ + const TPM2B_NAME* name = NULL; + TPM2_AUTH_SESSION* session; + + if (dev == NULL || handle == NULL || index >= MAX_SESSION_NUM) { + return BAD_FUNC_ARG; + } + + name = &handle->name; + session = &dev->session[index]; + + session->name.size = name->size; + XMEMCPY(session->name.name, name->name, session->name.size); + return TPM_RC_SUCCESS; +} + int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index, const WOLFTPM2_SESSION* tpmSession, TPMA_SESSION sessionAttributes) { @@ -446,6 +483,15 @@ int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index, session->nonceTPM.size = tpmSession->nonceTPM.size; XMEMCPY(session->nonceTPM.buffer, tpmSession->nonceTPM.buffer, session->nonceTPM.size); + + /* Parameter Encryption session will have an hmac added later. + * Reserve space, the same way it was done for nonceCaller above. + */ + if (session->sessionHandle != TPM_RS_PW && + ((session->sessionAttributes & TPMA_SESSION_encrypt) || + (session->sessionAttributes & TPMA_SESSION_decrypt))) { + session->auth.size = TPM2_GetHashDigestSize(session->authHash); + } } return rc; } @@ -2524,6 +2570,7 @@ int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, { int rc; NV_DefineSpace_In in; + TPM2B_NAME name; if (dev == NULL || nv == NULL) return BAD_FUNC_ARG; @@ -2533,6 +2580,7 @@ int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, wolfTPM2_SetAuthHandle(dev, 0, parent); } + XMEMSET(&name, 0, sizeof(name)); XMEMSET(&in, 0, sizeof(in)); in.authHandle = parent->hndl; if (auth && authSz > 0) { @@ -2560,9 +2608,15 @@ int wolfTPM2_NVCreateAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, return rc; } + /* Compute NV Index name in case of parameter encryption */ + rc = TPM2_HashNvPublic(&in.publicInfo.nvPublic, name.name, &name.size); + /* return new NV handle */ + XMEMSET(nv, 0, sizeof(*nv)); nv->handle.hndl = (TPM_HANDLE)nvIndex; nv->handle.auth = in.auth; + nv->handle.name.size = name.size; + XMEMCPY(&nv->handle.name.name, name.name, nv->handle.name.size); #ifdef DEBUG_WOLFTPM printf("TPM2_NV_DefineSpace: Auth 0x%x, Idx 0x%x, Attribs 0x%d, Size %d\n", @@ -2596,6 +2650,8 @@ int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, int rc = TPM_RC_SUCCESS; word32 pos = 0, towrite; NV_Write_In in; + NV_ReadPublic_In inPublic; + NV_ReadPublic_Out outPublic; if (dev == NULL || nv == NULL) return BAD_FUNC_ARG; @@ -2605,6 +2661,27 @@ int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, wolfTPM2_SetAuthHandle(dev, 0, &nv->handle); } + XMEMSET((byte*)&inPublic, 0, sizeof(inPublic)); + XMEMSET((byte*)&outPublic, 0, sizeof(outPublic)); + /* Read the NV Index publicArea to have up to date NV Index Name */ + inPublic.nvIndex = nv->handle.hndl; + rc = TPM2_NV_ReadPublic(&inPublic, &outPublic); + if (rc != TPM_RC_SUCCESS) { + #ifdef DEBUG_WOLFTPM + printf("Failed to read fresh NvPublic\n"); + #endif + return TPM_RC_FAILURE; + } + + /* Compute NV Index name in case of parameter encryption */ + rc = TPM2_HashNvPublic(&outPublic.nvPublic.nvPublic, + (byte*)&nv->handle.name.name, + &nv->handle.name.size); + + /* Necessary, because NVWrite has two handles, second is NV Index */ + wolfTPM2_SetNameHandle(dev, 0, &nv->handle); + wolfTPM2_SetNameHandle(dev, 1, &nv->handle); + while (dataSz > 0) { towrite = dataSz; if (towrite > MAX_NV_BUFFER_SIZE) @@ -2629,7 +2706,8 @@ int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, #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); + (word32)in.authHandle, (word32)in.nvIndex, + in.offset, in.data.size); #endif pos += towrite; @@ -2656,6 +2734,8 @@ int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, word32 pos = 0, toread, dataSz; NV_Read_In in; NV_Read_Out out; + NV_ReadPublic_In inPublic; + NV_ReadPublic_Out outPublic; if (dev == NULL || nv == NULL || pDataSz == NULL) return BAD_FUNC_ARG; @@ -2665,6 +2745,27 @@ int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv, wolfTPM2_SetAuthHandle(dev, 0, &nv->handle); } + XMEMSET((byte*)&inPublic, 0, sizeof(inPublic)); + XMEMSET((byte*)&outPublic, 0, sizeof(outPublic)); + /* Read the NV Index publicArea to have up to date NV Index Name */ + inPublic.nvIndex = nv->handle.hndl; + rc = TPM2_NV_ReadPublic(&inPublic, &outPublic); + if (rc != TPM_RC_SUCCESS) { + #ifdef DEBUG_WOLFTPM + printf("Failed to read fresh NvPublic\n"); + #endif + return TPM_RC_FAILURE; + } + + /* Compute NV Index name in case of parameter encryption */ + rc = TPM2_HashNvPublic(&outPublic.nvPublic.nvPublic, + (byte*)&nv->handle.name.name, + &nv->handle.name.size); + + /* Necessary, because NVWrite has two handles, second is NV Index */ + wolfTPM2_SetNameHandle(dev, 0, &nv->handle); + wolfTPM2_SetNameHandle(dev, 1, &nv->handle); + dataSz = *pDataSz; while (dataSz > 0) { @@ -2773,6 +2874,9 @@ int wolfTPM2_NVDeleteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* parent, /* set session auth for key */ if (dev->ctx.session) { wolfTPM2_SetAuthHandle(dev, 0, parent); + /* Make sure no other auth sessions exist */ + wolfTPM2_UnsetAuth(dev, 1); + wolfTPM2_UnsetAuth(dev, 2); } XMEMSET(&in, 0, sizeof(in)); diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 57dc4c8..b38a15a 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -2800,7 +2800,8 @@ WOLFTPM_API int TPM2_GetTpmCurve(int curveID); WOLFTPM_API int TPM2_GetWolfCurve(int curve_id); WOLFTPM_API int TPM2_ParseAttest(const TPM2B_ATTEST* in, TPMS_ATTEST* out); -WOLFTPM_LOCAL int TPM2_GetName(TPM2_CTX* ctx, int handleCnt, int idx, TPM2B_NAME* name); +WOLFTPM_LOCAL int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2B_NAME* name); +WOLFTPM_API int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size); #ifdef WOLFTPM2_USE_WOLF_RNG WOLFTPM_API int TPM2_GetWolfRng(WC_RNG** rng); diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index ff8af90..901de9d 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -131,6 +131,7 @@ WOLFTPM_API int wolfTPM2_GetTpmDevId(WOLFTPM2_DEV* dev); WOLFTPM_API int wolfTPM2_SelfTest(WOLFTPM2_DEV* dev); WOLFTPM_API int wolfTPM2_GetCapabilities(WOLFTPM2_DEV* dev, WOLFTPM2_CAPS* caps); +WOLFTPM_API int wolfTPM2_UnsetAuth(WOLFTPM2_DEV* dev, int index); WOLFTPM_API int wolfTPM2_SetAuth(WOLFTPM2_DEV* dev, int index, TPM_HANDLE sessionHandle, const TPM2B_AUTH* auth, TPMA_SESSION sessionAttributes, const TPM2B_NAME* name); @@ -138,6 +139,7 @@ WOLFTPM_API int wolfTPM2_SetAuthPassword(WOLFTPM2_DEV* dev, int index, const TPM WOLFTPM_API int wolfTPM2_SetAuthHandle(WOLFTPM2_DEV* dev, int index, const WOLFTPM2_HANDLE* handle); WOLFTPM_API int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index, const WOLFTPM2_SESSION* tpmSession, TPMA_SESSION sessionAttributes); +WOLFTPM_API int wolfTPM2_SetNameHandle(WOLFTPM2_DEV* dev, int index, const WOLFTPM2_HANDLE* handle); WOLFTPM_API int wolfTPM2_StartSession(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session, WOLFTPM2_KEY* tpmKey,