From f4f6661af1bf15fe7416dcca8f5fc84dcabd5242 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Thu, 21 May 2020 11:58:38 +0200 Subject: [PATCH 1/2] Enable legacy AES API to use AESNI or VPAES if available When no assembler support is available, we fall back to either the constant time C implementation or the non-constant time C code implementation. This is controlled by -DOPENSSL_AES_CONST_TIME. So this makes the legacy API completely constant time, if OPENSSL_AES_CONST_TIME is defined, otherwise it uses constant time assembler implementations when available, and may fall back to the non-constant time implementation. This works so far only for intel and aarch64 CPUs. [extended tests] --- crypto/aes/aes_core.c | 15 ++++++++ crypto/evp/e_aes.c | 82 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/crypto/aes/aes_core.c b/crypto/aes/aes_core.c index ad00c729e70..36e35dfdf49 100644 --- a/crypto/aes/aes_core.c +++ b/crypto/aes/aes_core.c @@ -43,6 +43,21 @@ #include #include "aes_local.h" +#if defined(OPENSSL_CPUID_OBJ) && !defined(AES_ASM) +int aes_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int aes_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +void aes_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void aes_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +# define AES_set_encrypt_key aes_set_encrypt_key +# define AES_set_decrypt_key aes_set_decrypt_key +# define AES_encrypt aes_encrypt +# define AES_decrypt aes_decrypt +#endif + #if defined(OPENSSL_AES_CONST_TIME) && !defined(AES_ASM) typedef union { unsigned char b[8]; diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index 405ddbf9bf0..8dbc947157d 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -100,6 +100,21 @@ typedef struct { #define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) +#if defined(OPENSSL_CPUID_OBJ) && !defined(AES_ASM) +int aes_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int aes_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +void aes_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void aes_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +# define AES_set_encrypt_key aes_set_encrypt_key +# define AES_set_dncrypt_key aes_set_decrypt_key +# define AES_encrypt aes_encrypt +# define AES_dncrypt aes_dncrypt +#endif + #ifdef VPAES_ASM int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); @@ -4287,3 +4302,70 @@ BLOCK_CIPHER_custom(NID_aes, 192, 16, 12, ocb, OCB, BLOCK_CIPHER_custom(NID_aes, 256, 16, 12, ocb, OCB, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) #endif /* OPENSSL_NO_OCB */ + +#if defined(OPENSSL_CPUID_OBJ) && !defined(AES_ASM) +# undef AES_set_encrypt_key +# undef AES_set_decrypt_key +# undef AES_encrypt +# undef AES_decrypt + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ +# ifdef AESNI_CAPABLE + if (AESNI_CAPABLE) + return aesni_set_encrypt_key(userKey, bits, key); +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) + return vpaes_set_encrypt_key(userKey, bits, key); +# endif + return aes_set_encrypt_key(userKey, bits, key); +} + +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ +# ifdef AESNI_CAPABLE + if (AESNI_CAPABLE) + return aesni_set_decrypt_key(userKey, bits, key); +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) + return vpaes_set_decrypt_key(userKey, bits, key); +# endif + return aes_set_decrypt_key(userKey, bits, key); +} + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) +{ +# ifdef AESNI_CAPABLE + if (AESNI_CAPABLE) + aesni_encrypt(in, out, key); + else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) + vpaes_encrypt(in, out, key); + else +# endif + aes_encrypt(in, out, key); +} + +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) +{ +# ifdef AESNI_CAPABLE + if (AESNI_CAPABLE) + aesni_decrypt(in, out, key); + else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) + vpaes_decrypt(in, out, key); + else +# endif + aes_decrypt(in, out, key); +} +#endif From 5de700ae03e0fdb8ca738f4c4912107437399d87 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Sat, 23 May 2020 23:43:36 +0200 Subject: [PATCH 2/2] Enable AES_cbc_encrypt to use AESNI or VPAES if available This makes the legacy API AES_cbc_encrypt outperform the EVP API. [extended tests] --- crypto/aes/aes_cbc.c | 7 +++++++ crypto/evp/e_aes.c | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/crypto/aes/aes_cbc.c b/crypto/aes/aes_cbc.c index 342841fc4ff..c1195bd432b 100644 --- a/crypto/aes/aes_cbc.c +++ b/crypto/aes/aes_cbc.c @@ -10,6 +10,13 @@ #include #include +#if defined(OPENSSL_CPUID_OBJ) && !defined(AES_ASM) +void aes_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec, const int enc); +# define AES_cbc_encrypt aes_cbc_encrypt +#endif + void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, const AES_KEY *key, unsigned char *ivec, const int enc) diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index 8dbc947157d..954425e6552 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -109,10 +109,14 @@ void aes_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); void aes_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); +void aes_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec, const int enc); # define AES_set_encrypt_key aes_set_encrypt_key # define AES_set_dncrypt_key aes_set_decrypt_key # define AES_encrypt aes_encrypt # define AES_dncrypt aes_dncrypt +# define AES_cbc_encrypt aes_cbc_encrypt #endif #ifdef VPAES_ASM @@ -4308,6 +4312,7 @@ BLOCK_CIPHER_custom(NID_aes, 256, 16, 12, ocb, OCB, # undef AES_set_decrypt_key # undef AES_encrypt # undef AES_decrypt +# undef AES_cbc_encrypt int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key) @@ -4368,4 +4373,21 @@ void AES_decrypt(const unsigned char *in, unsigned char *out, # endif aes_decrypt(in, out, key); } + +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec, const int enc) +{ +# ifdef AESNI_CAPABLE + if (AESNI_CAPABLE) + aesni_cbc_encrypt(in, out, len, key, ivec, enc); + else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) + vpaes_cbc_encrypt(in, out, len, key, ivec, enc); + else +# endif + aes_cbc_encrypt(in, out, len, key, ivec, enc); +} #endif