From ad156f18b7dba01b7addf552522f44e229527706 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 8 May 2024 13:55:50 -0700 Subject: [PATCH] Refactor to eliminate confusing cast between TPMS_AUTH_COMMAND and TPM2_AUTH_SESSION. --- src/tpm2.c | 34 ++++++++++++++++--------- src/tpm2_packet.c | 60 ++++++++++++++++++++++++++++++++++++--------- src/tpm2_wrap.c | 15 +----------- wolftpm/tpm2.h | 4 +-- wolftpm/tpm2_wrap.h | 6 +++-- 5 files changed, 77 insertions(+), 42 deletions(-) diff --git a/src/tpm2.c b/src/tpm2.c index d8f81004..28ad6abf 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -108,7 +108,7 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet, BYTE *param, *encParam = NULL; int paramSz, encParamSz = 0; int i, authPos; - int tmpSz = 0; /* Used to calculate the new total size of the Auth Area */ + int authTotalSzPos = 0; #ifndef WOLFTPM2_NO_WOLFCRYPT UINT32 handleValue1, handleValue2, handleValue3; int handlePos; @@ -120,8 +120,8 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet, /* Parse Auth */ TPM2_Packet_ParseU32(packet, &authSz); packet->pos -= sizeof(authSz); - /* Later Auth Area size is updated */ - TPM2_Packet_MarkU32(packet, &tmpSz); + /* Get position for total auth size to be updated later */ + TPM2_Packet_MarkU32(packet, &authTotalSzPos); /* Mark the position of the Auth Area data */ authPos = packet->pos; packet->pos += authSz; @@ -174,11 +174,23 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet, } } - /* Note: Copy between TPM2_AUTH_SESSION and TPMS_AUTH_COMMAND is allowed */ - XMEMCPY(&authCmd, session, sizeof(TPMS_AUTH_COMMAND)); - - if (TPM2_IS_HMAC_SESSION(session->sessionHandle) || - TPM2_IS_POLICY_SESSION(session->sessionHandle)) + /* Build auth */ + XMEMSET(&authCmd, 0, sizeof(authCmd)); + authCmd.sessionHandle = session->sessionHandle; + authCmd.sessionAttributes = session->sessionAttributes; + authCmd.nonce.size = session->nonceCaller.size; + XMEMCPY(authCmd.nonce.buffer, session->nonceCaller.buffer, + authCmd.nonce.size); + authCmd.hmac.size = session->auth.size; + + /* Password Auth */ + if (session->sessionHandle == TPM_RS_PW) { + XMEMCPY(authCmd.hmac.buffer, session->auth.buffer, + session->auth.size); + } + /* HMAC or Policy Session */ + else if (TPM2_IS_HMAC_SESSION(session->sessionHandle) || + TPM2_IS_POLICY_SESSION(session->sessionHandle)) { #ifndef WOLFTPM2_NO_WOLFCRYPT TPM2B_NAME name1, name2, name3; @@ -240,14 +252,14 @@ static int TPM2_CommandProcess(TPM2_CTX* ctx, TPM2_Packet* packet, #endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_HMAC */ } - /* Replace auth in session */ + /* Place session auth */ packet->pos = authPos; TPM2_Packet_AppendAuthCmd(packet, &authCmd); authPos = packet->pos; /* update auth position */ } - /* Update the Auth Area size in the command packet */ - TPM2_Packet_PlaceU32(packet, tmpSz); + /* Update the Auth Area total size in the command packet */ + TPM2_Packet_PlaceU32(packet, authTotalSzPos); (void)cmdCode; return rc; diff --git a/src/tpm2_packet.c b/src/tpm2_packet.c index 6d1f22b4..b2070ec0 100644 --- a/src/tpm2_packet.c +++ b/src/tpm2_packet.c @@ -251,18 +251,14 @@ void TPM2_Packet_PlaceU32(TPM2_Packet* packet, int markSz) void TPM2_Packet_AppendAuthCmd(TPM2_Packet* packet, TPMS_AUTH_COMMAND* authCmd) { - if (packet == NULL || authCmd == NULL) + 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 && - (authCmd->sessionAttributes & TPMA_SESSION_continueSession) == 0) { - authCmd->sessionAttributes |= TPMA_SESSION_continueSession; - } TPM2_Packet_AppendU32(packet, authCmd->sessionHandle); TPM2_Packet_AppendU16(packet, authCmd->nonce.size); TPM2_Packet_AppendBytes(packet, authCmd->nonce.buffer, authCmd->nonce.size); @@ -347,15 +343,55 @@ TPM_ST TPM2_Packet_AppendAuth(TPM2_Packet* packet, TPM2_CTX* ctx, CmdInfo_t* inf info->authCnt = TPM2_GetCmdAuthCount(ctx, info); if (info->authCnt > 0) { - int i, tmpSz = 0; - TPM2_Packet_MarkU32(packet, &tmpSz); + int i, authTotalSzPos = 0; + TPM2_Packet_MarkU32(packet, &authTotalSzPos); for (i=0; iauthCnt; i++) { - /* Note: Casting a TPM2_AUTH_SESSION to TPMS_AUTH_COMMAND here, - * this is allowed because top of structure matches */ - TPM2_Packet_AppendAuthCmd(packet, (TPMS_AUTH_COMMAND*)&ctx->session[i]); + TPM2_AUTH_SESSION* session = &ctx->session[i]; + + /* Determine auth size - appended later in TPM2_CommandProcess */ + + /* sessionHandle */ + packet->pos += sizeof(UINT32); + + /* Nonce size: + * Determined by us and TPM matches it on reply + * Typically use SHA2-256 digest size (16 bytes). The random nonce + * is populated in TPM2_CommandProcess */ + packet->pos += sizeof(UINT16); /* nonceSz */ + if (session->sessionHandle != TPM_RS_PW) { + session->nonceCaller.size = + TPM2_GetHashDigestSize(WOLFTPM2_WRAP_DIGEST); + packet->pos += session->nonceCaller.size; + } + + /* sessionAttributes */ + packet->pos += sizeof(UINT8); + if (session->sessionHandle == TPM_RS_PW) { + /* make sure continueSession is set for TPM_RS_PW */ + session->sessionAttributes |= TPMA_SESSION_continueSession; + } + + /* Password Auth */ + packet->pos += sizeof(UINT16); /* hmac.size */ + if (session->sessionHandle == TPM_RS_PW) { + packet->pos += session->auth.size; + } + /* HMAC or Policy Session */ + else if ((session->sessionHandle != TPM_RS_PW && + ((session->sessionAttributes & TPMA_SESSION_encrypt) || + (session->sessionAttributes & TPMA_SESSION_decrypt))) + || TPM2_IS_POLICY_SESSION(session->sessionHandle)) + { + if (session->auth.size == 0) { + /* default is a HMAC output (using alg authHash) */ + session->auth.size = + TPM2_GetHashDigestSize(session->authHash); + } + packet->pos += session->auth.size; + } } /* based on position difference places calculated size at marked U32 above */ - TPM2_Packet_PlaceU32(packet, tmpSz); + TPM2_Packet_PlaceU32(packet, authTotalSzPos); st = TPM_ST_SESSIONS; } return st; diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 9f77e322..b9ecba18 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -962,7 +962,7 @@ int wolfTPM2_SetAuthHandleName(WOLFTPM2_DEV* dev, int index, name = &handle->name; session = &dev->session[index]; - if (session->auth.size == 0 && handle->auth.size > 0) { + if (session->sessionHandle == TPM_RS_PW && handle->auth.size > 0) { session->auth.size = handle->auth.size; XMEMCPY(session->auth.buffer, handle->auth.buffer, handle->auth.size); } @@ -1000,24 +1000,11 @@ int wolfTPM2_SetAuthSession(WOLFTPM2_DEV* dev, int index, XMEMCPY(&session->symmetric, &tpmSession->handle.symmetric, sizeof(TPMT_SYM_DEF)); - /* fresh nonce generated in TPM2_CommandProcess based on this size */ - session->nonceCaller.size = TPM2_GetHashDigestSize(WOLFTPM2_WRAP_DIGEST); - /* Capture TPM provided nonce */ session->nonceTPM.size = tpmSession->nonceTPM.size; XMEMCPY(session->nonceTPM.buffer, tpmSession->nonceTPM.buffer, session->nonceTPM.size); - /* Parameter Encryption or Policy 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))) - || TPM2_IS_POLICY_SESSION(session->sessionHandle)) - { - session->auth.size = TPM2_GetHashDigestSize(session->authHash); - } } return rc; } diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 8332b253..74dcbc84 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -1621,13 +1621,11 @@ typedef struct TPMS_AUTH_RESPONSE { /* Implementation specific authorization session information */ typedef struct TPM2_AUTH_SESSION { - /* BEGIN */ - /* This section should match TPMS_AUTH_COMMAND */ + /* this section is used for TPMS_AUTH_COMMAND */ TPMI_SH_AUTH_SESSION sessionHandle; TPM2B_NONCE nonceCaller; TPMA_SESSION sessionAttributes; TPM2B_AUTH auth; - /* END */ /* additional auth data required for implementation */ TPM2B_NONCE nonceTPM; diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index 629f240d..a9807f56 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -31,10 +31,12 @@ typedef struct WOLFTPM2_HANDLE { TPM_HANDLE hndl; - TPM2B_AUTH auth; /* Used if policyAuth is not set */ + TPM2B_AUTH auth; TPMT_SYM_DEF symmetric; TPM2B_NAME name; - int policyAuth; /* Handle requires Policy, not password Auth */ + + /* bit-fields */ + unsigned int policyAuth : 1; /* Handle requires policy auth */ unsigned int nameLoaded : 1; /* flag to indicate if "name" was loaded and computed */ } WOLFTPM2_HANDLE;