Make sure we handle input NULL with length 0
authorMatt Caswell <matt@openssl.org>
Wed, 27 Nov 2019 16:06:34 +0000 (16:06 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 29 Nov 2019 10:41:06 +0000 (10:41 +0000)
If we call EVP_EncryptUpdate/EVP_DecryptUpdate with length 0 we should
be able to handle it. Most importantly we shouldn't get different
results if we do this compared to if we don't!

An exception is made for CCM mode which has special handling for this in
the low level cipher function.

Fixes #8675

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10530)

providers/common/ciphers/cipher_common.c
providers/common/ciphers/cipher_gcm.c
providers/implementations/ciphers/cipher_aes_ocb.c
providers/implementations/ciphers/cipher_aes_siv.c
providers/implementations/ciphers/cipher_aes_wrp.c
providers/implementations/ciphers/cipher_chacha20_poly1305.c
providers/implementations/ciphers/cipher_tdes_wrap.c

index 8f39a168c8536c91f4c383fd7530186b2b98d222..83c370793bf20ecbdd713a0cff9eff32bb926465 100644 (file)
@@ -291,6 +291,11 @@ int cipher_generic_stream_update(void *vctx, unsigned char *out, size_t *outl,
 {
     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;
index f479bc8fdabcd6cf717bb4b276f4693e1c0f7c80..619d4f61b0790d713d0b6ea88a60076a1d1af27c 100644 (file)
@@ -210,6 +210,11 @@ int gcm_stream_update(void *vctx, unsigned char *out, size_t *outl,
 {
     PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return -1;
index ba4e4f29f83e31616ef9ada3a4cb1444d402b26c..6b07caaa52e875677d43aff2b198c391b1e51ca3 100644 (file)
@@ -214,6 +214,11 @@ static int aes_ocb_block_update(void *vctx, unsigned char *out, size_t *outl,
     if (!ctx->key_set || !update_iv(ctx))
         return 0;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     /* Are we dealing with AAD or normal data here? */
     if (out == NULL) {
         buf = ctx->aad_buf;
index 18be36e9b32120c4bb78e4df2102a7f49c3c0a88..864ebc725edfb934644d29512728c373da114193 100644 (file)
@@ -76,6 +76,11 @@ static int siv_cipher(void *vctx, unsigned char *out, size_t *outl,
 {
     PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;
index 028676943e33308e5f9870c8d11510de041d0ff2..5dedde748a65efef705eeedeccf1a9960fc6a307 100644 (file)
@@ -164,6 +164,11 @@ static int aes_wrap_cipher(void *vctx,
     PROV_AES_WRAP_CTX *ctx = (PROV_AES_WRAP_CTX *)vctx;
     size_t len;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return -1;
index b92d8d545eeefff6ae96f589194621e2ba470798..6bf88dbd9e6ba99ecc9d4eac2a1dacb295ea6e3c 100644 (file)
@@ -262,6 +262,11 @@ static int chacha20_poly1305_cipher(void *vctx, unsigned char *out,
     PROV_CIPHER_HW_CHACHA20_POLY1305 *hw =
         (PROV_CIPHER_HW_CHACHA20_POLY1305 *)ctx->hw;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;
index d899985202b5d85f2c730ee6bcde565a17e32da3..fc49696fbd3f5b8bbcd081364c4991fd0074ee9a 100644 (file)
@@ -145,6 +145,8 @@ static int tdes_wrap_update(void *vctx, unsigned char *out, size_t *outl,
                             size_t inl)
 {
     *outl = 0;
+    if (inl == 0)
+        return 1;
     if (outsize < inl) {
         PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;