forked from pool/libica
d2f5998194
- 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
111 lines
3.4 KiB
Diff
111 lines
3.4 KiB
Diff
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;
|
|
}
|