Skip to content

Commit 9b11292

Browse files
committed
Don't overflow the output length in EVP_CipherUpdate calls
CVE-2021-23840 Reviewed-by: Paul Dale <pauli@openssl.org>
1 parent 30919ab commit 9b11292

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

Diff for: crypto/evp/evp.h

+2
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,7 @@ void ERR_load_EVP_strings(void);
14911491
# define EVP_F_EVP_DECRYPTFINAL_EX 101
14921492
# define EVP_F_EVP_DECRYPTUPDATE 181
14931493
# define EVP_F_EVP_DIGESTINIT_EX 128
1494+
# define EVP_F_EVP_ENCRYPTDECRYPTUPDATE 182
14941495
# define EVP_F_EVP_ENCRYPTFINAL_EX 127
14951496
# define EVP_F_EVP_ENCRYPTUPDATE 180
14961497
# define EVP_F_EVP_MD_CTX_COPY_EX 110
@@ -1602,6 +1603,7 @@ void ERR_load_EVP_strings(void);
16021603
# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
16031604
# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150
16041605
# define EVP_R_OPERATON_NOT_INITIALIZED 151
1606+
# define EVP_R_OUTPUT_WOULD_OVERFLOW 172
16051607
# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117
16061608
# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
16071609
# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146

Diff for: crypto/evp/evp_enc.c

+27
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
*/
5858

5959
#include <stdio.h>
60+
#include <limits.h>
6061
#include "cryptlib.h"
6162
#include <openssl/evp.h>
6263
#include <openssl/err.h>
@@ -357,6 +358,19 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
357358
return 1;
358359
} else {
359360
j = bl - i;
361+
362+
/*
363+
* Once we've processed the first j bytes from in, the amount of
364+
* data left that is a multiple of the block length is:
365+
* (inl - j) & ~(bl - 1)
366+
* We must ensure that this amount of data, plus the one block that
367+
* we process from ctx->buf does not exceed INT_MAX
368+
*/
369+
if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) {
370+
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE,
371+
EVP_R_OUTPUT_WOULD_OVERFLOW);
372+
return 0;
373+
}
360374
memcpy(&(ctx->buf[i]), in, j);
361375
if (!M_do_cipher(ctx, out, ctx->buf, bl))
362376
return 0;
@@ -482,6 +496,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
482496
OPENSSL_assert(b <= sizeof(ctx->final));
483497

484498
if (ctx->final_used) {
499+
/*
500+
* final_used is only ever set if buf_len is 0. Therefore the maximum
501+
* length output we will ever see from evp_EncryptDecryptUpdate is
502+
* the maximum multiple of the block length that is <= inl, or just:
503+
* inl & ~(b - 1)
504+
* Since final_used has been set then the final output length is:
505+
* (inl & ~(b - 1)) + b
506+
* This must never exceed INT_MAX
507+
*/
508+
if ((inl & ~(b - 1)) > INT_MAX - b) {
509+
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_OUTPUT_WOULD_OVERFLOW);
510+
return 0;
511+
}
485512
memcpy(out, ctx->final, b);
486513
out += b;
487514
fix_len = 1;

Diff for: crypto/evp/evp_err.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* crypto/evp/evp_err.c */
22
/* ====================================================================
3-
* Copyright (c) 1999-2019 The OpenSSL Project. All rights reserved.
3+
* Copyright (c) 1999-2021 The OpenSSL Project. All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
66
* modification, are permitted provided that the following conditions
@@ -94,6 +94,7 @@ static ERR_STRING_DATA EVP_str_functs[] = {
9494
{ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
9595
{ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"},
9696
{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
97+
{ERR_FUNC(EVP_F_EVP_ENCRYPTDECRYPTUPDATE), "EVP_ENCRYPTDECRYPTUPDATE"},
9798
{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
9899
{ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"},
99100
{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
@@ -215,6 +216,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = {
215216
{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
216217
"operation not supported for this keytype"},
217218
{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
219+
{ERR_REASON(EVP_R_OUTPUT_WOULD_OVERFLOW), "output would overflow"},
218220
{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),
219221
"pkcs8 unknown broken type"},
220222
{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"},

0 commit comments

Comments
 (0)