| Backport of: |
| |
| From 6a51b9e1d0cf0bf8515f7201b68fb0a3482b3dc1 Mon Sep 17 00:00:00 2001 |
| From: Matt Caswell <matt@openssl.org> |
| Date: Tue, 2 Feb 2021 17:17:23 +0000 |
| Subject: [PATCH] Don't overflow the output length in EVP_CipherUpdate calls |
| |
| CVE-2021-23840 |
| |
| Reviewed-by: Paul Dale <pauli@openssl.org> |
| --- |
| crypto/err/openssl.txt | 3 ++- |
| crypto/evp/evp_enc.c | 27 +++++++++++++++++++++++++++ |
| crypto/evp/evp_err.c | 4 +++- |
| include/openssl/evperr.h | 7 +++---- |
| 4 files changed, 35 insertions(+), 6 deletions(-) |
| |
| --- a/crypto/evp/evp_enc.c |
| +++ b/crypto/evp/evp_enc.c |
| @@ -354,6 +354,19 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ct |
| return 1; |
| } else { |
| j = bl - i; |
| + |
| + /* |
| + * Once we've processed the first j bytes from in, the amount of |
| + * data left that is a multiple of the block length is: |
| + * (inl - j) & ~(bl - 1) |
| + * We must ensure that this amount of data, plus the one block that |
| + * we process from ctx->buf does not exceed INT_MAX |
| + */ |
| + if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) { |
| + EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, |
| + EVP_R_OUTPUT_WOULD_OVERFLOW); |
| + return 0; |
| + } |
| memcpy(&(ctx->buf[i]), in, j); |
| if (!M_do_cipher(ctx, out, ctx->buf, bl)) |
| return 0; |
| @@ -455,6 +468,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ct |
| OPENSSL_assert(b <= sizeof ctx->final); |
| |
| if (ctx->final_used) { |
| + /* |
| + * final_used is only ever set if buf_len is 0. Therefore the maximum |
| + * length output we will ever see from evp_EncryptDecryptUpdate is |
| + * the maximum multiple of the block length that is <= inl, or just: |
| + * inl & ~(b - 1) |
| + * Since final_used has been set then the final output length is: |
| + * (inl & ~(b - 1)) + b |
| + * This must never exceed INT_MAX |
| + */ |
| + if ((inl & ~(b - 1)) > INT_MAX - b) { |
| + EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_OUTPUT_WOULD_OVERFLOW); |
| + return 0; |
| + } |
| memcpy(out, ctx->final, b); |
| out += b; |
| fix_len = 1; |
| --- a/crypto/evp/evp_err.c |
| +++ b/crypto/evp/evp_err.c |
| @@ -215,6 +215,7 @@ static ERR_STRING_DATA EVP_str_reasons[] |
| {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), |
| "operation not supported for this keytype"}, |
| {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, |
| + {ERR_REASON(EVP_R_OUTPUT_WOULD_OVERFLOW), "output would overflow"}, |
| {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), |
| "pkcs8 unknown broken type"}, |
| {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"}, |
| --- a/crypto/evp/evp.h |
| +++ b/crypto/evp/evp.h |
| @@ -1509,6 +1509,7 @@ void ERR_load_EVP_strings(void); |
| # define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 |
| # define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 |
| # define EVP_R_OPERATON_NOT_INITIALIZED 151 |
| +# define EVP_R_OUTPUT_WOULD_OVERFLOW 184 |
| # define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 |
| # define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 |
| # define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 |