forked from pool/libica
76 lines
2.8 KiB
Diff
76 lines
2.8 KiB
Diff
|
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;
|