fix warnings
[openssl.git] / crypto / engine / eng_aesni.c
index 2a997cae36dc0cf1daf44901d200af0bc2ff3f27..e9f277390aee0f0e66fe5394ed0ca9b599aadd13 100644 (file)
@@ -111,6 +111,35 @@ void ENGINE_load_aesni (void)
 }
 
 #ifdef COMPILE_HW_AESNI
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC)
+#  define BSWAP4(x) ({ u32 ret=(x);                    \
+                       asm volatile ("bswapl %0"       \
+                       : "+r"(ret));   ret;            })
+#elif defined(_MSC_VER)
+# if _MSC_VER>=1300
+#  pragma intrinsic(_byteswap_ulong)
+#  define BSWAP4(x)    _byteswap_ulong((u32)(x))
+# elif defined(_M_IX86)
+   __inline u32 _bswap4(u32 val) {
+       _asm mov eax,val
+       _asm bswap eax
+   }
+#  define BSWAP4(x)    _bswap4(x)
+# endif
+#endif
+
+#ifdef BSWAP4
+#define GETU32(p)      BSWAP4(*(const u32 *)(p))
+#define PUTU32(p,v)    *(u32 *)(p) = BSWAP4(v)
+#else
+#define GETU32(p)      ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
+#define PUTU32(p,v)    ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
+#endif
+
 int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
                              AES_KEY *key);
 int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
@@ -132,6 +161,12 @@ void aesni_cbc_encrypt(const unsigned char *in,
                           const AES_KEY *key,
                           unsigned char *ivec, int enc);
 
+void aesni_ctr32_encrypt_blocks(const unsigned char *in,
+                          unsigned char *out,
+                          size_t blocks,
+                          const void *key,
+                          const unsigned char *ivec);
+
 /* Function for ENGINE detection and control */
 static int aesni_init(ENGINE *e);
 
@@ -224,16 +259,19 @@ static int aesni_cipher_nids[] = {
        NID_aes_128_cbc,
        NID_aes_128_cfb,
        NID_aes_128_ofb,
+       NID_aes_128_ctr,
 
        NID_aes_192_ecb,
        NID_aes_192_cbc,
        NID_aes_192_cfb,
        NID_aes_192_ofb,
+       NID_aes_192_ctr,
 
        NID_aes_256_ecb,
        NID_aes_256_cbc,
        NID_aes_256_cfb,
        NID_aes_256_ofb,
+       NID_aes_256_ctr,
 };
 static int aesni_cipher_nids_num =
        (sizeof(aesni_cipher_nids)/sizeof(aesni_cipher_nids[0]));
@@ -251,18 +289,28 @@ aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *user_key,
        int ret;
        AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
 
-       if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
-           || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
-           || enc)
-               ret=aesni_set_encrypt_key(user_key, ctx->key_len * 8, key);
-       else
+       if (((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_ECB_MODE
+           || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CBC_MODE)
+           && !enc)
                ret=aesni_set_decrypt_key(user_key, ctx->key_len * 8, key);
+       else
+               ret=aesni_set_encrypt_key(user_key, ctx->key_len * 8, key);
 
        if(ret < 0) {
                EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
                return 0;
        }
 
+       if (ctx->cipher->flags&EVP_CIPH_CUSTOM_IV)
+               {
+               if (iv!=NULL)
+                       memcpy (ctx->iv,iv,ctx->cipher->iv_len);
+               else    {
+                       EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_IV_SETUP_FAILED);
+                       return 0;
+                       }
+               }
+
        return 1;
 }
 
@@ -336,6 +384,74 @@ DECLARE_AES_EVP(256,cbc,CBC);
 DECLARE_AES_EVP(256,cfb,CFB);
 DECLARE_AES_EVP(256,ofb,OFB);
 
+#if notused
+static void ctr96_inc(unsigned char *counter) {
+       u32 n=12;
+       u8  c;
+
+       do {
+               --n;
+               c = counter[n];
+               ++c;
+               counter[n] = c;
+               if (c) return;
+       } while (n);
+}
+#endif
+
+static int aesni_counter(EVP_CIPHER_CTX *ctx, unsigned char *out,
+               const unsigned char *in, size_t len)
+{
+       AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
+
+       CRYPTO_ctr128_encrypt_ctr32(in,out,len,key,
+                               ctx->iv,ctx->buf,(unsigned int *)&ctx->num,
+                               aesni_ctr32_encrypt_blocks);
+       return 1;
+}
+
+static const EVP_CIPHER aesni_128_ctr=
+       {
+       NID_aes_128_ctr,1,16,16,
+       EVP_CIPH_CUSTOM_IV,
+       aesni_init_key,
+       aesni_counter,
+       NULL,
+       sizeof(AESNI_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+       };
+
+static const EVP_CIPHER aesni_192_ctr=
+       {
+       NID_aes_192_ctr,1,24,16,
+       EVP_CIPH_CUSTOM_IV,
+       aesni_init_key,
+       aesni_counter,
+       NULL,
+       sizeof(AESNI_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+       };
+
+static const EVP_CIPHER aesni_256_ctr=
+       {
+       NID_aes_256_ctr,1,32,16,
+       EVP_CIPH_CUSTOM_IV,
+       aesni_init_key,
+       aesni_counter,
+       NULL,
+       sizeof(AESNI_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+       };
+
 static int
 aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher,
                      const int **nids, int nid)
@@ -360,6 +476,9 @@ aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher,
        case NID_aes_128_ofb:
                *cipher = &aesni_128_ofb;
                break;
+       case NID_aes_128_ctr:
+               *cipher = &aesni_128_ctr;
+               break;
 
        case NID_aes_192_ecb:
                *cipher = &aesni_192_ecb;
@@ -373,6 +492,9 @@ aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher,
        case NID_aes_192_ofb:
                *cipher = &aesni_192_ofb;
                break;
+       case NID_aes_192_ctr:
+               *cipher = &aesni_192_ctr;
+               break;
 
        case NID_aes_256_ecb:
                *cipher = &aesni_256_ecb;
@@ -386,6 +508,9 @@ aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher,
        case NID_aes_256_ofb:
                *cipher = &aesni_256_ofb;
                break;
+       case NID_aes_256_ctr:
+               *cipher = &aesni_256_ctr;
+               break;
 
        default:
                /* Sorry, we don't support this NID */