From 3683301ac11ac2b759655a92c2dd6da9227ccc65 Mon Sep 17 00:00:00 2001 From: Adrian Stanciu Date: Thu, 27 Feb 2025 10:59:36 +0200 Subject: [PATCH 1/4] Extract AES CFB implementation to cipher_aes_cfb* --- providers/implementations/ciphers/build.info | 1 + .../implementations/ciphers/cipher_aes.c | 25 +--- .../implementations/ciphers/cipher_aes.h | 4 - .../implementations/ciphers/cipher_aes_cfb.c | 62 +++++++++ .../implementations/ciphers/cipher_aes_cfb.h | 7 + .../ciphers/cipher_aes_cfb_hw.c | 83 ++++++++++++ .../ciphers/cipher_aes_cfb_hw_aesni.inc | 49 +++++++ .../ciphers/cipher_aes_cfb_hw_s390x.inc | 122 ++++++++++++++++++ .../implementations/ciphers/cipher_aes_hw.c | 5 +- .../ciphers/cipher_aes_hw_aesni.inc | 5 +- .../ciphers/cipher_aes_hw_s390x.inc | 91 ------------- 11 files changed, 331 insertions(+), 123 deletions(-) create mode 100644 providers/implementations/ciphers/cipher_aes_cfb.c create mode 100644 providers/implementations/ciphers/cipher_aes_cfb.h create mode 100644 providers/implementations/ciphers/cipher_aes_cfb_hw.c create mode 100644 providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc create mode 100644 providers/implementations/ciphers/cipher_aes_cfb_hw_s390x.inc diff --git a/providers/implementations/ciphers/build.info b/providers/implementations/ciphers/build.info index 1837070c21..bd790c78a0 100644 --- a/providers/implementations/ciphers/build.info +++ b/providers/implementations/ciphers/build.info @@ -100,6 +100,7 @@ SOURCE[$NULL_GOAL]=\ SOURCE[$AES_GOAL]=\ cipher_aes.c cipher_aes_hw.c \ cipher_aes_xts.c cipher_aes_xts_hw.c \ + cipher_aes_cfb.c cipher_aes_cfb_hw.c \ cipher_aes_gcm.c cipher_aes_gcm_hw.c \ cipher_aes_ccm.c cipher_aes_ccm_hw.c \ cipher_aes_wrp.c \ diff --git a/providers/implementations/ciphers/cipher_aes.c b/providers/implementations/ciphers/cipher_aes.c index 280be2dddc..e4d1d0f5f3 100644 --- a/providers/implementations/ciphers/cipher_aes.c +++ b/providers/implementations/ciphers/cipher_aes.c @@ -14,7 +14,7 @@ */ #include "internal/deprecated.h" -/* Dispatch functions for AES cipher modes ecb, cbc, ofb, cfb, ctr */ +/* Dispatch functions for AES cipher modes ecb, cbc, ofb, ctr */ #include "cipher_aes.h" #include "prov/implementations.h" @@ -28,7 +28,7 @@ static void aes_freectx(void *vctx) PROV_AES_CTX *ctx = (PROV_AES_CTX *)vctx; ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); - OPENSSL_clear_free(ctx, sizeof(*ctx)); + OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *aes_dupctx(void *ctx) @@ -53,36 +53,21 @@ IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 256, 128, 0, block) IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 192, 128, 0, block) /* ossl_aes128ecb_functions */ IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 128, 128, 0, block) + /* ossl_aes256cbc_functions */ IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 256, 128, 128, block) /* ossl_aes192cbc_functions */ IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 192, 128, 128, block) /* ossl_aes128cbc_functions */ IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 128, 128, 128, block) + /* ossl_aes256ofb_functions */ IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 256, 8, 128, stream) /* ossl_aes192ofb_functions */ IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 192, 8, 128, stream) /* ossl_aes128ofb_functions */ IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 128, 8, 128, stream) -/* ossl_aes256cfb_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 256, 8, 128, stream) -/* ossl_aes192cfb_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 192, 8, 128, stream) -/* ossl_aes128cfb_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 128, 8, 128, stream) -/* ossl_aes256cfb1_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 256, 8, 128, stream) -/* ossl_aes192cfb1_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 192, 8, 128, stream) -/* ossl_aes128cfb1_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 128, 8, 128, stream) -/* ossl_aes256cfb8_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 256, 8, 128, stream) -/* ossl_aes192cfb8_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 192, 8, 128, stream) -/* ossl_aes128cfb8_functions */ -IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 128, 8, 128, stream) + /* ossl_aes256ctr_functions */ IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 256, 8, 128, stream) /* ossl_aes192ctr_functions */ diff --git a/providers/implementations/ciphers/cipher_aes.h b/providers/implementations/ciphers/cipher_aes.h index c62ac5e7ea..bcfbb2d41b 100644 --- a/providers/implementations/ciphers/cipher_aes.h +++ b/providers/implementations/ciphers/cipher_aes.h @@ -51,11 +51,7 @@ typedef struct prov_aes_ctx_st { } PROV_AES_CTX; #define ossl_prov_cipher_hw_aes_ofb ossl_prov_cipher_hw_aes_ofb128 -#define ossl_prov_cipher_hw_aes_cfb ossl_prov_cipher_hw_aes_cfb128 const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ecb(size_t keybits); const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cbc(size_t keybits); const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ofb128(size_t keybits); -const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb128(size_t keybits); -const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb1(size_t keybits); -const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb8(size_t keybits); const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ctr(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aes_cfb.c b/providers/implementations/ciphers/cipher_aes_cfb.c new file mode 100644 index 0000000000..4da935d5d1 --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_cfb.c @@ -0,0 +1,62 @@ +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + +/* Dispatch functions for AES cipher mode cfb */ + +#include "cipher_aes.h" +#include +#include "cipher_aes_cfb.h" +#include "prov/implementations.h" +#include "prov/providercommon.h" + +static OSSL_FUNC_cipher_freectx_fn aes_freectx; +static OSSL_FUNC_cipher_dupctx_fn aes_dupctx; + +static void aes_freectx(void *vctx) +{ + PROV_AES_CTX *ctx = (PROV_AES_CTX *)vctx; + + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + OPENSSL_clear_free(ctx, sizeof(*ctx)); +} + +static void *aes_dupctx(void *ctx) +{ + PROV_AES_CTX *in = (PROV_AES_CTX *)ctx; + PROV_AES_CTX *ret; + + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); + if (ret == NULL) + return NULL; + in->base.hw->copyctx(&ret->base, &in->base); + + return ret; +} + +/* ossl_aes256cfb_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 256, 8, 128, stream) +/* ossl_aes192cfb_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 192, 8, 128, stream) +/* ossl_aes128cfb_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 128, 8, 128, stream) + +/* ossl_aes256cfb1_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 256, 8, 128, stream) +/* ossl_aes192cfb1_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 192, 8, 128, stream) +/* ossl_aes128cfb1_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 128, 8, 128, stream) + +/* ossl_aes256cfb8_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 256, 8, 128, stream) +/* ossl_aes192cfb8_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 192, 8, 128, stream) +/* ossl_aes128cfb8_functions */ +IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 128, 8, 128, stream) diff --git a/providers/implementations/ciphers/cipher_aes_cfb.h b/providers/implementations/ciphers/cipher_aes_cfb.h new file mode 100644 index 0000000000..be5ba23778 --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_cfb.h @@ -0,0 +1,7 @@ +#include "prov/ciphercommon.h" + +#define ossl_prov_cipher_hw_aes_cfb ossl_prov_cipher_hw_aes_cfb128 + +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb1(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb8(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aes_cfb_hw.c b/providers/implementations/ciphers/cipher_aes_cfb_hw.c new file mode 100644 index 0000000000..150d11511f --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_cfb_hw.c @@ -0,0 +1,83 @@ +/* + * This file uses the low level AES functions (which are deprecated for + * non-internal use) in order to implement provider AES ciphers. + */ +#include "internal/deprecated.h" + +#include +#include "cipher_aes.h" +#include "cipher_aes_cfb.h" + +static int cipher_hw_aes_initkey(PROV_CIPHER_CTX *dat, + const unsigned char *key, size_t keylen) +{ + int ret; + PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; + AES_KEY *ks = &adat->ks.ks; + + dat->ks = ks; + +#ifdef HWAES_CAPABLE + if (HWAES_CAPABLE) { + ret = HWAES_set_encrypt_key(key, keylen * 8, ks); + dat->block = (block128_f)HWAES_encrypt; + dat->stream.cbc = NULL; + } else +#endif +#ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + ret = vpaes_set_encrypt_key(key, keylen * 8, ks); + dat->block = (block128_f)vpaes_encrypt; + dat->stream.cbc = NULL; + } else +#endif + { + ret = AES_set_encrypt_key(key, keylen * 8, ks); + dat->block = (block128_f)AES_encrypt; + dat->stream.cbc = NULL; + } + + if (ret < 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_aes_copyctx, PROV_AES_CTX) + +#define PROV_CIPHER_HW_aes_mode(mode) \ +static const PROV_CIPHER_HW aes_##mode = { \ + cipher_hw_aes_initkey, \ + ossl_cipher_hw_generic_##mode, \ + cipher_hw_aes_copyctx \ +}; \ +PROV_CIPHER_HW_declare(mode) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_##mode(size_t keybits) \ +{ \ + PROV_CIPHER_HW_select(mode) \ + return &aes_##mode; \ +} + +#if defined(AESNI_CAPABLE) +# include "cipher_aes_cfb_hw_aesni.inc" +#elif defined(SPARC_AES_CAPABLE) +# include "cipher_aes_hw_t4.inc" +#elif defined(S390X_aes_128_CAPABLE) +# include "cipher_aes_cfb_hw_s390x.inc" +#elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64 +# include "cipher_aes_hw_rv64i.inc" +#elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32 +# include "cipher_aes_hw_rv32i.inc" +#elif defined(ARMv8_HWAES_CAPABLE) +# include "cipher_aes_hw_armv8.inc" +#else +/* The generic case */ +# define PROV_CIPHER_HW_declare(mode) +# define PROV_CIPHER_HW_select(mode) +#endif + +PROV_CIPHER_HW_aes_mode(cfb128) +PROV_CIPHER_HW_aes_mode(cfb1) +PROV_CIPHER_HW_aes_mode(cfb8) diff --git a/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc new file mode 100644 index 0000000000..4bd46cece6 --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc @@ -0,0 +1,49 @@ +/* + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/*- + * AES-NI support for AES mode cfb. + * This file is included by cipher_aes_cfb_hw.c + */ + +#define cipher_hw_aesni_cfb128 ossl_cipher_hw_generic_cfb128 +#define cipher_hw_aesni_cfb8 ossl_cipher_hw_generic_cfb8 +#define cipher_hw_aesni_cfb1 ossl_cipher_hw_generic_cfb1 + +static int cipher_hw_aesni_initkey(PROV_CIPHER_CTX *dat, + const unsigned char *key, size_t keylen) +{ + int ret; + PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; + AES_KEY *ks = &adat->ks.ks; + + dat->ks = ks; + + ret = aesni_set_encrypt_key(key, keylen * 8, ks); + + dat->block = (block128_f) aesni_encrypt; + dat->stream.cbc = NULL; + + if (ret < 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +#define PROV_CIPHER_HW_declare(mode) \ +static const PROV_CIPHER_HW aesni_##mode = { \ + cipher_hw_aesni_initkey, \ + cipher_hw_aesni_##mode, \ + cipher_hw_aes_copyctx \ +}; +#define PROV_CIPHER_HW_select(mode) \ +if (AESNI_CAPABLE) \ + return &aesni_##mode; diff --git a/providers/implementations/ciphers/cipher_aes_cfb_hw_s390x.inc b/providers/implementations/ciphers/cipher_aes_cfb_hw_s390x.inc new file mode 100644 index 0000000000..5c6958af30 --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_cfb_hw_s390x.inc @@ -0,0 +1,122 @@ +/* + * Copyright 2001-2024 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * IBM S390X support for AES mode cfb. + * This file is included by cipher_aes_cfb_hw.c + */ + +#include "s390x_arch.h" + +#include + +#define s390x_aes_cfb1_initkey cipher_hw_aes_initkey +#define s390x_aes_cfb1_cipher_hw ossl_cipher_hw_generic_cfb1 + +#define S390X_aes_128_cfb128_CAPABLE S390X_aes_128_cfb_CAPABLE +#define S390X_aes_192_cfb128_CAPABLE S390X_aes_192_cfb_CAPABLE +#define S390X_aes_256_cfb128_CAPABLE S390X_aes_256_cfb_CAPABLE + +static int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat, + const unsigned char *key, size_t keylen) +{ + PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; + + adat->plat.s390x.fc = S390X_AES_FC(keylen); + adat->plat.s390x.fc |= 16 << 24; /* 16 bytes cipher feedback */ + memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); + return 1; +} + +static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, + const unsigned char *in, size_t len) +{ + PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; + unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT; + int n = dat->num; + int rem; + unsigned char tmp; + + memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); + while (n && len) { + tmp = *in; + *out = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp; + adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp; + n = (n + 1) & 0xf; + --len; + ++in; + ++out; + } + + rem = len & 0xf; + + len &= ~(size_t)0xf; + if (len) { + s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier, + &adat->plat.s390x.param.kmo_kmf); + + out += len; + in += len; + } + + if (rem) { + s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16, + adat->plat.s390x.param.kmo_kmf.cv, + S390X_AES_FC(dat->keylen), + adat->plat.s390x.param.kmo_kmf.k); + + while (rem--) { + tmp = in[n]; + out[n] = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp; + adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp; + ++n; + } + } + + memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); + dat->num = n; + return 1; +} + +static int s390x_aes_cfb8_initkey(PROV_CIPHER_CTX *dat, + const unsigned char *key, size_t keylen) +{ + PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; + + adat->plat.s390x.fc = S390X_AES_FC(keylen); + adat->plat.s390x.fc |= 1 << 24; /* 1 byte cipher feedback */ + memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); + return 1; +} + +static int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, + const unsigned char *in, size_t len) +{ + PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; + unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT; + + memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); + s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier, + &adat->plat.s390x.param.kmo_kmf); + memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); + return 1; +} + +#define PROV_CIPHER_HW_declare(mode) \ +static const PROV_CIPHER_HW s390x_aes_##mode = { \ + s390x_aes_##mode##_initkey, \ + s390x_aes_##mode##_cipher_hw, \ + cipher_hw_aes_copyctx \ +}; +#define PROV_CIPHER_HW_select(mode) \ +if ((keybits == 128 && S390X_aes_128_##mode##_CAPABLE) \ + || (keybits == 192 && S390X_aes_192_##mode##_CAPABLE) \ + || (keybits == 256 && S390X_aes_256_##mode##_CAPABLE)) \ + return &s390x_aes_##mode; + diff --git a/providers/implementations/ciphers/cipher_aes_hw.c b/providers/implementations/ciphers/cipher_aes_hw.c index a3b72d9f72..d06efb5438 100644 --- a/providers/implementations/ciphers/cipher_aes_hw.c +++ b/providers/implementations/ciphers/cipher_aes_hw.c @@ -146,7 +146,7 @@ const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_##mode(size_t keybits) \ # include "cipher_aes_hw_rv64i.inc" #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32 # include "cipher_aes_hw_rv32i.inc" -#elif defined (ARMv8_HWAES_CAPABLE) +#elif defined(ARMv8_HWAES_CAPABLE) # include "cipher_aes_hw_armv8.inc" #else /* The generic case */ @@ -157,7 +157,4 @@ const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_##mode(size_t keybits) \ PROV_CIPHER_HW_aes_mode(cbc) PROV_CIPHER_HW_aes_mode(ecb) PROV_CIPHER_HW_aes_mode(ofb128) -PROV_CIPHER_HW_aes_mode(cfb128) -PROV_CIPHER_HW_aes_mode(cfb1) -PROV_CIPHER_HW_aes_mode(cfb8) PROV_CIPHER_HW_aes_mode(ctr) diff --git a/providers/implementations/ciphers/cipher_aes_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_hw_aesni.inc index 33b9046054..fe1941bd1f 100644 --- a/providers/implementations/ciphers/cipher_aes_hw_aesni.inc +++ b/providers/implementations/ciphers/cipher_aes_hw_aesni.inc @@ -8,14 +8,11 @@ */ /*- - * AES-NI support for AES modes ecb, cbc, ofb, cfb, ctr. + * AES-NI support for AES modes ecb, cbc, ofb, ctr. * This file is included by cipher_aes_hw.c */ #define cipher_hw_aesni_ofb128 ossl_cipher_hw_generic_ofb128 -#define cipher_hw_aesni_cfb128 ossl_cipher_hw_generic_cfb128 -#define cipher_hw_aesni_cfb8 ossl_cipher_hw_generic_cfb8 -#define cipher_hw_aesni_cfb1 ossl_cipher_hw_generic_cfb1 #define cipher_hw_aesni_ctr ossl_cipher_hw_generic_ctr static int cipher_hw_aesni_initkey(PROV_CIPHER_CTX *dat, diff --git a/providers/implementations/ciphers/cipher_aes_hw_s390x.inc b/providers/implementations/ciphers/cipher_aes_hw_s390x.inc index 6c4a4cc995..9dc2d9087f 100644 --- a/providers/implementations/ciphers/cipher_aes_hw_s390x.inc +++ b/providers/implementations/ciphers/cipher_aes_hw_s390x.inc @@ -17,18 +17,13 @@ #include #define s390x_aes_cbc_initkey cipher_hw_aes_initkey -#define s390x_aes_cfb1_initkey cipher_hw_aes_initkey #define s390x_aes_ctr_initkey cipher_hw_aes_initkey #define s390x_aes_cbc_cipher_hw ossl_cipher_hw_generic_cbc -#define s390x_aes_cfb1_cipher_hw ossl_cipher_hw_generic_cfb1 #define s390x_aes_ctr_cipher_hw ossl_cipher_hw_generic_ctr #define S390X_aes_128_ofb128_CAPABLE S390X_aes_128_ofb_CAPABLE #define S390X_aes_192_ofb128_CAPABLE S390X_aes_192_ofb_CAPABLE #define S390X_aes_256_ofb128_CAPABLE S390X_aes_256_ofb_CAPABLE -#define S390X_aes_128_cfb128_CAPABLE S390X_aes_128_cfb_CAPABLE -#define S390X_aes_192_cfb128_CAPABLE S390X_aes_192_cfb_CAPABLE -#define S390X_aes_256_cfb128_CAPABLE S390X_aes_256_cfb_CAPABLE static int s390x_aes_ecb_initkey(PROV_CIPHER_CTX *dat, const unsigned char *key, size_t keylen) @@ -105,91 +100,6 @@ static int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, return 1; } -static int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat, - const unsigned char *key, size_t keylen) -{ - PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; - - adat->plat.s390x.fc = S390X_AES_FC(keylen); - adat->plat.s390x.fc |= 16 << 24; /* 16 bytes cipher feedback */ - memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); - return 1; -} - -static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, - const unsigned char *in, size_t len) -{ - PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; - unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT; - int n = dat->num; - int rem; - unsigned char tmp; - - memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); - while (n && len) { - tmp = *in; - *out = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp; - adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp; - n = (n + 1) & 0xf; - --len; - ++in; - ++out; - } - - rem = len & 0xf; - - len &= ~(size_t)0xf; - if (len) { - s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier, - &adat->plat.s390x.param.kmo_kmf); - - out += len; - in += len; - } - - if (rem) { - s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16, - adat->plat.s390x.param.kmo_kmf.cv, - S390X_AES_FC(dat->keylen), - adat->plat.s390x.param.kmo_kmf.k); - - while (rem--) { - tmp = in[n]; - out[n] = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp; - adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp; - ++n; - } - } - - memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); - dat->num = n; - return 1; -} - -static int s390x_aes_cfb8_initkey(PROV_CIPHER_CTX *dat, - const unsigned char *key, size_t keylen) -{ - PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; - - adat->plat.s390x.fc = S390X_AES_FC(keylen); - adat->plat.s390x.fc |= 1 << 24; /* 1 byte cipher feedback */ - memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); - return 1; -} - -static int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, - const unsigned char *in, size_t len) -{ - PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; - unsigned int modifier = adat->base.enc ? 0 : S390X_DECRYPT; - - memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); - s390x_kmf(in, len, out, adat->plat.s390x.fc | modifier, - &adat->plat.s390x.param.kmo_kmf); - memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); - return 1; -} - #define PROV_CIPHER_HW_declare(mode) \ static const PROV_CIPHER_HW s390x_aes_##mode = { \ s390x_aes_##mode##_initkey, \ @@ -201,4 +111,3 @@ if ((keybits == 128 && S390X_aes_128_##mode##_CAPABLE) \ || (keybits == 192 && S390X_aes_192_##mode##_CAPABLE) \ || (keybits == 256 && S390X_aes_256_##mode##_CAPABLE)) \ return &s390x_aes_##mode; - From d7281ea20653edfe5b9c7844bbd1f67692af83fa Mon Sep 17 00:00:00 2001 From: Adrian Stanciu Date: Wed, 5 Mar 2025 15:55:59 +0200 Subject: [PATCH 2/4] Add VAES dispatcher logic --- .../ciphers/cipher_aes_cfb_hw_aesni.inc | 54 +++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc index 4bd46cece6..9fa96c8698 100644 --- a/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc +++ b/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc @@ -8,14 +8,45 @@ */ /*- - * AES-NI support for AES mode cfb. + * AES-NI and VAES support for AES mode cfb. * This file is included by cipher_aes_cfb_hw.c */ +#include + +#define cipher_hw_vaes_cfb128 aes_cfb128_vaes_encdec_wrapper +#define cipher_hw_vaes_cfb8 ossl_cipher_hw_generic_cfb8 +#define cipher_hw_vaes_cfb1 ossl_cipher_hw_generic_cfb1 + #define cipher_hw_aesni_cfb128 ossl_cipher_hw_generic_cfb128 #define cipher_hw_aesni_cfb8 ossl_cipher_hw_generic_cfb8 #define cipher_hw_aesni_cfb1 ossl_cipher_hw_generic_cfb1 +// active when AES-NI, AVX512F, and VAES are detected +static int aes_cfb128_vaes_encdec_wrapper( + PROV_CIPHER_CTX* dat, + unsigned char *out, + const unsigned char *in, + size_t len) +{ + assert(dat != NULL); + assert(out != NULL); + assert(in != NULL); + + assert(dat->mode == EVP_CIPH_CFB_MODE); + + assert(dat->keylen == 16 || dat->keylen == 24 || dat->keylen == 32); + assert(dat->ks != NULL); + + assert(dat->ivlen == 16); + assert(dat->iv != NULL); + + assert(dat->enc == 0 || dat->enc == 1); + + return ossl_cipher_hw_generic_cfb128(dat, out, in, len); +} + +// generates AES round keys for AES-NI and VAES implementations static int cipher_hw_aesni_initkey(PROV_CIPHER_CTX *dat, const unsigned char *key, size_t keylen) { @@ -38,12 +69,29 @@ static int cipher_hw_aesni_initkey(PROV_CIPHER_CTX *dat, return 1; } +#define VAES_BIT (1<<(41-32)) +#define AVX512F_BIT (1<<16) + +#define AVX512F_VAES_CAPABLE ( \ + (OPENSSL_ia32cap_P[3] & VAES_BIT) \ + && \ + (OPENSSL_ia32cap_P[2] & AVX512F_BIT) \ +) + #define PROV_CIPHER_HW_declare(mode) \ static const PROV_CIPHER_HW aesni_##mode = { \ cipher_hw_aesni_initkey, \ cipher_hw_aesni_##mode, \ cipher_hw_aes_copyctx \ +}; \ +static const PROV_CIPHER_HW vaes_##mode = { \ + cipher_hw_aesni_initkey, \ + cipher_hw_vaes_##mode, \ + cipher_hw_aes_copyctx \ }; #define PROV_CIPHER_HW_select(mode) \ -if (AESNI_CAPABLE) \ - return &aesni_##mode; +if (AESNI_CAPABLE) { \ + if (AVX512F_VAES_CAPABLE) \ + return &vaes_##mode; \ + return &aesni_##mode; \ +} From b4c5cab289b3d15b9c596246cbb4629a94442961 Mon Sep 17 00:00:00 2001 From: Adrian Stanciu Date: Mon, 17 Mar 2025 02:01:07 +0200 Subject: [PATCH 3/4] Add AES-CFB128 operations with AVX-512 and VAES --- crypto/aes/asm/aes-cfb-avx512.pl | 224 ++++++++++++++++++ crypto/aes/build.info | 3 +- crypto/modes/cfb128.c | 6 + include/crypto/aes_platform.h | 7 + .../implementations/ciphers/cipher_aes_cfb.c | 9 + .../implementations/ciphers/cipher_aes_cfb.h | 9 + .../ciphers/cipher_aes_cfb_hw.c | 9 + .../ciphers/cipher_aes_cfb_hw_aesni.inc | 22 +- 8 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 crypto/aes/asm/aes-cfb-avx512.pl diff --git a/crypto/aes/asm/aes-cfb-avx512.pl b/crypto/aes/asm/aes-cfb-avx512.pl new file mode 100644 index 0000000000..7f0020fb98 --- /dev/null +++ b/crypto/aes/asm/aes-cfb-avx512.pl @@ -0,0 +1,224 @@ +#! /usr/bin/env perl +# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright (c) 2025, Intel Corporation. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html +# +# Implements AES-CFB128 encryption and decryption with Intel(R) VAES + +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; +*STDOUT=*OUT; + +$code=".text\n"; + +################################################################# +# Signature: +# +# void aes_cfb128_vaes_enc( +# const unsigned char *in, +# unsigned char *out, +# size_t len, +# const AES_KEY *ks, +# const unsigned char ivec[16], +# /*in-out*/ int *num); +# +# Preconditions: +# - all pointers are valid (not NULL...) +# - AES key schedule and rounds in `ks` are precomputed +# +# Invariants: +# - `*num` is between 0 and 15 +################################################################# + +$code.=<<___; +.globl aes_cfb128_vaes_enc +.type aes_cfb128_vaes_enc,\@function,6 +.align 16 +aes_cfb128_vaes_enc: +.cfi_startproc + endbranch +___ + +$inp="%rdi"; # arg0 +$out="%rsi"; # arg1 +$len="%rdx"; # arg2 + +$key_original="%rcx"; # arg3 +$key_backup="%r10"; +$key_crt="%r10"; + +$ivp="%r8"; # arg4 +$nump="%r9"; # arg5 + +$num="%r11"; +$left="%rcx"; +$mask="%rax"; + +$rounds="%r11d"; + +$rnd0key="%xmm0"; +$rndNkey="%xmm1"; +$temp="%xmm2"; +$plain="%xmm3"; + +sub vaes_encrypt_block() { + my ($aes_enc_loop_label)=@_; + +$code.=<<___; + vmovups ($key_crt),$rnd0key # load round 0 key + vmovups 16($key_crt),$rndNkey # load round 1 key + lea 32($key_crt),$key_crt # key points to the 2nd round key + vpxor $rnd0key,$temp,$temp # pre-whitening + +$aes_enc_loop_label: + vaesenc $rndNkey,$temp,$temp # encrypt with current round key + dec $rounds + vmovups ($key_crt),$rndNkey # load next round key + lea 16($key_crt),$key_crt # key points to the next round key + jnz $aes_enc_loop_label # process all encryption rounds but the last + + vaesenclast $rndNkey,$temp,$temp # encrypt with the last round key +___ +} + +$code.=<<___; + + movsl ($nump),$num # $num is the current byte index in the first partial block + # $num belongs to 0..15; non-zero means a partial first block + + test $len,$len # return early if $len==0, unlikely to occur + jz .Laes_cfb128_vaes_enc + + test $num,$num # check if the first block is partial + jz .Laes_cfb128_enc_mid + +########################################################### +# first partial block pre-processing +########################################################### + + mov $key_original,$key_backup # make room for variable shl with cl + + mov \$0x10,$left # first block is partial + sub $num,$left # calculate how many bytes $left to process in the block + cmp $len,$left # + cmova $len,$left # $left = min(16-$num,$len) + + mov \$1,$mask # build a mask with the least significant $left bits set + shlq %cl,$mask # $left is left shift counter + dec $mask # $mask is 2^$left-1 + kmovq $mask,%k1 + + mov $num,%rax # keep in-out $num in %al + add $left,%rax # advance $num + and \$0x0F,%al # wrap-around $num in a 16-byte block + + leaq ($num,$ivp),%r11 # process $left iv bytes + vmovdqu8 (%r11),%xmm0 + vmovdqu8 ($inp),%xmm1 # process $left input bytes + vpxor %xmm0,%xmm1,%xmm2 # CipherFeedBack XOR + vmovdqu8 %xmm2,($out){%k1} # write $left output bytes + vmovdqu8 %xmm2,(%r11){%k1} # write $left chained/streaming input bytes + + add $left,$inp # advance pointers + add $left,$out + sub $left,$len + jz .Laes_cfb128_enc_end # return early if no AES encryption required + + mov $key_backup,$key_original # restore "key_original" as arg3 + +.Laes_cfb128_enc_mid: + +########################################################### +# inner full blocks processing +########################################################### + + vmovups ($ivp),$temp # load iv + + cmp \$0x10,$len # any full plaintext blocks left ? + jb .Laes_cfb128_enc_post + +.Loop_aes_cfb128_enc_main: + sub \$0x10,$len + + mov $key_original,$key_crt + mov 240($key_crt),$rounds # load AES rounds + # 240 is the byte-offset of the rounds field in AES_KEY + + vmovups ($inp),$plain # load plaintext block + lea 16($inp),$inp # inp points to next plaintext +___ + + &vaes_encrypt_block(".Loop_aes_enc_mid"); + +$code.=<<___; + vpxor $plain,$temp,$temp # CipherFeedBack XOR + cmp \$0x10,$len + vmovups $temp,($out) # write ciphertext + lea 16($out),$out # out points to the next output block + jge .Loop_aes_cfb128_enc_main + + xor %eax,%eax # reset num when processing full blocks + + vmovups $temp,($ivp) # latest ciphertext block is next encryption input + +.Laes_cfb128_enc_post: + +########################################################### +# last partial block post-processing +########################################################### + + test $len,$len + jz .Laes_cfb128_enc_end + + mov $key_original,$key_crt + mov 240($key_crt),$rounds # load AES rounds + # 240 is the byte-offset of the rounds field in AES_KEY +___ + + &vaes_encrypt_block(".Loop_aes_enc_post"); + +$code.=<<___; + mov $len,%rax # num=$len + mov \$1,%r11 # build a mask with the least significant $len bits set + mov %dl,%cl # $len is left shift counter less than 16 + shlq %cl,%r11 + dec %r11 # mask is 2^$len-1 + kmovq %r11,%k1 + + vmovdqu8 ($inp),%xmm1{%k1}{z} # read $len input bytes + vpxor $temp,%xmm1,%xmm0 # CipherFeedBack XOR + vmovdqu8 %xmm0,($out){%k1} # write $len output bytes + vmovdqu8 %xmm0,($ivp) # write $len chained/streaming input bytes + +.Laes_cfb128_enc_end: + + mov %eax,($nump) # num is in/out, update for future/chained calls + + vpxor $rnd0key,$rnd0key,$rnd0key # zeroize + vpxor $rndNkey,$rndNkey,$rndNkey # zeroize + vpxor $plain,$plain,$plain # zeroize + vpxor $temp,$temp,$temp # zeroize + +.Laes_cfb128_vaes_enc: + ret +.cfi_endproc +.size aes_cfb128_vaes_enc,.-aes_cfb128_vaes_enc +___ + +print $code; + +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/aes/build.info b/crypto/aes/build.info index 11d27d0451..b285428c34 100644 --- a/crypto/aes/build.info +++ b/crypto/aes/build.info @@ -10,7 +10,7 @@ IF[{- !$disabled{asm} -}] $AESASM_x86_64=\ aes-x86_64.s vpaes-x86_64.s bsaes-x86_64.s aesni-x86_64.s \ aesni-sha1-x86_64.s aesni-sha256-x86_64.s aesni-mb-x86_64.s \ - aesni-xts-avx512.s + aesni-xts-avx512.s aes-cfb-avx512.s $AESDEF_x86_64=AES_ASM VPAES_ASM BSAES_ASM $AESASM_ia64=aes_core.c aes_cbc.c aes-ia64.s @@ -105,6 +105,7 @@ GENERATE[aes-x86_64.s]=asm/aes-x86_64.pl GENERATE[vpaes-x86_64.s]=asm/vpaes-x86_64.pl GENERATE[bsaes-x86_64.s]=asm/bsaes-x86_64.pl GENERATE[aesni-x86_64.s]=asm/aesni-x86_64.pl +GENERATE[aes-cfb-avx512.s]=asm/aes-cfb-avx512.pl GENERATE[aesni-sha1-x86_64.s]=asm/aesni-sha1-x86_64.pl GENERATE[aesni-sha256-x86_64.s]=asm/aesni-sha256-x86_64.pl GENERATE[aesni-mb-x86_64.s]=asm/aesni-mb-x86_64.pl diff --git a/crypto/modes/cfb128.c b/crypto/modes/cfb128.c index 2d37bcb586..5b5da6e868 100644 --- a/crypto/modes/cfb128.c +++ b/crypto/modes/cfb128.c @@ -11,6 +11,8 @@ #include #include "crypto/modes.h" +#include + #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) typedef size_t size_t_aX __attribute((__aligned__(1))); #else @@ -52,6 +54,7 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, break; # endif while (len >= 16) { + assert(n == 0); (*block) (ivec, ivec, key); for (; n < 16; n += sizeof(size_t)) { *(size_t_aX *)(out + n) = @@ -64,6 +67,7 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, n = 0; } if (len) { + assert(n == 0); (*block) (ivec, ivec, key); while (len--) { out[n] = ivec[n] ^= in[n]; @@ -102,6 +106,7 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, break; # endif while (len >= 16) { + assert(n == 0); (*block) (ivec, ivec, key); for (; n < 16; n += sizeof(size_t)) { size_t t = *(size_t_aX *)(in + n); @@ -115,6 +120,7 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, n = 0; } if (len) { + assert(n == 0); (*block) (ivec, ivec, key); while (len--) { unsigned char c; diff --git a/include/crypto/aes_platform.h b/include/crypto/aes_platform.h index 67271b6df4..e0a4465f2d 100644 --- a/include/crypto/aes_platform.h +++ b/include/crypto/aes_platform.h @@ -199,6 +199,13 @@ int aesni_set_encrypt_key(const unsigned char *userKey, int bits, int aesni_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); +void aes_cfb128_vaes_enc(const unsigned char* in, unsigned char* out, + size_t len, const AES_KEY *ks, + const unsigned char ivec[16], int* num); +void aes_cfb128_vaes_dec(const unsigned char* in, unsigned char* out, + size_t len, const AES_KEY *ks, + const unsigned char ivec[16], int* num); + void aesni_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); void aesni_decrypt(const unsigned char *in, unsigned char *out, diff --git a/providers/implementations/ciphers/cipher_aes_cfb.c b/providers/implementations/ciphers/cipher_aes_cfb.c index 4da935d5d1..c2370f3365 100644 --- a/providers/implementations/ciphers/cipher_aes_cfb.c +++ b/providers/implementations/ciphers/cipher_aes_cfb.c @@ -1,3 +1,12 @@ +/* + * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + /* * AES low level APIs are deprecated for public use, but still ok for internal * use where we're using them to implement the higher level EVP interface, as is diff --git a/providers/implementations/ciphers/cipher_aes_cfb.h b/providers/implementations/ciphers/cipher_aes_cfb.h index be5ba23778..7e05c78b7a 100644 --- a/providers/implementations/ciphers/cipher_aes_cfb.h +++ b/providers/implementations/ciphers/cipher_aes_cfb.h @@ -1,3 +1,12 @@ +/* + * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + #include "prov/ciphercommon.h" #define ossl_prov_cipher_hw_aes_cfb ossl_prov_cipher_hw_aes_cfb128 diff --git a/providers/implementations/ciphers/cipher_aes_cfb_hw.c b/providers/implementations/ciphers/cipher_aes_cfb_hw.c index 150d11511f..bd7ae74918 100644 --- a/providers/implementations/ciphers/cipher_aes_cfb_hw.c +++ b/providers/implementations/ciphers/cipher_aes_cfb_hw.c @@ -1,3 +1,12 @@ +/* + * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + /* * This file uses the low level AES functions (which are deprecated for * non-internal use) in order to implement provider AES ciphers. diff --git a/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc index 9fa96c8698..f8d1cc08f9 100644 --- a/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc +++ b/providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc @@ -8,7 +8,7 @@ */ /*- - * AES-NI and VAES support for AES mode cfb. + * AES-NI and VAES support for AES CFB mode. * This file is included by cipher_aes_cfb_hw.c */ @@ -43,7 +43,25 @@ static int aes_cfb128_vaes_encdec_wrapper( assert(dat->enc == 0 || dat->enc == 1); - return ossl_cipher_hw_generic_cfb128(dat, out, in, len); + int num = dat->num; + assert(num < 16); + if (num < 0) { + // from CRYPTO_cfb128_encrypt + dat->num = -1; + return 1; + } + + if (dat->enc) { + aes_cfb128_vaes_enc(in, out, len, dat->ks, dat->iv, &num); + } else { + CRYPTO_cfb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc, + dat->block); + } + + assert(num < 16); + dat->num = num; + + return 1; } // generates AES round keys for AES-NI and VAES implementations From 0e7c7fe6856c513f0a034a260d37b12382108e55 Mon Sep 17 00:00:00 2001 From: "Stanciu, Adrian" Date: Wed, 19 Mar 2025 05:02:41 -0700 Subject: [PATCH 4/4] replace ps --- crypto/aes/asm/aes-cfb-avx512.pl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crypto/aes/asm/aes-cfb-avx512.pl b/crypto/aes/asm/aes-cfb-avx512.pl index 7f0020fb98..0155bac31a 100644 --- a/crypto/aes/asm/aes-cfb-avx512.pl +++ b/crypto/aes/asm/aes-cfb-avx512.pl @@ -79,15 +79,15 @@ sub vaes_encrypt_block() { my ($aes_enc_loop_label)=@_; $code.=<<___; - vmovups ($key_crt),$rnd0key # load round 0 key - vmovups 16($key_crt),$rndNkey # load round 1 key + vmovdqu ($key_crt),$rnd0key # load round 0 key + vmovdqu 16($key_crt),$rndNkey # load round 1 key lea 32($key_crt),$key_crt # key points to the 2nd round key vpxor $rnd0key,$temp,$temp # pre-whitening $aes_enc_loop_label: vaesenc $rndNkey,$temp,$temp # encrypt with current round key dec $rounds - vmovups ($key_crt),$rndNkey # load next round key + vmovdqu ($key_crt),$rndNkey # load next round key lea 16($key_crt),$key_crt # key points to the next round key jnz $aes_enc_loop_label # process all encryption rounds but the last @@ -146,7 +146,7 @@ $code.=<<___; # inner full blocks processing ########################################################### - vmovups ($ivp),$temp # load iv + vmovdqu ($ivp),$temp # load iv cmp \$0x10,$len # any full plaintext blocks left ? jb .Laes_cfb128_enc_post @@ -158,7 +158,7 @@ $code.=<<___; mov 240($key_crt),$rounds # load AES rounds # 240 is the byte-offset of the rounds field in AES_KEY - vmovups ($inp),$plain # load plaintext block + vmovdqu ($inp),$plain # load plaintext block lea 16($inp),$inp # inp points to next plaintext ___ @@ -167,13 +167,13 @@ ___ $code.=<<___; vpxor $plain,$temp,$temp # CipherFeedBack XOR cmp \$0x10,$len - vmovups $temp,($out) # write ciphertext + vmovdqu $temp,($out) # write ciphertext lea 16($out),$out # out points to the next output block jge .Loop_aes_cfb128_enc_main xor %eax,%eax # reset num when processing full blocks - vmovups $temp,($ivp) # latest ciphertext block is next encryption input + vmovdqu $temp,($ivp) # latest ciphertext block is next encryption input .Laes_cfb128_enc_post: