backport AES EVP ctr mode changes from HEAD
[openssl.git] / crypto / evp / e_aes.c
index bd6c0a3a62a323a970a6d2d0bbc0ba9b869c595f..a7fbba3689ff33ebacf98dc13c16f60fc4e289fc 100644 (file)
@@ -55,6 +55,7 @@
 #include <string.h>
 #include <assert.h>
 #include <openssl/aes.h>
+#include <openssl/modes.h>
 #include "evp_locl.h"
 
 static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
@@ -96,17 +97,90 @@ IMPLEMENT_AES_CFBR(128,8)
 IMPLEMENT_AES_CFBR(192,8)
 IMPLEMENT_AES_CFBR(256,8)
 
+static int aes_counter (EVP_CIPHER_CTX *ctx, unsigned char *out,
+               const unsigned char *in, size_t len)
+{
+       unsigned int num;
+       num = ctx->num;
+#ifdef AES_CTR_ASM
+       void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+                       size_t blocks, const AES_KEY *key,
+                       const unsigned char ivec[AES_BLOCK_SIZE]);
+
+       CRYPTO_ctr128_encrypt_ctr32(in,out,len,
+               &((EVP_AES_KEY *)ctx->cipher_data)->ks,
+               ctx->iv,ctx->buf,&num,(ctr128_f)AES_ctr32_encrypt);
+#else
+       CRYPTO_ctr128_encrypt(in,out,len,
+               &((EVP_AES_KEY *)ctx->cipher_data)->ks,
+               ctx->iv,ctx->buf,&num,(block128_f)AES_encrypt);
+#endif
+       ctx->num = (size_t)num;
+       return 1;
+}
+
+static const EVP_CIPHER aes_128_ctr_cipher=
+       {
+       NID_aes_128_ctr,1,16,16,
+       EVP_CIPH_CTR_MODE,
+       aes_init_key,
+       aes_counter,
+       NULL,
+       sizeof(EVP_AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+       };
+
+const EVP_CIPHER *EVP_aes_128_ctr (void)
+{      return &aes_128_ctr_cipher;     }
+
+static const EVP_CIPHER aes_192_ctr_cipher=
+       {
+       NID_aes_192_ctr,1,24,16,
+       EVP_CIPH_CTR_MODE,
+       aes_init_key,
+       aes_counter,
+       NULL,
+       sizeof(EVP_AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+       };
+
+const EVP_CIPHER *EVP_aes_192_ctr (void)
+{      return &aes_192_ctr_cipher;     }
+
+static const EVP_CIPHER aes_256_ctr_cipher=
+       {
+       NID_aes_256_ctr,1,32,16,
+       EVP_CIPH_CTR_MODE,
+       aes_init_key,
+       aes_counter,
+       NULL,
+       sizeof(EVP_AES_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+       };
+
+const EVP_CIPHER *EVP_aes_256_ctr (void)
+{      return &aes_256_ctr_cipher;     }
+
 static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                   const unsigned char *iv, int enc)
        {
        int ret;
 
-       if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
-           || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
-           || enc) 
-               ret=AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
-       else
+       if (((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_ECB_MODE
+           || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CBC_MODE)
+           && !enc) 
                ret=AES_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+       else
+               ret=AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
 
        if(ret < 0)
                {