From 68aa19dac7e1b80509a915ed72c2cbc1184b42bb Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 1 Mar 2021 09:19:02 -0500 Subject: [PATCH] tpm2: CryptSym: fix AES output IV The TPM is supposed to provide the output IV in the ivInOut parameter in CryptSymmetricEncrypt. In the case of using the openssl routines, the output IV is missed, and the resulting output from the TPM is in the input IV. OpenSSL unfortunately does not export EVP_CIPHER_CTX_iv() until tags/OpenSSL_1_1_0, so we have to fall back to the reference code for previous OpenSSL versions. Signed-off-by: William Roberts Signed-off-by: Stefan Berger --- configure.ac | 1 + src/tpm2/crypto/openssl/CryptSym.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/configure.ac b/configure.ac index c43f0ae9..cd44bfe9 100644 --- a/configure.ac +++ b/configure.ac @@ -165,6 +165,7 @@ AS_IF([test "x$enable_use_openssl_functions" != "xno"], [ AC_CHECK_LIB([crypto], [EVP_aes_128_cbc],, not_found=1) AC_CHECK_LIB([crypto], [EVP_des_ede3_cbc],, not_found=1) AC_CHECK_LIB([crypto], [DES_random_key],, not_found=1) + AC_CHECK_LIB([crypto], [EVP_CIPHER_CTX_iv],, not_found=1) if test "x$not_found" = "x0"; then use_openssl_functions_symmetric=1 use_openssl_functions_for="symmetric (AES, TDES) " diff --git a/src/tpm2/crypto/openssl/CryptSym.c b/src/tpm2/crypto/openssl/CryptSym.c index 40e018d4..ceb7cd5c 100644 --- a/src/tpm2/crypto/openssl/CryptSym.c +++ b/src/tpm2/crypto/openssl/CryptSym.c @@ -531,6 +531,7 @@ CryptSymmetricEncrypt( BYTE keyToUse[MAX_SYM_KEY_BYTES]; UINT16 keyToUseLen = (UINT16)sizeof(keyToUse); TPM_RC retVal = TPM_RC_SUCCESS; + int ivLen; pAssert(dOut != NULL && key != NULL && dIn != NULL); if(dSize == 0) @@ -595,6 +596,14 @@ CryptSymmetricEncrypt( if (EVP_EncryptFinal_ex(ctx, pOut + outlen1, &outlen2) != 1) ERROR_RETURN(TPM_RC_FAILURE); + if (ivInOut) { + ivLen = EVP_CIPHER_CTX_iv_length(ctx); + if (ivLen < 0 || (size_t)ivLen > sizeof(ivInOut->t.buffer)) + ERROR_RETURN(TPM_RC_FAILURE); + + ivInOut->t.size = ivLen; + memcpy(ivInOut->t.buffer, EVP_CIPHER_CTX_iv(ctx), ivInOut->t.size); + } Exit: if (retVal == TPM_RC_SUCCESS && pOut != dOut) memcpy(dOut, pOut, outlen1 + outlen2); @@ -636,6 +645,7 @@ CryptSymmetricDecrypt( BYTE keyToUse[MAX_SYM_KEY_BYTES]; UINT16 keyToUseLen = (UINT16)sizeof(keyToUse); TPM_RC retVal = TPM_RC_SUCCESS; + int ivLen; // 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 @@ -708,6 +718,15 @@ CryptSymmetricDecrypt( pAssert((int)buffersize >= outlen1 + outlen2); + if (ivInOut) { + ivLen = EVP_CIPHER_CTX_iv_length(ctx); + if (ivLen < 0 || (size_t)ivLen > sizeof(ivInOut->t.buffer)) + ERROR_RETURN(TPM_RC_FAILURE); + + ivInOut->t.size = ivLen; + memcpy(ivInOut->t.buffer, EVP_CIPHER_CTX_iv(ctx), ivInOut->t.size); + } + Exit: if (retVal == TPM_RC_SUCCESS) { pAssert(dSize >= outlen1 + outlen2);