diff --git a/src/tpm2/crypto/CryptSym.h b/src/tpm2/crypto/CryptSym.h index 2fab5178..66cfb977 100644 --- a/src/tpm2/crypto/CryptSym.h +++ b/src/tpm2/crypto/CryptSym.h @@ -3,7 +3,7 @@ /* Implementation of the symmetric block cipher modes */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ -/* $Id: CryptSym.h 1618 2020-05-19 15:28:41Z kgoldman $ */ +/* $Id: CryptSym.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, 2017 - 2019 */ +/* (c) Copyright IBM Corp. and others, 2017 - 2021 */ /* */ /********************************************************************************/ @@ -63,19 +63,47 @@ #ifndef CRYPTSYM_H #define CRYPTSYM_H -typedef union tpmCryptKeySchedule_t { #if ALG_AES - tpmKeyScheduleAES AES; +# define IF_IMPLEMENTED_AES(op) op(AES, aes) +#else +# define IF_IMPLEMENTED_AES(op) #endif #if ALG_SM4 - tpmKeyScheduleSM4 SM4; +# define IF_IMPLEMENTED_SM4(op) op(SM4, sm4) +#else +# define IF_IMPLEMENTED_SM4(op) #endif #if ALG_CAMELLIA - tpmKeyScheduleCAMELLIA CAMELLIA; +# define IF_IMPLEMENTED_CAMELLIA(op) op(CAMELLIA, camellia) +#else +# define IF_IMPLEMENTED_CAMELLIA(op) #endif #if ALG_TDES - tpmKeyScheduleTDES TDES[3]; +# define IF_IMPLEMENTED_TDES(op) op(TDES, tdes) +#else +# define IF_IMPLEMENTED_TDES(op) #endif + +#define FOR_EACH_SYM(op) \ + IF_IMPLEMENTED_AES(op) \ + IF_IMPLEMENTED_SM4(op) \ + IF_IMPLEMENTED_CAMELLIA(op) \ + IF_IMPLEMENTED_TDES(op) + + /* libtpms added begin */ +#define FOR_EACH_SYM_WITHOUT_TDES(op) \ + IF_IMPLEMENTED_AES(op) \ + IF_IMPLEMENTED_SM4(op) \ + IF_IMPLEMENTED_CAMELLIA(op) /* libtpms added end */ + +/* Macros for creating the key schedule union */ + +#define KEY_SCHEDULE(SYM, sym) tpmKeySchedule##SYM sym; +//#define TDES DES[3] /* libtpms commented */ +typedef union tpmCryptKeySchedule_t { + FOR_EACH_SYM_WITHOUT_TDES(KEY_SCHEDULE) /* libtpms changed from FOR_EACH_SYM */ + tpmKeyScheduleTDES tdes[3]; /* libtpms added */ + #if SYMMETRIC_ALIGNMENT == 8 uint64_t alignment; #else @@ -99,53 +127,16 @@ typedef union tpmCryptKeySchedule_t { /* Note that the macros rely on encrypt as local values in the functions that use these macros. Those parameters are set by the macro that set the key schedule to be used for the call. */ -#define ENCRYPT_CASE(ALG) \ + +#define ENCRYPT_CASE(ALG, alg) \ case TPM_ALG_##ALG: \ - TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.ALG); \ + TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.alg); \ encrypt = (TpmCryptSetSymKeyCall_t)TpmCryptEncrypt##ALG; \ break; -#define DECRYPT_CASE(ALG) \ +#define DECRYPT_CASE(ALG, alg) \ case TPM_ALG_##ALG: \ - TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.ALG); \ + TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.alg); \ decrypt = (TpmCryptSetSymKeyCall_t)TpmCryptDecrypt##ALG; \ break; -#if ALG_AES -#define ENCRYPT_CASE_AES ENCRYPT_CASE(AES) -#define DECRYPT_CASE_AES DECRYPT_CASE(AES) -#else -#define ENCRYPT_CASE_AES -#define DECRYPT_CASE_AES -#endif -#if ALG_SM4 -#define ENCRYPT_CASE_SM4 ENCRYPT_CASE(SM4) -#define DECRYPT_CASE_SM4 DECRYPT_CASE(SM4) -#else -#define ENCRYPT_CASE_SM4 -#define DECRYPT_CASE_SM4 -#endif -#if ALG_CAMELLIA -#define ENCRYPT_CASE_CAMELLIA ENCRYPT_CASE(CAMELLIA) -#define DECRYPT_CASE_CAMELLIA DECRYPT_CASE(CAMELLIA) -#else -#define ENCRYPT_CASE_CAMELLIA -#define DECRYPT_CASE_CAMELLIA -#endif -#if ALG_TDES -#define ENCRYPT_CASE_TDES ENCRYPT_CASE(TDES) -#define DECRYPT_CASE_TDES DECRYPT_CASE(TDES) -#else -#define ENCRYPT_CASE_TDES -#define DECRYPT_CASE_TDES -#endif -/* For each algorithm the case will either be defined or null. */ -#define SELECT(direction) \ - switch(algorithm) \ - { \ - direction##_CASE_AES \ - direction##_CASE_SM4 \ - direction##_CASE_CAMELLIA \ - direction##_CASE_TDES \ - default: \ - FAIL(FATAL_ERROR_INTERNAL); \ - } + #endif diff --git a/src/tpm2/crypto/openssl/CryptCmac.c b/src/tpm2/crypto/openssl/CryptCmac.c index 76f95762..0461e788 100644 --- a/src/tpm2/crypto/openssl/CryptCmac.c +++ b/src/tpm2/crypto/openssl/CryptCmac.c @@ -3,7 +3,7 @@ /* Message Authentication Codes Based on a Symmetric Block Cipher */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ -/* $Id: CryptCmac.c 1490 2019-07-26 21:13:22Z kgoldman $ */ +/* $Id: CryptCmac.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, 2018 */ +/* (c) Copyright IBM Corp. and others, 2018 - 2021 */ /* */ /********************************************************************************/ @@ -122,7 +122,13 @@ CryptCmacData( TpmCryptSetSymKeyCall_t encrypt; // memset(&keySchedule, 0, sizeof(keySchedule)); /* libtpms added: coverity */ - SELECT(ENCRYPT); + // Set up the encryption values based on the algorithm + switch (algorithm) + { + FOR_EACH_SYM(ENCRYPT_CASE) + default: + FAIL(FATAL_ERROR_INTERNAL); + } while(size > 0) { if(cmacState->bcount == cmacState->iv.t.size) @@ -163,7 +169,13 @@ CryptCmacEnd( subkey.t.size = cState->iv.t.size; // Encrypt a block of zero - SELECT(ENCRYPT); + // Set up the encryption values based on the algorithm + switch (algorithm) + { + FOR_EACH_SYM(ENCRYPT_CASE) + default: + return 0; + } ENCRYPT(&keySchedule, subkey.t.buffer, subkey.t.buffer); // shift left by 1 and XOR with 0x0...87 if the MSb was 0 diff --git a/src/tpm2/crypto/openssl/CryptSym.c b/src/tpm2/crypto/openssl/CryptSym.c index 44291b78..c8a0497f 100644 --- a/src/tpm2/crypto/openssl/CryptSym.c +++ b/src/tpm2/crypto/openssl/CryptSym.c @@ -3,7 +3,7 @@ /* Symmetric block cipher modes */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ -/* $Id: CryptSym.c 1594 2020-03-26 22:15:48Z kgoldman $ */ +/* $Id: CryptSym.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 */ /* */ /********************************************************************************/ @@ -74,18 +74,8 @@ #define KEY_BLOCK_SIZES(ALG, alg) \ static const INT16 alg##KeyBlockSizes[] = { \ ALG##_KEY_SIZES_BITS, -1, ALG##_BLOCK_SIZES }; -#if ALG_AES -KEY_BLOCK_SIZES(AES, aes); -#endif // ALG_AES -#if ALG_SM4 -KEY_BLOCK_SIZES(SM4, sm4); -#endif -#if ALG_CAMELLIA -KEY_BLOCK_SIZES(CAMELLIA, camellia); -#endif -#if ALG_TDES -KEY_BLOCK_SIZES(TDES, tdes); -#endif + +FOR_EACH_SYM(KEY_BLOCK_SIZES) /* 10.2.19.3 Initialization and Data Access Functions */ /* 10.2.19.3.1 CryptSymInit() */ @@ -126,21 +116,18 @@ CryptGetSymmetricBlockSize( { const INT16 *sizes; INT16 i; +#if 0 // libtpms added #define ALG_CASE(SYM, sym) case TPM_ALG_##SYM: sizes = sym##KeyBlockSizes; break +#endif // libtpms added switch(symmetricAlg) { -#if ALG_AES - ALG_CASE(AES, aes); -#endif -#if ALG_SM4 - ALG_CASE(SM4, sm4); -#endif -#if ALG_CAMELLIA - ALG_CASE(CAMELLIA, camellia); -#endif -#if ALG_TDES - ALG_CASE(TDES, tdes); -#endif +#define GET_KEY_BLOCK_POINTER(SYM, sym) \ + case TPM_ALG_##SYM: \ + sizes = sym##KeyBlockSizes; \ + break; + // Get the pointer to the block size array + FOR_EACH_SYM(GET_KEY_BLOCK_POINTER); + default: return 0; } @@ -191,6 +178,7 @@ CryptSymmetricEncrypt( BYTE *iv; BYTE defaultIv[MAX_SYM_BLOCK_SIZE] = {0}; // + memset(&keySchedule, 0, sizeof(keySchedule)); // libtpms added; coverity pAssert(dOut != NULL && key != NULL && dIn != NULL); if(dSize == 0) return TPM_RC_SUCCESS; @@ -210,7 +198,13 @@ CryptSymmetricEncrypt( iv = defaultIv; pIv = iv; // Create encrypt key schedule and set the encryption function pointer. - SELECT(ENCRYPT); + switch (algorithm) + { + FOR_EACH_SYM(ENCRYPT_CASE) + + default: + return TPM_RC_SYMMETRIC; + } switch(mode) { #if ALG_CTR @@ -333,6 +327,8 @@ CryptSymmetricDecrypt( TpmCryptSetSymKeyCall_t encrypt; TpmCryptSetSymKeyCall_t decrypt; BYTE defaultIv[MAX_SYM_BLOCK_SIZE] = {0}; + + memset(&keySchedule, 0, sizeof(keySchedule)); // libtpms added; coverity // These are used but the compiler can't tell because they are initialized // in case statements and it can't tell if they are always initialized // when needed, so... Comment these out if the compiler can tell or doesn't @@ -369,13 +365,22 @@ CryptSymmetricDecrypt( // cipher block size if((dSize % blockSize) != 0) return TPM_RC_SIZE; - SELECT(DECRYPT); + switch (algorithm) + { + FOR_EACH_SYM(DECRYPT_CASE) + default: + return TPM_RC_SYMMETRIC; + } break; #endif default: // For the remaining stream ciphers, use encryption to decrypt - SELECT(ENCRYPT); - break; + switch (algorithm) + { + FOR_EACH_SYM(ENCRYPT_CASE) + default: + return TPM_RC_SYMMETRIC; + } } // Now do the mode-dependent decryption switch(mode) @@ -485,12 +490,12 @@ static void TDES_CTR(const BYTE *key, // IN BYTE *pT; TDES_set_encrypt_key(key, keySizeInBits, - (tpmKeyScheduleTDES *)&keySchedule.TDES); + (tpmKeyScheduleTDES *)&keySchedule.tdes); for(; dSize > 0; dSize -= blockSize) { // Encrypt the current value of the IV(counter) - TDES_encrypt(iv, tmp, (tpmKeyScheduleTDES *)&keySchedule.TDES); + TDES_encrypt(iv, tmp, (tpmKeyScheduleTDES *)&keySchedule.tdes); //increment the counter (counter is big-endian so start at end) for(i = blockSize - 1; i >= 0; i--) if((iv[i] += 1) != 0)