From f0234f5a33ecf3b2784f3e73bdf1e937abe56599 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Sun, 13 Jul 2025 06:01:33 +0000 Subject: Simplify AES-XTS implementation and remove AES-NI specific code from EVP. Provide aes_xts_encrypt_internal() and call that from aes_xts_cipher(). Have amd64 and i386 provide their own versions that dispatch to aesni_xts_encrypt()/aesni_xts_decrypt() as appropriate. The AESNI_CAPABLE code and methods can then be removed. ok tb@ --- src/lib/libcrypto/aes/aes.c | 32 ++++++- src/lib/libcrypto/aes/aes_amd64.c | 31 ++++++- src/lib/libcrypto/aes/aes_i386.c | 31 ++++++- src/lib/libcrypto/aes/aes_local.h | 6 +- src/lib/libcrypto/arch/amd64/crypto_arch.h | 3 +- src/lib/libcrypto/arch/i386/crypto_arch.h | 3 +- src/lib/libcrypto/evp/e_aes.c | 139 ++++------------------------- src/lib/libcrypto/modes/modes_local.h | 4 +- 8 files changed, 117 insertions(+), 132 deletions(-) (limited to 'src/lib/libcrypto') diff --git a/src/lib/libcrypto/aes/aes.c b/src/lib/libcrypto/aes/aes.c index e9dbe975e3..45b7a3b109 100644 --- a/src/lib/libcrypto/aes/aes.c +++ b/src/lib/libcrypto/aes/aes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aes.c,v 1.10 2025/06/27 17:10:45 jsing Exp $ */ +/* $OpenBSD: aes.c,v 1.11 2025/07/13 06:01:33 jsing Exp $ */ /* ==================================================================== * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. * @@ -57,6 +57,7 @@ #include "crypto_arch.h" #include "crypto_internal.h" +#include "modes_local.h" static const unsigned char aes_wrap_default_iv[] = { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, @@ -322,6 +323,35 @@ AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, } LCRYPTO_ALIAS(AES_ofb128_encrypt); +void +aes_xts_encrypt_generic(const unsigned char *in, unsigned char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16], + int encrypt) +{ + XTS128_CONTEXT xctx; + + if (encrypt) + xctx.block1 = aes_encrypt_block128; + else + xctx.block1 = aes_decrypt_block128; + + xctx.block2 = aes_encrypt_block128; + xctx.key1 = key1; + xctx.key2 = key2; + + CRYPTO_xts128_encrypt(&xctx, iv, in, out, len, encrypt); +} + +#ifndef HAVE_AES_XTS_ENCRYPT_INTERNAL +void +aes_xts_encrypt_internal(const unsigned char *in, unsigned char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16], + int encrypt) +{ + aes_xts_encrypt_generic(in, out, len, key1, key2, iv, encrypt); +} +#endif + int AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, const unsigned char *in, unsigned int inlen) diff --git a/src/lib/libcrypto/aes/aes_amd64.c b/src/lib/libcrypto/aes/aes_amd64.c index 456409d186..5a40274675 100644 --- a/src/lib/libcrypto/aes/aes_amd64.c +++ b/src/lib/libcrypto/aes/aes_amd64.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aes_amd64.c,v 1.2 2025/06/27 17:10:45 jsing Exp $ */ +/* $OpenBSD: aes_amd64.c,v 1.3 2025/07/13 06:01:33 jsing Exp $ */ /* * Copyright (c) 2025 Joel Sing * @@ -18,6 +18,7 @@ #include #include "crypto_arch.h" +#include "modes_local.h" int aes_set_encrypt_key_generic(const unsigned char *userKey, const int bits, AES_KEY *key); @@ -35,6 +36,10 @@ void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, void aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out, size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]); +void aes_xts_encrypt_generic(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16], int encrypt); + int aesni_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); int aesni_set_decrypt_key(const unsigned char *userKey, int bits, @@ -51,6 +56,14 @@ void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t blocks, const void *key, const unsigned char *ivec); +void aesni_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_xts_decrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + int aes_set_encrypt_key_internal(const unsigned char *userKey, const int bits, AES_KEY *key) @@ -118,3 +131,19 @@ aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out, aes_ctr32_encrypt_generic(in, out, blocks, key, ivec); } + +void +aes_xts_encrypt_internal(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16], int encrypt) +{ + if ((crypto_cpu_caps_amd64 & CRYPTO_CPU_CAPS_AMD64_AES) != 0) { + if (encrypt) + aesni_xts_encrypt(in, out, len, key1, key2, iv); + else + aesni_xts_decrypt(in, out, len, key1, key2, iv); + return; + } + + aes_xts_encrypt_generic(in, out, len, key1, key2, iv, encrypt); +} diff --git a/src/lib/libcrypto/aes/aes_i386.c b/src/lib/libcrypto/aes/aes_i386.c index 2da02a8d35..73b75d28f5 100644 --- a/src/lib/libcrypto/aes/aes_i386.c +++ b/src/lib/libcrypto/aes/aes_i386.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aes_i386.c,v 1.2 2025/06/27 17:10:45 jsing Exp $ */ +/* $OpenBSD: aes_i386.c,v 1.3 2025/07/13 06:01:33 jsing Exp $ */ /* * Copyright (c) 2025 Joel Sing * @@ -18,6 +18,7 @@ #include #include "crypto_arch.h" +#include "modes_local.h" int aes_set_encrypt_key_generic(const unsigned char *userKey, const int bits, AES_KEY *key); @@ -35,6 +36,10 @@ void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, void aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out, size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]); +void aes_xts_encrypt_generic(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16], int encrypt); + int aesni_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); int aesni_set_decrypt_key(const unsigned char *userKey, int bits, @@ -51,6 +56,14 @@ void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t blocks, const void *key, const unsigned char *ivec); +void aesni_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_xts_decrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + int aes_set_encrypt_key_internal(const unsigned char *userKey, const int bits, AES_KEY *key) @@ -118,3 +131,19 @@ aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out, aes_ctr32_encrypt_generic(in, out, blocks, key, ivec); } + +void +aes_xts_encrypt_internal(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16], int encrypt) +{ + if ((crypto_cpu_caps_i386 & CRYPTO_CPU_CAPS_I386_AES) != 0) { + if (encrypt) + aesni_xts_encrypt(in, out, len, key1, key2, iv); + else + aesni_xts_decrypt(in, out, len, key1, key2, iv); + return; + } + + aes_xts_encrypt_generic(in, out, len, key1, key2, iv, encrypt); +} diff --git a/src/lib/libcrypto/aes/aes_local.h b/src/lib/libcrypto/aes/aes_local.h index 5052cf9e70..f68d4624e7 100644 --- a/src/lib/libcrypto/aes/aes_local.h +++ b/src/lib/libcrypto/aes/aes_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: aes_local.h,v 1.8 2025/07/06 15:37:33 jsing Exp $ */ +/* $OpenBSD: aes_local.h,v 1.9 2025/07/13 06:01:33 jsing Exp $ */ /* ==================================================================== * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. * @@ -69,6 +69,10 @@ void aes_ctr32_encrypt_ctr128f(const unsigned char *in, unsigned char *out, void aes_ecb_encrypt_internal(const unsigned char *in, unsigned char *out, size_t len, const AES_KEY *key, int encrypt); +void aes_xts_encrypt_internal(const char unsigned *in, char unsigned *out, + size_t len, const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16], int encrypt); + __END_HIDDEN_DECLS #endif /* !HEADER_AES_LOCAL_H */ diff --git a/src/lib/libcrypto/arch/amd64/crypto_arch.h b/src/lib/libcrypto/arch/amd64/crypto_arch.h index 9f292cc530..7c3c89a088 100644 --- a/src/lib/libcrypto/arch/amd64/crypto_arch.h +++ b/src/lib/libcrypto/arch/amd64/crypto_arch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto_arch.h,v 1.9 2025/06/28 12:39:10 jsing Exp $ */ +/* $OpenBSD: crypto_arch.h,v 1.10 2025/07/13 06:01:33 jsing Exp $ */ /* * Copyright (c) 2024 Joel Sing * @@ -39,6 +39,7 @@ extern uint64_t crypto_cpu_caps_amd64; #define HAVE_AES_DECRYPT_INTERNAL #define HAVE_AES_CBC_ENCRYPT_INTERNAL #define HAVE_AES_CTR32_ENCRYPT_INTERNAL +#define HAVE_AES_XTS_ENCRYPT_INTERNAL #define HAVE_GCM128_INIT diff --git a/src/lib/libcrypto/arch/i386/crypto_arch.h b/src/lib/libcrypto/arch/i386/crypto_arch.h index 95d4cc468b..8b292165fb 100644 --- a/src/lib/libcrypto/arch/i386/crypto_arch.h +++ b/src/lib/libcrypto/arch/i386/crypto_arch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto_arch.h,v 1.8 2025/06/28 12:39:10 jsing Exp $ */ +/* $OpenBSD: crypto_arch.h,v 1.9 2025/07/13 06:01:33 jsing Exp $ */ /* * Copyright (c) 2024 Joel Sing * @@ -39,6 +39,7 @@ extern uint64_t crypto_cpu_caps_i386; #define HAVE_AES_DECRYPT_INTERNAL #define HAVE_AES_CBC_ENCRYPT_INTERNAL #define HAVE_AES_CTR32_ENCRYPT_INTERNAL +#define HAVE_AES_XTS_ENCRYPT_INTERNAL #define HAVE_GCM128_INIT diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c index 1779acec66..851da9ded6 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.78 2025/07/06 15:37:33 jsing Exp $ */ +/* $OpenBSD: e_aes.c,v 1.79 2025/07/13 06:01:33 jsing Exp $ */ /* ==================================================================== * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. * @@ -84,10 +84,7 @@ typedef struct { typedef struct { AES_KEY ks1, ks2; /* AES key schedules to use */ - XTS128_CONTEXT xts; - void (*stream)(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); + XTS128_CONTEXT xts; /* XXX - replace with flags. */ } EVP_AES_XTS_CTX; typedef struct { @@ -103,13 +100,6 @@ typedef struct { #define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) -#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]); -void AES_xts_decrypt(const char *inp, char *out, size_t len, - const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); -#endif - #if defined(AES_ASM) && ( \ ((defined(__i386) || defined(__i386__) || \ defined(_M_IX86)))|| \ @@ -137,14 +127,6 @@ void aesni_decrypt(const unsigned char *in, unsigned char *out, void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, int enc); -void aesni_xts_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); - -void aesni_xts_decrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); - void aesni_ccm64_encrypt_blocks (const unsigned char *in, unsigned char *out, size_t blocks, const void *key, const unsigned char ivec[16], unsigned char cmac[16]); @@ -165,44 +147,6 @@ aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -static int -aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_XTS_CTX *xctx = ctx->cipher_data; - - if (!iv && !key) - return 1; - - if (key) { - /* key_len is two AES keys */ - if (enc) { - aesni_set_encrypt_key(key, ctx->key_len * 4, - &xctx->ks1); - xctx->xts.block1 = (block128_f)aesni_encrypt; - xctx->stream = aesni_xts_encrypt; - } else { - aesni_set_decrypt_key(key, ctx->key_len * 4, - &xctx->ks1); - xctx->xts.block1 = (block128_f)aesni_decrypt; - xctx->stream = aesni_xts_decrypt; - } - - aesni_set_encrypt_key(key + ctx->key_len / 2, - ctx->key_len * 4, &xctx->ks2); - xctx->xts.block2 = (block128_f)aesni_encrypt; - - xctx->xts.key1 = &xctx->ks1; - } - - if (iv) { - xctx->xts.key2 = &xctx->ks2; - memcpy(ctx->iv, iv, 16); - } - - return 1; -} - static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@ -1242,36 +1186,24 @@ aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) + const unsigned char *iv, int encrypt) { EVP_AES_XTS_CTX *xctx = ctx->cipher_data; - if (!iv && !key) - return 1; - - if (key) { -#ifdef AES_XTS_ASM - xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; -#else - xctx->stream = NULL; -#endif + if (key != NULL) { /* key_len is two AES keys */ - if (enc) { + if (encrypt) AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); - xctx->xts.block1 = (block128_f)AES_encrypt; - } else { + else AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); - xctx->xts.block1 = (block128_f)AES_decrypt; - } - AES_set_encrypt_key(key + ctx->key_len / 2, - ctx->key_len * 4, &xctx->ks2); - xctx->xts.block2 = (block128_f)AES_encrypt; + AES_set_encrypt_key(key + ctx->key_len / 2, ctx->key_len * 4, + &xctx->ks2); xctx->xts.key1 = &xctx->ks1; } - if (iv) { + if (iv != NULL) { xctx->xts.key2 = &xctx->ks2; memcpy(ctx->iv, iv, 16); } @@ -1285,17 +1217,15 @@ aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { EVP_AES_XTS_CTX *xctx = ctx->cipher_data; - if (!xctx->xts.key1 || !xctx->xts.key2) - return 0; - if (!out || !in || len < AES_BLOCK_SIZE) + if (xctx->xts.key1 == NULL || xctx->xts.key2 == NULL) return 0; - if (xctx->stream) - (*xctx->stream)(in, out, len, xctx->xts.key1, xctx->xts.key2, - ctx->iv); - else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, - ctx->encrypt)) + if (out == NULL || in == NULL || len < AES_BLOCK_SIZE) return 0; + + aes_xts_encrypt_internal(in, out, len, xctx->xts.key1, xctx->xts.key2, + ctx->iv, ctx->encrypt); + return 1; } @@ -1303,22 +1233,6 @@ aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ( EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV | \ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY ) - -#ifdef AESNI_CAPABLE -static const EVP_CIPHER aesni_128_xts = { - .nid = NID_aes_128_xts, - .block_size = 1, - .key_len = 2 * 16, - .iv_len = 16, - .flags = XTS_FLAGS | EVP_CIPH_XTS_MODE, - .init = aesni_xts_init_key, - .do_cipher = aes_xts_cipher, - .cleanup = NULL, - .ctx_size = sizeof(EVP_AES_XTS_CTX), - .ctrl = aes_xts_ctrl, -}; -#endif - static const EVP_CIPHER aes_128_xts = { .nid = NID_aes_128_xts, .block_size = 1, @@ -1335,29 +1249,10 @@ static const EVP_CIPHER aes_128_xts = { const EVP_CIPHER * EVP_aes_128_xts(void) { -#ifdef AESNI_CAPABLE - return AESNI_CAPABLE ? &aesni_128_xts : &aes_128_xts; -#else return &aes_128_xts; -#endif } LCRYPTO_ALIAS(EVP_aes_128_xts); -#ifdef AESNI_CAPABLE -static const EVP_CIPHER aesni_256_xts = { - .nid = NID_aes_256_xts, - .block_size = 1, - .key_len = 2 * 32, - .iv_len = 16, - .flags = XTS_FLAGS | EVP_CIPH_XTS_MODE, - .init = aesni_xts_init_key, - .do_cipher = aes_xts_cipher, - .cleanup = NULL, - .ctx_size = sizeof(EVP_AES_XTS_CTX), - .ctrl = aes_xts_ctrl, -}; -#endif - static const EVP_CIPHER aes_256_xts = { .nid = NID_aes_256_xts, .block_size = 1, @@ -1374,11 +1269,7 @@ static const EVP_CIPHER aes_256_xts = { const EVP_CIPHER * EVP_aes_256_xts(void) { -#ifdef AESNI_CAPABLE - return AESNI_CAPABLE ? &aesni_256_xts : &aes_256_xts; -#else return &aes_256_xts; -#endif } LCRYPTO_ALIAS(EVP_aes_256_xts); diff --git a/src/lib/libcrypto/modes/modes_local.h b/src/lib/libcrypto/modes/modes_local.h index d833d40ee3..5c1acfc25f 100644 --- a/src/lib/libcrypto/modes/modes_local.h +++ b/src/lib/libcrypto/modes/modes_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: modes_local.h,v 1.6 2025/05/18 09:05:59 jsing Exp $ */ +/* $OpenBSD: modes_local.h,v 1.7 2025/07/13 06:01:33 jsing Exp $ */ /* ==================================================================== * Copyright (c) 2010 The OpenSSL Project. All rights reserved. * @@ -46,7 +46,7 @@ struct gcm128_context { }; struct xts128_context { - void *key1, *key2; + const void *key1, *key2; block128_f block1, block2; }; -- cgit v1.2.3-55-g6feb