mirror of
https://github.com/stefanberger/libtpms
synced 2026-01-11 16:51:29 +00:00
rev164: Introduce FOR_EACH_SYM and use it
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
parent
941c8ebdc8
commit
cc2accea2b
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user