rev164: Introduce FOR_EACH_SYM and use it

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2021-02-22 19:33:10 -05:00 committed by Stefan Berger
parent 941c8ebdc8
commit cc2accea2b
3 changed files with 94 additions and 86 deletions

View File

@ -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

View File

@ -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

View File

@ -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)