SHA256
1
0
forked from pool/libica

- libica: AES-GCM/CCM sometimes compute wrong tag values (bsc#1058567)

- Added the following patches (bsc#1058567)
    - libica-3.0.2-01-fix-old-aes-gcm-decrypt-code-path.patch
    - libica-3.0.2-02-fix-aes-ccm-encrypt-code-path.patch
    - libica-3.0.2-03-fix-aes-ctr.patch
    - libica-3.0.2-04-fix-aes-gcm-to-allow-zero-pt-ct-length.patch

OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/libica?expand=0&rev=13
This commit is contained in:
Mark Post 2017-09-19 20:49:59 +00:00 committed by Git OBS Bridge
parent e301b1f452
commit d2f5998194
6 changed files with 333 additions and 0 deletions

View File

@ -0,0 +1,110 @@
From: Patrick Steuer <patrick.steuer@de.ibm.com>
Subject: fix old aes-gcm decrypt code path.
Patch-mainline: v3.1.1
Git-commit: b95a9fd29fbdab9fd201c8f347bd4710d1811ada
References: LTC#158531
Description: libica: AES-GCM/CCM sometimes compute wrong tag values
Symptom: When the tag values of (unmodified) data are wrong, it is
(wrongly) indicated that the data has been modified.
Problem: With AES-GCM in-place decryption, the tag is computed from the
plaintext. With AES-CCM in-place encryption, the tag is computed
from the ciphertext.
Solution: AES-GCM decryption always computes the tag from the ciphertext.
AES-CCM encryption always computes the tag from the plaintext.
Reproduction: When used with the ibmca 1.4 openssl engine (which enables
libica's AES-GCM for libcrypto): (1) A SSH connection fails
using an AES-GCM based cipher-suite, (2) A connection of
openssl's s_client and s_server using an AES-GCM based
cipher-suite fails.
Upstream-Description:
fix old aes-gcm decrypt code path.
The old aes-gcm decrypt code was like pt<-dec(ct), tag<-mac(ct).
So in case of "in-place" decryption (pt=ct), the tag was computed
from the plaintext.
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
---
src/include/s390_gcm.h | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
--- a/src/include/s390_gcm.h
+++ b/src/include/s390_gcm.h
@@ -321,8 +321,14 @@ static inline int s390_gcm(unsigned int
memcpy(tmp_ctr, j0, AES_BLOCK_SIZE);
__inc_aes_ctr((struct uint128 *)tmp_ctr, GCM_CTR_WIDTH);
- /* en-/decrypt payload */
if (function_code % 2) {
+ /* mac */
+ rc = s390_gcm_authenticate(ciphertext, text_length,
+ aad, aad_length,
+ subkey_h, tmp_tag);
+ if (rc)
+ return rc;
+
/* decrypt */
rc = s390_aes_ctr(UNDIRECTED_FC(function_code),
ciphertext, plaintext, text_length,
@@ -336,14 +342,14 @@ static inline int s390_gcm(unsigned int
key, tmp_ctr, GCM_CTR_WIDTH);
if (rc)
return rc;
- }
- /* generate authentication tag */
- rc = s390_gcm_authenticate(ciphertext, text_length,
- aad, aad_length,
- subkey_h, tmp_tag);
- if (rc)
- return rc;
+ /* mac */
+ rc = s390_gcm_authenticate(ciphertext, text_length,
+ aad, aad_length,
+ subkey_h, tmp_tag);
+ if (rc)
+ return rc;
+ }
/* encrypt tag */
return s390_aes_ctr(UNDIRECTED_FC(function_code),
@@ -393,8 +399,13 @@ static inline int s390_gcm_intermediate(
if (!msa4_switch)
return EPERM;
- /* en-/decrypt payload */
if (function_code % 2) {
+ /* mac */
+ rc = s390_gcm_authenticate_intermediate(ciphertext, text_length, aad,
+ aad_length, subkey, tag);
+ if (rc)
+ return rc;
+
/* decrypt */
rc = s390_aes_ctr(UNDIRECTED_FC(function_code), ciphertext, plaintext,
text_length, key, ctr, GCM_CTR_WIDTH);
@@ -406,13 +417,13 @@ static inline int s390_gcm_intermediate(
text_length, key, ctr, GCM_CTR_WIDTH);
if (rc)
return rc;
- }
- /* generate authentication tag */
- rc = s390_gcm_authenticate_intermediate(ciphertext, text_length, aad,
- aad_length, subkey, tag);
- if (rc)
- return rc;
+ /* mac */
+ rc = s390_gcm_authenticate_intermediate(ciphertext, text_length, aad,
+ aad_length, subkey, tag);
+ if (rc)
+ return rc;
+ }
return 0;
}

View File

@ -0,0 +1,81 @@
From: Patrick Steuer <patrick.steuer@de.ibm.com>
Subject: fix aes-ccm encrypt code path.
Patch-mainline: v3.1.1
Git-commit: d901d1c06b1a5e3717907e3a8b32d4bb8f3cc03b
References: LTC#158531
Description: libica: AES-GCM/CCM sometimes compute wrong tag values
Symptom: When the tag values of (unmodified) data are wrong, it is
(wrongly) indicated that the data has been modified.
Problem: With AES-GCM in-place decryption, the tag is computed from the
plaintext. With AES-CCM in-place encryption, the tag is computed
from the ciphertext.
Solution: AES-GCM decryption always computes the tag from the ciphertext.
AES-CCM encryption always computes the tag from the plaintext.
Reproduction: When used with the ibmca 1.4 openssl engine (which enables
libica's AES-GCM for libcrypto): (1) A SSH connection fails
using an AES-GCM based cipher-suite, (2) A connection of
openssl's s_client and s_server using an AES-GCM based
cipher-suite fails.
Upstream-Description:
fix aes-ccm encrypt code path.
The aes-ccm encrypt code was like ct<-enc(pt), tag<-mac(pt). So in
case of "in-place" encryption (pt=ct), the tag was computed from
the ciphertext.
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
---
src/include/s390_ccm.h | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
--- a/src/include/s390_ccm.h
+++ b/src/include/s390_ccm.h
@@ -314,7 +314,26 @@ static inline unsigned int s390_ccm(unsi
key, cipher_ctr, ccm_ctr_width);
if (rc)
return rc;
+ /* mac */
+ rc = s390_ccm_authenticate(UNDIRECTED_FC(function_code),
+ payload, payload_length,
+ assoc_data, assoc_data_length,
+ nonce, nonce_length,
+ tag, mac_length,
+ key, fc_to_key_length(function_code));
+ if (rc)
+ return rc;
} else {
+ /* mac */
+ rc = s390_ccm_authenticate(UNDIRECTED_FC(function_code),
+ payload, payload_length,
+ assoc_data, assoc_data_length,
+ nonce, nonce_length,
+ tag, mac_length,
+ key, fc_to_key_length(function_code));
+ if (rc)
+ return rc;
+
/*encrypt */
rc = s390_aes_ctr(UNDIRECTED_FC(function_code),
payload, ciphertext, payload_length,
@@ -324,16 +343,6 @@ static inline unsigned int s390_ccm(unsi
}
}
- /* generate tag */
- rc = s390_ccm_authenticate(UNDIRECTED_FC(function_code),
- payload, payload_length,
- assoc_data, assoc_data_length,
- nonce, nonce_length,
- tag, mac_length,
- key, fc_to_key_length(function_code));
- if (rc)
- return rc;
-
/* encrypt tag into mac */
return s390_aes_ctr(UNDIRECTED_FC(function_code),
tag, mac, mac_length,

View File

@ -0,0 +1,48 @@
From: Patrick Steuer <patrick.steuer@de.ibm.com>
Subject: fix aes-ctr.
Patch-mainline: v3.1.1
Git-commit: 6b9da36a0e616025bc80615d66ba735ec558e263
References: LTC#158531
Description: libica: AES-GCM/CCM sometimes compute wrong tag values
Symptom: When the tag values of (unmodified) data are wrong, it is
(wrongly) indicated that the data has been modified.
Problem: With AES-GCM in-place decryption, the tag is computed from the
plaintext. With AES-CCM in-place encryption, the tag is computed
from the ciphertext.
Solution: AES-GCM decryption always computes the tag from the ciphertext.
AES-CCM encryption always computes the tag from the plaintext.
Reproduction: When used with the ibmca 1.4 openssl engine (which enables
libica's AES-GCM for libcrypto): (1) A SSH connection fails
using an AES-GCM based cipher-suite, (2) A connection of
openssl's s_client and s_server using an AES-GCM based
cipher-suite fails.
Upstream-Description:
fix aes-ctr.
aes-ctr incremented the counter even if it was called with zero
input. aes-gcm with non-zero aad and zero pt/ct (ghash) called
aes-ctr with zero input, whereby the counter was erroneously
incremented.
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
---
src/include/s390_aes.h | 3 +++
1 file changed, 3 insertions(+)
--- a/src/include/s390_aes.h
+++ b/src/include/s390_aes.h
@@ -110,6 +110,9 @@ static inline int s390_aes_ctr(unsigned
int rc = 0;
+ if (data_length == 0)
+ return 0;
+
if (data_length <= AES_BLOCK_SIZE) {
/* short message handling */
rc = s390_aes_ctrlist(fc, data_length, in_data, ctr,

View File

@ -0,0 +1,75 @@
From: Patrick Steuer <patrick.steuer@de.ibm.com>
Subject: fix aes-gcm to allow zero pt/ct length.
Patch-mainline: v3.1.1
Git-commit: 089670367c8f645fcf5e4f8e59640877d2400ce4
References: LTC#158531
Description: libica: AES-GCM/CCM sometimes compute wrong tag values
Symptom: When the tag values of (unmodified) data are wrong, it is
(wrongly) indicated that the data has been modified.
Problem: With AES-GCM in-place decryption, the tag is computed from the
plaintext. With AES-CCM in-place encryption, the tag is computed
from the ciphertext.
Solution: AES-GCM decryption always computes the tag from the ciphertext.
AES-CCM encryption always computes the tag from the plaintext.
Reproduction: When used with the ibmca 1.4 openssl engine (which enables
libica's AES-GCM for libcrypto): (1) A SSH connection fails
using an AES-GCM based cipher-suite, (2) A connection of
openssl's s_client and s_server using an AES-GCM based
cipher-suite fails.
Upstream-Description:
fix aes-gcm to allow zero pt/ct length.
In case of zero pt/ct lenght, only aad is processed (ghash).
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
---
src/ica_api.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
--- a/src/ica_api.c
+++ b/src/ica_api.c
@@ -1750,9 +1750,16 @@ unsigned int ica_aes_gcm(unsigned char *
return EACCES;
#endif /* ICA_FIPS */
- if (check_aes_parms(MODE_GCM, plaintext_length, plaintext, iv, key_length,
- key, ciphertext))
- return EINVAL;
+ if (plaintext_length != 0) {
+ if (check_aes_parms(MODE_GCM, plaintext_length, plaintext, iv, key_length,
+ key, ciphertext))
+ return EINVAL;
+ } else {
+ /* If only aad is processed (ghash), pt/ct may be NULL. */
+ if (check_aes_parms(MODE_GCM, plaintext_length, (unsigned char *)1,
+ iv, key_length, key, (unsigned char *)1))
+ return EINVAL;
+ }
if (check_gcm_parms(plaintext_length, aad, aad_length, tag, tag_length, iv_length))
return EINVAL;
@@ -1825,9 +1832,16 @@ unsigned int ica_aes_gcm_intermediate(un
return EACCES;
#endif /* ICA_FIPS */
- if (check_aes_parms(MODE_GCM, plaintext_length, plaintext, cb, key_length,
- key, ciphertext))
- return EINVAL;
+ if (plaintext_length != 0) {
+ if (check_aes_parms(MODE_GCM, plaintext_length, plaintext, cb, key_length,
+ key, ciphertext))
+ return EINVAL;
+ } else {
+ /* If only aad is processed (ghash), pt/ct may be NULL. */
+ if (check_aes_parms(MODE_GCM, plaintext_length, (unsigned char *)1,
+ cb, key_length, key, (unsigned char *)1))
+ return EINVAL;
+ }
if (check_gcm_parms(plaintext_length, aad, aad_length, tag, tag_length,
iv_length_dummy))
return EINVAL;

View File

@ -1,3 +1,13 @@
-------------------------------------------------------------------
Wed Sep 13 20:23:05 UTC 2017 - mpost@suse.com
- libica: AES-GCM/CCM sometimes compute wrong tag values (bsc#1058567)
- Added the following patches (bsc#1058567)
- libica-3.0.2-01-fix-old-aes-gcm-decrypt-code-path.patch
- libica-3.0.2-02-fix-aes-ccm-encrypt-code-path.patch
- libica-3.0.2-03-fix-aes-ctr.patch
- libica-3.0.2-04-fix-aes-gcm-to-allow-zero-pt-ct-length.patch
-------------------------------------------------------------------
Thu Jun 1 14:36:04 UTC 2017 - fcrozat@suse.com

View File

@ -36,6 +36,11 @@ Source5: sysconfig.z90crypt
Source6: baselibs.conf
Source7: %{name}-rpmlintrc
Patch1: libica-3.0.2-01-fix-old-aes-gcm-decrypt-code-path.patch
Patch2: libica-3.0.2-02-fix-aes-ccm-encrypt-code-path.patch
Patch3: libica-3.0.2-03-fix-aes-ctr.patch
Patch4: libica-3.0.2-04-fix-aes-gcm-to-allow-zero-pt-ct-length.patch
Url: http://sourceforge.net/projects/opencryptoki/files/libica
BuildRoot: %{_tmppath}/%{name}-%{version}-build
PreReq: %fillup_prereq %insserv_prereq
@ -99,6 +104,10 @@ the libica library.
%prep
%setup -a 1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build
mkdir -p include/linux/