[PATCH] cipher: length checks for geniv

Jussi Kivilinna jussi.kivilinna at iki.fi
Thu Aug 25 18:41:24 CEST 2022


* cipher/cipher.c (_gcry_cipher_setup_geniv, _gcry_cipher_geniv): Check
input lengths for valid range; Avoid calling memcpy with zero length.
--

Patch adds few length checks for setup_geniv and makes sure that memcpy
is not called with zero length.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/cipher.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/cipher/cipher.c b/cipher/cipher.c
index e8743496..91379d13 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -1271,12 +1271,22 @@ _gcry_cipher_setup_geniv (gcry_cipher_hd_t hd, int method,
   if (method != GCRY_CIPHER_GENIV_METHOD_CONCAT)
     return GPG_ERR_INV_ARG;
 
+  if (fixed_iv_len > sizeof(hd->aead.fixed))
+    return GPG_ERR_INV_LENGTH;
+
+  if (dyn_iv_len > sizeof(hd->aead.dynamic))
+    return GPG_ERR_INV_LENGTH;
+
+  if (dyn_iv_len == 0) /* Zero-length dynamic would mean fixed IV only. */
+    return GPG_ERR_INV_LENGTH;
+
   hd->aead.geniv_method = GCRY_CIPHER_GENIV_METHOD_CONCAT;
   hd->aead.fixed_iv_len = fixed_iv_len;
   hd->aead.dynamic_iv_len = dyn_iv_len;
   memset (hd->aead.fixed, 0, MAX_BLOCKSIZE);
   memset (hd->aead.dynamic, 0, MAX_BLOCKSIZE);
-  memcpy (hd->aead.fixed, fixed_iv, fixed_iv_len);
+  if (fixed_iv_len > 0)
+    memcpy (hd->aead.fixed, fixed_iv, fixed_iv_len);
   memcpy (hd->aead.dynamic, dyn_iv, dyn_iv_len);
 
   return rc;
@@ -1295,7 +1305,11 @@ _gcry_cipher_geniv (gcry_cipher_hd_t hd, void *iv, size_t iv_len)
   if (iv_len != hd->aead.fixed_iv_len + hd->aead.dynamic_iv_len)
     return GPG_ERR_INV_ARG;
 
-  memcpy (iv, hd->aead.fixed, hd->aead.fixed_iv_len);
+  if (hd->aead.dynamic_iv_len == 0)
+    return GPG_ERR_INV_STATE; /* Dynamic not set through setup_geniv. */
+
+  if (hd->aead.fixed_iv_len > 0)
+    memcpy (iv, hd->aead.fixed, hd->aead.fixed_iv_len);
   memcpy ((byte *)iv+hd->aead.fixed_iv_len,
           hd->aead.dynamic, hd->aead.dynamic_iv_len);
   rc = hd->mode_ops.setiv (hd, iv, iv_len);
-- 
2.34.1




More information about the Gcrypt-devel mailing list