From c2782d1f52bceb30584b71c11631e00eacebcc4e Mon Sep 17 00:00:00 2001 From: jsing <> Date: Mon, 19 May 2025 04:32:52 +0000 Subject: Simplify EVP AES code for ECB. AES_ecb_encrypt() does not really do ECB - provide an aes_ecb_encrypt_internal that actually does multiple blocks and call this from aes_ecb_cipher(). Provide ECB with its own key initialisation function, which allows aes_init_key() to be simplified considerably. The block function pointer is now unused, so mop this up. ok joshua@ tb@ --- src/lib/libcrypto/aes/aes.c | 14 +++++++++- src/lib/libcrypto/evp/e_aes.c | 65 ++++++++++++++++++++++--------------------- 2 files changed, 46 insertions(+), 33 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libcrypto/aes/aes.c b/src/lib/libcrypto/aes/aes.c index 712168e9fa..1c1c61a7a9 100644 --- a/src/lib/libcrypto/aes/aes.c +++ b/src/lib/libcrypto/aes/aes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aes.c,v 1.6 2025/05/19 04:01:07 jsing Exp $ */ +/* $OpenBSD: aes.c,v 1.7 2025/05/19 04:32:51 jsing Exp $ */ /* ==================================================================== * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. * @@ -190,6 +190,18 @@ AES_ecb_encrypt(const unsigned char *in, unsigned char *out, } LCRYPTO_ALIAS(AES_ecb_encrypt); +void +aes_ecb_encrypt_internal(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, int encrypt) +{ + while (len >= AES_BLOCK_SIZE) { + AES_ecb_encrypt(in, out, key, encrypt); + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + len -= AES_BLOCK_SIZE; + } +} + void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, int *num) diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c index d0bcb2b3dd..bfdfed8172 100644 --- a/src/lib/libcrypto/evp/e_aes.c +++ b/src/lib/libcrypto/evp/e_aes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: e_aes.c,v 1.67 2025/05/19 03:55:09 jsing Exp $ */ +/* $OpenBSD: e_aes.c,v 1.68 2025/05/19 04:32:52 jsing Exp $ */ /* ==================================================================== * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. * @@ -67,7 +67,6 @@ typedef struct { AES_KEY ks; - block128_f block; } EVP_AES_KEY; typedef struct { @@ -104,6 +103,9 @@ typedef struct { #define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) +void aes_ecb_encrypt_internal(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, int encrypt); + #ifdef AES_XTS_ASM void AES_xts_encrypt(const char *inp, char *out, size_t len, const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); @@ -164,7 +166,6 @@ aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { int ret, mode; - EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; mode = ctx->cipher->flags & EVP_CIPH_MODE; @@ -172,11 +173,9 @@ aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, !enc) { ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data); - dat->block = (block128_f)aesni_decrypt; } else { ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data); - dat->block = (block128_f)aesni_encrypt; } if (ret < 0) { @@ -267,9 +266,7 @@ static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - size_t bl = ctx->cipher->block_size; - - if (len < bl) + if (len < ctx->cipher->block_size) return 1; aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt); @@ -390,20 +387,9 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - int ret, mode; - EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; - - mode = ctx->cipher->flags & EVP_CIPH_MODE; - - if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { - ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks); - dat->block = (block128_f)AES_decrypt; - } else { - ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks); - dat->block = (block128_f)AES_encrypt; - } + EVP_AES_KEY *eak = ctx->cipher_data; - if (ret < 0) { + if (AES_set_encrypt_key(key, ctx->key_len * 8, &eak->ks) < 0) { EVPerror(EVP_R_AES_KEY_SETUP_FAILED); return 0; } @@ -443,19 +429,34 @@ aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } +static int +aes_ecb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int encrypt) +{ + EVP_AES_KEY *eak = ctx->cipher_data; + + if (encrypt) { + if (AES_set_encrypt_key(key, ctx->key_len * 8, &eak->ks) < 0) { + EVPerror(EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + } else { + if (AES_set_decrypt_key(key, ctx->key_len * 8, &eak->ks) < 0) { + EVPerror(EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + } + + return 1; +} + static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - size_t bl = ctx->cipher->block_size; - size_t i; - EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; - - if (len < bl) - return 1; + EVP_AES_KEY *eak = ctx->cipher_data; - for (i = 0, len -= bl; i <= len; i += bl) - (*dat->block)(in + i, out + i, &dat->ks); + aes_ecb_encrypt_internal(in, out, len, &eak->ks, ctx->encrypt); return 1; } @@ -590,7 +591,7 @@ static const EVP_CIPHER aes_128_ecb = { .key_len = 16, .iv_len = 0, .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, - .init = aes_init_key, + .init = aes_ecb_init_key, .do_cipher = aes_ecb_cipher, .ctx_size = sizeof(EVP_AES_KEY), }; @@ -836,7 +837,7 @@ static const EVP_CIPHER aes_192_ecb = { .key_len = 24, .iv_len = 0, .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, - .init = aes_init_key, + .init = aes_ecb_init_key, .do_cipher = aes_ecb_cipher, .ctx_size = sizeof(EVP_AES_KEY), }; @@ -1082,7 +1083,7 @@ static const EVP_CIPHER aes_256_ecb = { .key_len = 32, .iv_len = 0, .flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE, - .init = aes_init_key, + .init = aes_ecb_init_key, .do_cipher = aes_ecb_cipher, .ctx_size = sizeof(EVP_AES_KEY), }; -- cgit v1.2.3-55-g6feb