diff options
author | tb <> | 2021-02-18 19:12:29 +0000 |
---|---|---|
committer | tb <> | 2021-02-18 19:12:29 +0000 |
commit | c0a82707368e11e3872c506071effd56313abf17 (patch) | |
tree | a383d64fa77b273ce134ee057cb2ddd3d9ad5e50 | |
parent | 1001613abb83932d408d4bae5f18f14b18ac99f1 (diff) | |
download | openbsd-c0a82707368e11e3872c506071effd56313abf17.tar.gz openbsd-c0a82707368e11e3872c506071effd56313abf17.tar.bz2 openbsd-c0a82707368e11e3872c506071effd56313abf17.zip |
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>
-rw-r--r-- | src/lib/libcrypto/evp/evp_enc.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c index bb49e28267..896b9e1a16 100644 --- a/src/lib/libcrypto/evp/evp_enc.c +++ b/src/lib/libcrypto/evp/evp_enc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: evp_enc.c,v 1.43 2019/04/14 17:16:57 jsing Exp $ */ | 1 | /* $OpenBSD: evp_enc.c,v 1.44 2021/02/18 19:12:29 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -56,6 +56,7 @@ | |||
56 | * [including the GNU Public Licence.] | 56 | * [including the GNU Public Licence.] |
57 | */ | 57 | */ |
58 | 58 | ||
59 | #include <limits.h> | ||
59 | #include <stdio.h> | 60 | #include <stdio.h> |
60 | #include <stdlib.h> | 61 | #include <stdlib.h> |
61 | #include <string.h> | 62 | #include <string.h> |
@@ -337,6 +338,17 @@ EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
337 | return 1; | 338 | return 1; |
338 | } else { | 339 | } else { |
339 | j = bl - i; | 340 | j = bl - i; |
341 | |||
342 | /* | ||
343 | * Once we've processed the first j bytes from in, the | ||
344 | * amount of data left that is a multiple of the block | ||
345 | * length is (inl - j) & ~(bl - 1). Ensure this plus | ||
346 | * the block processed from ctx-buf doesn't overflow. | ||
347 | */ | ||
348 | if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) { | ||
349 | EVPerror(EVP_R_TOO_LARGE); | ||
350 | return 0; | ||
351 | } | ||
340 | memcpy(&(ctx->buf[i]), in, j); | 352 | memcpy(&(ctx->buf[i]), in, j); |
341 | if (!M_do_cipher(ctx, out, ctx->buf, bl)) | 353 | if (!M_do_cipher(ctx, out, ctx->buf, bl)) |
342 | return 0; | 354 | return 0; |
@@ -451,6 +463,16 @@ EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | |||
451 | } | 463 | } |
452 | 464 | ||
453 | if (ctx->final_used) { | 465 | if (ctx->final_used) { |
466 | /* | ||
467 | * final_used is only ever set if buf_len is 0. Therefore the | ||
468 | * maximum length output we will ever see from EVP_EncryptUpdate | ||
469 | * is inl & ~(b - 1). Since final_used is set, the final output | ||
470 | * length is (inl & ~(b - 1)) + b. Ensure it doesn't overflow. | ||
471 | */ | ||
472 | if ((inl & ~(b - 1)) > INT_MAX - b) { | ||
473 | EVPerror(EVP_R_TOO_LARGE); | ||
474 | return 0; | ||
475 | } | ||
454 | memcpy(out, ctx->final, b); | 476 | memcpy(out, ctx->final, b); |
455 | out += b; | 477 | out += b; |
456 | fix_len = 1; | 478 | fix_len = 1; |