New ctrl to set current certificate.
[oweals/openssl.git] / crypto / evp / e_aes.c
index 463de1cfe651a9f67a756d1361271dfd8fe01709..77e4bead71450334d85b69d744582121d671d9ff 100644 (file)
@@ -157,6 +157,11 @@ 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))
+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))|| \
@@ -897,6 +902,13 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
 { 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)      \
@@ -994,7 +1006,7 @@ static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
        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;
 }
@@ -1227,48 +1239,47 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
                }
        }
 
-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.
                 */
@@ -1978,193 +1989,4 @@ const EVP_CIPHER *EVP_aes_256_wrap(void)
        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