git: 9e94eac9765f - stable/11 - OpenSSL: Don't overflow the output length in EVP_CipherUpdate calls

Jung-uk Kim jkim at FreeBSD.org
Thu Feb 18 17:47:36 UTC 2021


The branch stable/11 has been updated by jkim:

URL: https://cgit.FreeBSD.org/src/commit/?id=9e94eac9765f54671b90150955e0851579959daa

commit 9e94eac9765f54671b90150955e0851579959daa
Author:     Jung-uk Kim <jkim at FreeBSD.org>
AuthorDate: 2021-02-18 17:43:29 +0000
Commit:     Jung-uk Kim <jkim at FreeBSD.org>
CommitDate: 2021-02-18 17:43:29 +0000

    OpenSSL: Don't overflow the output length in EVP_CipherUpdate calls
    
    Note it is backported from OpenSSL 1.1.1j to fix CVE-2021-23840.
    
    https://github.com/openssl/openssl/commit/6a51b9e1d0cf0bf8515f7201b68fb0a3482b3dc1
---
 crypto/openssl/crypto/evp/evp.h     |  2 ++
 crypto/openssl/crypto/evp/evp_enc.c | 27 +++++++++++++++++++++++++++
 crypto/openssl/crypto/evp/evp_err.c |  4 +++-
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/crypto/openssl/crypto/evp/evp.h b/crypto/openssl/crypto/evp/evp.h
index 883a9434899b..4ec0e25d07ac 100644
--- a/crypto/openssl/crypto/evp/evp.h
+++ b/crypto/openssl/crypto/evp/evp.h
@@ -1491,6 +1491,7 @@ void ERR_load_EVP_strings(void);
 # define EVP_F_EVP_DECRYPTFINAL_EX                        101
 # define EVP_F_EVP_DECRYPTUPDATE                          181
 # define EVP_F_EVP_DIGESTINIT_EX                          128
+# define EVP_F_EVP_ENCRYPTDECRYPTUPDATE                   182
 # define EVP_F_EVP_ENCRYPTFINAL_EX                        127
 # define EVP_F_EVP_ENCRYPTUPDATE                          180
 # define EVP_F_EVP_MD_CTX_COPY_EX                         110
@@ -1602,6 +1603,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                      172
 # define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE                  117
 # define EVP_R_PRIVATE_KEY_DECODE_ERROR                   145
 # define EVP_R_PRIVATE_KEY_ENCODE_ERROR                   146
diff --git a/crypto/openssl/crypto/evp/evp_enc.c b/crypto/openssl/crypto/evp/evp_enc.c
index c63fb53ac85e..f392f6d01363 100644
--- a/crypto/openssl/crypto/evp/evp_enc.c
+++ b/crypto/openssl/crypto/evp/evp_enc.c
@@ -57,6 +57,7 @@
  */
 
 #include <stdio.h>
+#include <limits.h>
 #include "cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -357,6 +358,19 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
             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;
@@ -482,6 +496,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     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;
diff --git a/crypto/openssl/crypto/evp/evp_err.c b/crypto/openssl/crypto/evp/evp_err.c
index 11647b92c613..0b1e59ead606 100644
--- a/crypto/openssl/crypto/evp/evp_err.c
+++ b/crypto/openssl/crypto/evp/evp_err.c
@@ -1,6 +1,6 @@
 /* crypto/evp/evp_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2019 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2021 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -94,6 +94,7 @@ static ERR_STRING_DATA EVP_str_functs[] = {
     {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
     {ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"},
     {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
+    {ERR_FUNC(EVP_F_EVP_ENCRYPTDECRYPTUPDATE), "EVP_ENCRYPTDECRYPTUPDATE"},
     {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
     {ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"},
     {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[] = {
     {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"},


More information about the dev-commits-src-all mailing list