Engage POWER8 AES support.
[openssl.git] / crypto / evp / e_aes.c
index f8a69a0b5e5697d24c8c28c9028b32c5ad4b7780..51714a4a4f0f2aad3d943ff393e8bf2536313e00 100644 (file)
@@ -154,9 +154,17 @@ void AES_xts_decrypt(const char *inp,char *out,size_t len,
                        const unsigned char iv[16]);
 #endif
 
-#if    defined(VPAES_ASM) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+#if    defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
 extern unsigned int OPENSSL_ppccap_P;
-#define        VPAES_CAPABLE   (OPENSSL_ppccap_P&(1<<1))
+# ifdef VPAES_ASM
+#  define VPAES_CAPABLE        (OPENSSL_ppccap_P&(1<<1))
+# endif
+# define HWAES_CAPABLE (OPENSSL_ppccap_P&(1<<2))
+# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
+# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
+# define HWAES_encrypt aes_p8_encrypt
+# define HWAES_decrypt aes_p8_decrypt
+# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
 #endif
 
 #if    defined(AES_ASM) && !defined(I386_ONLY) &&      (  \
@@ -900,13 +908,38 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
 
 #endif
 
-#if defined(AES_ASM) && defined(BSAES_ASM) && (defined(__arm__) || defined(__arm))
+#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__))
 #include "arm_arch.h"
 #if __ARM_ARCH__>=7
-#define BSAES_CAPABLE  (OPENSSL_armcap_P & ARMV7_NEON)
+# if defined(BSAES_ASM)
+#  define BSAES_CAPABLE        (OPENSSL_armcap_P & ARMV7_NEON)
+# endif
+# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
+# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
+# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
+# define HWAES_encrypt aes_v8_encrypt
+# define HWAES_decrypt aes_v8_decrypt
+# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
+# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
 #endif
 #endif
 
+#if defined(HWAES_CAPABLE)
+int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
+       AES_KEY *key);
+int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
+       AES_KEY *key);
+void HWAES_encrypt(const unsigned char *in, unsigned char *out,
+       const AES_KEY *key);
+void HWAES_decrypt(const unsigned char *in, unsigned char *out,
+       const AES_KEY *key);
+void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+       size_t length, const AES_KEY *key,
+       unsigned char *ivec, const int enc);
+void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+       size_t len, const AES_KEY *key, const unsigned char ivec[16]);
+#endif
+
 #define BLOCK_CIPHER_generic_pack(nid,keylen,flags)            \
        BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)     \
        BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)      \
@@ -925,6 +958,19 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        mode = ctx->cipher->flags & EVP_CIPH_MODE;
        if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
            && !enc)
+#ifdef HWAES_CAPABLE
+           if (HWAES_CAPABLE)
+               {
+               ret = HWAES_set_decrypt_key(key,ctx->key_len*8,&dat->ks.ks);
+               dat->block      = (block128_f)HWAES_decrypt;
+               dat->stream.cbc = NULL;
+#ifdef HWAES_cbc_encrypt
+               if (mode==EVP_CIPH_CBC_MODE)
+                   dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
+#endif
+               }
+           else
+#endif
 #ifdef BSAES_CAPABLE
            if (BSAES_CAPABLE && mode==EVP_CIPH_CBC_MODE)
                {
@@ -953,6 +999,26 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                                        NULL;
                }
        else
+#ifdef HWAES_CAPABLE
+           if (HWAES_CAPABLE)
+               {
+               ret = HWAES_set_encrypt_key(key,ctx->key_len*8,&dat->ks.ks);
+               dat->block      = (block128_f)HWAES_encrypt;
+               dat->stream.cbc = NULL;
+#ifdef HWAES_cbc_encrypt
+               if (mode==EVP_CIPH_CBC_MODE)
+                   dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
+               else
+#endif
+#ifdef HWAES_ctr32_encrypt_blocks
+               if (mode==EVP_CIPH_CTR_MODE)
+                   dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks;
+               else
+#endif
+               (void)0;        /* terminate potentially open 'else' */
+               }
+           else
+#endif
 #ifdef BSAES_CAPABLE
            if (BSAES_CAPABLE && mode==EVP_CIPH_CTR_MODE)
                {