From 3324b55bde96d4098df2f1138be5fd243206ceba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2017 11:41:32 -0700 Subject: lib: crypt: Prepare the existing code to switch to Intel AES hardware instructions. Rename the old struct aes_key as an intermediate struct aes_key_rj and wrap it in a union so we can chose an alternate aes_key struct when using Intel AES hardware. Rename the original software implementations of: AES_set_encrypt_key() AES_set_decrypt_key() AES_encrypt() AES_decrypt() by adding an _rj on the end, and call them via a wrapper function. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13008 Based on original work by Justin Maggard Signed-off-by: Jeremy Allison Reviewed-by: Stefan Metzmacher --- lib/crypto/aes.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++-------- lib/crypto/aes.h | 8 ++++++- 2 files changed, 67 insertions(+), 11 deletions(-) (limited to 'lib/crypto') diff --git a/lib/crypto/aes.c b/lib/crypto/aes.c index 800a97ee705..8e6d8418f16 100644 --- a/lib/crypto/aes.c +++ b/lib/crypto/aes.c @@ -37,35 +37,85 @@ #ifdef SAMBA_RIJNDAEL #include "rijndael-alg-fst.h" -int -AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key) +/* + * The next 4 functions are the pure software implementations + * of: + * + * AES_set_encrypt_key() + * AES_set_decrypt_key() + * AES_encrypt() + * AES_decrypt() + */ + +static int +AES_set_encrypt_key_rj(const unsigned char *userkey, const int bits, AES_KEY *key) { - key->rounds = rijndaelKeySetupEnc(key->key, userkey, bits); - if (key->rounds == 0) + key->u.aes_rj.rounds = rijndaelKeySetupEnc(key->u.aes_rj.key, userkey, bits); + if (key->u.aes_rj.rounds == 0) return -1; return 0; } -int -AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key) +static int +AES_set_decrypt_key_rj(const unsigned char *userkey, const int bits, AES_KEY *key) { - key->rounds = rijndaelKeySetupDec(key->key, userkey, bits); - if (key->rounds == 0) + key->u.aes_rj.rounds = rijndaelKeySetupDec(key->u.aes_rj.key, userkey, bits); + if (key->u.aes_rj.rounds == 0) return -1; return 0; } +static void +AES_encrypt_rj(const unsigned char *in, unsigned char *out, const AES_KEY *key) +{ + rijndaelEncrypt(key->u.aes_rj.key, key->u.aes_rj.rounds, in, out); +} + +static void +AES_decrypt_rj(const unsigned char *in, unsigned char *out, const AES_KEY *key) +{ + rijndaelDecrypt(key->u.aes_rj.key, key->u.aes_rj.rounds, in, out); +} + +/* + * The next 4 functions are the runtime switch for Intel AES hardware + * implementations of: + * + * AES_set_encrypt_key() + * AES_set_decrypt_key() + * AES_encrypt() + * AES_decrypt() + * + * If the hardware instructions don't exist, fall back to the software + * versions. + * + * Currently only use the software implementations. + */ + +int +AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key) +{ + return AES_set_encrypt_key_rj(userkey, bits, key); +} + +int +AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key) +{ + return AES_set_decrypt_key_rj(userkey, bits, key); +} + void AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) { - rijndaelEncrypt(key->key, key->rounds, in, out); + return AES_encrypt_rj(in, out, key); } void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) { - rijndaelDecrypt(key->key, key->rounds, in, out); + return AES_decrypt_rj(in, out, key); } + #endif /* SAMBA_RIJNDAEL */ #ifdef SAMBA_AES_CBC_ENCRYPT diff --git a/lib/crypto/aes.h b/lib/crypto/aes.h index 48ea764d514..0ab0a376757 100644 --- a/lib/crypto/aes.h +++ b/lib/crypto/aes.h @@ -59,9 +59,15 @@ #define AES_ENCRYPT 1 #define AES_DECRYPT 0 -typedef struct aes_key { +struct aes_key_rj { uint32_t key[(AES_MAXNR+1)*4]; int rounds; +}; + +typedef struct aes_key { + union { + struct aes_key_rj aes_rj; + } u; } AES_KEY; #ifdef __cplusplus -- cgit v1.2.1