From 4b9c750be83644aca15a98e75b566e7f6c3644d7 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 27 Nov 2019 16:06:34 +0000 Subject: [PATCH] Make sure we handle input NULL with length 0 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 (Merged from https://github.com/openssl/openssl/pull/10530) --- providers/common/ciphers/cipher_common.c | 5 +++++ providers/common/ciphers/cipher_gcm.c | 5 +++++ providers/implementations/ciphers/cipher_aes_ocb.c | 5 +++++ providers/implementations/ciphers/cipher_aes_siv.c | 5 +++++ providers/implementations/ciphers/cipher_aes_wrp.c | 5 +++++ providers/implementations/ciphers/cipher_chacha20_poly1305.c | 5 +++++ providers/implementations/ciphers/cipher_tdes_wrap.c | 2 ++ 7 files changed, 32 insertions(+) diff --git a/providers/common/ciphers/cipher_common.c b/providers/common/ciphers/cipher_common.c index 8f39a168c8..83c370793b 100644 --- a/providers/common/ciphers/cipher_common.c +++ b/providers/common/ciphers/cipher_common.c @@ -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; diff --git a/providers/common/ciphers/cipher_gcm.c b/providers/common/ciphers/cipher_gcm.c index f479bc8fda..619d4f61b0 100644 --- a/providers/common/ciphers/cipher_gcm.c +++ b/providers/common/ciphers/cipher_gcm.c @@ -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; diff --git a/providers/implementations/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c index ba4e4f29f8..6b07caaa52 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb.c +++ b/providers/implementations/ciphers/cipher_aes_ocb.c @@ -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; diff --git a/providers/implementations/ciphers/cipher_aes_siv.c b/providers/implementations/ciphers/cipher_aes_siv.c index 18be36e9b3..864ebc725e 100644 --- a/providers/implementations/ciphers/cipher_aes_siv.c +++ b/providers/implementations/ciphers/cipher_aes_siv.c @@ -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; diff --git a/providers/implementations/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c index 028676943e..5dedde748a 100644 --- a/providers/implementations/ciphers/cipher_aes_wrp.c +++ b/providers/implementations/ciphers/cipher_aes_wrp.c @@ -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; diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c index b92d8d545e..6bf88dbd9e 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c @@ -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; diff --git a/providers/implementations/ciphers/cipher_tdes_wrap.c b/providers/implementations/ciphers/cipher_tdes_wrap.c index d899985202..fc49696fbd 100644 --- a/providers/implementations/ciphers/cipher_tdes_wrap.c +++ b/providers/implementations/ciphers/cipher_tdes_wrap.c @@ -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; -- 2.25.1