diff --git a/src/tpm2/AlgorithmTests.c b/src/tpm2/AlgorithmTests.c index ae96494d..0098b1ec 100644 --- a/src/tpm2/AlgorithmTests.c +++ b/src/tpm2/AlgorithmTests.c @@ -108,36 +108,13 @@ TestHash( const TPM2B *testDigest = NULL; // TPM2B_TYPE(HMAC_BLOCK, DEFAULT_TEST_HASH_BLOCK_SIZE); pAssert(hashAlg != ALG_NULL_VALUE); +#define HASH_CASE_FOR_TEST(HASH, hash) case ALG_##HASH##_VALUE: \ + testDigest = &c_##HASH##_digest.b; \ + break; switch(hashAlg) { -#if ALG_SHA1 - case ALG_SHA1_VALUE: - testDigest = &c_SHA1_digest.b; - break; -#endif -#if ALG_SHA256 - case ALG_SHA256_VALUE: - testDigest = &c_SHA256_digest.b; - break; -#endif -#if ALG_SHA384 - case ALG_SHA384_VALUE: - testDigest = &c_SHA384_digest.b; - break; -#endif -#if ALG_SHA512 - case ALG_SHA512_VALUE: - testDigest = &c_SHA512_digest.b; - break; -#endif -#if ALG_SM3_256 - case ALG_SM3_256_VALUE: -#error Missing test case for SM3 // libtpms added - // There are currently no test vectors for SM3 - // testDigest = &c_SM3_256_digest.b; - testDigest = NULL; - break; -#endif + FOR_EACH_HASH(HASH_CASE_FOR_TEST) + default: FAIL(FATAL_ERROR_INTERNAL); } @@ -145,7 +122,7 @@ TestHash( CLEAR_BOTH(hashAlg); // If there is an algorithm without test vectors, then assume that things are OK. - if(testDigest == NULL) + if(testDigest == NULL || testDigest->size == 0) return TPM_RC_SUCCESS; // Set the HMAC key to twice the digest size @@ -920,25 +897,14 @@ TestAlgorithm( // tested because this uses HMAC SET_BOTH(DEFAULT_TEST_HASH); break; -#if ALG_SHA1 - case ALG_SHA1_VALUE: -#endif // TPM_ALG_SHA1 -#if ALG_SHA256 - case ALG_SHA256_VALUE: -#endif // TPM_ALG_SHA256 -#if ALG_SHA384 - case ALG_SHA384_VALUE: -#endif // TPM_ALG_SHA384 -#if ALG_SHA512 - case ALG_SHA512_VALUE: -#endif // TPM_ALG_SHA512 - // if SM3 is implemented its test is like any other hash, but there - // aren't any test vectors yet. -#if ALG_SM3_256 - // case ALG_SM3_256_VALUE: -#endif // TPM_ALG_SM3_256 - if(doTest) - result = TestHash(alg, toTest); + // Have to use two arguments for the macro even though only the first is used in the + // expansion. +#define HASH_CASE_TEST(HASH, hash) \ + case ALG_##HASH##_VALUE: + FOR_EACH_HASH(HASH_CASE_TEST) +#undef HASH_CASE_TEST + if(doTest) + result = TestHash(alg, toTest); break; // RSA-dependent #if ALG_RSA diff --git a/src/tpm2/Global.h b/src/tpm2/Global.h index 165a33e3..007b0a02 100644 --- a/src/tpm2/Global.h +++ b/src/tpm2/Global.h @@ -3,7 +3,7 @@ /* Internal Global Type Definitions */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ -/* $Id: Global.h 1600 2020-03-30 22:08:01Z kgoldman $ */ +/* $Id: Global.h 1658 2021-01-22 23:14:01Z kgoldman $ */ /* */ /* Licenses and Notices */ /* */ @@ -55,7 +55,7 @@ /* arising in any way out of use or reliance upon this specification or any */ /* information herein. */ /* */ -/* (c) Copyright IBM Corp. and others, 2016 - 2020 */ +/* (c) Copyright IBM Corp. and others, 2016 - 2021 */ /* */ /********************************************************************************/ @@ -418,23 +418,13 @@ typedef BYTE SESSION_BUF[sizeof(SESSION)]; static PCR are required to be saved across power cycles. The DRTM and resettable PCR are not saved. The number of static and resettable PCR is determined by the platform-specific specification to which the TPM is built. */ + +#define PCR_SAVE_SPACE(HASH, Hash) BYTE Hash[NUM_STATIC_PCR][HASH##_DIGEST_SIZE]; + typedef struct PCR_SAVE { -#if ALG_SHA1 - BYTE sha1[NUM_STATIC_PCR][SHA1_DIGEST_SIZE]; -#endif -#if ALG_SHA256 - BYTE sha256[NUM_STATIC_PCR][SHA256_DIGEST_SIZE]; -#endif -#if ALG_SHA384 - BYTE sha384[NUM_STATIC_PCR][SHA384_DIGEST_SIZE]; -#endif -#if ALG_SHA512 - BYTE sha512[NUM_STATIC_PCR][SHA512_DIGEST_SIZE]; -#endif -#if ALG_SM3_256 - BYTE sm3_256[NUM_STATIC_PCR][SM3_256_DIGEST_SIZE]; -#endif + FOR_EACH_HASH(PCR_SAVE_SPACE) + // This counter increments whenever the PCR are updated. // NOTE: A platform-specific specification may designate // certain PCR changes as not causing this counter @@ -1061,7 +1051,15 @@ typedef struct _COMMAND_FLAGS_ #endif /* libtpms added */ /* This structure is used to avoid having to manage a large number of parameters being passed - through various levels of the command input processing. */ + through various levels of the command input processing. + + The following macros are used to define the space for the CP and RP hashes. Space is provided + for each implemented hash algorithm because it is not known what the caller may use. +*/ + +#define CP_HASH(HASH, Hash) TPM2B_##HASH##_DIGEST Hash##CpHash; +#define RP_HASH(HASH, Hash) TPM2B_##HASH##_DIGEST Hash##RpHash; + typedef struct _COMMAND_ { TPM_ST tag; // the parsed command tag @@ -1079,26 +1077,8 @@ typedef struct _COMMAND_ // of authorizationSize field and should be zero when the authorizations are parsed. BYTE *parameterBuffer; // input to ExecuteCommand BYTE *responseBuffer; // input to ExecuteCommand -#if ALG_SHA1 - TPM2B_SHA1_DIGEST sha1CpHash; - TPM2B_SHA1_DIGEST sha1RpHash; -#endif -#if ALG_SHA256 - TPM2B_SHA256_DIGEST sha256CpHash; - TPM2B_SHA256_DIGEST sha256RpHash; -#endif -#if ALG_SHA384 - TPM2B_SHA384_DIGEST sha384CpHash; - TPM2B_SHA384_DIGEST sha384RpHash; -#endif -#if ALG_SHA512 - TPM2B_SHA512_DIGEST sha512CpHash; - TPM2B_SHA512_DIGEST sha512RpHash; -#endif -#if ALG_SM3_256 - TPM2B_SM3_256_DIGEST sm3_256CpHash; - TPM2B_SM3_256_DIGEST sm3_256RpHash; -#endif + FOR_EACH_HASH(CP_HASH) // space for the CP hashes + FOR_EACH_HASH(RP_HASH) // space for the RP hashes } COMMAND; // Global string constants for consistency in KDF function calls. These string constants are shared @@ -1256,28 +1236,14 @@ EXTERN OBJECT s_objects[MAX_LOADED_OBJECTS]; #if defined PCR_C || defined GLOBAL_C +/* The following macro is used to define the per-implemented-hash space. This implementation + reserves space for all implemented hashes. */ + +#define PCR_ALL_HASH(HASH, Hash) BYTE Hash##Pcr[HASH##_DIGEST_SIZE]; + typedef struct { -#if ALG_SHA1 - // SHA1 PCR - BYTE sha1Pcr[SHA1_DIGEST_SIZE]; -#endif -#if ALG_SHA256 - // SHA256 PCR - BYTE sha256Pcr[SHA256_DIGEST_SIZE]; -#endif -#if ALG_SHA384 - // SHA384 PCR - BYTE sha384Pcr[SHA384_DIGEST_SIZE]; -#endif -#if ALG_SHA512 - // SHA512 PCR - BYTE sha512Pcr[SHA512_DIGEST_SIZE]; -#endif -#if ALG_SM3_256 - // SHA256 PCR - BYTE sm3_256Pcr[SM3_256_DIGEST_SIZE]; -#endif + FOR_EACH_HASH(PCR_ALL_HASH) } PCR; typedef struct diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c index b8f31bde..b57f245e 100644 --- a/src/tpm2/NVMarshal.c +++ b/src/tpm2/NVMarshal.c @@ -733,45 +733,45 @@ PCR_SAVE_Marshal(PCR_SAVE *data, BYTE **buffer, INT32 *size) algid = TPM_ALG_SHA1; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sha1); + array_size = sizeof(data->Sha1); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sha1, array_size, + written += Array_Marshal((BYTE *)&data->Sha1, array_size, buffer, size); #endif #if ALG_SHA256 algid = TPM_ALG_SHA256; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sha256); + array_size = sizeof(data->Sha256); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sha256, array_size, + written += Array_Marshal((BYTE *)&data->Sha256, array_size, buffer, size); #endif #if ALG_SHA384 algid = TPM_ALG_SHA384; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sha384); + array_size = sizeof(data->Sha384); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sha384, array_size, + written += Array_Marshal((BYTE *)&data->Sha384, array_size, buffer, size); #endif #if ALG_SHA512 algid = TPM_ALG_SHA512; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sha512); + array_size = sizeof(data->Sha512); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sha512, array_size, + written += Array_Marshal((BYTE *)&data->Sha512, array_size, buffer, size); #endif #if ALG_SM3_256 algid = TPM_ALG_SM3_256; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sm3_256); + array_size = sizeof(data->Sm3_256); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sm3_256, array_size, + written += Array_Marshal((BYTE *)&data->Sm3_256, array_size, buffer, size); #endif #if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256 @@ -851,32 +851,32 @@ PCR_SAVE_Unmarshal(PCR_SAVE *data, BYTE **buffer, INT32 *size, switch (algid) { #if ALG_SHA1 case TPM_ALG_SHA1: - needed_size = sizeof(data->sha1); - t = (BYTE *)&data->sha1; + needed_size = sizeof(data->Sha1); + t = (BYTE *)&data->Sha1; break; #endif #if ALG_SHA256 case TPM_ALG_SHA256: - needed_size = sizeof(data->sha256); - t = (BYTE *)&data->sha256; + needed_size = sizeof(data->Sha256); + t = (BYTE *)&data->Sha256; break; #endif #if ALG_SHA384 case TPM_ALG_SHA384: - needed_size = sizeof(data->sha384); - t = (BYTE *)&data->sha384; + needed_size = sizeof(data->Sha384); + t = (BYTE *)&data->Sha384; break; #endif #if ALG_SHA512 case TPM_ALG_SHA512: - needed_size = sizeof(data->sha512); - t = (BYTE *)&data->sha512; + needed_size = sizeof(data->Sha512); + t = (BYTE *)&data->Sha512; break; #endif #if ALG_SM3_256 case TPM_ALG_SM3_256: - needed_size = sizeof(data->sm3_256); - t = (BYTE *)&data->sm3_256; + needed_size = sizeof(data->Sm3_256); + t = (BYTE *)&data->Sm3_256; break; #endif #if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256 @@ -949,45 +949,45 @@ PCR_Marshal(PCR *data, BYTE **buffer, INT32 *size) algid = TPM_ALG_SHA1; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sha1Pcr); + array_size = sizeof(data->Sha1Pcr); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sha1Pcr, array_size, + written += Array_Marshal((BYTE *)&data->Sha1Pcr, array_size, buffer, size); #endif #if ALG_SHA256 algid = TPM_ALG_SHA256; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sha256Pcr); + array_size = sizeof(data->Sha256Pcr); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sha256Pcr, array_size, + written += Array_Marshal((BYTE *)&data->Sha256Pcr, array_size, buffer, size); #endif #if ALG_SHA384 algid = TPM_ALG_SHA384; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sha384Pcr); + array_size = sizeof(data->Sha384Pcr); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sha384Pcr, array_size, + written += Array_Marshal((BYTE *)&data->Sha384Pcr, array_size, buffer, size); #endif #if ALG_SHA512 algid = TPM_ALG_SHA512; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sha512Pcr); + array_size = sizeof(data->Sha512Pcr); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sha512Pcr, array_size, + written += Array_Marshal((BYTE *)&data->Sha512Pcr, array_size, buffer, size); #endif #if ALG_SM3_256 algid = TPM_ALG_SM3_256; written += TPM_ALG_ID_Marshal(&algid, buffer, size); - array_size = sizeof(data->sm3_256Pcr); + array_size = sizeof(data->Sm3_256Pcr); written += UINT16_Marshal(&array_size, buffer, size); - written += Array_Marshal((BYTE *)&data->sm3_256Pcr, array_size, + written += Array_Marshal((BYTE *)&data->Sm3_256Pcr, array_size, buffer, size); #endif #if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256 @@ -1033,32 +1033,32 @@ PCR_Unmarshal(PCR *data, BYTE **buffer, INT32 *size, switch (algid) { #if ALG_SHA1 case TPM_ALG_SHA1: - needed_size = sizeof(data->sha1Pcr); - t = (BYTE *)&data->sha1Pcr; + needed_size = sizeof(data->Sha1Pcr); + t = (BYTE *)&data->Sha1Pcr; break; #endif #if ALG_SHA256 case TPM_ALG_SHA256: - needed_size = sizeof(data->sha256Pcr); - t = (BYTE *)&data->sha256Pcr; + needed_size = sizeof(data->Sha256Pcr); + t = (BYTE *)&data->Sha256Pcr; break; #endif #if ALG_SHA384 case TPM_ALG_SHA384: - needed_size = sizeof(data->sha384Pcr); - t = (BYTE *)&data->sha384Pcr; + needed_size = sizeof(data->Sha384Pcr); + t = (BYTE *)&data->Sha384Pcr; break; #endif #if ALG_SHA512 case TPM_ALG_SHA512: - needed_size = sizeof(data->sha512Pcr); - t = (BYTE *)&data->sha512Pcr; + needed_size = sizeof(data->Sha512Pcr); + t = (BYTE *)&data->Sha512Pcr; break; #endif #if ALG_SM3_256 case TPM_ALG_SM3_256: - needed_size = sizeof(data->sm3_256Pcr); - t = (BYTE *)&data->sm3_256Pcr; + needed_size = sizeof(data->Sm3_256Pcr); + t = (BYTE *)&data->Sm3_256Pcr; break; #endif #if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256 diff --git a/src/tpm2/PCR.c b/src/tpm2/PCR.c index b2d6f7f8..464d9c04 100644 --- a/src/tpm2/PCR.c +++ b/src/tpm2/PCR.c @@ -3,7 +3,7 @@ /* PCR access and manipulation */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ -/* $Id: PCR.c 1628 2020-05-27 19:35:29Z kgoldman $ */ +/* $Id: PCR.c 1658 2021-01-22 23:14:01Z kgoldman $ */ /* */ /* Licenses and Notices */ /* */ @@ -55,7 +55,7 @@ /* arising in any way out of use or reliance upon this specification or any */ /* information herein. */ /* */ -/* (c) Copyright IBM Corp. and others, 2016 - 2020 */ +/* (c) Copyright IBM Corp. and others, 2016 - 2021 */ /* */ /********************************************************************************/ @@ -288,31 +288,14 @@ GetSavedPcrPointer( BYTE *retVal; switch(alg) { -#if ALG_SHA1 - case TPM_ALG_SHA1: - retVal = gc.pcrSave.sha1[pcrIndex]; - break; -#endif -#if ALG_SHA256 - case TPM_ALG_SHA256: - retVal = gc.pcrSave.sha256[pcrIndex]; - break; -#endif -#if ALG_SHA384 - case TPM_ALG_SHA384: - retVal = gc.pcrSave.sha384[pcrIndex]; - break; -#endif -#if ALG_SHA512 - case TPM_ALG_SHA512: - retVal = gc.pcrSave.sha512[pcrIndex]; - break; -#endif -#if ALG_SM3_256 - case TPM_ALG_SM3_256: - retVal = gc.pcrSave.sm3_256[pcrIndex]; - break; -#endif +#define HASH_CASE(HASH, Hash) \ + case TPM_ALG_##HASH: \ + retVal = gc.pcrSave.Hash[pcrIndex]; \ + break; + + FOR_EACH_HASH(HASH_CASE) +#undef HASH_CASE + default: FAIL(FATAL_ERROR_INTERNAL); } @@ -367,31 +350,14 @@ GetPcrPointer( return NULL; switch(alg) { -#if ALG_SHA1 - case TPM_ALG_SHA1: - pcr = s_pcrs[pcrNumber].sha1Pcr; - break; -#endif -#if ALG_SHA256 - case TPM_ALG_SHA256: - pcr = s_pcrs[pcrNumber].sha256Pcr; - break; -#endif -#if ALG_SHA384 - case TPM_ALG_SHA384: - pcr = s_pcrs[pcrNumber].sha384Pcr; - break; -#endif -#if ALG_SHA512 - case TPM_ALG_SHA512: - pcr = s_pcrs[pcrNumber].sha512Pcr; - break; -#endif -#if ALG_SM3_256 - case TPM_ALG_SM3_256: - pcr = s_pcrs[pcrNumber].sm3_256Pcr; - break; -#endif +#define HASH_CASE(HASH, Hash) \ + case TPM_ALG_##HASH: \ + pcr = s_pcrs[pcrNumber].Hash##Pcr; \ + break; + + FOR_EACH_HASH(HASH_CASE) +#undef HASH_CASE + default: FAIL(FATAL_ERROR_INTERNAL); break; diff --git a/src/tpm2/SessionProcess.c b/src/tpm2/SessionProcess.c index 62cc1878..f8efc688 100644 --- a/src/tpm2/SessionProcess.c +++ b/src/tpm2/SessionProcess.c @@ -3,7 +3,7 @@ /* Process the Authorization Sessions */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ -/* $Id: SessionProcess.c 1594 2020-03-26 22:15:48Z kgoldman $ */ +/* $Id: SessionProcess.c 1658 2021-01-22 23:14:01Z kgoldman $ */ /* */ /* Licenses and Notices */ /* */ @@ -55,7 +55,7 @@ /* arising in any way out of use or reliance upon this specification or any */ /* information herein. */ /* */ -/* (c) Copyright IBM Corp. and others, 2016 - 2020 */ +/* (c) Copyright IBM Corp. and others, 2016 - 2021 */ /* */ /********************************************************************************/ @@ -502,26 +502,14 @@ ClearCpRpHashes( COMMAND *command ) { -#if ALG_SHA1 - command->sha1CpHash.t.size = 0; - command->sha1RpHash.t.size = 0; -#endif -#if ALG_SHA256 - command->sha256CpHash.t.size = 0; - command->sha256RpHash.t.size = 0; -#endif -#if ALG_SHA384 - command->sha384CpHash.t.size = 0; - command->sha384RpHash.t.size = 0; -#endif -#if ALG_SHA512 - command->sha512CpHash.t.size = 0; - command->sha512RpHash.t.size = 0; -#endif -#if ALG_SM3_256 - command->sm3_256CpHash.t.size = 0; - command->sm3_256RpHash.t.size = 0; -#endif + // The macros expand according to the implemented hash algorithms. An IDE may + // complain that COMMAND does not contain SHA1CpHash or SHA1RpHash because of the + // complexity of the macro expansion where the data space is defined; but, if SHA1 + // is implemented, it actually does and the compiler is happy. +#define CLEAR_CP_HASH(HASH, Hash) command->Hash##CpHash.b.size = 0; + FOR_EACH_HASH(CLEAR_CP_HASH) +#define CLEAR_RP_HASH(HASH, Hash) command->Hash##RpHash.b.size = 0; + FOR_EACH_HASH(CLEAR_RP_HASH) } /* 6.4.4.2 GetCpHashPointer() */ @@ -532,32 +520,27 @@ GetCpHashPointer( TPMI_ALG_HASH hashAlg ) { + TPM2B_DIGEST *retVal; + // + // Define the macro that will expand for each implemented algorithm in the switch + // statement below. +#define GET_CP_HASH_POINTER(HASH, Hash) \ + case ALG_##HASH##_VALUE: \ + retVal = (TPM2B_DIGEST *)&command->Hash##CpHash; \ + break; + switch(hashAlg) { -#if ALG_SHA1 - case TPM_ALG_SHA1: - return (TPM2B_DIGEST *)&command->sha1CpHash; -#endif -#if ALG_SHA256 - case TPM_ALG_SHA256: - return (TPM2B_DIGEST *)&command->sha256CpHash; -#endif -#if ALG_SHA384 - case TPM_ALG_SHA384: - return (TPM2B_DIGEST *)&command->sha384CpHash; -#endif -#if ALG_SHA512 - case TPM_ALG_SHA512: - return (TPM2B_DIGEST *)&command->sha512CpHash; -#endif -#if ALG_SM3_256 - case TPM_ALG_SM3_256: - return (TPM2B_DIGEST *)&command->sm3_256CpHash; -#endif + // For each implemented hash, this will expand as defined above + // by GET_CP_HASH_POINTER. Your IDE may complain that + // 'struct "COMMAND" has no field "SHA1CpHash"' but the compiler says + // it does, so... + FOR_EACH_HASH(GET_CP_HASH_POINTER) default: + retVal = NULL; break; } - return NULL; + return retVal; } /* 6.4.4.3 GetRpHashPointer() */ @@ -568,32 +551,27 @@ GetRpHashPointer( TPMI_ALG_HASH hashAlg ) { + TPM2B_DIGEST *retVal; + // + // Define the macro that will expand for each implemented algorithm in the switch + // statement below. +#define GET_RP_HASH_POINTER(HASH, Hash) \ + case ALG_##HASH##_VALUE: \ + retVal = (TPM2B_DIGEST *)&command->Hash##RpHash; \ + break; + switch(hashAlg) { -#if ALG_SHA1 - case TPM_ALG_SHA1: - return (TPM2B_DIGEST *)&command->sha1RpHash; -#endif -#if ALG_SHA256 - case TPM_ALG_SHA256: - return (TPM2B_DIGEST *)&command->sha256RpHash; -#endif -#if ALG_SHA384 - case TPM_ALG_SHA384: - return (TPM2B_DIGEST *)&command->sha384RpHash; -#endif -#if ALG_SHA512 - case TPM_ALG_SHA512: - return (TPM2B_DIGEST *)&command->sha512RpHash; -#endif -#if ALG_SM3_256 - case TPM_ALG_SM3_256: - return (TPM2B_DIGEST *)&command->sm3_256RpHash; -#endif + // For each implemented hash, this will expand as defined above + // by GET_RP_HASH_POINTER. Your IDE may complain that + // 'struct "COMMAND" has no field 'SHA1RpHash'" but the compiler says + // it does, so... + FOR_EACH_HASH(GET_RP_HASH_POINTER) default: + retVal = NULL; break; } - return NULL; + return retVal; } /* 6.4.4.4 ComputeCpHash() */ diff --git a/src/tpm2/crypto/CryptHash.h b/src/tpm2/crypto/CryptHash.h index 1c280aec..fee394f3 100644 --- a/src/tpm2/crypto/CryptHash.h +++ b/src/tpm2/crypto/CryptHash.h @@ -3,7 +3,7 @@ /* Hash structure definitions */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ -/* $Id: CryptHash.h 1594 2020-03-26 22:15:48Z kgoldman $ */ +/* $Id: CryptHash.h 1658 2021-01-22 23:14:01Z kgoldman $ */ /* */ /* Licenses and Notices */ /* */ @@ -55,7 +55,7 @@ /* arising in any way out of use or reliance upon this specification or any */ /* information herein. */ /* */ -/* (c) Copyright IBM Corp. and others, 2016 - 2020 */ +/* (c) Copyright IBM Corp. and others, 2016 - 2021 */ /* */ /********************************************************************************/ @@ -120,23 +120,64 @@ typedef struct SMAC_STATE { SMAC_METHODS smacMethods; SMAC_STATES state; } SMAC_STATE; -typedef union -{ + #if ALG_SHA1 - tpmHashStateSHA1_t Sha1; +# define IF_IMPLEMENTED_SHA1(op) op(SHA1, Sha1) +#else +# define IF_IMPLEMENTED_SHA1(op) #endif #if ALG_SHA256 - tpmHashStateSHA256_t Sha256; +# define IF_IMPLEMENTED_SHA256(op) op(SHA256, Sha256) +#else +# define IF_IMPLEMENTED_SHA256(op) #endif #if ALG_SHA384 - tpmHashStateSHA384_t Sha384; +# define IF_IMPLEMENTED_SHA384(op) op(SHA384, Sha384) +#else +# define IF_IMPLEMENTED_SHA384(op) #endif #if ALG_SHA512 - tpmHashStateSHA512_t Sha512; +# define IF_IMPLEMENTED_SHA512(op) op(SHA512, Sha512) +#else +# define IF_IMPLEMENTED_SHA512(op) #endif #if ALG_SM3_256 - tpmHashStateSM3_256_t Sm3_256; +# define IF_IMPLEMENTED_SM3_256(op) op(SM3_256, Sm3_256) +#else +# define IF_IMPLEMENTED_SM3_256(op) #endif +#if ALG_SHA3_256 +# define IF_IMPLEMENTED_SHA3_256(op) op(SHA3_256, Sha3_256) +#else +# define IF_IMPLEMENTED_SHA3_256(op) +#endif +#if ALG_SHA3_384 +# define IF_IMPLEMENTED_SHA3_384(op) op(SHA3_384, Sha3_384) +#else +# define IF_IMPLEMENTED_SHA3_384(op) +#endif +#if ALG_SHA3_512 +# define IF_IMPLEMENTED_SHA3_512(op) op(SHA3_512, Sha3_512) +#else +# define IF_IMPLEMENTED_SHA3_512(op) +#endif + +/* SHA512 added kgold */ +#define FOR_EACH_HASH(op) \ + IF_IMPLEMENTED_SHA1(op) \ + IF_IMPLEMENTED_SHA256(op) \ + IF_IMPLEMENTED_SHA384(op) \ + IF_IMPLEMENTED_SHA512(op) \ + IF_IMPLEMENTED_SM3_256(op) \ + IF_IMPLEMENTED_SHA3_256(op) \ + IF_IMPLEMENTED_SHA3_384(op) \ + IF_IMPLEMENTED_SHA3_512(op) + +#define HASH_TYPE(HASH, Hash) tpmHashState##HASH##_t Hash; + +typedef union +{ + FOR_EACH_HASH(HASH_TYPE) // Additions for symmetric block cipher MAC #if SMAC_IMPLEMENTED SMAC_STATE smac; @@ -201,21 +242,10 @@ typedef struct _HASH_METHODS HASH_STATE_IMPORT_METHOD *copyIn; // Copy a hash block to a proper hash // context } HASH_METHODS, *PHASH_METHODS; -#if ALG_SHA1 -TPM2B_TYPE(SHA1_DIGEST, SHA1_DIGEST_SIZE); -#endif -#if ALG_SHA256 -TPM2B_TYPE(SHA256_DIGEST, SHA256_DIGEST_SIZE); -#endif -#if ALG_SHA384 -TPM2B_TYPE(SHA384_DIGEST, SHA384_DIGEST_SIZE); -#endif -#if ALG_SHA512 -TPM2B_TYPE(SHA512_DIGEST, SHA512_DIGEST_SIZE); -#endif -#if ALG_SM3_256 -TPM2B_TYPE(SM3_256_DIGEST, SM3_256_DIGEST_SIZE); -#endif + +#define HASH_TPM2B(HASH, Hash) TPM2B_TYPE(HASH##_DIGEST, HASH##_DIGEST_SIZE); + +FOR_EACH_HASH(HASH_TPM2B) /* When the TPM implements RSA, the hash-dependent OID pointers are part of the HASH_DEF. These macros conditionally add the OID reference to the HASH_DEF and the HASH_DEF_TEMPLATE. */ diff --git a/src/tpm2/crypto/openssl/CryptHash.c b/src/tpm2/crypto/openssl/CryptHash.c index ae74564f..cb5bd0fb 100644 --- a/src/tpm2/crypto/openssl/CryptHash.c +++ b/src/tpm2/crypto/openssl/CryptHash.c @@ -3,7 +3,7 @@ /* Implementation of cryptographic functions for hashing. */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ -/* $Id: CryptHash.c 1594 2020-03-26 22:15:48Z kgoldman $ */ +/* $Id: CryptHash.c 1658 2021-01-22 23:14:01Z kgoldman $ */ /* */ /* Licenses and Notices */ /* */ @@ -55,7 +55,7 @@ /* arising in any way out of use or reliance upon this specification or any */ /* information herein. */ /* */ -/* (c) Copyright IBM Corp. and others, 2016 - 2020 */ +/* (c) Copyright IBM Corp. and others, 2016 - 2021 */ /* */ /********************************************************************************/ @@ -68,39 +68,21 @@ #include "CryptHash_fp.h" #include "CryptHash.h" #include "OIDs.h" -#define HASH_TABLE_SIZE (HASH_COUNT + 1) -#if ALG_SHA1 -HASH_DEF_TEMPLATE(SHA1, Sha1); -#endif -#if ALG_SHA256 -HASH_DEF_TEMPLATE(SHA256, Sha256); -#endif -#if ALG_SHA384 -HASH_DEF_TEMPLATE(SHA384, Sha384); -#endif -#if ALG_SHA512 -HASH_DEF_TEMPLATE(SHA512, Sha512); -#endif -#if ALG_SM3_256 -HASH_DEF_TEMPLATE(SM3_256, Sm3_256); -#endif -HASH_DEF NULL_Def = {{0}}; + +/* Instance each of the hash descriptors based on the implemented algorithms */ + +FOR_EACH_HASH(HASH_DEF_TEMPLATE) + +/* Instance a null def. */ + + HASH_DEF NULL_Def = {{0}}; + +/* Create a table of pointers to the defined hash definitions */ + +#define HASH_DEF_ENTRY(HASH, Hash) &Hash##_Def, PHASH_DEF HashDefArray[] = { -#if ALG_SHA1 - &Sha1_Def, -#endif -#if ALG_SHA256 - &Sha256_Def, -#endif -#if ALG_SHA384 - &Sha384_Def, -#endif -#if ALG_SHA512 - &Sha512_Def, -#endif -#if ALG_SM3_256 - &Sm3_256_Def, -#endif + // for each implemented HASH, expands to: &HASH_Def, + FOR_EACH_HASH(HASH_DEF_ENTRY) &NULL_Def }; @@ -139,15 +121,14 @@ CryptGetHashDef( TPM_ALG_ID hashAlg ) { - size_t i; -#define HASHES (sizeof(HashDefArray) / sizeof(PHASH_DEF)) - for(i = 0; i < HASHES; i++) +#define GET_DEF(HASH, Hash) case ALG_##HASH##_VALUE: return &Hash##_Def; + switch(hashAlg) { - PHASH_DEF p = HashDefArray[i]; - if(p->hashAlg == hashAlg) - return p; + FOR_EACH_HASH(GET_DEF) + default: + return &NULL_Def; } - return &NULL_Def; +#undef GET_DEF } /* 10.2.13.4.3 CryptHashIsValidAlg() */ /* This function tests to see if an algorithm ID is a valid hash algorithm. If flag is true, then