From d2f5998194942675a989347d6b8696f5b16bcee9593b82682942777ce27a7ea5 Mon Sep 17 00:00:00 2001 From: Mark Post Date: Tue, 19 Sep 2017 20:49:59 +0000 Subject: [PATCH] - 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 --- ...01-fix-old-aes-gcm-decrypt-code-path.patch | 110 ++++++++++++++++++ ...0.2-02-fix-aes-ccm-encrypt-code-path.patch | 81 +++++++++++++ libica-3.0.2-03-fix-aes-ctr.patch | 48 ++++++++ ...x-aes-gcm-to-allow-zero-pt-ct-length.patch | 75 ++++++++++++ libica.changes | 10 ++ libica.spec | 9 ++ 6 files changed, 333 insertions(+) create mode 100644 libica-3.0.2-01-fix-old-aes-gcm-decrypt-code-path.patch create mode 100644 libica-3.0.2-02-fix-aes-ccm-encrypt-code-path.patch create mode 100644 libica-3.0.2-03-fix-aes-ctr.patch create mode 100644 libica-3.0.2-04-fix-aes-gcm-to-allow-zero-pt-ct-length.patch diff --git a/libica-3.0.2-01-fix-old-aes-gcm-decrypt-code-path.patch b/libica-3.0.2-01-fix-old-aes-gcm-decrypt-code-path.patch new file mode 100644 index 0000000..caecc11 --- /dev/null +++ b/libica-3.0.2-01-fix-old-aes-gcm-decrypt-code-path.patch @@ -0,0 +1,110 @@ +From: Patrick Steuer +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 + +Signed-off-by: Patrick Steuer +--- + 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; + } diff --git a/libica-3.0.2-02-fix-aes-ccm-encrypt-code-path.patch b/libica-3.0.2-02-fix-aes-ccm-encrypt-code-path.patch new file mode 100644 index 0000000..a4c1363 --- /dev/null +++ b/libica-3.0.2-02-fix-aes-ccm-encrypt-code-path.patch @@ -0,0 +1,81 @@ +From: Patrick Steuer +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 + +Signed-off-by: Patrick Steuer +--- + 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, diff --git a/libica-3.0.2-03-fix-aes-ctr.patch b/libica-3.0.2-03-fix-aes-ctr.patch new file mode 100644 index 0000000..7e9133e --- /dev/null +++ b/libica-3.0.2-03-fix-aes-ctr.patch @@ -0,0 +1,48 @@ +From: Patrick Steuer +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 + +Signed-off-by: Patrick Steuer +--- + 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, diff --git a/libica-3.0.2-04-fix-aes-gcm-to-allow-zero-pt-ct-length.patch b/libica-3.0.2-04-fix-aes-gcm-to-allow-zero-pt-ct-length.patch new file mode 100644 index 0000000..d675e2a --- /dev/null +++ b/libica-3.0.2-04-fix-aes-gcm-to-allow-zero-pt-ct-length.patch @@ -0,0 +1,75 @@ +From: Patrick Steuer +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 + +Signed-off-by: Patrick Steuer +--- + 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; diff --git a/libica.changes b/libica.changes index 9129dcb..3b35d02 100644 --- a/libica.changes +++ b/libica.changes @@ -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 diff --git a/libica.spec b/libica.spec index 73218c5..0d13d8a 100644 --- a/libica.spec +++ b/libica.spec @@ -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/