summaryrefslogtreecommitdiff
path: root/lib/libcrypto
diff options
context:
space:
mode:
authorTheo Buehler <tb@cvs.openbsd.org>2021-02-18 19:12:30 +0000
committerTheo Buehler <tb@cvs.openbsd.org>2021-02-18 19:12:30 +0000
commitbfe6a3c3c55053dabcee6522b0ded0581b06163b (patch)
treeef252f6a3eef7ae33dbf0d8e8b0d3424f1481956 /lib/libcrypto
parentc4a53b6d562a630fbd8c8262e40eea04f0aec3c9 (diff)
Pull in fix for EVP_CipherUpdate() overflow from OpenSSL.
ok inoguchi commit 6a51b9e1d0cf0bf8515f7201b68fb0a3482b3dc1 Author: Matt Caswell <matt@openssl.org> Date: Tue Feb 2 17:17:23 2021 +0000 Don't overflow the output length in EVP_CipherUpdate calls CVE-2021-23840 Reviewed-by: Paul Dale <pauli@openssl.org>
Diffstat (limited to 'lib/libcrypto')
-rw-r--r--lib/libcrypto/evp/evp_enc.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/libcrypto/evp/evp_enc.c b/lib/libcrypto/evp/evp_enc.c
index bb49e28267a..896b9e1a16f 100644
--- a/lib/libcrypto/evp/evp_enc.c
+++ b/lib/libcrypto/evp/evp_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_enc.c,v 1.43 2019/04/14 17:16:57 jsing Exp $ */
+/* $OpenBSD: evp_enc.c,v 1.44 2021/02/18 19:12:29 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -56,6 +56,7 @@
* [including the GNU Public Licence.]
*/
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -337,6 +338,17 @@ EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
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). Ensure this plus
+ * the block processed from ctx-buf doesn't overflow.
+ */
+ if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) {
+ EVPerror(EVP_R_TOO_LARGE);
+ return 0;
+ }
memcpy(&(ctx->buf[i]), in, j);
if (!M_do_cipher(ctx, out, ctx->buf, bl))
return 0;
@@ -451,6 +463,16 @@ EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
}
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_EncryptUpdate
+ * is inl & ~(b - 1). Since final_used is set, the final output
+ * length is (inl & ~(b - 1)) + b. Ensure it doesn't overflow.
+ */
+ if ((inl & ~(b - 1)) > INT_MAX - b) {
+ EVPerror(EVP_R_TOO_LARGE);
+ return 0;
+ }
memcpy(out, ctx->final, b);
out += b;
fix_len = 1;