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 8f39a16..83c3707 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 f479bc8..619d4f6 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 ba4e4f2..6b07caa 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 18be36e..864ebc7 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 0286769..5dedde7 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 b92d8d5..6bf88db 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 d899985..fc49696 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;