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.

Fixes: CVE-2021-3446
buglink:https://bugzilla.redhat.com/show_bug.cgi?id=1939664

Signed-off-by: William Roberts <william.c.roberts@intel.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: jiangfangjie 00559066 <jiangfangjie@huawei.com>
This commit is contained in:
jiangfangjie 00559066 2021-04-06 18:19:30 +08:00
parent d817276ca1
commit a1a4809abf
2 changed files with 96 additions and 3 deletions

View File

@ -0,0 +1,85 @@
From 8a1716c3bb18bac169f68d24cdd095cf617eb908 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Tue, 6 Apr 2021 16:22:04 +0800
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 <william.c.roberts@intel.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
configure.ac | 1 +
src/tpm2/crypto/openssl/CryptSym.c | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/configure.ac b/configure.ac
index 1bb45d1..0c57ef3 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 7aa90da..856def6 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
@@ -707,6 +717,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);
--
2.27.0

View File

@ -5,8 +5,8 @@
%define name libtpms
%define versionx 0.7.3
%define release 2
%define versionx 0.7.3
%define release 3
# Valid crypto subsystems are 'freebl' and 'openssl'
%if "%{?crypto_subsystem}" == ""
@ -19,13 +19,15 @@
Summary: Library providing Trusted Platform Module (TPM) functionality
Name: %{name}
Version: %{versionx}
Release: 2
Release: 3
License: BSD
Group: Development/Libraries
Url: http://github.com/stefanberger/libtpms
Source0: %{url}/archive/%{gitcommit}/%{name}-%{gitshortcommit}.tar.gz
Provides: libtpms-%{crypto_subsystem} = %{version}-%{release}
Patch0: 0001-tpm2-CryptSym-fix-AES-output-IV.patch
%if "%{crypto_subsystem}" == "openssl"
BuildRequires: openssl-devel
%else
@ -116,6 +118,12 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libtpms.la
%postun -p /sbin/ldconfig
%changelog
* Mon Apr 5 2021 jiangfangjie <jiangfangjie@huawei.com> - 0.7.3-3
- Type:CVE
- ID:NA
- SUG:NA
- DESC: fix CVE-2021-3446
* Mon Sep 14 2020 jiangfangjie <jiangfangjie@huawei.com> - 0.7.3-2
- update spec file including source0 and update source file