const unsigned char iv[16]);
#endif
+#if defined(VPAES_ASM) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+extern unsigned int OPENSSL_ppccap_P;
+#define VPAES_CAPABLE (OPENSSL_ppccap_P&(1<<1))
+#endif
+
#if defined(AES_ASM) && !defined(I386_ONLY) && ( \
((defined(__i386) || defined(__i386__) || \
defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
{ return &aes_##keylen##_##mode; }
#endif
+#if defined(AES_ASM) && defined(BSAES_ASM) && (defined(__arm__) || defined(__arm))
+#include "arm_arch.h"
+#if __ARM_ARCH__>=7
+#define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
+#endif
+#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) \
else if (ctx->encrypt)
CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
else
- CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
+ CRYPTO_cbc128_decrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
return 1;
}
}
}
-static ctr128_f aes_gcm_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
- const unsigned char *key, size_t key_len)
+static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key)
+ { do {
#ifdef BSAES_CAPABLE
if (BSAES_CAPABLE)
{
- AES_set_encrypt_key(key,key_len*8,aes_key);
- CRYPTO_gcm128_init(gcm_ctx,aes_key,
+ AES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
(block128_f)AES_encrypt);
- return (ctr128_f)bsaes_ctr32_encrypt_blocks;
+ gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
+ break;
}
+ else
#endif
#ifdef VPAES_CAPABLE
if (VPAES_CAPABLE)
{
- vpaes_set_encrypt_key(key,key_len*8,aes_key);
- CRYPTO_gcm128_init(gcm_ctx,aes_key,
+ vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
(block128_f)vpaes_encrypt);
- return NULL;
+ gctx->ctr = NULL;
+ break;
}
else
#endif
(void)0; /* terminate potentially open 'else' */
- AES_set_encrypt_key(key, key_len*8, aes_key);
- CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
+ AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt);
#ifdef AES_CTR_ASM
- return (ctr128_f)AES_ctr32_encrypt;
+ gctx->ctr = (ctr128_f)AES_ctr32_encrypt;
#else
- return NULL;
+ gctx->ctr = NULL;
#endif
- }
+ } while (0);
-static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc)
- {
- EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
- if (!iv && !key)
- return 1;
- if (key)
- {
- gctx->ctr = aes_gcm_set_key(&gctx->ks.ks, &gctx->gcm, key, ctx->key_len);
/* If we have an iv can set it directly, otherwise use
* saved IV.
*/
return &aes_256_wrap;
}
-#define EVP_AEAD_AES_GCM_TAG_LEN 16
-
-struct aead_aes_gcm_ctx {
- union { double align; AES_KEY ks; } ks;
- GCM128_CONTEXT gcm;
- ctr128_f ctr;
- unsigned char tag_len;
-};
-
-static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx,
- const unsigned char *key, size_t key_len, size_t tag_len)
- {
- struct aead_aes_gcm_ctx *gcm_ctx;
- const size_t key_bits = key_len * 8;
-
- if (key_bits != 128 && key_bits != 256)
- {
- EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_BAD_KEY_LENGTH);
- return 0; /* EVP_AEAD_CTX_init should catch this. */
- }
-
- if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
- tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
-
- if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN)
- {
- EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_TAG_TOO_LARGE);
- return 0;
- }
-
- gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_ctx));
- if (gcm_ctx == NULL)
- return 0;
-
-#ifdef AESNI_CAPABLE
- if (AESNI_CAPABLE)
- {
- aesni_set_encrypt_key(key, key_bits, &gcm_ctx->ks.ks);
- CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks,
- (block128_f)aesni_encrypt);
- gcm_ctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
- }
- else
-#endif
- {
- gcm_ctx->ctr = aes_gcm_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm,
- key, key_len);
- }
- gcm_ctx->tag_len = tag_len;
- ctx->aead_state = gcm_ctx;
-
- return 1;
- }
-
-static void aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx)
- {
- struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
- OPENSSL_free(gcm_ctx);
- }
-
-static ssize_t aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx,
- unsigned char *out, size_t max_out_len,
- const unsigned char *nonce, size_t nonce_len,
- const unsigned char *in, size_t in_len,
- const unsigned char *ad, size_t ad_len)
- {
- size_t bulk = 0;
- const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
- GCM128_CONTEXT gcm;
-
- if (max_out_len < in_len + gcm_ctx->tag_len)
- {
- EVPerr(EVP_F_AEAD_AES_GCM_SEAL, EVP_R_BUFFER_TOO_SMALL);
- return -1;
- }
-
- memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
- CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
-
- if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len))
- return -1;
-
- if (gcm_ctx->ctr)
- {
- if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk,
- in_len - bulk, gcm_ctx->ctr))
- return -1;
- }
- else
- {
- if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk,
- in_len - bulk))
- return -1;
- }
-
- CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len);
- return in_len + gcm_ctx->tag_len;
- }
-
-static ssize_t aead_aes_gcm_open(const EVP_AEAD_CTX *ctx,
- unsigned char *out, size_t max_out_len,
- const unsigned char *nonce, size_t nonce_len,
- const unsigned char *in, size_t in_len,
- const unsigned char *ad, size_t ad_len)
- {
- size_t bulk = 0;
- const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
- unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN];
- size_t out_len;
- GCM128_CONTEXT gcm;
-
- if (in_len < gcm_ctx->tag_len)
- {
- EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT);
- return -1;
- }
-
- out_len = in_len - gcm_ctx->tag_len;
-
- if (max_out_len < out_len)
- {
- EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL);
- return -1;
- }
-
- memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
- CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
-
- if (CRYPTO_gcm128_aad(&gcm, ad, ad_len))
- return -1;
-
- if (gcm_ctx->ctr)
- {
- if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
- in_len-bulk-gcm_ctx->tag_len,
- gcm_ctx->ctr))
- return -1;
- }
- else
- {
- if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
- in_len - bulk - gcm_ctx->tag_len))
- return -1;
- }
-
- CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
- if (CRYPTO_memcmp(tag, in + out_len, gcm_ctx->tag_len) != 0)
- {
- EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT);
- return -1;
- }
-
- return out_len;
- }
-
-static const EVP_AEAD aead_aes_128_gcm = {
- 16, /* key len */
- 12, /* nonce len */
- EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */
- EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
-
- aead_aes_gcm_init,
- aead_aes_gcm_cleanup,
- aead_aes_gcm_seal,
- aead_aes_gcm_open,
-};
-
-static const EVP_AEAD aead_aes_256_gcm = {
- 32, /* key len */
- 12, /* nonce len */
- EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */
- EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
-
- aead_aes_gcm_init,
- aead_aes_gcm_cleanup,
- aead_aes_gcm_seal,
- aead_aes_gcm_open,
-};
-
-const EVP_AEAD *EVP_aead_aes_128_gcm()
- {
- return &aead_aes_128_gcm;
- }
-
-const EVP_AEAD *EVP_aead_aes_256_gcm()
- {
- return &aead_aes_256_gcm;
- }
-
#endif