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,