summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2023-12-20 10:35:25 +0000
committertb <>2023-12-20 10:35:25 +0000
commita9a5598c7249fefcb98e69b5a75ee16d3c01d5ee (patch)
tree4b8deba64a935d81b714b45fdd6ed99942ce2021 /src
parentc0cd30c4ff668c8c13b4ff65ea9d6c956cb08b27 (diff)
downloadopenbsd-a9a5598c7249fefcb98e69b5a75ee16d3c01d5ee.tar.gz
openbsd-a9a5598c7249fefcb98e69b5a75ee16d3c01d5ee.tar.bz2
openbsd-a9a5598c7249fefcb98e69b5a75ee16d3c01d5ee.zip
Simplify EVP_DecryptUpdate() a bit
This time the block size is called b and there's some awful length fiddling with fix_len, which until recently also served as store for the return value for do_cipher()... If we land on a block boundary, we keep the last block decrypted and don't count it as part of the output. So in the next call we need to feed it back in. Feeding it back in counts as output written this time around, so instead of remembering that we need to adjust outl, keep a tally of the bytes written. This way we can also do some overflow and underflow checking. ok jsing
Diffstat (limited to 'src')
-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}