From: tb Date: Wed, 20 Dec 2023 11:01:34 +0000 (+0000) Subject: Clean up EVP_DecryptFinal_ex() X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=357ffaeda13c9b72bd90eb2f425b5dd414652a93;p=openbsd Clean up EVP_DecryptFinal_ex() Rework the code to use the usual variable names, return early if we have block size 1 and unindent the remainder of the code for block sizes 8 and 16. Rework the padding check to be less acrobatic and copy the remainder of the plain text into out using memcpy() rather than a for loop. input/ok jsing --- diff --git a/lib/libcrypto/evp/evp_enc.c b/lib/libcrypto/evp/evp_enc.c index b00150513c2..2bcef15fc2b 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.65 2023/12/20 10:42:43 tb Exp $ */ +/* $OpenBSD: evp_enc.c,v 1.66 2023/12/20 11:01:34 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -487,50 +487,53 @@ EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { - int i, n; - unsigned int b; + const int block_size = ctx->cipher->block_size; + int buf_offset = ctx->buf_len; + int i, pad, plain_len; *outl = 0; if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0) return evp_cipher(ctx, out, outl, NULL, 0); - b = ctx->cipher->block_size; - if (ctx->flags & EVP_CIPH_NO_PADDING) { - if (ctx->buf_len) { + if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0) { + if (buf_offset != 0) { EVPerror(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); return 0; } - *outl = 0; return 1; } - if (b > 1) { - if (ctx->buf_len || !ctx->final_used) { - EVPerror(EVP_R_WRONG_FINAL_BLOCK_LENGTH); - return (0); - } - if (b > sizeof ctx->final) { - EVPerror(EVP_R_BAD_BLOCK_LENGTH); - return 0; - } - n = ctx->final[b - 1]; - if (n == 0 || n > (int)b) { + + if (block_size == 1) + return 1; + + if (buf_offset != 0 || !ctx->final_used) { + EVPerror(EVP_R_WRONG_FINAL_BLOCK_LENGTH); + return 0; + } + + if (block_size > sizeof(ctx->final)) { + EVPerror(EVP_R_BAD_BLOCK_LENGTH); + return 0; + } + + pad = ctx->final[block_size - 1]; + if (pad <= 0 || pad > block_size) { + EVPerror(EVP_R_BAD_DECRYPT); + return 0; + } + plain_len = block_size - pad; + for (i = plain_len; i < block_size; i++) { + if (ctx->final[i] != pad) { EVPerror(EVP_R_BAD_DECRYPT); - return (0); - } - for (i = 0; i < n; i++) { - if (ctx->final[--b] != n) { - EVPerror(EVP_R_BAD_DECRYPT); - return (0); - } + return 0; } - n = ctx->cipher->block_size - n; - for (i = 0; i < n; i++) - out[i] = ctx->final[i]; - *outl = n; - } else - *outl = 0; - return (1); + } + + memcpy(out, ctx->final, plain_len); + *outl = plain_len; + + return 1; } EVP_CIPHER_CTX *