diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/evp/evp_enc.c | 54 |
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 | |||
| 420 | EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, | 420 | EVP_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 | } |
