File openssl-CVE-2021-23840.patch of Package openssl-1_1.18609
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(-)
Index: openssl-1.1.1d/crypto/err/openssl.txt
===================================================================
--- openssl-1.1.1d.orig/crypto/err/openssl.txt
+++ openssl-1.1.1d/crypto/err/openssl.txt
@@ -2315,6 +2315,7 @@ EVP_R_ONLY_ONESHOT_SUPPORTED:177:only on
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\
operation not supported for this keytype
EVP_R_OPERATON_NOT_INITIALIZED:151:operaton not initialized
+EVP_R_OUTPUT_WOULD_OVERFLOW:184:output would overflow
EVP_R_PARAMETER_TOO_LARGE:187:parameter too large
EVP_R_PARTIALLY_OVERLAPPING:162:partially overlapping buffers
EVP_R_PBKDF2_ERROR:181:pbkdf2 error
Index: openssl-1.1.1d/crypto/evp/evp_enc.c
===================================================================
--- openssl-1.1.1d.orig/crypto/evp/evp_enc.c
+++ openssl-1.1.1d/crypto/evp/evp_enc.c
@@ -8,6 +8,7 @@
*/
#include <stdio.h>
+#include <limits.h>
#include <assert.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
@@ -381,6 +382,19 @@ static int evp_EncryptDecryptUpdate(EVP_
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);
inl -= j;
in += j;
@@ -522,6 +536,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ct
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
}
+ /*
+ * 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;
Index: openssl-1.1.1d/crypto/evp/evp_err.c
===================================================================
--- openssl-1.1.1d.orig/crypto/evp/evp_err.c
+++ openssl-1.1.1d/crypto/evp/evp_err.c
@@ -245,6 +245,8 @@ static const ERR_STRING_DATA EVP_str_rea
"operation not supported for this keytype"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED),
"operaton not initialized"},
+ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OUTPUT_WOULD_OVERFLOW),
+ "output would overflow"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARAMETER_TOO_LARGE),
"parameter too large"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING),
Index: openssl-1.1.1d/include/openssl/evperr.h
===================================================================
--- openssl-1.1.1d.orig/include/openssl/evperr.h
+++ openssl-1.1.1d/include/openssl/evperr.h
@@ -11,9 +11,7 @@
#ifndef HEADER_EVPERR_H
# define HEADER_EVPERR_H
-# ifndef HEADER_SYMHACKS_H
-# include <openssl/symhacks.h>
-# endif
+# include <openssl/symhacks.h>
# ifdef __cplusplus
extern "C"
@@ -185,6 +183,7 @@ int ERR_load_EVP_strings(void);
# define EVP_R_ONLY_ONESHOT_SUPPORTED 177
# 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_PARAMETER_TOO_LARGE 187
# define EVP_R_PARTIALLY_OVERLAPPING 162
# define EVP_R_PBKDF2_ERROR 181