From a012348fe9cf60a82d4a5e79312c086fb20634f2 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 21 Aug 2024 11:23:58 -0700 Subject: [PATCH] Fixes for `TPM2_SetupPCRSel`. Added test cases. Fixes ZD 18492 --- src/tpm2.c | 21 ++++++++++++++--- tests/unit_tests.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++ wolftpm/tpm2.h | 19 ++++++++++------ 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/tpm2.c b/src/tpm2.c index d349221..53b7c4e 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -5650,6 +5650,7 @@ int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2 return TPM_RC_SUCCESS; } +/* Caller must zeroize/memset(0) pcr (TPML_PCR_SELECTION) */ void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, int pcrIndex) { int i = 0; @@ -5662,21 +5663,35 @@ void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, int pcrIndex) else { /* iterate over all banks until the alg matches */ for (i = 0; (word32)i < pcr->count; i++) { - if (pcr->pcrSelections[0].hash == alg) + if (pcr->pcrSelections[i].hash == alg) break; } /* if no match increase the number of banks */ - if ((word32)i >= pcr->count) + if ((word32)i >= pcr->count) { + if (pcr->count + 1 > HASH_COUNT) { + #ifdef DEBUG_WOLFTPM + printf("TPM2_SetupPCRSel: Hash algorithm count error\n"); + #endif + return; + } pcr->count++; + } } pcr->pcrSelections[i].hash = alg; pcr->pcrSelections[i].sizeofSelect = PCR_SELECT_MAX; - pcr->pcrSelections[i].pcrSelect[pcrIndex >> 3] = (1 << (pcrIndex & 0x7)); + pcr->pcrSelections[i].pcrSelect[pcrIndex >> 3] |= + (1 << (pcrIndex & 0x7)); } +#ifdef DEBUG_WOLFTPM + else { + printf("Invalid PCR Index %d\n", pcrIndex); + } +#endif } +/* Caller must zeroize/memset(0) pcr (TPML_PCR_SELECTION) */ void TPM2_SetupPCRSelArray(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, byte* pcrArray, word32 pcrArraySz) { diff --git a/tests/unit_tests.c b/tests/unit_tests.c index b0d2928..4a08e0b 100644 --- a/tests/unit_tests.c +++ b/tests/unit_tests.c @@ -241,6 +241,62 @@ static void test_wolfTPM2_GetRandom(void) rc == 0 ? "Passed" : "Failed"); } +static void test_TPM2_PCRSel(void) +{ + int rc = 0; + TPML_PCR_SELECTION pcr; + byte pcrArray[PCR_SELECT_MAX]; + word32 pcrArraySz; + + XMEMSET(&pcr, 0, sizeof(pcr)); + XMEMSET(pcrArray, 0, sizeof(pcrArray)); + + pcrArraySz = 0; + pcrArray[pcrArraySz++] = 1; + pcrArray[pcrArraySz++] = 2; + pcrArray[pcrArraySz++] = 3; + TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA, pcrArray, pcrArraySz); + + pcrArraySz = 0; + pcrArray[pcrArraySz++] = 4; + pcrArray[pcrArraySz++] = 5; + pcrArray[pcrArraySz++] = 6; + TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA256, pcrArray, pcrArraySz); + + if (pcr.count != 2 || + pcr.pcrSelections[0].hash != TPM_ALG_SHA || + pcr.pcrSelections[0].pcrSelect[0] != 0x0E || + pcr.pcrSelections[1].hash != TPM_ALG_SHA256 || + pcr.pcrSelections[1].pcrSelect[0] != 0x70 + ) { + rc = BAD_FUNC_ARG; + } + AssertIntEQ(rc, 0); + + /* Test bad case - invalid PCR */ + XMEMSET(&pcr, 0, sizeof(pcr)); + pcrArray[0] = PCR_SELECT_MAX+1; + TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA256, pcrArray, 1); + if (pcr.count != 0) { + rc = BAD_FUNC_ARG; + } + + /* Test bad case - too many hash algorithms */ + XMEMSET(&pcr, 0, sizeof(pcr)); + pcrArray[0] = 1; + TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA, pcrArray, 1); + pcrArray[0] = 2; + TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA256, pcrArray, 1); + pcrArray[0] = 3; + TPM2_SetupPCRSelArray(&pcr, TPM_ALG_SHA384, pcrArray, 1); + if (pcr.count != 2) { + rc = BAD_FUNC_ARG; + } + + printf("Test TPM Wrapper:\tPCR Select Array:\t%s\n", + rc == 0 ? "Passed" : "Failed"); +} + static void test_wolfTPM2_Cleanup(void) { int rc; @@ -603,6 +659,7 @@ int unit_tests(int argc, char *argv[]) test_wolfTPM2_OpenExisting(); test_wolfTPM2_GetCapabilities(); test_wolfTPM2_GetRandom(); + test_TPM2_PCRSel(); test_TPM2_KDFa(); test_wolfTPM2_ReadPublicKey(); test_wolfTPM2_CSR(); diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 474f1b9..e18c36f 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -3363,7 +3363,7 @@ WOLFTPM_API int TPM2_GetNonce(byte* nonceBuf, int nonceSz); \brief Helper function to prepare a correct PCR selection For example, when preparing to create a TPM2_Quote - \param pcr pointer to a structure of type TPML_PCR_SELECTION + \param pcr pointer to a structure of type TPML_PCR_SELECTION. Note: Caller must zeroize/memset(0) \param alg value of type TPM_ALG_ID specifying the type of hash algorithm used \param pcrIndex value between 0 and 23 specifying the PCR register for use @@ -3371,7 +3371,7 @@ WOLFTPM_API int TPM2_GetNonce(byte* nonceBuf, int nonceSz); \code int pcrIndex = 16; // This is a PCR register for DEBUG & testing purposes PCR_Read_In pcrRead; - + XMEMSET(&pcrRead, 0, sizeof(pcrRead)); TPM2_SetupPCRSel(&pcrRead.pcrSelectionIn, TPM_ALG_SHA256, pcrIndex); \endcode @@ -3388,17 +3388,22 @@ WOLFTPM_API void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, \brief Helper function to prepare a correct PCR selection with multiple indices For example, when preparing to create a TPM2_Quote - \param pcr pointer to a structure of type TPML_PCR_SELECTION + \param pcr pointer to a structure of type TPML_PCR_SELECTION. Note: Caller must zeroize/memset(0) \param alg value of type TPM_ALG_ID specifying the type of hash algorithm used \param pcrArray array of values between 0 and 23 specifying the PCR register for use - \param pcrArrayLen length of the pcrArray + \param pcrArraySz length of the pcrArray _Example_ \code - int pcrIndex = 16; // This is a PCR register for DEBUG & testing purposes PCR_Read_In pcrRead; + byte pcrArray[PCR_SELECT_MAX]; + word32 pcrArraySz = 0; - TPM2_SetupPCRSel(&pcrRead.pcrSelectionIn, TPM_ALG_SHA256, pcrIndex); + XMEMSET(&pcrRead, 0, sizeof(pcrRead)); + XMEMSET(pcrArray, 0, sizeof(pcrArray)); + pcrArray[pcrArraySz++] = 16; // This is a PCR register for DEBUG & testing purposes + + TPM2_SetupPCRSelArray(&pcrRead.pcrSelectionIn, TPM_ALG_SHA256, pcrArray, pcrArraySz); \endcode \sa TPM2_PCR_Read @@ -3407,7 +3412,7 @@ WOLFTPM_API void TPM2_SetupPCRSel(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, \sa TPM2_Quote */ WOLFTPM_API void TPM2_SetupPCRSelArray(TPML_PCR_SELECTION* pcr, TPM_ALG_ID alg, - byte* pcrArray, word32 pcrArrayLen); + byte* pcrArray, word32 pcrArraySz); /*! \ingroup TPM2_Proprietary