summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/evp/evp_enc.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c
index 0b58a6d9ee..16a993eb0d 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.63 2023/12/16 17:40:22 tb Exp $ */ 1/* $OpenBSD: evp_enc.c,v 1.64 2023/12/20 10:35:25 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 *
@@ -420,8 +420,8 @@ int
420EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 420EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
421 const unsigned char *in, int inl) 421 const unsigned char *in, int inl)
422{ 422{
423 int fix_len; 423 const int block_size = ctx->cipher->block_size;
424 unsigned int b; 424 int len = 0, total_len = 0;
425 425
426 *outl = 0; 426 *outl = 0;
427 427
@@ -434,47 +434,49 @@ EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
434 if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0) 434 if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0)
435 return evp_cipher(ctx, out, outl, in, inl); 435 return evp_cipher(ctx, out, outl, in, inl);
436 436
437 if (ctx->flags & EVP_CIPH_NO_PADDING) 437 if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0)
438 return EVP_EncryptUpdate(ctx, out, outl, in, inl); 438 return EVP_EncryptUpdate(ctx, out, outl, in, inl);
439 439
440 b = ctx->cipher->block_size; 440 if (block_size > sizeof(ctx->final)) {
441 if (b > sizeof ctx->final) {
442 EVPerror(EVP_R_BAD_BLOCK_LENGTH); 441 EVPerror(EVP_R_BAD_BLOCK_LENGTH);
443 return 0; 442 return 0;
444 } 443 }
445 444
446 if (ctx->final_used) { 445 if (ctx->final_used) {
447 /* 446 /*
448 * final_used is only ever set if buf_len is 0. Therefore the 447 * final_used is only set if buf_len is 0. Therefore the maximum
449 * maximum length output we will ever see from EVP_EncryptUpdate 448 * length output from EVP_EncryptUpdate() is inl & ~block_mask.
450 * is inl & ~(b - 1). Since final_used is set, the final output 449 * Ensure (inl & ~block_mask) + block_size doesn't overflow.
451 * length is (inl & ~(b - 1)) + b. Ensure it doesn't overflow.
452 */ 450 */
453 if ((inl & ~(b - 1)) > INT_MAX - b) { 451 if ((inl & ~ctx->block_mask) > INT_MAX - block_size) {
454 EVPerror(EVP_R_TOO_LARGE); 452 EVPerror(EVP_R_TOO_LARGE);
455 return 0; 453 return 0;
456 } 454 }
457 memcpy(out, ctx->final, b); 455 memcpy(out, ctx->final, block_size);
458 out += b; 456 out += block_size;
459 fix_len = 1; 457 total_len = block_size;
460 } else 458 }
461 fix_len = 0;
462 459
460 ctx->final_used = 0;
463 461
464 if (!EVP_EncryptUpdate(ctx, out, outl, in, inl)) 462 len = 0;
463 if (!EVP_EncryptUpdate(ctx, out, &len, in, inl))
465 return 0; 464 return 0;
466 465
467 /* if we have 'decrypted' a multiple of block size, make sure 466 /* Keep copy of last block if a multiple of block_size was decrypted. */
468 * we have a copy of this last block */ 467 if (block_size > 1 && ctx->buf_len == 0) {
469 if (b > 1 && !ctx->buf_len) { 468 if (len < block_size)
470 *outl -= b; 469 return 0;
470 len -= block_size;
471 memcpy(ctx->final, &out[len], block_size);
471 ctx->final_used = 1; 472 ctx->final_used = 1;
472 memcpy(ctx->final, &out[*outl], b); 473 }
473 } else
474 ctx->final_used = 0;
475 474
476 if (fix_len) 475 if (len > INT_MAX - total_len)
477 *outl += b; 476 return 0;
477 total_len += len;
478
479 *outl = total_len;
478 480
479 return 1; 481 return 1;
480} 482}