}
#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,
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);
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]));
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;
}
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)
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;
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;
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 */