Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DO-NOT-MERGE: tpm2: Replace deprecated symmetric functions with EVP functions (OSSL 3) #349

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/tpm2/crypto/openssl/CryptCmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
#define _CRYPT_HASH_C_
#include "Tpm.h"
#include "CryptSym.h"
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include "Helpers_fp.h"
#endif
#if ALG_CMAC
/* 10.2.6.3 Functions */
/* 10.2.6.3.1 CryptCmacStart() */
Expand Down Expand Up @@ -118,6 +121,7 @@ CryptCmacData(
TPM_ALG_ID algorithm = cmacState->symAlg;
BYTE *key = cmacState->symKey.t.buffer;
UINT16 keySizeInBits = cmacState->keySizeBits;
#if OPENSSL_VERSION_NUMBER < 0x30000000L
tpmCryptKeySchedule_t keySchedule;
TpmCryptSetSymKeyCall_t encrypt;
TpmCryptSymFinal_t final; /* libtpms added */
Expand All @@ -130,11 +134,35 @@ CryptCmacData(
default:
FAIL(FATAL_ERROR_INTERNAL);
}
#else
const EVP_CIPHER *evp_cipher;
BYTE keyToUse[MAX_SYM_KEY_BYTES];
UINT16 keyToUseLen = (UINT16)sizeof(keyToUse);
EVP_CIPHER_CTX *ctx;
BYTE out[MAX_SYM_BLOCK_SIZE];
int inl;

evp_cipher = GetEVPCipher(algorithm, keySizeInBits, TPM_ALG_ECB, key,
keyToUse, &keyToUseLen);

if (!evp_cipher ||
(ctx = EVP_CIPHER_CTX_new()) == NULL ||
(inl = EVP_CIPHER_get_block_size(evp_cipher)) <= 0)
pAssert(false);
#endif

while(size > 0)
{
if(cmacState->bcount == cmacState->iv.t.size)
{
#if OPENSSL_VERSION_NUMBER < 0x30000000L
ENCRYPT(&keySchedule, cmacState->iv.t.buffer, cmacState->iv.t.buffer);
#else
if (DoEVPCryptOneBlock(ctx, evp_cipher, keyToUse, cmacState->iv.t.buffer,
inl, out, TRUE))
pAssert(false);
memcpy(cmacState->iv.t.buffer, out, inl);
#endif
cmacState->bcount = 0;
}
for(;(size > 0) && (cmacState->bcount < cmacState->iv.t.size);
Expand All @@ -143,8 +171,12 @@ CryptCmacData(
cmacState->iv.t.buffer[cmacState->bcount] ^= *buffer++;
}
}
#if OPENSSL_VERSION_NUMBER < 0x30000000L
if (final) // libtpms added begin
FINAL(&keySchedule); // libtpms added end
#else
EVP_CIPHER_CTX_free(ctx);
#endif
}

/* 10.2.6.3.3 CryptCmacEnd() */
Expand All @@ -163,24 +195,50 @@ CryptCmacEnd(
TPM_ALG_ID algorithm = cState->symAlg;
BYTE *key = cState->symKey.t.buffer;
UINT16 keySizeInBits = cState->keySizeBits;
#if OPENSSL_VERSION_NUMBER < 0x30000000L
tpmCryptKeySchedule_t keySchedule;
TpmCryptSetSymKeyCall_t encrypt;
TpmCryptSymFinal_t final; // libtpms added
#else
const EVP_CIPHER *evp_cipher;
BYTE keyToUse[MAX_SYM_KEY_BYTES];
UINT16 keyToUseLen = (UINT16)sizeof(keyToUse);
EVP_CIPHER_CTX *ctx;
BYTE out[MAX_SYM_BLOCK_SIZE];
int inl;
#endif
TPM2B_IV subkey = {{0, {0}}};
BOOL xorVal;
UINT16 i;
#if OPENSSL_VERSION_NUMBER < 0x30000000L
memset(&keySchedule, 0, sizeof(keySchedule)); /* libtpms added: coverity */
#endif

subkey.t.size = cState->iv.t.size;
// Encrypt a block of zero
// Set up the encryption values based on the algorithm
#if OPENSSL_VERSION_NUMBER < 0x30000000L
switch (algorithm)
{
FOR_EACH_SYM(ENCRYPT_CASE)
default:
return 0;
}
ENCRYPT(&keySchedule, subkey.t.buffer, subkey.t.buffer);
#else
evp_cipher = GetEVPCipher(algorithm, keySizeInBits, TPM_ALG_ECB, key,
keyToUse, &keyToUseLen);

if (!evp_cipher ||
(ctx = EVP_CIPHER_CTX_new()) == NULL ||
(inl = EVP_CIPHER_get_block_size(evp_cipher)) <= 0)
pAssert(false);

if (DoEVPCryptOneBlock(ctx, evp_cipher, keyToUse, subkey.t.buffer, inl,
out, TRUE))
pAssert(false);
memcpy(subkey.t.buffer, out, inl);
#endif

// shift left by 1 and XOR with 0x0...87 if the MSb was 0
xorVal = ((subkey.t.buffer[0] & 0x80) == 0) ? 0 : 0x87;
Expand All @@ -204,12 +262,23 @@ CryptCmacEnd(
// XOR the subkey into the IV
for(i = 0; i < subkey.t.size; i++)
cState->iv.t.buffer[i] ^= subkey.t.buffer[i];
#if OPENSSL_VERSION_NUMBER < 0x30000000L
ENCRYPT(&keySchedule, cState->iv.t.buffer, cState->iv.t.buffer);
#else
if (DoEVPCryptOneBlock(ctx, evp_cipher, keyToUse, cState->iv.t.buffer, inl,
out, TRUE))
pAssert(false);
memcpy(cState->iv.t.buffer, out, inl);
#endif
i = (UINT16)MIN(cState->iv.t.size, outSize);
MemoryCopy(outBuffer, cState->iv.t.buffer, i);

#if OPENSSL_VERSION_NUMBER < 0x30000000L
if (final) // libtpms added begin
FINAL(&keySchedule); // libtpms added end
#else
EVP_CIPHER_CTX_free(ctx);
#endif
return i;
}

Expand Down
8 changes: 8 additions & 0 deletions src/tpm2/crypto/openssl/CryptSym.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,18 +494,26 @@ static void TDES_CTR(const BYTE *key, // IN
INT16 blockSize // IN
)
{
#if OPENSSL_VERSION_NUMBER < 0x30000000L
tpmCryptKeySchedule_t keySchedule;
#endif
int i;
BYTE tmp[MAX_SYM_BLOCK_SIZE];
BYTE *pT;

#if OPENSSL_VERSION_NUMBER < 0x30000000L
TDES_set_encrypt_key(key, keySizeInBits,
(tpmKeyScheduleTDES *)&keySchedule.tdes);
#endif

for(; dSize > 0; dSize -= blockSize)
{
// Encrypt the current value of the IV(counter)
#if OPENSSL_VERSION_NUMBER < 0x30000000L
TDES_encrypt(iv, tmp, (tpmKeyScheduleTDES *)&keySchedule.tdes);
#else
TDES_crypt(key, keySizeInBits, iv, tmp, TRUE);
#endif
//increment the counter (counter is big-endian so start at end)
for(i = blockSize - 1; i >= 0; i--)
if((iv[i] += 1) != 0)
Expand Down
77 changes: 55 additions & 22 deletions src/tpm2/crypto/openssl/Helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,32 @@ OpenSSLCryptGenerateKeyDes(
return retVal;
}

TPM_RC DoEVPGetIV(
EVP_CIPHER_CTX *ctx, // IN: required context
unsigned char *iv, // IN: pointer to buffer for IV
size_t iv_len // IN: size of the buffer
)
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PARAM params[] = {
OSSL_PARAM_octet_ptr(OSSL_CIPHER_PARAM_UPDATED_IV, &iv, iv_len),
OSSL_PARAM_END
};
if (EVP_CIPHER_CTX_get_params(ctx, params) != 1)
return TPM_RC_FAILURE;
#else
const unsigned char *c_iv;

c_iv = EVP_CIPHER_CTX_iv(ctx);
if (!c_iv)
return TPM_RC_FAILURE;
memcpy(iv, c_iv, iv_len);
#endif // OPENSSL_VERSION_NUMBER

return 0;
}

#endif // USE_OPENSSL_FUNCTIONS_SYMMETRIC

#define __NUM_ALGS 4 /* AES, TDES, Camellia, SM4 */
#define __NUM_MODES 5 /* CTR, OFB, CBC, CFB, ECB */
Expand Down Expand Up @@ -339,33 +365,40 @@ GetEVPCipher(TPM_ALG_ID algorithm, // IN
return GetCachedEVPCipher(evpfn, algIdx, mode, i);
}

TPM_RC DoEVPGetIV(
EVP_CIPHER_CTX *ctx, // IN: required context
unsigned char *iv, // IN: pointer to buffer for IV
size_t iv_len // IN: size of the buffer
)
TPM_RC
DoEVPCryptOneBlock(
EVP_CIPHER_CTX *ctx, // IN: optional context
const EVP_CIPHER *evp_cipher, // IN: EVP_CIPHER to use
const BYTE *key, // IN: key whose size is suitable for evpfn
const BYTE *in, // IN: input block
int inl, // IN: size of input block in bytes
BYTE *out, // OUT: output block; must be different memory than in
BOOL encrypt // IN: encrypto (TRUE) or decrypt (FALSE)
)
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PARAM params[] = {
OSSL_PARAM_octet_ptr(OSSL_CIPHER_PARAM_UPDATED_IV, &iv, iv_len),
OSSL_PARAM_END
};
if (EVP_CIPHER_CTX_get_params(ctx, params) != 1)
return TPM_RC_FAILURE;
#else
const unsigned char *c_iv;
EVP_CIPHER_CTX *l_ctx = NULL;
TPM_RC retVal = 0;
int outlen1 = 0;
int outlen2 = 0;

l_ctx = ctx ? ctx : EVP_CIPHER_CTX_new();
if (!l_ctx)
ERROR_RETURN(TPM_RC_MEMORY);

if (EVP_CipherInit(l_ctx, evp_cipher, key, NULL, encrypt) != 1 ||
EVP_CIPHER_CTX_set_padding(l_ctx, 0) != 1 ||
EVP_CipherUpdate(l_ctx, out, &outlen1, in, inl) != 1 ||
EVP_CipherFinal_ex(l_ctx, out + outlen1, &outlen2) != 1 ||
outlen1 + outlen2 != inl)
ERROR_RETURN(TPM_RC_FAILURE);

c_iv = EVP_CIPHER_CTX_iv(ctx);
if (!c_iv)
return TPM_RC_FAILURE;
memcpy(iv, c_iv, iv_len);
#endif // OPENSSL_VERSION_NUMBER
Exit:
if (!ctx)
EVP_CIPHER_CTX_free(l_ctx);

return 0;
return retVal;
}

#endif // USE_OPENSSL_FUNCTIONS_SYMMETRIC

#if USE_OPENSSL_FUNCTIONS_EC
BOOL
OpenSSLEccGetPrivate(
Expand Down
27 changes: 20 additions & 7 deletions src/tpm2/crypto/openssl/Helpers_fp.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ OpenSSLCryptGenerateKeyDes(
TPMT_SENSITIVE *sensitive // OUT: sensitive area
);

TPM_RC DoEVPGetIV(
EVP_CIPHER_CTX *ctx, // IN: required context
unsigned char *iv, // IN: pointer to buffer for IV
size_t iv_len // IN: size of the buffer
);
#endif

/* The following functions to support symmetric crypto using
OpenSSL are needed for CMAC for example */

const EVP_CIPHER *GetEVPCipher(TPM_ALG_ID algorithm, // IN
UINT16 keySizeInBits, // IN
TPM_ALG_ID mode, // IN
Expand All @@ -79,13 +89,16 @@ const EVP_CIPHER *GetEVPCipher(TPM_ALG_ID algorithm, // IN
UINT16 *keyToUseLen // IN/OUT
);

TPM_RC DoEVPGetIV(
EVP_CIPHER_CTX *ctx, // IN: required context
unsigned char *iv, // IN: pointer to buffer for IV
size_t iv_len // IN: size of the buffer
);

#endif
TPM_RC
DoEVPCryptOneBlock(
EVP_CIPHER_CTX *ctx, // IN: optional context
const EVP_CIPHER *evp_cipher, // IN: crypto function
const BYTE *key, // IN: key whose size is suitable for evpfn
const BYTE *in, // IN: input block
int inl, // IN: size of input block in bytes
BYTE *out, // OUT: output block; must be different memory than in
BOOL encrypt // IN: encrypto (TRUE) or decrypt (FALSE)
);

#if USE_OPENSSL_FUNCTIONS_EC
BOOL OpenSSLEccGetPrivate(
Expand Down
27 changes: 27 additions & 0 deletions src/tpm2/crypto/openssl/TpmToOsslDesSupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
library. */
/* B.2.3.1.2. Defines and Includes */
#include "Tpm.h"
#include "Helpers_fp.h" // libtpms added
#if (defined SYM_LIB_OSSL) && ALG_TDES
/* B.2.3.1.3. Functions */
/* B.2.3.1.3.1. TDES_set_encyrpt_key() */
Expand Down Expand Up @@ -101,6 +102,7 @@ void TDES_encrypt(
&ks[0], &ks[1], &ks[2],
DES_ENCRYPT);
}

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stray newline

#if !USE_OPENSSL_FUNCTIONS_SYMMETRIC
/* B.2.3.1.3.3. TDES_decrypt() */
/* As with TDES_encypt() this function bridges between the TPM single schedule model and the
Expand All @@ -116,4 +118,29 @@ void TDES_decrypt(
DES_DECRYPT);
}
#endif // !USE_OPENSSL_FUNCTIONS_SYMMETRIC

#if OPENSSL_VERSION_NUMBER > 0x30000000L

void TDES_crypt(
const BYTE *key,
UINT16 keySizeInBits,
const BYTE *in,
BYTE *out,
BOOL encrypt
)
{
static const EVP_CIPHER *evp_cipher_cached = NULL;

if (!evp_cipher_cached) {
evp_cipher_cached = EVP_des_ede3_ecb();
pAssert(evp_cipher_cached);
}

if (DoEVPCryptOneBlock(NULL, evp_cipher_cached, key, in, sizeof(DES_cblock),
out, encrypt))
pAssert(false)
}

#endif // OPENSSL_VERSION_NUMBER

#endif // SYM_LIB_OSSL
11 changes: 11 additions & 0 deletions src/tpm2/crypto/openssl/TpmToOsslDesSupport_fp.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,16 @@ void TDES_decrypt(
tpmKeyScheduleTDES *ks
);

#if OPENSSL_VERSION_NUMBER >= 0x30000000L

void TDES_crypt(
const BYTE *key,
UINT16 keySizeInBits,
const BYTE *in,
BYTE *out,
BOOL encrypt
);

#endif

#endif