summaryrefslogtreecommitdiff
path: root/app/openssl/crypto/evp
diff options
context:
space:
mode:
authorParménides GV <parmegv@sdf.org>2014-06-13 12:13:04 +0200
committerParménides GV <parmegv@sdf.org>2014-06-13 12:13:04 +0200
commit3a71bc9e4aa4296f460e2e3c55de74c9852477ad (patch)
treef816597a7c4322137f0657e7aa2bf392404d1870 /app/openssl/crypto/evp
parentcfe67bfd8260253ce9288225b9e26f666d27133f (diff)
parent36247e71df88fa13c6c5a887de3b11d9a883615f (diff)
Merge branch 'feature/establish-an-upstream-relationship-with-ics-openvpn-codebase-#5381' into develop
Diffstat (limited to 'app/openssl/crypto/evp')
-rw-r--r--app/openssl/crypto/evp/bio_b64.c2
-rw-r--r--app/openssl/crypto/evp/bio_md.c11
-rw-r--r--app/openssl/crypto/evp/bio_ok.c103
-rw-r--r--app/openssl/crypto/evp/c_allc.c18
-rw-r--r--app/openssl/crypto/evp/digest.c34
-rw-r--r--app/openssl/crypto/evp/e_aes.c1290
-rw-r--r--app/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c581
-rw-r--r--app/openssl/crypto/evp/e_des3.c9
-rw-r--r--app/openssl/crypto/evp/e_null.c4
-rw-r--r--app/openssl/crypto/evp/e_rc2.c3
-rw-r--r--app/openssl/crypto/evp/e_rc4.c1
-rw-r--r--app/openssl/crypto/evp/e_rc4_hmac_md5.c298
-rw-r--r--app/openssl/crypto/evp/evp.h102
-rw-r--r--app/openssl/crypto/evp/evp_cnf.c125
-rw-r--r--app/openssl/crypto/evp/evp_enc.c95
-rw-r--r--app/openssl/crypto/evp/evp_err.c26
-rw-r--r--app/openssl/crypto/evp/evp_key.c27
-rw-r--r--app/openssl/crypto/evp/evp_lib.c4
-rw-r--r--app/openssl/crypto/evp/evp_locl.h40
-rw-r--r--app/openssl/crypto/evp/evp_pbe.c5
-rw-r--r--app/openssl/crypto/evp/evptests.txt13
-rw-r--r--app/openssl/crypto/evp/m_dss.c4
-rw-r--r--app/openssl/crypto/evp/m_dss1.c5
-rw-r--r--app/openssl/crypto/evp/m_ecdsa.c3
-rw-r--r--app/openssl/crypto/evp/m_md4.c2
-rw-r--r--app/openssl/crypto/evp/m_md5.c1
-rw-r--r--app/openssl/crypto/evp/m_mdc2.c2
-rw-r--r--app/openssl/crypto/evp/m_ripemd.c1
-rw-r--r--app/openssl/crypto/evp/m_sha1.c7
-rw-r--r--app/openssl/crypto/evp/m_wp.c1
-rw-r--r--app/openssl/crypto/evp/names.c5
-rw-r--r--app/openssl/crypto/evp/p5_crpt.c33
-rw-r--r--app/openssl/crypto/evp/p5_crpt2.c121
-rw-r--r--app/openssl/crypto/evp/p_lib.c6
-rw-r--r--app/openssl/crypto/evp/p_open.c3
-rw-r--r--app/openssl/crypto/evp/p_seal.c3
-rw-r--r--app/openssl/crypto/evp/p_sign.c10
-rw-r--r--app/openssl/crypto/evp/p_verify.c10
-rw-r--r--app/openssl/crypto/evp/pmeth_gn.c5
-rw-r--r--app/openssl/crypto/evp/pmeth_lib.c55
40 files changed, 2891 insertions, 177 deletions
diff --git a/app/openssl/crypto/evp/bio_b64.c b/app/openssl/crypto/evp/bio_b64.c
index 72a2a672..ac6d441a 100644
--- a/app/openssl/crypto/evp/bio_b64.c
+++ b/app/openssl/crypto/evp/bio_b64.c
@@ -264,7 +264,7 @@ static int b64_read(BIO *b, char *out, int outl)
}
/* we fell off the end without starting */
- if (j == i)
+ if ((j == i) && (num == 0))
{
/* Is this is one long chunk?, if so, keep on
* reading until a new line. */
diff --git a/app/openssl/crypto/evp/bio_md.c b/app/openssl/crypto/evp/bio_md.c
index 9841e32e..144fdfd5 100644
--- a/app/openssl/crypto/evp/bio_md.c
+++ b/app/openssl/crypto/evp/bio_md.c
@@ -153,8 +153,12 @@ static int md_write(BIO *b, const char *in, int inl)
{
if (ret > 0)
{
- EVP_DigestUpdate(ctx,(const unsigned char *)in,
- (unsigned int)ret);
+ if (!EVP_DigestUpdate(ctx,(const unsigned char *)in,
+ (unsigned int)ret))
+ {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
}
}
if(b->next_bio != NULL)
@@ -220,7 +224,8 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_DUP:
dbio=ptr;
dctx=dbio->ptr;
- EVP_MD_CTX_copy_ex(dctx,ctx);
+ if (!EVP_MD_CTX_copy_ex(dctx,ctx))
+ return 0;
b->init=1;
break;
default:
diff --git a/app/openssl/crypto/evp/bio_ok.c b/app/openssl/crypto/evp/bio_ok.c
index 98bc1ab4..e6433535 100644
--- a/app/openssl/crypto/evp/bio_ok.c
+++ b/app/openssl/crypto/evp/bio_ok.c
@@ -133,10 +133,10 @@ static int ok_new(BIO *h);
static int ok_free(BIO *data);
static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-static void sig_out(BIO* b);
-static void sig_in(BIO* b);
-static void block_out(BIO* b);
-static void block_in(BIO* b);
+static int sig_out(BIO* b);
+static int sig_in(BIO* b);
+static int block_out(BIO* b);
+static int block_in(BIO* b);
#define OK_BLOCK_SIZE (1024*4)
#define OK_BLOCK_BLOCK 4
#define IOBS (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
@@ -266,10 +266,24 @@ static int ok_read(BIO *b, char *out, int outl)
ctx->buf_len+= i;
/* no signature yet -- check if we got one */
- if (ctx->sigio == 1) sig_in(b);
+ if (ctx->sigio == 1)
+ {
+ if (!sig_in(b))
+ {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
/* signature ok -- check if we got block */
- if (ctx->sigio == 0) block_in(b);
+ if (ctx->sigio == 0)
+ {
+ if (!block_in(b))
+ {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
/* invalid block -- cancel */
if (ctx->cont <= 0) break;
@@ -293,7 +307,8 @@ static int ok_write(BIO *b, const char *in, int inl)
if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
- if(ctx->sigio) sig_out(b);
+ if(ctx->sigio && !sig_out(b))
+ return 0;
do{
BIO_clear_retry_flags(b);
@@ -332,7 +347,11 @@ static int ok_write(BIO *b, const char *in, int inl)
if(ctx->buf_len >= OK_BLOCK_SIZE+ OK_BLOCK_BLOCK)
{
- block_out(b);
+ if (!block_out(b))
+ {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
}
}while(inl > 0);
@@ -379,7 +398,8 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_FLUSH:
/* do a final write */
if(ctx->blockout == 0)
- block_out(b);
+ if (!block_out(b))
+ return 0;
while (ctx->blockout)
{
@@ -408,7 +428,8 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_C_SET_MD:
md=ptr;
- EVP_DigestInit_ex(&ctx->md, md, NULL);
+ if (!EVP_DigestInit_ex(&ctx->md, md, NULL))
+ return 0;
b->init=1;
break;
case BIO_C_GET_MD:
@@ -455,7 +476,7 @@ static void longswap(void *_ptr, size_t len)
}
}
-static void sig_out(BIO* b)
+static int sig_out(BIO* b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
@@ -463,9 +484,10 @@ static void sig_out(BIO* b)
ctx=b->ptr;
md=&ctx->md;
- if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return;
+ if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return 1;
- EVP_DigestInit_ex(md, md->digest, NULL);
+ if (!EVP_DigestInit_ex(md, md->digest, NULL))
+ goto berr;
/* FIXME: there's absolutely no guarantee this makes any sense at all,
* particularly now EVP_MD_CTX has been restructured.
*/
@@ -474,14 +496,20 @@ static void sig_out(BIO* b)
longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
ctx->buf_len+= md->digest->md_size;
- EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
- EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
+ if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+ goto berr;
ctx->buf_len+= md->digest->md_size;
ctx->blockout= 1;
ctx->sigio= 0;
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
}
-static void sig_in(BIO* b)
+static int sig_in(BIO* b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
@@ -491,15 +519,18 @@ static void sig_in(BIO* b)
ctx=b->ptr;
md=&ctx->md;
- if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return;
+ if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return 1;
- EVP_DigestInit_ex(md, md->digest, NULL);
+ if (!EVP_DigestInit_ex(md, md->digest, NULL))
+ goto berr;
memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
longswap(md->md_data, md->digest->md_size);
ctx->buf_off+= md->digest->md_size;
- EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
- EVP_DigestFinal_ex(md, tmp, NULL);
+ if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, tmp, NULL))
+ goto berr;
ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
ctx->buf_off+= md->digest->md_size;
if(ret == 1)
@@ -516,9 +547,13 @@ static void sig_in(BIO* b)
{
ctx->cont= 0;
}
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
}
-static void block_out(BIO* b)
+static int block_out(BIO* b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
@@ -532,13 +567,20 @@ static void block_out(BIO* b)
ctx->buf[1]=(unsigned char)(tl>>16);
ctx->buf[2]=(unsigned char)(tl>>8);
ctx->buf[3]=(unsigned char)(tl);
- EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
- EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
+ if (!EVP_DigestUpdate(md,
+ (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+ goto berr;
ctx->buf_len+= md->digest->md_size;
ctx->blockout= 1;
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
}
-static void block_in(BIO* b)
+static int block_in(BIO* b)
{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
@@ -554,10 +596,13 @@ static void block_in(BIO* b)
tl|=ctx->buf[2]; tl<<=8;
tl|=ctx->buf[3];
- if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return;
+ if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return 1;
- EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
- EVP_DigestFinal_ex(md, tmp, NULL);
+ if (!EVP_DigestUpdate(md,
+ (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, tmp, NULL))
+ goto berr;
if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0)
{
/* there might be parts from next block lurking around ! */
@@ -571,5 +616,9 @@ static void block_in(BIO* b)
{
ctx->cont= 0;
}
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
}
diff --git a/app/openssl/crypto/evp/c_allc.c b/app/openssl/crypto/evp/c_allc.c
index c5f92683..2a45d435 100644
--- a/app/openssl/crypto/evp/c_allc.c
+++ b/app/openssl/crypto/evp/c_allc.c
@@ -98,6 +98,9 @@ void OpenSSL_add_all_ciphers(void)
#ifndef OPENSSL_NO_RC4
EVP_add_cipher(EVP_rc4());
EVP_add_cipher(EVP_rc4_40());
+#ifndef OPENSSL_NO_MD5
+ EVP_add_cipher(EVP_rc4_hmac_md5());
+#endif
#endif
#ifndef OPENSSL_NO_IDEA
@@ -166,9 +169,9 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_128_cfb1());
EVP_add_cipher(EVP_aes_128_cfb8());
EVP_add_cipher(EVP_aes_128_ofb());
-#if 0
EVP_add_cipher(EVP_aes_128_ctr());
-#endif
+ EVP_add_cipher(EVP_aes_128_gcm());
+ EVP_add_cipher(EVP_aes_128_xts());
EVP_add_cipher_alias(SN_aes_128_cbc,"AES128");
EVP_add_cipher_alias(SN_aes_128_cbc,"aes128");
EVP_add_cipher(EVP_aes_192_ecb());
@@ -177,9 +180,8 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_192_cfb1());
EVP_add_cipher(EVP_aes_192_cfb8());
EVP_add_cipher(EVP_aes_192_ofb());
-#if 0
EVP_add_cipher(EVP_aes_192_ctr());
-#endif
+ EVP_add_cipher(EVP_aes_192_gcm());
EVP_add_cipher_alias(SN_aes_192_cbc,"AES192");
EVP_add_cipher_alias(SN_aes_192_cbc,"aes192");
EVP_add_cipher(EVP_aes_256_ecb());
@@ -188,11 +190,15 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_256_cfb1());
EVP_add_cipher(EVP_aes_256_cfb8());
EVP_add_cipher(EVP_aes_256_ofb());
-#if 0
EVP_add_cipher(EVP_aes_256_ctr());
-#endif
+ EVP_add_cipher(EVP_aes_256_gcm());
+ EVP_add_cipher(EVP_aes_256_xts());
EVP_add_cipher_alias(SN_aes_256_cbc,"AES256");
EVP_add_cipher_alias(SN_aes_256_cbc,"aes256");
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+ EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
+ EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+#endif
#endif
#ifndef OPENSSL_NO_CAMELLIA
diff --git a/app/openssl/crypto/evp/digest.c b/app/openssl/crypto/evp/digest.c
index 982ba2b1..d14e8e48 100644
--- a/app/openssl/crypto/evp/digest.c
+++ b/app/openssl/crypto/evp/digest.c
@@ -117,6 +117,10 @@
#include <openssl/engine.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
{
memset(ctx,'\0',sizeof *ctx);
@@ -225,12 +229,26 @@ skip_to_init:
}
if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
return 1;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ {
+ if (FIPS_digestinit(ctx, type))
+ return 1;
+ OPENSSL_free(ctx->md_data);
+ ctx->md_data = NULL;
+ return 0;
+ }
+#endif
return ctx->digest->init(ctx);
}
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
{
+#ifdef OPENSSL_FIPS
+ return FIPS_digestupdate(ctx, data, count);
+#else
return ctx->update(ctx,data,count);
+#endif
}
/* The caller can assume that this removes any secret data from the context */
@@ -245,6 +263,9 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
/* The caller can assume that this removes any secret data from the context */
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
{
+#ifdef OPENSSL_FIPS
+ return FIPS_digestfinal(ctx, md, size);
+#else
int ret;
OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
@@ -258,6 +279,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
}
memset(ctx->md_data,0,ctx->digest->ctx_size);
return ret;
+#endif
}
int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
@@ -344,13 +366,17 @@ int EVP_Digest(const void *data, size_t count,
void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
{
- EVP_MD_CTX_cleanup(ctx);
- OPENSSL_free(ctx);
+ if (ctx)
+ {
+ EVP_MD_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+ }
}
/* This call frees resources associated with the context */
int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
{
+#ifndef OPENSSL_FIPS
/* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
* because sometimes only copies of the context are ever finalised.
*/
@@ -363,6 +389,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
OPENSSL_free(ctx->md_data);
}
+#endif
if (ctx->pctx)
EVP_PKEY_CTX_free(ctx->pctx);
#ifndef OPENSSL_NO_ENGINE
@@ -371,6 +398,9 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
* functional reference we held for this reason. */
ENGINE_finish(ctx->engine);
#endif
+#ifdef OPENSSL_FIPS
+ FIPS_md_ctx_cleanup(ctx);
+#endif
memset(ctx,'\0',sizeof *ctx);
return 1;
diff --git a/app/openssl/crypto/evp/e_aes.c b/app/openssl/crypto/evp/e_aes.c
index bd6c0a3a..41cee42d 100644
--- a/app/openssl/crypto/evp/e_aes.c
+++ b/app/openssl/crypto/evp/e_aes.c
@@ -1,5 +1,5 @@
/* ====================================================================
- * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -56,57 +56,519 @@
#include <assert.h>
#include <openssl/aes.h>
#include "evp_locl.h"
-
-static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc);
+#ifndef OPENSSL_FIPS
+#include "modes_lcl.h"
+#include <openssl/rand.h>
typedef struct
{
AES_KEY ks;
+ block128_f block;
+ union {
+ cbc128_f cbc;
+ ctr128_f ctr;
+ } stream;
} EVP_AES_KEY;
-#define data(ctx) EVP_C_DATA(EVP_AES_KEY,ctx)
-
-IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY,
- NID_aes_128, 16, 16, 16, 128,
- 0, aes_init_key, NULL,
- EVP_CIPHER_set_asn1_iv,
- EVP_CIPHER_get_asn1_iv,
- NULL)
-IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY,
- NID_aes_192, 16, 24, 16, 128,
- 0, aes_init_key, NULL,
- EVP_CIPHER_set_asn1_iv,
- EVP_CIPHER_get_asn1_iv,
- NULL)
-IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY,
- NID_aes_256, 16, 32, 16, 128,
- 0, aes_init_key, NULL,
- EVP_CIPHER_set_asn1_iv,
- EVP_CIPHER_get_asn1_iv,
- NULL)
-
-#define IMPLEMENT_AES_CFBR(ksize,cbits) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16)
-
-IMPLEMENT_AES_CFBR(128,1)
-IMPLEMENT_AES_CFBR(192,1)
-IMPLEMENT_AES_CFBR(256,1)
-
-IMPLEMENT_AES_CFBR(128,8)
-IMPLEMENT_AES_CFBR(192,8)
-IMPLEMENT_AES_CFBR(256,8)
+typedef struct
+ {
+ AES_KEY ks; /* AES key schedule to use */
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ GCM128_CONTEXT gcm;
+ unsigned char *iv; /* Temporary IV store */
+ int ivlen; /* IV length */
+ int taglen;
+ int iv_gen; /* It is OK to generate IVs */
+ int tls_aad_len; /* TLS AAD length */
+ ctr128_f ctr;
+ } EVP_AES_GCM_CTX;
+
+typedef struct
+ {
+ AES_KEY ks1, ks2; /* AES key schedules to use */
+ XTS128_CONTEXT xts;
+ void (*stream)(const unsigned char *in,
+ unsigned char *out, size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+ } EVP_AES_XTS_CTX;
+
+typedef struct
+ {
+ AES_KEY ks; /* AES key schedule to use */
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ int tag_set; /* Set if tag is valid */
+ int len_set; /* Set if message length set */
+ int L, M; /* L and M parameters from RFC3610 */
+ CCM128_CONTEXT ccm;
+ ccm128_f str;
+ } EVP_AES_CCM_CTX;
+
+#define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
+
+#ifdef VPAES_ASM
+int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void vpaes_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void vpaes_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void vpaes_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ unsigned char *ivec, int enc);
+#endif
+#ifdef BSAES_ASM
+void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char ivec[16], int enc);
+void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ const unsigned char ivec[16]);
+void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
+ size_t len, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char iv[16]);
+void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
+ size_t len, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char iv[16]);
+#endif
+#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]);
+#endif
+#ifdef AES_XTS_ASM
+void AES_xts_encrypt(const char *inp,char *out,size_t len,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+void AES_xts_decrypt(const char *inp,char *out,size_t len,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+#endif
+
+#if defined(AES_ASM) && !defined(I386_ONLY) && ( \
+ ((defined(__i386) || defined(__i386__) || \
+ defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+extern unsigned int OPENSSL_ia32cap_P[2];
+
+#ifdef VPAES_ASM
+#define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+#endif
+#ifdef BSAES_ASM
+#define BSAES_CAPABLE VPAES_CAPABLE
+#endif
+/*
+ * AES-NI section
+ */
+#define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
+
+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,
+ AES_KEY *key);
+
+void aesni_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void aesni_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void aesni_ecb_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ int enc);
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ 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);
+
+void aesni_xts_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+
+void aesni_xts_decrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+
+void aesni_ccm64_encrypt_blocks (const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+void aesni_ccm64_decrypt_blocks (const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ int ret, mode;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc)
+ {
+ ret = aesni_set_decrypt_key(key, ctx->key_len*8, ctx->cipher_data);
+ dat->block = (block128_f)aesni_decrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)aesni_cbc_encrypt :
+ NULL;
+ }
+ else {
+ ret = aesni_set_encrypt_key(key, ctx->key_len*8, ctx->cipher_data);
+ dat->block = (block128_f)aesni_encrypt;
+ if (mode==EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f)aesni_cbc_encrypt;
+ else if (mode==EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
+ else
+ dat->stream.cbc = NULL;
+ }
+
+ if(ret < 0)
+ {
+ EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+ }
+
+static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ aesni_cbc_encrypt(in,out,len,ctx->cipher_data,ctx->iv,ctx->encrypt);
+
+ return 1;
+}
+
+static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+
+ if (len<bl) return 1;
+
+ aesni_ecb_encrypt(in,out,len,ctx->cipher_data,ctx->encrypt);
+
+ return 1;
+}
+
+#define aesni_ofb_cipher aes_ofb_cipher
+static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len);
+
+#define aesni_cfb_cipher aes_cfb_cipher
+static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len);
+
+#define aesni_cfb8_cipher aes_cfb8_cipher
+static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len);
+
+#define aesni_cfb1_cipher aes_cfb1_cipher
+static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len);
+
+#define aesni_ctr_cipher aes_ctr_cipher
+static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_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)
+ {
+ aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f)aesni_encrypt);
+ gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
+ /* If we have an iv can set it directly, otherwise use
+ * saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv)
+ {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ }
+ else
+ {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+ }
+
+#define aesni_gcm_cipher aes_gcm_cipher
+static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key)
+ {
+ /* key_len is two AES keys */
+ if (enc)
+ {
+ aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)aesni_encrypt;
+ xctx->stream = aesni_xts_encrypt;
+ }
+ else
+ {
+ aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)aesni_decrypt;
+ xctx->stream = aesni_xts_decrypt;
+ }
+
+ aesni_set_encrypt_key(key + ctx->key_len/2,
+ ctx->key_len * 4, &xctx->ks2);
+ xctx->xts.block2 = (block128_f)aesni_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ }
+
+ if (iv)
+ {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+ }
+
+#define aesni_xts_cipher aes_xts_cipher
+static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key)
+ {
+ aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f)aesni_encrypt);
+ cctx->str = enc?(ccm128_f)aesni_ccm64_encrypt_blocks :
+ (ccm128_f)aesni_ccm64_decrypt_blocks;
+ cctx->key_set = 1;
+ }
+ if (iv)
+ {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+ }
+
+#define aesni_ccm_cipher aes_ccm_cipher
+static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aesni_init_key, \
+ aesni_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize, \
+ keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aesni_##mode##_init_key, \
+ aesni_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+#else
+
+#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+
+#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+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) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
- int ret;
+ int ret, mode;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)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=AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc)
+#ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE && mode==EVP_CIPH_CBC_MODE)
+ {
+ ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)AES_decrypt;
+ dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
+ }
+ else
+#endif
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ ret = vpaes_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)vpaes_decrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)vpaes_cbc_encrypt :
+ NULL;
+ }
+ else
+#endif
+ {
+ ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)AES_decrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)AES_cbc_encrypt :
+ NULL;
+ }
else
- ret=AES_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+#ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE && mode==EVP_CIPH_CTR_MODE)
+ {
+ ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)AES_encrypt;
+ dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
+ }
+ else
+#endif
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ ret = vpaes_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)vpaes_encrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)vpaes_cbc_encrypt :
+ NULL;
+ }
+ else
+#endif
+ {
+ ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
+ dat->block = (block128_f)AES_encrypt;
+ dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
+ (cbc128_f)AES_cbc_encrypt :
+ NULL;
+#ifdef AES_CTR_ASM
+ if (mode==EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
+#endif
+ }
if(ret < 0)
{
@@ -117,4 +579,752 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
return 1;
}
+static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ if (dat->stream.cbc)
+ (*dat->stream.cbc)(in,out,len,&dat->ks,ctx->iv,ctx->encrypt);
+ 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);
+
+ return 1;
+}
+
+static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+ size_t i;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ if (len<bl) return 1;
+
+ for (i=0,len-=bl;i<=len;i+=bl)
+ (*dat->block)(in+i,out+i,&dat->ks);
+
+ return 1;
+}
+
+static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ CRYPTO_ofb128_encrypt(in,out,len,&dat->ks,
+ ctx->iv,&ctx->num,dat->block);
+ return 1;
+}
+
+static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ CRYPTO_cfb128_encrypt(in,out,len,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+ return 1;
+}
+
+static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ CRYPTO_cfb128_8_encrypt(in,out,len,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+ return 1;
+}
+
+static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
+ const unsigned char *in,size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) {
+ CRYPTO_cfb128_1_encrypt(in,out,len,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+ return 1;
+ }
+
+ while (len>=MAXBITCHUNK) {
+ CRYPTO_cfb128_1_encrypt(in,out,MAXBITCHUNK*8,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+ len-=MAXBITCHUNK;
+ }
+ if (len)
+ CRYPTO_cfb128_1_encrypt(in,out,len*8,&dat->ks,
+ ctx->iv,&ctx->num,ctx->encrypt,dat->block);
+
+ return 1;
+}
+
+static int aes_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ unsigned int num = ctx->num;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ if (dat->stream.ctr)
+ CRYPTO_ctr128_encrypt_ctr32(in,out,len,&dat->ks,
+ ctx->iv,ctx->buf,&num,dat->stream.ctr);
+ else
+ CRYPTO_ctr128_encrypt(in,out,len,&dat->ks,
+ ctx->iv,ctx->buf,&num,dat->block);
+ ctx->num = (size_t)num;
+ return 1;
+}
+
+BLOCK_CIPHER_generic_pack(NID_aes,128,EVP_CIPH_FLAG_FIPS)
+BLOCK_CIPHER_generic_pack(NID_aes,192,EVP_CIPH_FLAG_FIPS)
+BLOCK_CIPHER_generic_pack(NID_aes,256,EVP_CIPH_FLAG_FIPS)
+
+static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
+ {
+ EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
+ if (gctx->iv != c->iv)
+ OPENSSL_free(gctx->iv);
+ return 1;
+ }
+
+/* increment counter (64-bit int) by 1 */
+static void ctr64_inc(unsigned char *counter) {
+ int n=8;
+ unsigned char c;
+
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c) return;
+ } while (n);
+}
+
+static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+ {
+ EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ switch (type)
+ {
+ case EVP_CTRL_INIT:
+ gctx->key_set = 0;
+ gctx->iv_set = 0;
+ gctx->ivlen = c->cipher->iv_len;
+ gctx->iv = c->iv;
+ gctx->taglen = -1;
+ gctx->iv_gen = 0;
+ gctx->tls_aad_len = -1;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IVLEN:
+ if (arg <= 0)
+ return 0;
+#ifdef OPENSSL_FIPS
+ if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)
+ && arg < 12)
+ return 0;
+#endif
+ /* Allocate memory for IV if needed */
+ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen))
+ {
+ if (gctx->iv != c->iv)
+ OPENSSL_free(gctx->iv);
+ gctx->iv = OPENSSL_malloc(arg);
+ if (!gctx->iv)
+ return 0;
+ }
+ gctx->ivlen = arg;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_TAG:
+ if (arg <= 0 || arg > 16 || c->encrypt)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->taglen = arg;
+ return 1;
+
+ case EVP_CTRL_GCM_GET_TAG:
+ if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0)
+ return 0;
+ memcpy(ptr, c->buf, arg);
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IV_FIXED:
+ /* Special case: -1 length restores whole IV */
+ if (arg == -1)
+ {
+ memcpy(gctx->iv, ptr, gctx->ivlen);
+ gctx->iv_gen = 1;
+ return 1;
+ }
+ /* Fixed field must be at least 4 bytes and invocation field
+ * at least 8.
+ */
+ if ((arg < 4) || (gctx->ivlen - arg) < 8)
+ return 0;
+ if (arg)
+ memcpy(gctx->iv, ptr, arg);
+ if (c->encrypt &&
+ RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
+ return 0;
+ gctx->iv_gen = 1;
+ return 1;
+
+ case EVP_CTRL_GCM_IV_GEN:
+ if (gctx->iv_gen == 0 || gctx->key_set == 0)
+ return 0;
+ CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ if (arg <= 0 || arg > gctx->ivlen)
+ arg = gctx->ivlen;
+ memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
+ /* Invocation field will be at least 8 bytes in size and
+ * so no need to check wrap around or increment more than
+ * last 8 bytes.
+ */
+ ctr64_inc(gctx->iv + gctx->ivlen - 8);
+ gctx->iv_set = 1;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IV_INV:
+ if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt)
+ return 0;
+ memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
+ CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ return 1;
+
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ /* Save the AAD for later use */
+ if (arg != 13)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->tls_aad_len = arg;
+ {
+ unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1];
+ /* Correct length for explicit IV */
+ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ /* If decrypting correct for tag too */
+ if (!c->encrypt)
+ len -= EVP_GCM_TLS_TAG_LEN;
+ c->buf[arg-2] = len>>8;
+ c->buf[arg-1] = len & 0xff;
+ }
+ /* Extra padding: tag appended to record */
+ return EVP_GCM_TLS_TAG_LEN;
+
+ default:
+ return -1;
+
+ }
+ }
+
+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,ctx->key_len*8,&gctx->ks);
+ CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
+ (block128_f)AES_encrypt);
+ gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
+ break;
+ }
+ else
+#endif
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
+ CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
+ (block128_f)vpaes_encrypt);
+ gctx->ctr = NULL;
+ break;
+ }
+ else
+#endif
+ (void)0; /* terminate potentially open 'else' */
+
+ AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt);
+#ifdef AES_CTR_ASM
+ gctx->ctr = (ctr128_f)AES_ctr32_encrypt;
+#else
+ gctx->ctr = NULL;
+#endif
+ } while (0);
+
+ /* If we have an iv can set it directly, otherwise use
+ * saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv)
+ {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ }
+ else
+ {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+ }
+
+/* Handle TLS GCM packet format. This consists of the last portion of the IV
+ * followed by the payload and finally the tag. On encrypt generate IV,
+ * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
+ * and verify tag.
+ */
+
+static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ int rv = -1;
+ /* Encrypt/decrypt must be performed in place */
+ if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN+EVP_GCM_TLS_TAG_LEN))
+ return -1;
+ /* Set IV from start of buffer or generate IV and write to start
+ * of buffer.
+ */
+ if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ?
+ EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
+ EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
+ goto err;
+ /* Use saved AAD */
+ if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len))
+ goto err;
+ /* Fix buffer and length to point to payload */
+ in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ if (ctx->encrypt)
+ {
+ /* Encrypt payload */
+ if (gctx->ctr)
+ {
+ if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+ in, out, len,
+ gctx->ctr))
+ goto err;
+ }
+ else {
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
+ goto err;
+ }
+ out += len;
+ /* Finally write tag */
+ CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
+ rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ }
+ else
+ {
+ /* Decrypt */
+ if (gctx->ctr)
+ {
+ if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+ in, out, len,
+ gctx->ctr))
+ goto err;
+ }
+ else {
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
+ goto err;
+ }
+ /* Retrieve tag */
+ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf,
+ EVP_GCM_TLS_TAG_LEN);
+ /* If tag mismatch wipe buffer */
+ if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
+ {
+ OPENSSL_cleanse(out, len);
+ goto err;
+ }
+ rv = len;
+ }
+
+ err:
+ gctx->iv_set = 0;
+ gctx->tls_aad_len = -1;
+ return rv;
+ }
+
+static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ /* If not set up, return error */
+ if (!gctx->key_set)
+ return -1;
+
+ if (gctx->tls_aad_len >= 0)
+ return aes_gcm_tls_cipher(ctx, out, in, len);
+
+ if (!gctx->iv_set)
+ return -1;
+ if (in)
+ {
+ if (out == NULL)
+ {
+ if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
+ return -1;
+ }
+ else if (ctx->encrypt)
+ {
+ if (gctx->ctr)
+ {
+ if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+ in, out, len,
+ gctx->ctr))
+ return -1;
+ }
+ else {
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
+ return -1;
+ }
+ }
+ else
+ {
+ if (gctx->ctr)
+ {
+ if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+ in, out, len,
+ gctx->ctr))
+ return -1;
+ }
+ else {
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
+ return -1;
+ }
+ }
+ return len;
+ }
+ else
+ {
+ if (!ctx->encrypt)
+ {
+ if (gctx->taglen < 0)
+ return -1;
+ if (CRYPTO_gcm128_finish(&gctx->gcm,
+ ctx->buf, gctx->taglen) != 0)
+ return -1;
+ gctx->iv_set = 0;
+ return 0;
+ }
+ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
+ gctx->taglen = 16;
+ /* Don't reuse the IV */
+ gctx->iv_set = 0;
+ return 0;
+ }
+
+ }
+
+#define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
+ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
+
+BLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM,
+ EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM,
+ EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM,
+ EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+
+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+ {
+ EVP_AES_XTS_CTX *xctx = c->cipher_data;
+ if (type != EVP_CTRL_INIT)
+ return -1;
+ /* key1 and key2 are used as an indicator both key and IV are set */
+ xctx->xts.key1 = NULL;
+ xctx->xts.key2 = NULL;
+ return 1;
+ }
+
+static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key) do
+ {
+#ifdef AES_XTS_ASM
+ xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
+#else
+ xctx->stream = NULL;
+#endif
+ /* key_len is two AES keys */
+#if !(defined(__arm__) || defined(__arm)) /* not yet? */
+#ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE)
+ xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
+ else
+#endif
+#endif
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ if (enc)
+ {
+ vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)vpaes_encrypt;
+ }
+ else
+ {
+ vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)vpaes_decrypt;
+ }
+
+ vpaes_set_encrypt_key(key + ctx->key_len/2,
+ ctx->key_len * 4, &xctx->ks2);
+ xctx->xts.block2 = (block128_f)vpaes_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ break;
+ }
+ else
+#endif
+ (void)0; /* terminate potentially open 'else' */
+
+ if (enc)
+ {
+ AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)AES_encrypt;
+ }
+ else
+ {
+ AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+ xctx->xts.block1 = (block128_f)AES_decrypt;
+ }
+
+ AES_set_encrypt_key(key + ctx->key_len/2,
+ ctx->key_len * 4, &xctx->ks2);
+ xctx->xts.block2 = (block128_f)AES_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ } while (0);
+
+ if (iv)
+ {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+ }
+
+static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!xctx->xts.key1 || !xctx->xts.key2)
+ return 0;
+ if (!out || !in || len<AES_BLOCK_SIZE)
+ return 0;
+#ifdef OPENSSL_FIPS
+ /* Requirement of SP800-38E */
+ if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) &&
+ (len > (1UL<<20)*16))
+ {
+ EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE);
+ return 0;
+ }
+#endif
+ if (xctx->stream)
+ (*xctx->stream)(in, out, len,
+ xctx->xts.key1, xctx->xts.key2, ctx->iv);
+ else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
+ ctx->encrypt))
+ return 0;
+ return 1;
+ }
+
+#define aes_xts_cleanup NULL
+
+#define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
+
+BLOCK_CIPHER_custom(NID_aes,128,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,256,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
+
+static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+ {
+ EVP_AES_CCM_CTX *cctx = c->cipher_data;
+ switch (type)
+ {
+ case EVP_CTRL_INIT:
+ cctx->key_set = 0;
+ cctx->iv_set = 0;
+ cctx->L = 8;
+ cctx->M = 12;
+ cctx->tag_set = 0;
+ cctx->len_set = 0;
+ return 1;
+
+ case EVP_CTRL_CCM_SET_IVLEN:
+ arg = 15 - arg;
+ case EVP_CTRL_CCM_SET_L:
+ if (arg < 2 || arg > 8)
+ return 0;
+ cctx->L = arg;
+ return 1;
+
+ case EVP_CTRL_CCM_SET_TAG:
+ if ((arg & 1) || arg < 4 || arg > 16)
+ return 0;
+ if ((c->encrypt && ptr) || (!c->encrypt && !ptr))
+ return 0;
+ if (ptr)
+ {
+ cctx->tag_set = 1;
+ memcpy(c->buf, ptr, arg);
+ }
+ cctx->M = arg;
+ return 1;
+
+ case EVP_CTRL_CCM_GET_TAG:
+ if (!c->encrypt || !cctx->tag_set)
+ return 0;
+ if(!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
+ return 0;
+ cctx->tag_set = 0;
+ cctx->iv_set = 0;
+ cctx->len_set = 0;
+ return 1;
+
+ default:
+ return -1;
+
+ }
+ }
+
+static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) do
+ {
+#ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE)
+ {
+ vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f)vpaes_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ break;
+ }
+#endif
+ AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f)AES_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ } while (0);
+ if (iv)
+ {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+ }
+
+static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ CCM128_CONTEXT *ccm = &cctx->ccm;
+ /* If not set up, return error */
+ if (!cctx->iv_set && !cctx->key_set)
+ return -1;
+ if (!ctx->encrypt && !cctx->tag_set)
+ return -1;
+ if (!out)
+ {
+ if (!in)
+ {
+ if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L,len))
+ return -1;
+ cctx->len_set = 1;
+ return len;
+ }
+ /* If have AAD need message length */
+ if (!cctx->len_set && len)
+ return -1;
+ CRYPTO_ccm128_aad(ccm, in, len);
+ return len;
+ }
+ /* EVP_*Final() doesn't return any data */
+ if (!in)
+ return 0;
+ /* If not set length yet do it */
+ if (!cctx->len_set)
+ {
+ if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
+ return -1;
+ cctx->len_set = 1;
+ }
+ if (ctx->encrypt)
+ {
+ if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
+ cctx->str) :
+ CRYPTO_ccm128_encrypt(ccm, in, out, len))
+ return -1;
+ cctx->tag_set = 1;
+ return len;
+ }
+ else
+ {
+ int rv = -1;
+ if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
+ cctx->str) :
+ !CRYPTO_ccm128_decrypt(ccm, in, out, len))
+ {
+ unsigned char tag[16];
+ if (CRYPTO_ccm128_tag(ccm, tag, cctx->M))
+ {
+ if (!memcmp(tag, ctx->buf, cctx->M))
+ rv = len;
+ }
+ }
+ if (rv == -1)
+ OPENSSL_cleanse(out, len);
+ cctx->iv_set = 0;
+ cctx->tag_set = 0;
+ cctx->len_set = 0;
+ return rv;
+ }
+
+ }
+
+#define aes_ccm_cleanup NULL
+
+BLOCK_CIPHER_custom(NID_aes,128,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+
+#endif
#endif
diff --git a/app/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/app/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
new file mode 100644
index 00000000..fb2c884a
--- /dev/null
+++ b/app/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -0,0 +1,581 @@
+/* ====================================================================
+ * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/aes.h>
+#include <openssl/sha.h>
+#include "evp_locl.h"
+
+#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+#define EVP_CTRL_AEAD_TLS1_AAD 0x16
+#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+#endif
+
+#if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
+#define EVP_CIPH_FLAG_DEFAULT_ASN1 0
+#endif
+
+#define TLS1_1_VERSION 0x0302
+
+typedef struct
+ {
+ AES_KEY ks;
+ SHA_CTX head,tail,md;
+ size_t payload_length; /* AAD length in decrypt case */
+ union {
+ unsigned int tls_ver;
+ unsigned char tls_aad[16]; /* 13 used */
+ } aux;
+ } EVP_AES_HMAC_SHA1;
+
+#define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+#if defined(AES_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC)
+# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
+#endif
+
+extern unsigned int OPENSSL_ia32cap_P[2];
+#define AESNI_CAPABLE (1<<(57-32))
+
+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,
+ AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ unsigned char *ivec, int enc);
+
+void aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks,
+ const AES_KEY *key, unsigned char iv[16],
+ SHA_CTX *ctx,const void *in0);
+
+#define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
+
+static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+ int ret;
+
+ if (enc)
+ ret=aesni_set_encrypt_key(inkey,ctx->key_len*8,&key->ks);
+ else
+ ret=aesni_set_decrypt_key(inkey,ctx->key_len*8,&key->ks);
+
+ SHA1_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return ret<0?0:1;
+ }
+
+#define STITCHED_CALL
+
+#if !defined(STITCHED_CALL)
+#define aes_off 0
+#endif
+
+void sha1_block_data_order (void *c,const void *p,size_t len);
+
+static void sha1_update(SHA_CTX *c,const void *data,size_t len)
+{ const unsigned char *ptr = data;
+ size_t res;
+
+ if ((res = c->num)) {
+ res = SHA_CBLOCK-res;
+ if (len<res) res=len;
+ SHA1_Update (c,ptr,res);
+ ptr += res;
+ len -= res;
+ }
+
+ res = len % SHA_CBLOCK;
+ len -= res;
+
+ if (len) {
+ sha1_block_data_order(c,ptr,len/SHA_CBLOCK);
+
+ ptr += len;
+ c->Nh += len>>29;
+ c->Nl += len<<=3;
+ if (c->Nl<(unsigned int)len) c->Nh++;
+ }
+
+ if (res)
+ SHA1_Update(c,ptr,res);
+}
+
+#ifdef SHA1_Update
+#undef SHA1_Update
+#endif
+#define SHA1_Update sha1_update
+
+static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+ unsigned int l;
+ size_t plen = key->payload_length,
+ iv = 0, /* explicit IV in TLS 1.1 and later */
+ sha_off = 0;
+#if defined(STITCHED_CALL)
+ size_t aes_off = 0,
+ blocks;
+
+ sha_off = SHA_CBLOCK-key->md.num;
+#endif
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ if (len%AES_BLOCK_SIZE) return 0;
+
+ if (ctx->encrypt) {
+ if (plen==NO_PAYLOAD_LENGTH)
+ plen = len;
+ else if (len!=((plen+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE))
+ return 0;
+ else if (key->aux.tls_ver >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+#if defined(STITCHED_CALL)
+ if (plen>(sha_off+iv) && (blocks=(plen-(sha_off+iv))/SHA_CBLOCK)) {
+ SHA1_Update(&key->md,in+iv,sha_off);
+
+ aesni_cbc_sha1_enc(in,out,blocks,&key->ks,
+ ctx->iv,&key->md,in+iv+sha_off);
+ blocks *= SHA_CBLOCK;
+ aes_off += blocks;
+ sha_off += blocks;
+ key->md.Nh += blocks>>29;
+ key->md.Nl += blocks<<=3;
+ if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
+ } else {
+ sha_off = 0;
+ }
+#endif
+ sha_off += iv;
+ SHA1_Update(&key->md,in+sha_off,plen-sha_off);
+
+ if (plen!=len) { /* "TLS" mode of operation */
+ if (in!=out)
+ memcpy(out+aes_off,in+aes_off,plen-aes_off);
+
+ /* calculate HMAC and append it to payload */
+ SHA1_Final(out+plen,&key->md);
+ key->md = key->tail;
+ SHA1_Update(&key->md,out+plen,SHA_DIGEST_LENGTH);
+ SHA1_Final(out+plen,&key->md);
+
+ /* pad the payload|hmac */
+ plen += SHA_DIGEST_LENGTH;
+ for (l=len-plen-1;plen<len;plen++) out[plen]=l;
+ /* encrypt HMAC|padding at once */
+ aesni_cbc_encrypt(out+aes_off,out+aes_off,len-aes_off,
+ &key->ks,ctx->iv,1);
+ } else {
+ aesni_cbc_encrypt(in+aes_off,out+aes_off,len-aes_off,
+ &key->ks,ctx->iv,1);
+ }
+ } else {
+ union { unsigned int u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
+ unsigned char c[32+SHA_DIGEST_LENGTH]; } mac, *pmac;
+
+ /* arrange cache line alignment */
+ pmac = (void *)(((size_t)mac.c+31)&((size_t)0-32));
+
+ /* decrypt HMAC|padding at once */
+ aesni_cbc_encrypt(in,out,len,
+ &key->ks,ctx->iv,0);
+
+ if (plen) { /* "TLS" mode of operation */
+ size_t inp_len, mask, j, i;
+ unsigned int res, maxpad, pad, bitlen;
+ int ret = 1;
+ union { unsigned int u[SHA_LBLOCK];
+ unsigned char c[SHA_CBLOCK]; }
+ *data = (void *)key->md.data;
+
+ if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
+ >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+ if (len<(iv+SHA_DIGEST_LENGTH+1))
+ return 0;
+
+ /* omit explicit iv */
+ out += iv;
+ len -= iv;
+
+ /* figure out payload length */
+ pad = out[len-1];
+ maxpad = len-(SHA_DIGEST_LENGTH+1);
+ maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8);
+ maxpad &= 255;
+
+ inp_len = len - (SHA_DIGEST_LENGTH+pad+1);
+ mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1)));
+ inp_len &= mask;
+ ret &= (int)mask;
+
+ key->aux.tls_aad[plen-2] = inp_len>>8;
+ key->aux.tls_aad[plen-1] = inp_len;
+
+ /* calculate HMAC */
+ key->md = key->head;
+ SHA1_Update(&key->md,key->aux.tls_aad,plen);
+
+#if 1
+ len -= SHA_DIGEST_LENGTH; /* amend mac */
+ if (len>=(256+SHA_CBLOCK)) {
+ j = (len-(256+SHA_CBLOCK))&(0-SHA_CBLOCK);
+ j += SHA_CBLOCK-key->md.num;
+ SHA1_Update(&key->md,out,j);
+ out += j;
+ len -= j;
+ inp_len -= j;
+ }
+
+ /* but pretend as if we hashed padded payload */
+ bitlen = key->md.Nl+(inp_len<<3); /* at most 18 bits */
+#ifdef BSWAP
+ bitlen = BSWAP(bitlen);
+#else
+ mac.c[0] = 0;
+ mac.c[1] = (unsigned char)(bitlen>>16);
+ mac.c[2] = (unsigned char)(bitlen>>8);
+ mac.c[3] = (unsigned char)bitlen;
+ bitlen = mac.u[0];
+#endif
+
+ pmac->u[0]=0;
+ pmac->u[1]=0;
+ pmac->u[2]=0;
+ pmac->u[3]=0;
+ pmac->u[4]=0;
+
+ for (res=key->md.num, j=0;j<len;j++) {
+ size_t c = out[j];
+ mask = (j-inp_len)>>(sizeof(j)*8-8);
+ c &= mask;
+ c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8));
+ data->c[res++]=(unsigned char)c;
+
+ if (res!=SHA_CBLOCK) continue;
+
+ /* j is not incremented yet */
+ mask = 0-((inp_len+7-j)>>(sizeof(j)*8-1));
+ data->u[SHA_LBLOCK-1] |= bitlen&mask;
+ sha1_block_data_order(&key->md,data,1);
+ mask &= 0-((j-inp_len-72)>>(sizeof(j)*8-1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+ res=0;
+ }
+
+ for(i=res;i<SHA_CBLOCK;i++,j++) data->c[i]=0;
+
+ if (res>SHA_CBLOCK-8) {
+ mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+ data->u[SHA_LBLOCK-1] |= bitlen&mask;
+ sha1_block_data_order(&key->md,data,1);
+ mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+
+ memset(data,0,SHA_CBLOCK);
+ j+=64;
+ }
+ data->u[SHA_LBLOCK-1] = bitlen;
+ sha1_block_data_order(&key->md,data,1);
+ mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+
+#ifdef BSWAP
+ pmac->u[0] = BSWAP(pmac->u[0]);
+ pmac->u[1] = BSWAP(pmac->u[1]);
+ pmac->u[2] = BSWAP(pmac->u[2]);
+ pmac->u[3] = BSWAP(pmac->u[3]);
+ pmac->u[4] = BSWAP(pmac->u[4]);
+#else
+ for (i=0;i<5;i++) {
+ res = pmac->u[i];
+ pmac->c[4*i+0]=(unsigned char)(res>>24);
+ pmac->c[4*i+1]=(unsigned char)(res>>16);
+ pmac->c[4*i+2]=(unsigned char)(res>>8);
+ pmac->c[4*i+3]=(unsigned char)res;
+ }
+#endif
+ len += SHA_DIGEST_LENGTH;
+#else
+ SHA1_Update(&key->md,out,inp_len);
+ res = key->md.num;
+ SHA1_Final(pmac->c,&key->md);
+
+ {
+ unsigned int inp_blocks, pad_blocks;
+
+ /* but pretend as if we hashed padded payload */
+ inp_blocks = 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+ res += (unsigned int)(len-inp_len);
+ pad_blocks = res / SHA_CBLOCK;
+ res %= SHA_CBLOCK;
+ pad_blocks += 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+ for (;inp_blocks<pad_blocks;inp_blocks++)
+ sha1_block_data_order(&key->md,data,1);
+ }
+#endif
+ key->md = key->tail;
+ SHA1_Update(&key->md,pmac->c,SHA_DIGEST_LENGTH);
+ SHA1_Final(pmac->c,&key->md);
+
+ /* verify HMAC */
+ out += inp_len;
+ len -= inp_len;
+#if 1
+ {
+ unsigned char *p = out+len-1-maxpad-SHA_DIGEST_LENGTH;
+ size_t off = out-p;
+ unsigned int c, cmask;
+
+ maxpad += SHA_DIGEST_LENGTH;
+ for (res=0,i=0,j=0;j<maxpad;j++) {
+ c = p[j];
+ cmask = ((int)(j-off-SHA_DIGEST_LENGTH))>>(sizeof(int)*8-1);
+ res |= (c^pad)&~cmask; /* ... and padding */
+ cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1);
+ res |= (c^pmac->c[i])&cmask;
+ i += 1&cmask;
+ }
+ maxpad -= SHA_DIGEST_LENGTH;
+
+ res = 0-((0-res)>>(sizeof(res)*8-1));
+ ret &= (int)~res;
+ }
+#else
+ for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++)
+ res |= out[i]^pmac->c[i];
+ res = 0-((0-res)>>(sizeof(res)*8-1));
+ ret &= (int)~res;
+
+ /* verify padding */
+ pad = (pad&~res) | (maxpad&res);
+ out = out+len-1-pad;
+ for (res=0,i=0;i<pad;i++)
+ res |= out[i]^pad;
+
+ res = (0-res)>>(sizeof(res)*8-1);
+ ret &= (int)~res;
+#endif
+ return ret;
+ } else {
+ SHA1_Update(&key->md,out,len);
+ }
+ }
+
+ return 1;
+ }
+
+static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+ {
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+
+ switch (type)
+ {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset (hmac_key,0,sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ SHA1_Init(&key->head);
+ SHA1_Update(&key->head,ptr,arg);
+ SHA1_Final(hmac_key,&key->head);
+ } else {
+ memcpy(hmac_key,ptr,arg);
+ }
+
+ for (i=0;i<sizeof(hmac_key);i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ SHA1_Init(&key->head);
+ SHA1_Update(&key->head,hmac_key,sizeof(hmac_key));
+
+ for (i=0;i<sizeof(hmac_key);i++)
+ hmac_key[i] ^= 0x36^0x5c; /* opad */
+ SHA1_Init(&key->tail);
+ SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
+
+ OPENSSL_cleanse(hmac_key,sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p=ptr;
+ unsigned int len=p[arg-2]<<8|p[arg-1];
+
+ if (ctx->encrypt)
+ {
+ key->payload_length = len;
+ if ((key->aux.tls_ver=p[arg-4]<<8|p[arg-3]) >= TLS1_1_VERSION) {
+ len -= AES_BLOCK_SIZE;
+ p[arg-2] = len>>8;
+ p[arg-1] = len;
+ }
+ key->md = key->head;
+ SHA1_Update(&key->md,p,arg);
+
+ return (int)(((len+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE)
+ - len);
+ }
+ else
+ {
+ if (arg>13) arg = 13;
+ memcpy(key->aux.tls_aad,ptr,arg);
+ key->payload_length = arg;
+
+ return SHA_DIGEST_LENGTH;
+ }
+ }
+ default:
+ return -1;
+ }
+ }
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher =
+ {
+#ifdef NID_aes_128_cbc_hmac_sha1
+ NID_aes_128_cbc_hmac_sha1,
+#else
+ NID_undef,
+#endif
+ 16,16,16,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
+ aesni_cbc_hmac_sha1_init_key,
+ aesni_cbc_hmac_sha1_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA1),
+ EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha1_ctrl,
+ NULL
+ };
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher =
+ {
+#ifdef NID_aes_256_cbc_hmac_sha1
+ NID_aes_256_cbc_hmac_sha1,
+#else
+ NID_undef,
+#endif
+ 16,32,16,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_FLAG_AEAD_CIPHER,
+ aesni_cbc_hmac_sha1_init_key,
+ aesni_cbc_hmac_sha1_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA1),
+ EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1?NULL:EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha1_ctrl,
+ NULL
+ };
+
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+ {
+ return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
+ &aesni_128_cbc_hmac_sha1_cipher:NULL);
+ }
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+ {
+ return(OPENSSL_ia32cap_P[1]&AESNI_CAPABLE?
+ &aesni_256_cbc_hmac_sha1_cipher:NULL);
+ }
+#else
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+ {
+ return NULL;
+ }
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+ {
+ return NULL;
+ }
+#endif
+#endif
diff --git a/app/openssl/crypto/evp/e_des3.c b/app/openssl/crypto/evp/e_des3.c
index 3232cfe0..8d7b7de2 100644
--- a/app/openssl/crypto/evp/e_des3.c
+++ b/app/openssl/crypto/evp/e_des3.c
@@ -65,6 +65,8 @@
#include <openssl/des.h>
#include <openssl/rand.h>
+#ifndef OPENSSL_FIPS
+
static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv,int enc);
@@ -99,7 +101,7 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
- if (inl>=EVP_MAXCHUNK)
+ while (inl>=EVP_MAXCHUNK)
{
DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
@@ -130,7 +132,7 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
printf("\n");
}
#endif /* KSSL_DEBUG */
- if (inl>=EVP_MAXCHUNK)
+ while (inl>=EVP_MAXCHUNK)
{
DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
@@ -149,7 +151,7 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
- if (inl>=EVP_MAXCHUNK)
+ while (inl>=EVP_MAXCHUNK)
{
DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
@@ -311,3 +313,4 @@ const EVP_CIPHER *EVP_des_ede3(void)
return &des_ede3_ecb;
}
#endif
+#endif
diff --git a/app/openssl/crypto/evp/e_null.c b/app/openssl/crypto/evp/e_null.c
index 7cf50e14..f0c1f78b 100644
--- a/app/openssl/crypto/evp/e_null.c
+++ b/app/openssl/crypto/evp/e_null.c
@@ -61,6 +61,8 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
+#ifndef OPENSSL_FIPS
+
static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv,int enc);
static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
@@ -99,4 +101,4 @@ static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
memcpy((char *)out,(const char *)in,inl);
return 1;
}
-
+#endif
diff --git a/app/openssl/crypto/evp/e_rc2.c b/app/openssl/crypto/evp/e_rc2.c
index f78d7811..d4c33b58 100644
--- a/app/openssl/crypto/evp/e_rc2.c
+++ b/app/openssl/crypto/evp/e_rc2.c
@@ -183,7 +183,8 @@ static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
key_bits =rc2_magic_to_meth((int)num);
if (!key_bits)
return(-1);
- if(i > 0) EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1);
+ if(i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
+ return -1;
EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
EVP_CIPHER_CTX_set_key_length(c, key_bits / 8);
}
diff --git a/app/openssl/crypto/evp/e_rc4.c b/app/openssl/crypto/evp/e_rc4.c
index 8b5175e0..b4f6bda8 100644
--- a/app/openssl/crypto/evp/e_rc4.c
+++ b/app/openssl/crypto/evp/e_rc4.c
@@ -62,6 +62,7 @@
#ifndef OPENSSL_NO_RC4
#include <openssl/evp.h>
+#include "evp_locl.h"
#include <openssl/objects.h>
#include <openssl/rc4.h>
diff --git a/app/openssl/crypto/evp/e_rc4_hmac_md5.c b/app/openssl/crypto/evp/e_rc4_hmac_md5.c
new file mode 100644
index 00000000..56563191
--- /dev/null
+++ b/app/openssl/crypto/evp/e_rc4_hmac_md5.c
@@ -0,0 +1,298 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/rc4.h>
+#include <openssl/md5.h>
+
+#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+#define EVP_CTRL_AEAD_TLS1_AAD 0x16
+#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+#endif
+
+/* FIXME: surely this is available elsewhere? */
+#define EVP_RC4_KEY_SIZE 16
+
+typedef struct
+ {
+ RC4_KEY ks;
+ MD5_CTX head,tail,md;
+ size_t payload_length;
+ } EVP_RC4_HMAC_MD5;
+
+#define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+void rc4_md5_enc (RC4_KEY *key, const void *in0, void *out,
+ MD5_CTX *ctx,const void *inp,size_t blocks);
+
+#define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data)
+
+static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+ {
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+ RC4_set_key(&key->ks,EVP_CIPHER_CTX_key_length(ctx),
+ inkey);
+
+ MD5_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return 1;
+ }
+
+#if !defined(OPENSSL_NO_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) ) && \
+ !(defined(__APPLE__) && defined(__MACH__))
+#define STITCHED_CALL
+#endif
+
+#if !defined(STITCHED_CALL)
+#define rc4_off 0
+#define md5_off 0
+#endif
+
+static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+ {
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+#if defined(STITCHED_CALL)
+ size_t rc4_off = 32-1-(key->ks.x&(32-1)), /* 32 is $MOD from rc4_md5-x86_64.pl */
+ md5_off = MD5_CBLOCK-key->md.num,
+ blocks;
+ unsigned int l;
+ extern unsigned int OPENSSL_ia32cap_P[];
+#endif
+ size_t plen = key->payload_length;
+
+ if (plen!=NO_PAYLOAD_LENGTH && len!=(plen+MD5_DIGEST_LENGTH)) return 0;
+
+ if (ctx->encrypt) {
+ if (plen==NO_PAYLOAD_LENGTH) plen = len;
+#if defined(STITCHED_CALL)
+ /* cipher has to "fall behind" */
+ if (rc4_off>md5_off) md5_off+=MD5_CBLOCK;
+
+ if (plen>md5_off && (blocks=(plen-md5_off)/MD5_CBLOCK) &&
+ (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
+ MD5_Update(&key->md,in,md5_off);
+ RC4(&key->ks,rc4_off,in,out);
+
+ rc4_md5_enc(&key->ks,in+rc4_off,out+rc4_off,
+ &key->md,in+md5_off,blocks);
+ blocks *= MD5_CBLOCK;
+ rc4_off += blocks;
+ md5_off += blocks;
+ key->md.Nh += blocks>>29;
+ key->md.Nl += blocks<<=3;
+ if (key->md.Nl<(unsigned int)blocks) key->md.Nh++;
+ } else {
+ rc4_off = 0;
+ md5_off = 0;
+ }
+#endif
+ MD5_Update(&key->md,in+md5_off,plen-md5_off);
+
+ if (plen!=len) { /* "TLS" mode of operation */
+ if (in!=out)
+ memcpy(out+rc4_off,in+rc4_off,plen-rc4_off);
+
+ /* calculate HMAC and append it to payload */
+ MD5_Final(out+plen,&key->md);
+ key->md = key->tail;
+ MD5_Update(&key->md,out+plen,MD5_DIGEST_LENGTH);
+ MD5_Final(out+plen,&key->md);
+ /* encrypt HMAC at once */
+ RC4(&key->ks,len-rc4_off,out+rc4_off,out+rc4_off);
+ } else {
+ RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off);
+ }
+ } else {
+ unsigned char mac[MD5_DIGEST_LENGTH];
+#if defined(STITCHED_CALL)
+ /* digest has to "fall behind" */
+ if (md5_off>rc4_off) rc4_off += 2*MD5_CBLOCK;
+ else rc4_off += MD5_CBLOCK;
+
+ if (len>rc4_off && (blocks=(len-rc4_off)/MD5_CBLOCK) &&
+ (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
+ RC4(&key->ks,rc4_off,in,out);
+ MD5_Update(&key->md,out,md5_off);
+
+ rc4_md5_enc(&key->ks,in+rc4_off,out+rc4_off,
+ &key->md,out+md5_off,blocks);
+ blocks *= MD5_CBLOCK;
+ rc4_off += blocks;
+ md5_off += blocks;
+ l = (key->md.Nl+(blocks<<3))&0xffffffffU;
+ if (l<key->md.Nl) key->md.Nh++;
+ key->md.Nl = l;
+ key->md.Nh += blocks>>29;
+ } else {
+ md5_off=0;
+ rc4_off=0;
+ }
+#endif
+ /* decrypt HMAC at once */
+ RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off);
+ if (plen!=NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+ MD5_Update(&key->md,out+md5_off,plen-md5_off);
+
+ /* calculate HMAC and verify it */
+ MD5_Final(mac,&key->md);
+ key->md = key->tail;
+ MD5_Update(&key->md,mac,MD5_DIGEST_LENGTH);
+ MD5_Final(mac,&key->md);
+
+ if (memcmp(out+plen,mac,MD5_DIGEST_LENGTH))
+ return 0;
+ } else {
+ MD5_Update(&key->md,out+md5_off,len-md5_off);
+ }
+ }
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return 1;
+ }
+
+static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+ {
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+ switch (type)
+ {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset (hmac_key,0,sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ MD5_Init(&key->head);
+ MD5_Update(&key->head,ptr,arg);
+ MD5_Final(hmac_key,&key->head);
+ } else {
+ memcpy(hmac_key,ptr,arg);
+ }
+
+ for (i=0;i<sizeof(hmac_key);i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ MD5_Init(&key->head);
+ MD5_Update(&key->head,hmac_key,sizeof(hmac_key));
+
+ for (i=0;i<sizeof(hmac_key);i++)
+ hmac_key[i] ^= 0x36^0x5c; /* opad */
+ MD5_Init(&key->tail);
+ MD5_Update(&key->tail,hmac_key,sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p=ptr;
+ unsigned int len=p[arg-2]<<8|p[arg-1];
+
+ if (!ctx->encrypt)
+ {
+ len -= MD5_DIGEST_LENGTH;
+ p[arg-2] = len>>8;
+ p[arg-1] = len;
+ }
+ key->payload_length=len;
+ key->md = key->head;
+ MD5_Update(&key->md,p,arg);
+
+ return MD5_DIGEST_LENGTH;
+ }
+ default:
+ return -1;
+ }
+ }
+
+static EVP_CIPHER r4_hmac_md5_cipher=
+ {
+#ifdef NID_rc4_hmac_md5
+ NID_rc4_hmac_md5,
+#else
+ NID_undef,
+#endif
+ 1,EVP_RC4_KEY_SIZE,0,
+ EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH|EVP_CIPH_FLAG_AEAD_CIPHER,
+ rc4_hmac_md5_init_key,
+ rc4_hmac_md5_cipher,
+ NULL,
+ sizeof(EVP_RC4_HMAC_MD5),
+ NULL,
+ NULL,
+ rc4_hmac_md5_ctrl,
+ NULL
+ };
+
+const EVP_CIPHER *EVP_rc4_hmac_md5(void)
+ {
+ return(&r4_hmac_md5_cipher);
+ }
+#endif
diff --git a/app/openssl/crypto/evp/evp.h b/app/openssl/crypto/evp/evp.h
index 9f9795e2..e43a58e6 100644
--- a/app/openssl/crypto/evp/evp.h
+++ b/app/openssl/crypto/evp/evp.h
@@ -83,7 +83,7 @@
#define EVP_RC5_32_12_16_KEY_SIZE 16
*/
#define EVP_MAX_MD_SIZE 64 /* longest known is SHA512 */
-#define EVP_MAX_KEY_LENGTH 32
+#define EVP_MAX_KEY_LENGTH 64
#define EVP_MAX_IV_LENGTH 16
#define EVP_MAX_BLOCK_LENGTH 32
@@ -116,6 +116,7 @@
#define EVP_PKEY_DH NID_dhKeyAgreement
#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
#define EVP_PKEY_HMAC NID_hmac
+#define EVP_PKEY_CMAC NID_cmac
#ifdef __cplusplus
extern "C" {
@@ -216,6 +217,8 @@ typedef int evp_verify_method(int type,const unsigned char *m,
#define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018
+#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */
+
/* Digest ctrls */
#define EVP_MD_CTRL_DIGALGID 0x1
@@ -325,6 +328,10 @@ struct evp_cipher_st
#define EVP_CIPH_CBC_MODE 0x2
#define EVP_CIPH_CFB_MODE 0x3
#define EVP_CIPH_OFB_MODE 0x4
+#define EVP_CIPH_CTR_MODE 0x5
+#define EVP_CIPH_GCM_MODE 0x6
+#define EVP_CIPH_CCM_MODE 0x7
+#define EVP_CIPH_XTS_MODE 0x10001
#define EVP_CIPH_MODE 0xF0007
/* Set if variable length cipher */
#define EVP_CIPH_VARIABLE_LENGTH 0x8
@@ -346,6 +353,15 @@ struct evp_cipher_st
#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000
/* Buffer length in bits not bytes: CFB1 mode only */
#define EVP_CIPH_FLAG_LENGTH_BITS 0x2000
+/* Note if suitable for use in FIPS mode */
+#define EVP_CIPH_FLAG_FIPS 0x4000
+/* Allow non FIPS cipher in FIPS mode */
+#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000
+/* Cipher handles any and all padding logic as well
+ * as finalisation.
+ */
+#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000
+#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
/* ctrl() values */
@@ -358,6 +374,33 @@ struct evp_cipher_st
#define EVP_CTRL_RAND_KEY 0x6
#define EVP_CTRL_PBE_PRF_NID 0x7
#define EVP_CTRL_COPY 0x8
+#define EVP_CTRL_GCM_SET_IVLEN 0x9
+#define EVP_CTRL_GCM_GET_TAG 0x10
+#define EVP_CTRL_GCM_SET_TAG 0x11
+#define EVP_CTRL_GCM_SET_IV_FIXED 0x12
+#define EVP_CTRL_GCM_IV_GEN 0x13
+#define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN
+#define EVP_CTRL_CCM_GET_TAG EVP_CTRL_GCM_GET_TAG
+#define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG
+#define EVP_CTRL_CCM_SET_L 0x14
+#define EVP_CTRL_CCM_SET_MSGLEN 0x15
+/* AEAD cipher deduces payload length and returns number of bytes
+ * required to store MAC and eventual padding. Subsequent call to
+ * EVP_Cipher even appends/verifies MAC.
+ */
+#define EVP_CTRL_AEAD_TLS1_AAD 0x16
+/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
+#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+/* Set the GCM invocation field, decrypt only */
+#define EVP_CTRL_GCM_SET_IV_INV 0x18
+
+/* GCM TLS constants */
+/* Length of fixed part of IV derived from PRF */
+#define EVP_GCM_TLS_FIXED_IV_LEN 4
+/* Length of explicit part of IV part of TLS records */
+#define EVP_GCM_TLS_EXPLICIT_IV_LEN 8
+/* Length of tag for TLS */
+#define EVP_GCM_TLS_TAG_LEN 16
typedef struct evp_cipher_info_st
{
@@ -375,7 +418,7 @@ struct evp_cipher_ctx_st
unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */
- int num; /* used by cfb/ofb mode */
+ int num; /* used by cfb/ofb/ctr mode */
void *app_data; /* application stuff */
int key_len; /* May change for variable length cipher */
@@ -695,6 +738,9 @@ const EVP_MD *EVP_dev_crypto_md5(void);
#ifndef OPENSSL_NO_RC4
const EVP_CIPHER *EVP_rc4(void);
const EVP_CIPHER *EVP_rc4_40(void);
+#ifndef OPENSSL_NO_MD5
+const EVP_CIPHER *EVP_rc4_hmac_md5(void);
+#endif
#endif
#ifndef OPENSSL_NO_IDEA
const EVP_CIPHER *EVP_idea_ecb(void);
@@ -741,9 +787,10 @@ const EVP_CIPHER *EVP_aes_128_cfb8(void);
const EVP_CIPHER *EVP_aes_128_cfb128(void);
# define EVP_aes_128_cfb EVP_aes_128_cfb128
const EVP_CIPHER *EVP_aes_128_ofb(void);
-#if 0
const EVP_CIPHER *EVP_aes_128_ctr(void);
-#endif
+const EVP_CIPHER *EVP_aes_128_ccm(void);
+const EVP_CIPHER *EVP_aes_128_gcm(void);
+const EVP_CIPHER *EVP_aes_128_xts(void);
const EVP_CIPHER *EVP_aes_192_ecb(void);
const EVP_CIPHER *EVP_aes_192_cbc(void);
const EVP_CIPHER *EVP_aes_192_cfb1(void);
@@ -751,9 +798,9 @@ const EVP_CIPHER *EVP_aes_192_cfb8(void);
const EVP_CIPHER *EVP_aes_192_cfb128(void);
# define EVP_aes_192_cfb EVP_aes_192_cfb128
const EVP_CIPHER *EVP_aes_192_ofb(void);
-#if 0
const EVP_CIPHER *EVP_aes_192_ctr(void);
-#endif
+const EVP_CIPHER *EVP_aes_192_ccm(void);
+const EVP_CIPHER *EVP_aes_192_gcm(void);
const EVP_CIPHER *EVP_aes_256_ecb(void);
const EVP_CIPHER *EVP_aes_256_cbc(void);
const EVP_CIPHER *EVP_aes_256_cfb1(void);
@@ -761,8 +808,13 @@ const EVP_CIPHER *EVP_aes_256_cfb8(void);
const EVP_CIPHER *EVP_aes_256_cfb128(void);
# define EVP_aes_256_cfb EVP_aes_256_cfb128
const EVP_CIPHER *EVP_aes_256_ofb(void);
-#if 0
const EVP_CIPHER *EVP_aes_256_ctr(void);
+const EVP_CIPHER *EVP_aes_256_ccm(void);
+const EVP_CIPHER *EVP_aes_256_gcm(void);
+const EVP_CIPHER *EVP_aes_256_xts(void);
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
#endif
#endif
#ifndef OPENSSL_NO_CAMELLIA
@@ -869,6 +921,7 @@ struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
#endif
EVP_PKEY * EVP_PKEY_new(void);
+EVP_PKEY * EVP_PKEY_dup(EVP_PKEY *pkey);
void EVP_PKEY_free(EVP_PKEY *pkey);
EVP_PKEY * d2i_PublicKey(int type,EVP_PKEY **a, const unsigned char **pp,
@@ -1047,13 +1100,22 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
#define EVP_PKEY_CTRL_CMS_DECRYPT 10
#define EVP_PKEY_CTRL_CMS_SIGN 11
+#define EVP_PKEY_CTRL_CIPHER 12
+
#define EVP_PKEY_ALG_CTRL 0x1000
#define EVP_PKEY_FLAG_AUTOARGLEN 2
+/* Method handles all operations: don't assume any digest related
+ * defaults.
+ */
+#define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4
const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags);
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+ const EVP_PKEY_METHOD *meth);
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src);
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
@@ -1071,7 +1133,7 @@ int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
- unsigned char *key, int keylen);
+ const unsigned char *key, int keylen);
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
@@ -1181,6 +1243,8 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
int (*ctrl_str)(EVP_PKEY_CTX *ctx,
const char *type, const char *value));
+void EVP_add_alg_module(void);
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -1190,8 +1254,14 @@ void ERR_load_EVP_strings(void);
/* Error codes for the EVP functions. */
/* Function codes. */
+#define EVP_F_AESNI_INIT_KEY 165
+#define EVP_F_AESNI_XTS_CIPHER 176
#define EVP_F_AES_INIT_KEY 133
+#define EVP_F_AES_XTS 172
+#define EVP_F_AES_XTS_CIPHER 175
+#define EVP_F_ALG_MODULE_INIT 177
#define EVP_F_CAMELLIA_INIT_KEY 159
+#define EVP_F_CMAC_INIT 173
#define EVP_F_D2I_PKEY 100
#define EVP_F_DO_SIGVER_INIT 161
#define EVP_F_DSAPKEY2PKCS8 134
@@ -1246,15 +1316,24 @@ void ERR_load_EVP_strings(void);
#define EVP_F_EVP_RIJNDAEL 126
#define EVP_F_EVP_SIGNFINAL 107
#define EVP_F_EVP_VERIFYFINAL 108
+#define EVP_F_FIPS_CIPHERINIT 166
+#define EVP_F_FIPS_CIPHER_CTX_COPY 170
+#define EVP_F_FIPS_CIPHER_CTX_CTRL 167
+#define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171
+#define EVP_F_FIPS_DIGESTINIT 168
+#define EVP_F_FIPS_MD_CTX_COPY 169
+#define EVP_F_HMAC_INIT_EX 174
#define EVP_F_INT_CTX_NEW 157
#define EVP_F_PKCS5_PBE_KEYIVGEN 117
#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118
+#define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164
#define EVP_F_PKCS8_SET_BROKEN 112
#define EVP_F_PKEY_SET_TYPE 158
#define EVP_F_RC2_MAGIC_TO_METH 109
#define EVP_F_RC5_CTRL 125
/* Reason codes. */
+#define EVP_R_AES_IV_SETUP_FAILED 162
#define EVP_R_AES_KEY_SETUP_FAILED 143
#define EVP_R_ASN1_LIB 140
#define EVP_R_BAD_BLOCK_LENGTH 136
@@ -1272,16 +1351,21 @@ void ERR_load_EVP_strings(void);
#define EVP_R_DECODE_ERROR 114
#define EVP_R_DIFFERENT_KEY_TYPES 101
#define EVP_R_DIFFERENT_PARAMETERS 153
+#define EVP_R_DISABLED_FOR_FIPS 163
#define EVP_R_ENCODE_ERROR 115
+#define EVP_R_ERROR_LOADING_SECTION 165
+#define EVP_R_ERROR_SETTING_FIPS_MODE 166
#define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119
#define EVP_R_EXPECTING_AN_RSA_KEY 127
#define EVP_R_EXPECTING_A_DH_KEY 128
#define EVP_R_EXPECTING_A_DSA_KEY 129
#define EVP_R_EXPECTING_A_ECDSA_KEY 141
#define EVP_R_EXPECTING_A_EC_KEY 142
+#define EVP_R_FIPS_MODE_NOT_SUPPORTED 167
#define EVP_R_INITIALIZATION_ERROR 134
#define EVP_R_INPUT_NOT_INITIALIZED 111
#define EVP_R_INVALID_DIGEST 152
+#define EVP_R_INVALID_FIPS_MODE 168
#define EVP_R_INVALID_KEY_LENGTH 130
#define EVP_R_INVALID_OPERATION 148
#define EVP_R_IV_TOO_LARGE 102
@@ -1303,8 +1387,10 @@ void ERR_load_EVP_strings(void);
#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
#define EVP_R_PUBLIC_KEY_NOT_RSA 106
+#define EVP_R_TOO_LARGE 164
#define EVP_R_UNKNOWN_CIPHER 160
#define EVP_R_UNKNOWN_DIGEST 161
+#define EVP_R_UNKNOWN_OPTION 169
#define EVP_R_UNKNOWN_PBE_ALGORITHM 121
#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135
#define EVP_R_UNSUPPORTED_ALGORITHM 156
diff --git a/app/openssl/crypto/evp/evp_cnf.c b/app/openssl/crypto/evp/evp_cnf.c
new file mode 100644
index 00000000..2e4db302
--- /dev/null
+++ b/app/openssl/crypto/evp/evp_cnf.c
@@ -0,0 +1,125 @@
+/* evp_cnf.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
+ {
+ int i;
+ const char *oid_section;
+ STACK_OF(CONF_VALUE) *sktmp;
+ CONF_VALUE *oval;
+ oid_section = CONF_imodule_get_value(md);
+ if(!(sktmp = NCONF_get_section(cnf, oid_section)))
+ {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+ return 0;
+ }
+ for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
+ {
+ oval = sk_CONF_VALUE_value(sktmp, i);
+ if (!strcmp(oval->name, "fips_mode"))
+ {
+ int m;
+ if (!X509V3_get_value_bool(oval, &m))
+ {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
+ return 0;
+ }
+ if (m > 0)
+ {
+#ifdef OPENSSL_FIPS
+ if (!FIPS_mode() && !FIPS_mode_set(1))
+ {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE);
+ return 0;
+ }
+#else
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
+ return 0;
+#endif
+ }
+ }
+ else
+ {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+ ERR_add_error_data(4, "name=", oval->name,
+ ", value=", oval->value);
+ }
+
+ }
+ return 1;
+ }
+
+void EVP_add_alg_module(void)
+ {
+ CONF_module_add("alg_section", alg_module_init, 0);
+ }
diff --git a/app/openssl/crypto/evp/evp_enc.c b/app/openssl/crypto/evp/evp_enc.c
index c268d25c..0c54f05e 100644
--- a/app/openssl/crypto/evp/evp_enc.c
+++ b/app/openssl/crypto/evp/evp_enc.c
@@ -64,8 +64,18 @@
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
#include "evp_locl.h"
+#ifdef OPENSSL_FIPS
+#define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl)
+#else
+#define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
+#endif
+
+
const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
@@ -115,10 +125,14 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
/* Ensure a context left lying around from last time is cleared
* (the previous check attempted to avoid this if the same
* ENGINE and EVP_CIPHER could be used). */
- EVP_CIPHER_CTX_cleanup(ctx);
-
- /* Restore encrypt field: it is zeroed by cleanup */
- ctx->encrypt = enc;
+ if (ctx->cipher)
+ {
+ unsigned long flags = ctx->flags;
+ EVP_CIPHER_CTX_cleanup(ctx);
+ /* Restore encrypt and flags */
+ ctx->encrypt = enc;
+ ctx->flags = flags;
+ }
#ifndef OPENSSL_NO_ENGINE
if(impl)
{
@@ -155,6 +169,10 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
ctx->engine = NULL;
#endif
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+#endif
ctx->cipher=cipher;
if (ctx->cipher->ctx_size)
{
@@ -188,6 +206,10 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp
#ifndef OPENSSL_NO_ENGINE
skip_to_init:
#endif
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+#endif
/* we assume block size is a power of 2 in *cryptUpdate */
OPENSSL_assert(ctx->cipher->block_size == 1
|| ctx->cipher->block_size == 8
@@ -214,6 +236,13 @@ skip_to_init:
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
break;
+ case EVP_CIPH_CTR_MODE:
+ ctx->num = 0;
+ /* Don't reuse IV for CTR mode */
+ if(iv)
+ memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ break;
+
default:
return 0;
break;
@@ -280,6 +309,16 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
{
int i,j,bl;
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ {
+ i = M_do_cipher(ctx, out, in, inl);
+ if (i < 0)
+ return 0;
+ else
+ *outl = i;
+ return 1;
+ }
+
if (inl <= 0)
{
*outl = 0;
@@ -288,7 +327,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
{
- if(ctx->cipher->do_cipher(ctx,out,in,inl))
+ if(M_do_cipher(ctx,out,in,inl))
{
*outl=inl;
return 1;
@@ -315,7 +354,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
{
j=bl-i;
memcpy(&(ctx->buf[i]),in,j);
- if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
+ if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
inl-=j;
in+=j;
out+=bl;
@@ -328,7 +367,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
inl-=i;
if (inl > 0)
{
- if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
+ if(!M_do_cipher(ctx,out,in,inl)) return 0;
*outl+=inl;
}
@@ -350,6 +389,16 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int n,ret;
unsigned int i, b, bl;
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ {
+ ret = M_do_cipher(ctx, out, NULL, 0);
+ if (ret < 0)
+ return 0;
+ else
+ *outl = ret;
+ return 1;
+ }
+
b=ctx->cipher->block_size;
OPENSSL_assert(b <= sizeof ctx->buf);
if (b == 1)
@@ -372,7 +421,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
n=b-bl;
for (i=bl; i<b; i++)
ctx->buf[i]=n;
- ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
+ ret=M_do_cipher(ctx,out,ctx->buf,b);
if(ret)
@@ -387,6 +436,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
int fix_len;
unsigned int b;
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ {
+ fix_len = M_do_cipher(ctx, out, in, inl);
+ if (fix_len < 0)
+ {
+ *outl = 0;
+ return 0;
+ }
+ else
+ *outl = fix_len;
+ return 1;
+ }
+
if (inl <= 0)
{
*outl = 0;
@@ -440,8 +502,18 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i,n;
unsigned int b;
-
*outl=0;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ {
+ i = M_do_cipher(ctx, out, NULL, 0);
+ if (i < 0)
+ return 0;
+ else
+ *outl = i;
+ return 1;
+ }
+
b=ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING)
{
@@ -496,6 +568,7 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
{
+#ifndef OPENSSL_FIPS
if (c->cipher != NULL)
{
if(c->cipher->cleanup && !c->cipher->cleanup(c))
@@ -506,12 +579,16 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
}
if (c->cipher_data)
OPENSSL_free(c->cipher_data);
+#endif
#ifndef OPENSSL_NO_ENGINE
if (c->engine)
/* The EVP_CIPHER we used belongs to an ENGINE, release the
* functional reference we held for this reason. */
ENGINE_finish(c->engine);
#endif
+#ifdef OPENSSL_FIPS
+ FIPS_cipher_ctx_cleanup(c);
+#endif
memset(c,0,sizeof(EVP_CIPHER_CTX));
return 1;
}
diff --git a/app/openssl/crypto/evp/evp_err.c b/app/openssl/crypto/evp/evp_err.c
index d8bfec09..08eab988 100644
--- a/app/openssl/crypto/evp/evp_err.c
+++ b/app/openssl/crypto/evp/evp_err.c
@@ -1,6 +1,6 @@
/* crypto/evp/evp_err.c */
/* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -70,8 +70,14 @@
static ERR_STRING_DATA EVP_str_functs[]=
{
+{ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"},
+{ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"},
{ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
+{ERR_FUNC(EVP_F_AES_XTS), "AES_XTS"},
+{ERR_FUNC(EVP_F_AES_XTS_CIPHER), "AES_XTS_CIPHER"},
+{ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"},
{ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"},
+{ERR_FUNC(EVP_F_CMAC_INIT), "CMAC_INIT"},
{ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"},
{ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"},
{ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"},
@@ -86,7 +92,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
-{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_SIZE"},
+{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"},
{ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"},
{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"},
{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"},
@@ -126,9 +132,17 @@ static ERR_STRING_DATA EVP_str_functs[]=
{ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"},
{ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"},
{ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"},
+{ERR_FUNC(EVP_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"},
+{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY), "FIPS_CIPHER_CTX_COPY"},
+{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"},
+{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH), "FIPS_CIPHER_CTX_SET_KEY_LENGTH"},
+{ERR_FUNC(EVP_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"},
+{ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY), "FIPS_MD_CTX_COPY"},
+{ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"},
{ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"},
{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
+{ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_KEYIVGEN"},
{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"},
{ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"},
{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"},
@@ -138,6 +152,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
static ERR_STRING_DATA EVP_str_reasons[]=
{
+{ERR_REASON(EVP_R_AES_IV_SETUP_FAILED) ,"aes iv setup failed"},
{ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED) ,"aes key setup failed"},
{ERR_REASON(EVP_R_ASN1_LIB) ,"asn1 lib"},
{ERR_REASON(EVP_R_BAD_BLOCK_LENGTH) ,"bad block length"},
@@ -155,16 +170,21 @@ static ERR_STRING_DATA EVP_str_reasons[]=
{ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"},
{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) ,"different parameters"},
+{ERR_REASON(EVP_R_DISABLED_FOR_FIPS) ,"disabled for fips"},
{ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"},
+{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
+{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_DH_KEY) ,"expecting a dh key"},
{ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY) ,"expecting a dsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) ,"expecting a ec key"},
+{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
{ERR_REASON(EVP_R_INITIALIZATION_ERROR) ,"initialization error"},
{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
{ERR_REASON(EVP_R_INVALID_DIGEST) ,"invalid digest"},
+{ERR_REASON(EVP_R_INVALID_FIPS_MODE) ,"invalid fips mode"},
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"},
{ERR_REASON(EVP_R_INVALID_OPERATION) ,"invalid operation"},
{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"},
@@ -186,8 +206,10 @@ static ERR_STRING_DATA EVP_str_reasons[]=
{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"},
{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"},
{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"},
+{ERR_REASON(EVP_R_TOO_LARGE) ,"too large"},
{ERR_REASON(EVP_R_UNKNOWN_CIPHER) ,"unknown cipher"},
{ERR_REASON(EVP_R_UNKNOWN_DIGEST) ,"unknown digest"},
+{ERR_REASON(EVP_R_UNKNOWN_OPTION) ,"unknown option"},
{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
diff --git a/app/openssl/crypto/evp/evp_key.c b/app/openssl/crypto/evp/evp_key.c
index 839d6a3a..7961fbeb 100644
--- a/app/openssl/crypto/evp/evp_key.c
+++ b/app/openssl/crypto/evp/evp_key.c
@@ -120,7 +120,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
unsigned char md_buf[EVP_MAX_MD_SIZE];
int niv,nkey,addmd=0;
unsigned int mds=0,i;
-
+ int rv = 0;
nkey=type->key_len;
niv=type->iv_len;
OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
@@ -134,17 +134,24 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
if (!EVP_DigestInit_ex(&c,md, NULL))
return 0;
if (addmd++)
- EVP_DigestUpdate(&c,&(md_buf[0]),mds);
- EVP_DigestUpdate(&c,data,datal);
+ if (!EVP_DigestUpdate(&c,&(md_buf[0]),mds))
+ goto err;
+ if (!EVP_DigestUpdate(&c,data,datal))
+ goto err;
if (salt != NULL)
- EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN);
- EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds);
+ if (!EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN))
+ goto err;
+ if (!EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds))
+ goto err;
for (i=1; i<(unsigned int)count; i++)
{
- EVP_DigestInit_ex(&c,md, NULL);
- EVP_DigestUpdate(&c,&(md_buf[0]),mds);
- EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds);
+ if (!EVP_DigestInit_ex(&c,md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&c,&(md_buf[0]),mds))
+ goto err;
+ if (!EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds))
+ goto err;
}
i=0;
if (nkey)
@@ -173,8 +180,10 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
}
if ((nkey == 0) && (niv == 0)) break;
}
+ rv = type->key_len;
+ err:
EVP_MD_CTX_cleanup(&c);
OPENSSL_cleanse(&(md_buf[0]),EVP_MAX_MD_SIZE);
- return(type->key_len);
+ return rv;
}
diff --git a/app/openssl/crypto/evp/evp_lib.c b/app/openssl/crypto/evp/evp_lib.c
index 40951a04..b180e482 100644
--- a/app/openssl/crypto/evp/evp_lib.c
+++ b/app/openssl/crypto/evp/evp_lib.c
@@ -67,6 +67,8 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
if (c->cipher->set_asn1_parameters != NULL)
ret=c->cipher->set_asn1_parameters(c,type);
+ else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
+ ret=EVP_CIPHER_set_asn1_iv(c, type);
else
ret=-1;
return(ret);
@@ -78,6 +80,8 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
if (c->cipher->get_asn1_parameters != NULL)
ret=c->cipher->get_asn1_parameters(c,type);
+ else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
+ ret=EVP_CIPHER_get_asn1_iv(c, type);
else
ret=-1;
return(ret);
diff --git a/app/openssl/crypto/evp/evp_locl.h b/app/openssl/crypto/evp/evp_locl.h
index 292d74c1..08c0a66d 100644
--- a/app/openssl/crypto/evp/evp_locl.h
+++ b/app/openssl/crypto/evp/evp_locl.h
@@ -343,3 +343,43 @@ struct evp_pkey_method_st
} /* EVP_PKEY_METHOD */;
void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+ ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md, int en_de);
+
+#ifdef OPENSSL_FIPS
+
+#ifdef OPENSSL_DOING_MAKEDEPEND
+#undef SHA1_Init
+#undef SHA1_Update
+#undef SHA224_Init
+#undef SHA256_Init
+#undef SHA384_Init
+#undef SHA512_Init
+#undef DES_set_key_unchecked
+#endif
+
+#define RIPEMD160_Init private_RIPEMD160_Init
+#define WHIRLPOOL_Init private_WHIRLPOOL_Init
+#define MD5_Init private_MD5_Init
+#define MD4_Init private_MD4_Init
+#define MD2_Init private_MD2_Init
+#define MDC2_Init private_MDC2_Init
+#define SHA_Init private_SHA_Init
+#define SHA1_Init private_SHA1_Init
+#define SHA224_Init private_SHA224_Init
+#define SHA256_Init private_SHA256_Init
+#define SHA384_Init private_SHA384_Init
+#define SHA512_Init private_SHA512_Init
+
+#define BF_set_key private_BF_set_key
+#define CAST_set_key private_CAST_set_key
+#define idea_set_encrypt_key private_idea_set_encrypt_key
+#define SEED_set_key private_SEED_set_key
+#define RC2_set_key private_RC2_set_key
+#define RC4_set_key private_RC4_set_key
+#define DES_set_key_unchecked private_DES_set_key_unchecked
+#define Camellia_set_key private_Camellia_set_key
+
+#endif
diff --git a/app/openssl/crypto/evp/evp_pbe.c b/app/openssl/crypto/evp/evp_pbe.c
index c9d932d2..f8c32d82 100644
--- a/app/openssl/crypto/evp/evp_pbe.c
+++ b/app/openssl/crypto/evp/evp_pbe.c
@@ -61,6 +61,7 @@
#include <openssl/evp.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
+#include "evp_locl.h"
/* Password based encryption (PBE) functions */
@@ -87,6 +88,10 @@ static const EVP_PBE_CTL builtin_pbe[] =
{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+#ifndef OPENSSL_NO_HMAC
+ {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
+#endif
+
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
diff --git a/app/openssl/crypto/evp/evptests.txt b/app/openssl/crypto/evp/evptests.txt
index beb12144..c273707c 100644
--- a/app/openssl/crypto/evp/evptests.txt
+++ b/app/openssl/crypto/evp/evptests.txt
@@ -158,6 +158,19 @@ AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7B
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
+# AES Counter test vectors from RFC3686
+aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1
+aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1
+aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1
+
+aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1
+aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1
+aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1
+
+aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1
+aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1
+aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1
+
# DES ECB tests (from destest)
DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7
diff --git a/app/openssl/crypto/evp/m_dss.c b/app/openssl/crypto/evp/m_dss.c
index 48c26895..6fb7e9a8 100644
--- a/app/openssl/crypto/evp/m_dss.c
+++ b/app/openssl/crypto/evp/m_dss.c
@@ -60,12 +60,13 @@
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_SHA
+#ifndef OPENSSL_FIPS
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
@@ -97,3 +98,4 @@ const EVP_MD *EVP_dss(void)
return(&dsa_md);
}
#endif
+#endif
diff --git a/app/openssl/crypto/evp/m_dss1.c b/app/openssl/crypto/evp/m_dss1.c
index 4f03fb70..2df362a6 100644
--- a/app/openssl/crypto/evp/m_dss1.c
+++ b/app/openssl/crypto/evp/m_dss1.c
@@ -63,11 +63,13 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
+#ifndef OPENSSL_FIPS
+
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
@@ -98,3 +100,4 @@ const EVP_MD *EVP_dss1(void)
return(&dss1_md);
}
#endif
+#endif
diff --git a/app/openssl/crypto/evp/m_ecdsa.c b/app/openssl/crypto/evp/m_ecdsa.c
index 8d87a49e..4b15fb0f 100644
--- a/app/openssl/crypto/evp/m_ecdsa.c
+++ b/app/openssl/crypto/evp/m_ecdsa.c
@@ -116,6 +116,8 @@
#include <openssl/x509.h>
#ifndef OPENSSL_NO_SHA
+#ifndef OPENSSL_FIPS
+
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
@@ -146,3 +148,4 @@ const EVP_MD *EVP_ecdsa(void)
return(&ecdsa_md);
}
#endif
+#endif
diff --git a/app/openssl/crypto/evp/m_md4.c b/app/openssl/crypto/evp/m_md4.c
index 1e0b7c5b..6d47f61b 100644
--- a/app/openssl/crypto/evp/m_md4.c
+++ b/app/openssl/crypto/evp/m_md4.c
@@ -69,6 +69,8 @@
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
+
static int init(EVP_MD_CTX *ctx)
{ return MD4_Init(ctx->md_data); }
diff --git a/app/openssl/crypto/evp/m_md5.c b/app/openssl/crypto/evp/m_md5.c
index 63c14211..9a8bae02 100644
--- a/app/openssl/crypto/evp/m_md5.c
+++ b/app/openssl/crypto/evp/m_md5.c
@@ -68,6 +68,7 @@
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
static int init(EVP_MD_CTX *ctx)
{ return MD5_Init(ctx->md_data); }
diff --git a/app/openssl/crypto/evp/m_mdc2.c b/app/openssl/crypto/evp/m_mdc2.c
index b08d5598..3602bed3 100644
--- a/app/openssl/crypto/evp/m_mdc2.c
+++ b/app/openssl/crypto/evp/m_mdc2.c
@@ -69,6 +69,8 @@
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
+
static int init(EVP_MD_CTX *ctx)
{ return MDC2_Init(ctx->md_data); }
diff --git a/app/openssl/crypto/evp/m_ripemd.c b/app/openssl/crypto/evp/m_ripemd.c
index a1d60ee7..7bf4804c 100644
--- a/app/openssl/crypto/evp/m_ripemd.c
+++ b/app/openssl/crypto/evp/m_ripemd.c
@@ -68,6 +68,7 @@
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
+#include "evp_locl.h"
static int init(EVP_MD_CTX *ctx)
{ return RIPEMD160_Init(ctx->md_data); }
diff --git a/app/openssl/crypto/evp/m_sha1.c b/app/openssl/crypto/evp/m_sha1.c
index 9a2790fd..bd0c01ad 100644
--- a/app/openssl/crypto/evp/m_sha1.c
+++ b/app/openssl/crypto/evp/m_sha1.c
@@ -59,15 +59,18 @@
#include <stdio.h>
#include "cryptlib.h"
+#ifndef OPENSSL_FIPS
+
#ifndef OPENSSL_NO_SHA
#include <openssl/evp.h>
#include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
+
static int init(EVP_MD_CTX *ctx)
{ return SHA1_Init(ctx->md_data); }
@@ -202,3 +205,5 @@ static const EVP_MD sha512_md=
const EVP_MD *EVP_sha512(void)
{ return(&sha512_md); }
#endif /* ifndef OPENSSL_NO_SHA512 */
+
+#endif
diff --git a/app/openssl/crypto/evp/m_wp.c b/app/openssl/crypto/evp/m_wp.c
index 1ce47c04..c51bc2d5 100644
--- a/app/openssl/crypto/evp/m_wp.c
+++ b/app/openssl/crypto/evp/m_wp.c
@@ -9,6 +9,7 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/whrlpool.h>
+#include "evp_locl.h"
static int init(EVP_MD_CTX *ctx)
{ return WHIRLPOOL_Init(ctx->md_data); }
diff --git a/app/openssl/crypto/evp/names.c b/app/openssl/crypto/evp/names.c
index f2869f5c..6311ad7c 100644
--- a/app/openssl/crypto/evp/names.c
+++ b/app/openssl/crypto/evp/names.c
@@ -66,6 +66,10 @@ int EVP_add_cipher(const EVP_CIPHER *c)
{
int r;
+ if (c == NULL) return 0;
+
+ OPENSSL_init();
+
r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
if (r == 0) return(0);
check_defer(c->nid);
@@ -78,6 +82,7 @@ int EVP_add_digest(const EVP_MD *md)
{
int r;
const char *name;
+ OPENSSL_init();
name=OBJ_nid2sn(md->type);
r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md);
diff --git a/app/openssl/crypto/evp/p5_crpt.c b/app/openssl/crypto/evp/p5_crpt.c
index 7ecfa8da..294cc90d 100644
--- a/app/openssl/crypto/evp/p5_crpt.c
+++ b/app/openssl/crypto/evp/p5_crpt.c
@@ -82,6 +82,8 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
unsigned char *salt;
const unsigned char *pbuf;
int mdsize;
+ int rv = 0;
+ EVP_MD_CTX_init(&ctx);
/* Extract useful info from parameter */
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
@@ -104,29 +106,38 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
if(!pass) passlen = 0;
else if(passlen == -1) passlen = strlen(pass);
- EVP_MD_CTX_init(&ctx);
- EVP_DigestInit_ex(&ctx, md, NULL);
- EVP_DigestUpdate(&ctx, pass, passlen);
- EVP_DigestUpdate(&ctx, salt, saltlen);
+ if (!EVP_DigestInit_ex(&ctx, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, pass, passlen))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, salt, saltlen))
+ goto err;
PBEPARAM_free(pbe);
- EVP_DigestFinal_ex(&ctx, md_tmp, NULL);
+ if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+ goto err;
mdsize = EVP_MD_size(md);
if (mdsize < 0)
return 0;
for (i = 1; i < iter; i++) {
- EVP_DigestInit_ex(&ctx, md, NULL);
- EVP_DigestUpdate(&ctx, md_tmp, mdsize);
- EVP_DigestFinal_ex (&ctx, md_tmp, NULL);
+ if (!EVP_DigestInit_ex(&ctx, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize))
+ goto err;
+ if (!EVP_DigestFinal_ex (&ctx, md_tmp, NULL))
+ goto err;
}
- EVP_MD_CTX_cleanup(&ctx);
OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
EVP_CIPHER_iv_length(cipher));
- EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de);
+ if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
+ goto err;
OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
- return 1;
+ rv = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return rv;
}
diff --git a/app/openssl/crypto/evp/p5_crpt2.c b/app/openssl/crypto/evp/p5_crpt2.c
index 334379f3..fe3c6c88 100644
--- a/app/openssl/crypto/evp/p5_crpt2.c
+++ b/app/openssl/crypto/evp/p5_crpt2.c
@@ -62,6 +62,7 @@
#include <openssl/x509.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#include "evp_locl.h"
/* set this to print out info about the keygen algorithm */
/* #define DEBUG_PKCS5V2 */
@@ -84,19 +85,24 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
int cplen, j, k, tkeylen, mdlen;
unsigned long i = 1;
- HMAC_CTX hctx;
+ HMAC_CTX hctx_tpl, hctx;
mdlen = EVP_MD_size(digest);
if (mdlen < 0)
return 0;
- HMAC_CTX_init(&hctx);
+ HMAC_CTX_init(&hctx_tpl);
p = out;
tkeylen = keylen;
if(!pass)
passlen = 0;
else if(passlen == -1)
passlen = strlen(pass);
+ if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL))
+ {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
while(tkeylen)
{
if(tkeylen > mdlen)
@@ -110,15 +116,36 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
itmp[1] = (unsigned char)((i >> 16) & 0xff);
itmp[2] = (unsigned char)((i >> 8) & 0xff);
itmp[3] = (unsigned char)(i & 0xff);
- HMAC_Init_ex(&hctx, pass, passlen, digest, NULL);
- HMAC_Update(&hctx, salt, saltlen);
- HMAC_Update(&hctx, itmp, 4);
- HMAC_Final(&hctx, digtmp, NULL);
+ if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
+ {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
+ if (!HMAC_Update(&hctx, salt, saltlen)
+ || !HMAC_Update(&hctx, itmp, 4)
+ || !HMAC_Final(&hctx, digtmp, NULL))
+ {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ HMAC_CTX_cleanup(&hctx);
+ return 0;
+ }
+ HMAC_CTX_cleanup(&hctx);
memcpy(p, digtmp, cplen);
for(j = 1; j < iter; j++)
{
- HMAC(digest, pass, passlen,
- digtmp, mdlen, digtmp, NULL);
+ if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
+ {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
+ if (!HMAC_Update(&hctx, digtmp, mdlen)
+ || !HMAC_Final(&hctx, digtmp, NULL))
+ {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ HMAC_CTX_cleanup(&hctx);
+ return 0;
+ }
+ HMAC_CTX_cleanup(&hctx);
for(k = 0; k < cplen; k++)
p[k] ^= digtmp[k];
}
@@ -126,7 +153,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
i++;
p+= cplen;
}
- HMAC_CTX_cleanup(&hctx);
+ HMAC_CTX_cleanup(&hctx_tpl);
#ifdef DEBUG_PKCS5V2
fprintf(stderr, "Password:\n");
h__dump (pass, passlen);
@@ -168,27 +195,24 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md,
int en_de)
{
- unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
const unsigned char *pbuf;
- int saltlen, iter, plen;
- unsigned int keylen;
+ int plen;
PBE2PARAM *pbe2 = NULL;
const EVP_CIPHER *cipher;
- PBKDF2PARAM *kdf = NULL;
- const EVP_MD *prfmd;
- int prf_nid, hmac_md_nid;
+
+ int rv = 0;
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
param->value.sequence == NULL) {
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
- return 0;
+ goto err;
}
pbuf = param->value.sequence->data;
plen = param->value.sequence->length;
if(!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
- return 0;
+ goto err;
}
/* See if we recognise the key derivation function */
@@ -211,38 +235,63 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
}
/* Fixup cipher based on AlgorithmIdentifier */
- EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de);
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
+ goto err;
if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
EVP_R_CIPHER_PARAMETER_ERROR);
goto err;
}
+ rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
+ pbe2->keyfunc->parameter, c, md, en_de);
+ err:
+ PBE2PARAM_free(pbe2);
+ return rv;
+}
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+ ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+ unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+ const unsigned char *pbuf;
+ int saltlen, iter, plen;
+ int rv = 0;
+ unsigned int keylen = 0;
+ int prf_nid, hmac_md_nid;
+ PBKDF2PARAM *kdf = NULL;
+ const EVP_MD *prfmd;
+
+ if (EVP_CIPHER_CTX_cipher(ctx) == NULL)
+ {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_NO_CIPHER_SET);
+ goto err;
+ }
keylen = EVP_CIPHER_CTX_key_length(ctx);
OPENSSL_assert(keylen <= sizeof key);
- /* Now decode key derivation function */
+ /* Decode parameter */
- if(!pbe2->keyfunc->parameter ||
- (pbe2->keyfunc->parameter->type != V_ASN1_SEQUENCE))
+ if(!param || (param->type != V_ASN1_SEQUENCE))
{
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_DECODE_ERROR);
goto err;
}
- pbuf = pbe2->keyfunc->parameter->value.sequence->data;
- plen = pbe2->keyfunc->parameter->value.sequence->length;
+ pbuf = param->value.sequence->data;
+ plen = param->value.sequence->length;
+
if(!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_DECODE_ERROR);
goto err;
}
- PBE2PARAM_free(pbe2);
- pbe2 = NULL;
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
/* Now check the parameters of the kdf */
if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
EVP_R_UNSUPPORTED_KEYLENGTH);
goto err;
}
@@ -254,19 +303,19 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0))
{
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
goto err;
}
prfmd = EVP_get_digestbynid(hmac_md_nid);
if (prfmd == NULL)
{
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
goto err;
}
if(kdf->salt->type != V_ASN1_OCTET_STRING) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
EVP_R_UNSUPPORTED_SALT_TYPE);
goto err;
}
@@ -278,15 +327,11 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
keylen, key))
goto err;
- EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
- OPENSSL_cleanse(key, keylen);
- PBKDF2PARAM_free(kdf);
- return 1;
-
+ rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
err:
- PBE2PARAM_free(pbe2);
+ OPENSSL_cleanse(key, keylen);
PBKDF2PARAM_free(kdf);
- return 0;
+ return rv;
}
#ifdef DEBUG_PKCS5V2
diff --git a/app/openssl/crypto/evp/p_lib.c b/app/openssl/crypto/evp/p_lib.c
index e26ccd0d..bd1977d7 100644
--- a/app/openssl/crypto/evp/p_lib.c
+++ b/app/openssl/crypto/evp/p_lib.c
@@ -200,6 +200,12 @@ EVP_PKEY *EVP_PKEY_new(void)
return(ret);
}
+EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
+ {
+ CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ return pkey;
+ }
+
/* Setup a public key ASN1 method and ENGINE from a NID or a string.
* If pkey is NULL just return 1 or 0 if the algorithm exists.
*/
diff --git a/app/openssl/crypto/evp/p_open.c b/app/openssl/crypto/evp/p_open.c
index 53a59a29..c748fbea 100644
--- a/app/openssl/crypto/evp/p_open.c
+++ b/app/openssl/crypto/evp/p_open.c
@@ -115,7 +115,8 @@ int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int i;
i=EVP_DecryptFinal_ex(ctx,out,outl);
- EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL);
+ if (i)
+ i = EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL);
return(i);
}
#else /* !OPENSSL_NO_RSA */
diff --git a/app/openssl/crypto/evp/p_seal.c b/app/openssl/crypto/evp/p_seal.c
index d8324526..e5919b0f 100644
--- a/app/openssl/crypto/evp/p_seal.c
+++ b/app/openssl/crypto/evp/p_seal.c
@@ -110,6 +110,7 @@ int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i;
i = EVP_EncryptFinal_ex(ctx,out,outl);
- EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL);
+ if (i)
+ i = EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL);
return i;
}
diff --git a/app/openssl/crypto/evp/p_sign.c b/app/openssl/crypto/evp/p_sign.c
index bb893f5b..8afb6643 100644
--- a/app/openssl/crypto/evp/p_sign.c
+++ b/app/openssl/crypto/evp/p_sign.c
@@ -80,18 +80,20 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
{
unsigned char m[EVP_MAX_MD_SIZE];
unsigned int m_len;
- int i,ok=0,v;
+ int i = 0,ok = 0,v;
EVP_MD_CTX tmp_ctx;
+ EVP_PKEY_CTX *pkctx = NULL;
*siglen=0;
EVP_MD_CTX_init(&tmp_ctx);
- EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
- EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+ goto err;
+ if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
+ goto err;
EVP_MD_CTX_cleanup(&tmp_ctx);
if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
{
- EVP_PKEY_CTX *pkctx = NULL;
size_t sltmp = (size_t)EVP_PKEY_size(pkey);
i = 0;
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
diff --git a/app/openssl/crypto/evp/p_verify.c b/app/openssl/crypto/evp/p_verify.c
index 41d4b671..c66d63cc 100644
--- a/app/openssl/crypto/evp/p_verify.c
+++ b/app/openssl/crypto/evp/p_verify.c
@@ -67,17 +67,19 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
{
unsigned char m[EVP_MAX_MD_SIZE];
unsigned int m_len;
- int i,ok=0,v;
+ int i = 0,ok = 0,v;
EVP_MD_CTX tmp_ctx;
+ EVP_PKEY_CTX *pkctx = NULL;
EVP_MD_CTX_init(&tmp_ctx);
- EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
- EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+ goto err;
+ if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
+ goto err;
EVP_MD_CTX_cleanup(&tmp_ctx);
if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
{
- EVP_PKEY_CTX *pkctx = NULL;
i = -1;
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!pkctx)
diff --git a/app/openssl/crypto/evp/pmeth_gn.c b/app/openssl/crypto/evp/pmeth_gn.c
index 5d74161a..4651c813 100644
--- a/app/openssl/crypto/evp/pmeth_gn.c
+++ b/app/openssl/crypto/evp/pmeth_gn.c
@@ -199,7 +199,7 @@ int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
}
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
- unsigned char *key, int keylen)
+ const unsigned char *key, int keylen)
{
EVP_PKEY_CTX *mac_ctx = NULL;
EVP_PKEY *mac_key = NULL;
@@ -209,7 +209,8 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
goto merr;
if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
- EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0)
+ EVP_PKEY_CTRL_SET_MAC_KEY,
+ keylen, (void *)key) <= 0)
goto merr;
if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
goto merr;
diff --git a/app/openssl/crypto/evp/pmeth_lib.c b/app/openssl/crypto/evp/pmeth_lib.c
index 5481d4b8..acfa7b6f 100644
--- a/app/openssl/crypto/evp/pmeth_lib.c
+++ b/app/openssl/crypto/evp/pmeth_lib.c
@@ -73,7 +73,7 @@ DECLARE_STACK_OF(EVP_PKEY_METHOD)
STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
-extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
static const EVP_PKEY_METHOD *standard_methods[] =
{
@@ -90,6 +90,7 @@ static const EVP_PKEY_METHOD *standard_methods[] =
&ec_pkey_meth,
#endif
&hmac_pkey_meth,
+ &cmac_pkey_meth
};
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
@@ -203,6 +204,8 @@ EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
if (!pmeth)
return NULL;
+ memset(pmeth, 0, sizeof(EVP_PKEY_METHOD));
+
pmeth->pkey_id = id;
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
@@ -235,6 +238,56 @@ EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
return pmeth;
}
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+ const EVP_PKEY_METHOD *meth)
+ {
+ if (ppkey_id)
+ *ppkey_id = meth->pkey_id;
+ if (pflags)
+ *pflags = meth->flags;
+ }
+
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
+ {
+
+ dst->init = src->init;
+ dst->copy = src->copy;
+ dst->cleanup = src->cleanup;
+
+ dst->paramgen_init = src->paramgen_init;
+ dst->paramgen = src->paramgen;
+
+ dst->keygen_init = src->keygen_init;
+ dst->keygen = src->keygen;
+
+ dst->sign_init = src->sign_init;
+ dst->sign = src->sign;
+
+ dst->verify_init = src->verify_init;
+ dst->verify = src->verify;
+
+ dst->verify_recover_init = src->verify_recover_init;
+ dst->verify_recover = src->verify_recover;
+
+ dst->signctx_init = src->signctx_init;
+ dst->signctx = src->signctx;
+
+ dst->verifyctx_init = src->verifyctx_init;
+ dst->verifyctx = src->verifyctx;
+
+ dst->encrypt_init = src->encrypt_init;
+ dst->encrypt = src->encrypt;
+
+ dst->decrypt_init = src->decrypt_init;
+ dst->decrypt = src->decrypt;
+
+ dst->derive_init = src->derive_init;
+ dst->derive = src->derive;
+
+ dst->ctrl = src->ctrl;
+ dst->ctrl_str = src->ctrl_str;
+ }
+
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
{
if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))