From 7f64706e37a4402a5f265cf9abfa42aace5733f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Thu, 24 Sep 2015 17:10:01 -0700 Subject: [PATCH] Use armv8 functions for of AES_[en|de]crypt and AES_set_[en|de]crypt_key, if available. This change causes ARM and Aarch64 to use the ARMv8 AES instructions, if provided by the current CPU. Change-Id: I50cb36270139fcf4ce42e5ebb8afe24ffcab22e3 Reviewed-on: https://boringssl-review.googlesource.com/6002 Reviewed-by: David Benjamin Reviewed-by: Adam Langley --- crypto/aes/aes.c | 63 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/crypto/aes/aes.c b/crypto/aes/aes.c index 933aa073..12cd2f3c 100644 --- a/crypto/aes/aes.c +++ b/crypto/aes/aes.c @@ -49,10 +49,49 @@ #include #include +#include #include "internal.h" +#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) +#include + +static int hwaes_capable(void) { + return (OPENSSL_armcap_P & ARMV8_AES) != 0; +} + +int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits, + AES_KEY *key); +int aes_v8_set_decrypt_key(const uint8_t *user_key, const int bits, + AES_KEY *key); +void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); + +#else + +static int hwaes_capable(void) { + return 0; +} + +static int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) { + abort(); +} + +static int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) { + abort(); +} + +static void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + abort(); +} + +static void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + abort(); +} + +#endif + #if defined(OPENSSL_NO_ASM) || \ (!defined(OPENSSL_X86) && !defined(OPENSSL_X86_64) && !defined(OPENSSL_ARM)) @@ -1064,22 +1103,38 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { void asm_AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { - asm_AES_encrypt(in, out, key); + if (hwaes_capable()) { + aes_v8_encrypt(in, out, key); + } else { + asm_AES_encrypt(in, out, key); + } } void asm_AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { - asm_AES_decrypt(in, out, key); + if (hwaes_capable()) { + aes_v8_decrypt(in, out, key); + } else { + asm_AES_decrypt(in, out, key); + } } int asm_AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey); int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { - return asm_AES_set_encrypt_key(key, bits, aeskey); + if (hwaes_capable()) { + return aes_v8_set_encrypt_key(key, bits, aeskey); + } else { + return asm_AES_set_encrypt_key(key, bits, aeskey); + } } int asm_AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey); int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { - return asm_AES_set_decrypt_key(key, bits, aeskey); + if (hwaes_capable()) { + return aes_v8_set_decrypt_key(key, bits, aeskey); + } else { + return asm_AES_set_decrypt_key(key, bits, aeskey); + } } #endif /* OPENSSL_NO_ASM || (!OPENSSL_X86 && !OPENSSL_X86_64 && !OPENSSL_ARM) */