From 46423017b02650c68ef2ac67a7c84b1a34ce9679 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Fri, 27 Jun 2025 17:26:57 +0000 Subject: Simplify EVP AES-GCM implementation and remove AES-NI specific code. Like CTR, the mode implementation for GCM has two variants - rather than using multiple variants (one for AES-NI, another for non-AES-NI), consistently use CRYPTO_gcm128_{en,de}crypt_ctr32() with the aes_ctr32_encrypt_internal() function added for CTR mode. This lets us remove the AES-NI specific code, AES-NI specific EVP_CIPHER methods and the ctr function pointer from EVP_AES_GCM_CTX. ok tb@ --- src/lib/libcrypto/Makefile | 3 +- src/lib/libcrypto/aes/aes_local.h | 5 +- src/lib/libcrypto/evp/e_aes.c | 198 +++++--------------------------------- 3 files changed, 31 insertions(+), 175 deletions(-) (limited to 'src') diff --git a/src/lib/libcrypto/Makefile b/src/lib/libcrypto/Makefile index 3ad03831f8..a33a209ef7 100644 --- a/src/lib/libcrypto/Makefile +++ b/src/lib/libcrypto/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.237 2025/05/25 06:27:02 jsing Exp $ +# $OpenBSD: Makefile,v 1.238 2025/06/27 17:26:57 jsing Exp $ LIB= crypto LIBREBUILD=y @@ -25,6 +25,7 @@ CFLAGS+= -DLIBRESSL_NAMESPACE -DLIBRESSL_CRYPTO_NAMESPACE CFLAGS+= -DHAVE_FUNOPEN CFLAGS+= -I${LCRYPTO_SRC} +CFLAGS+= -I${LCRYPTO_SRC}/aes CFLAGS+= -I${LCRYPTO_SRC}/arch/${MACHINE_CPU} CFLAGS+= -I${LCRYPTO_SRC}/asn1 CFLAGS+= -I${LCRYPTO_SRC}/bio diff --git a/src/lib/libcrypto/aes/aes_local.h b/src/lib/libcrypto/aes/aes_local.h index dab12ed3f9..f9bd363802 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.6 2025/06/27 16:43:54 jsing Exp $ */ +/* $OpenBSD: aes_local.h,v 1.7 2025/06/27 17:26:57 jsing Exp $ */ /* ==================================================================== * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. * @@ -63,6 +63,9 @@ __BEGIN_HIDDEN_DECLS /* This controls loop-unrolling in aes_core.c */ #undef FULL_UNROLL +void aes_ctr32_encrypt_ctr128f(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, const unsigned char ivec[AES_BLOCK_SIZE]); + __END_HIDDEN_DECLS #endif /* !HEADER_AES_LOCAL_H */ diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c index b00eb048e8..b9d673c978 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.76 2025/06/27 17:10:45 jsing Exp $ */ +/* $OpenBSD: e_aes.c,v 1.77 2025/06/27 17:26:57 jsing Exp $ */ /* ==================================================================== * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. * @@ -61,6 +61,7 @@ #include #include +#include "aes_local.h" #include "err_local.h" #include "evp_local.h" #include "modes_local.h" @@ -79,7 +80,6 @@ typedef struct { int taglen; int iv_gen; /* It is OK to generate IVs */ int tls_aad_len; /* TLS AAD length */ - ctr128_f ctr; } EVP_AES_GCM_CTX; typedef struct { @@ -140,9 +140,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_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]); @@ -171,41 +168,6 @@ aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -static int -aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_GCM_CTX *gctx = ctx->cipher_data; - - if (!iv && !key) - return 1; - if (key) { - aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); - CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, - (block128_f)aesni_encrypt); - gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks; - /* If we have an iv can set it directly, otherwise use - * saved IV. - */ - if (iv == NULL && gctx->iv_set) - iv = gctx->iv; - if (iv) { - CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); - gctx->iv_set = 1; - } - gctx->key_set = 1; - } else { - /* If key set use IV, otherwise copy */ - if (gctx->key_set) - CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); - else - memcpy(gctx->iv, iv, gctx->ivlen); - gctx->iv_set = 1; - gctx->iv_gen = 0; - } - return 1; -} - static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@ -1028,15 +990,6 @@ aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) } } -static ctr128_f -aes_gcm_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx, - const unsigned char *key, size_t key_len) -{ - AES_set_encrypt_key(key, key_len * 8, aes_key); - CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt); - return NULL; -} - static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@ -1046,8 +999,8 @@ aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (!iv && !key) return 1; if (key) { - gctx->ctr = aes_gcm_set_key(&gctx->ks, &gctx->gcm, - key, ctx->key_len); + AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt); /* If we have an iv can set it directly, otherwise use * saved IV. @@ -1107,14 +1060,9 @@ aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; if (ctx->encrypt) { /* Encrypt payload */ - if (gctx->ctr) { - if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, in, out, - len, gctx->ctr)) - goto err; - } else { - if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) - goto err; - } + if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, in, out, len, + aes_ctr32_encrypt_ctr128f)) + goto err; out += len; /* Finally write tag */ @@ -1122,14 +1070,10 @@ aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; } else { /* Decrypt */ - if (gctx->ctr) { - if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, in, out, - len, gctx->ctr)) - goto err; - } else { - if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) - goto err; - } + if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, in, out, len, + aes_ctr32_encrypt_ctr128f)) + goto err; + /* Retrieve tag */ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); @@ -1168,25 +1112,13 @@ aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) return -1; } else if (ctx->encrypt) { - if (gctx->ctr) { - if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, - in, out, len, gctx->ctr)) - return -1; - } else { - if (CRYPTO_gcm128_encrypt(&gctx->gcm, - in, out, len)) - return -1; - } + if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, + in, out, len, aes_ctr32_encrypt_ctr128f)) + return -1; } else { - if (gctx->ctr) { - if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, - in, out, len, gctx->ctr)) - return -1; - } else { - if (CRYPTO_gcm128_decrypt(&gctx->gcm, - in, out, len)) - return -1; - } + if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, + in, out, len, aes_ctr32_encrypt_ctr128f)) + return -1; } return len; } else { @@ -1215,22 +1147,6 @@ aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | \ EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY ) - -#ifdef AESNI_CAPABLE -static const EVP_CIPHER aesni_128_gcm = { - .nid = NID_aes_128_gcm, - .block_size = 1, - .key_len = 16, - .iv_len = 12, - .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, - .init = aesni_gcm_init_key, - .do_cipher = aes_gcm_cipher, - .cleanup = aes_gcm_cleanup, - .ctx_size = sizeof(EVP_AES_GCM_CTX), - .ctrl = aes_gcm_ctrl, -}; -#endif - static const EVP_CIPHER aes_128_gcm = { .nid = NID_aes_128_gcm, .block_size = 1, @@ -1247,29 +1163,10 @@ static const EVP_CIPHER aes_128_gcm = { const EVP_CIPHER * EVP_aes_128_gcm(void) { -#ifdef AESNI_CAPABLE - return AESNI_CAPABLE ? &aesni_128_gcm : &aes_128_gcm; -#else return &aes_128_gcm; -#endif } LCRYPTO_ALIAS(EVP_aes_128_gcm); -#ifdef AESNI_CAPABLE -static const EVP_CIPHER aesni_192_gcm = { - .nid = NID_aes_192_gcm, - .block_size = 1, - .key_len = 24, - .iv_len = 12, - .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, - .init = aesni_gcm_init_key, - .do_cipher = aes_gcm_cipher, - .cleanup = aes_gcm_cleanup, - .ctx_size = sizeof(EVP_AES_GCM_CTX), - .ctrl = aes_gcm_ctrl, -}; -#endif - static const EVP_CIPHER aes_192_gcm = { .nid = NID_aes_192_gcm, .block_size = 1, @@ -1286,29 +1183,10 @@ static const EVP_CIPHER aes_192_gcm = { const EVP_CIPHER * EVP_aes_192_gcm(void) { -#ifdef AESNI_CAPABLE - return AESNI_CAPABLE ? &aesni_192_gcm : &aes_192_gcm; -#else return &aes_192_gcm; -#endif } LCRYPTO_ALIAS(EVP_aes_192_gcm); -#ifdef AESNI_CAPABLE -static const EVP_CIPHER aesni_256_gcm = { - .nid = NID_aes_256_gcm, - .block_size = 1, - .key_len = 32, - .iv_len = 12, - .flags = EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS | EVP_CIPH_GCM_MODE, - .init = aesni_gcm_init_key, - .do_cipher = aes_gcm_cipher, - .cleanup = aes_gcm_cleanup, - .ctx_size = sizeof(EVP_AES_GCM_CTX), - .ctrl = aes_gcm_ctrl, -}; -#endif - static const EVP_CIPHER aes_256_gcm = { .nid = NID_aes_256_gcm, .block_size = 1, @@ -1325,11 +1203,7 @@ static const EVP_CIPHER aes_256_gcm = { const EVP_CIPHER * EVP_aes_256_gcm(void) { -#ifdef AESNI_CAPABLE - return AESNI_CAPABLE ? &aesni_256_gcm : &aes_256_gcm; -#else return &aes_256_gcm; -#endif } LCRYPTO_ALIAS(EVP_aes_256_gcm); @@ -1821,18 +1695,8 @@ aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len, if ((gcm_ctx = calloc(1, sizeof(struct aead_aes_gcm_ctx))) == NULL) return 0; -#ifdef AESNI_CAPABLE - if (AESNI_CAPABLE) { - aesni_set_encrypt_key(key, key_bits, &gcm_ctx->ks.ks); - CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks, - (block128_f)aesni_encrypt); - gcm_ctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; - } else -#endif - { - gcm_ctx->ctr = aes_gcm_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, - key, key_len); - } + AES_set_encrypt_key(key, key_bits, &gcm_ctx->ks.ks); + CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks, (block128_f)AES_encrypt); gcm_ctx->tag_len = tag_len; ctx->aead_state = gcm_ctx; @@ -1873,15 +1737,9 @@ aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len)) return 0; - if (gcm_ctx->ctr) { - if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk, - in_len - bulk, gcm_ctx->ctr)) - return 0; - } else { - if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk, - in_len - bulk)) - return 0; - } + if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk, + in_len - bulk, aes_ctr32_encrypt_ctr128f)) + return 0; CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len); *out_len = in_len + gcm_ctx->tag_len; @@ -1924,15 +1782,9 @@ aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, if (CRYPTO_gcm128_aad(&gcm, ad, ad_len)) return 0; - if (gcm_ctx->ctr) { - if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk, - in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr)) - return 0; - } else { - if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk, - in_len - bulk - gcm_ctx->tag_len)) - return 0; - } + if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk, + in_len - bulk - gcm_ctx->tag_len, aes_ctr32_encrypt_ctr128f)) + return 0; CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len); if (timingsafe_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) { -- cgit v1.2.3-55-g6feb