提交 e6b336ef 编写于 作者: M Matt Caswell

Add EVP support for OCB mode

Reviewed-by: NTim Hudson <tjh@openssl.org>
上级 c857a80c
......@@ -172,6 +172,7 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_128_ofb());
EVP_add_cipher(EVP_aes_128_ctr());
EVP_add_cipher(EVP_aes_128_gcm());
EVP_add_cipher(EVP_aes_128_ocb());
EVP_add_cipher(EVP_aes_128_xts());
EVP_add_cipher(EVP_aes_128_ccm());
EVP_add_cipher(EVP_aes_128_wrap());
......@@ -186,6 +187,7 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_192_ofb());
EVP_add_cipher(EVP_aes_192_ctr());
EVP_add_cipher(EVP_aes_192_gcm());
EVP_add_cipher(EVP_aes_192_ocb());
EVP_add_cipher(EVP_aes_192_ccm());
EVP_add_cipher(EVP_aes_192_wrap());
EVP_add_cipher(EVP_aes_192_wrap_pad());
......@@ -199,6 +201,7 @@ void OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_aes_256_ofb());
EVP_add_cipher(EVP_aes_256_ctr());
EVP_add_cipher(EVP_aes_256_gcm());
EVP_add_cipher(EVP_aes_256_ocb());
EVP_add_cipher(EVP_aes_256_xts());
EVP_add_cipher(EVP_aes_256_ccm());
EVP_add_cipher(EVP_aes_256_wrap());
......
......@@ -107,6 +107,24 @@ typedef struct
ccm128_f str;
} EVP_AES_CCM_CTX;
typedef struct
{
AES_KEY ksenc; /* AES key schedule to use for encryption */
AES_KEY ksdec; /* AES key schedule to use for decryption */
int key_set; /* Set if key initialised */
int iv_set; /* Set if an iv is set */
OCB128_CONTEXT ocb;
unsigned char *iv; /* Temporary IV store */
unsigned char tag[16];
unsigned char data_buf[16]; /* Store partial data blocks */
unsigned char aad_buf[16]; /* Store partial AAD blocks */
int data_buf_len;
int aad_buf_len;
int ivlen; /* IV length */
int taglen;
} EVP_AES_OCB_CTX;
#define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
#ifdef VPAES_ASM
......@@ -451,6 +469,58 @@ static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t len);
static int aesni_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
EVP_AES_OCB_CTX *octx = ctx->cipher_data;
if (!iv && !key)
return 1;
if (key)
{
do
{
/* We set both the encrypt and decrypt key here because decrypt
* needs both. We could possibly optimise to remove setting the
* decrypt for an encryption operation.
*/
aesni_set_encrypt_key(key, ctx->key_len * 8, &octx->ksenc);
aesni_set_decrypt_key(key, ctx->key_len * 8, &octx->ksdec);
if(!CRYPTO_ocb128_init(&octx->ocb, &octx->ksenc, &octx->ksdec,
(block128_f)aesni_encrypt, (block128_f)aesni_decrypt))
return 0;
}
while (0);
/* If we have an iv we can set it directly, otherwise use
* saved IV.
*/
if (iv == NULL && octx->iv_set)
iv = octx->iv;
if (iv)
{
if(CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen) != 1)
return 0;
octx->iv_set = 1;
}
octx->key_set = 1;
}
else
{
/* If key set use IV, otherwise copy */
if (octx->key_set)
CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
else
memcpy(octx->iv, iv, octx->ivlen);
octx->iv_set = 1;
}
return 1;
}
#define aesni_ocb_cipher aes_ocb_cipher
static int aesni_ocb_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, \
......@@ -837,6 +907,59 @@ static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
static int aes_t4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t len);
static int aes_t4_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
EVP_AES_OCB_CTX *octx = ctx->cipher_data;
if (!iv && !key)
return 1;
if (key)
{
do
{
/* We set both the encrypt and decrypt key here because decrypt
* needs both. We could possibly optimise to remove setting the
* decrypt for an encryption operation.
*/
aes_t4_set_encrypt_key(key, ctx->key_len * 8, &octx->ksenc);
aes_t4_set_decrypt_key(key, ctx->key_len * 8, &octx->ksdec);
if(!CRYPTO_ocb128_init(&octx->ocb, &octx->ksenc, &octx->ksdec,
(block128_f)aes_t4_encrypt, (block128_f)aes_t4_decrypt))
return 0;
}
while (0);
/* If we have an iv we can set it directly, otherwise use
* saved IV.
*/
if (iv == NULL && octx->iv_set)
iv = octx->iv;
if (iv)
{
if(CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen) != 1)
return 0;
octx->iv_set = 1;
}
octx->key_set = 1;
}
else
{
/* If key set use IV, otherwise copy */
if (octx->key_set)
CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
else
memcpy(octx->iv, iv, octx->ivlen);
octx->iv_set = 1;
}
return 1;
}
#define aes_t4_ocb_cipher aes_ocb_cipher
static int aes_t4_ocb_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 aes_t4_##keylen##_##mode = { \
nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
......@@ -2238,4 +2361,289 @@ const EVP_CIPHER *EVP_aes_256_wrap_pad(void)
return &aes_256_wrap_pad;
}
static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
EVP_AES_OCB_CTX *octx = c->cipher_data;
EVP_CIPHER_CTX *newc;
EVP_AES_OCB_CTX *new_octx;
switch (type)
{
case EVP_CTRL_INIT:
octx->key_set = 0;
octx->iv_set = 0;
octx->ivlen = c->cipher->iv_len;
octx->iv = c->iv;
octx->taglen = 16;
octx->data_buf_len = 0;
octx->aad_buf_len = 0;
return 1;
case EVP_CTRL_SET_IVLEN:
/* IV len must be 1 to 15 */
if (arg <= 0 || arg > 15)
return 0;
octx->ivlen = arg;
return 1;
case EVP_CTRL_OCB_SET_TAGLEN:
/* Tag len must be 0 to 16 */
if (arg < 0 || arg > 16)
return 0;
octx->taglen = arg;
return 1;
case EVP_CTRL_SET_TAG:
if (arg != octx->taglen || c->encrypt)
return 0;
memcpy(octx->tag, ptr, arg);
return 1;
case EVP_CTRL_GET_TAG:
if (arg != octx->taglen || !c->encrypt)
return 0;
memcpy(ptr, octx->tag, arg);
return 1;
case EVP_CTRL_COPY:
newc = (EVP_CIPHER_CTX *)ptr;
new_octx = newc->cipher_data;
return CRYPTO_ocb128_copy_ctx(&new_octx->ocb, &octx->ocb,
&new_octx->ksenc, &new_octx->ksdec);
default:
return -1;
}
}
static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
EVP_AES_OCB_CTX *octx = ctx->cipher_data;
if (!iv && !key)
return 1;
if (key)
{
do
{
/* We set both the encrypt and decrypt key here because decrypt
* needs both. We could possibly optimise to remove setting the
* decrypt for an encryption operation.
*/
#ifdef VPAES_CAPABLE
if (VPAES_CAPABLE)
{
vpaes_set_encrypt_key(key,ctx->key_len*8,&octx->ksenc);
vpaes_set_decrypt_key(key,ctx->key_len*8,&octx->ksdec);
if(!CRYPTO_ocb128_init(&octx->ocb,&octx->ksenc,&octx->ksdec,
(block128_f)vpaes_encrypt,(block128_f)vpaes_decrypt))
return 0;
break;
}
#endif
AES_set_encrypt_key(key, ctx->key_len * 8, &octx->ksenc);
AES_set_decrypt_key(key, ctx->key_len * 8, &octx->ksdec);
if(!CRYPTO_ocb128_init(&octx->ocb, &octx->ksenc, &octx->ksdec,
(block128_f)AES_encrypt, (block128_f)AES_decrypt))
return 0;
}
while (0);
/* If we have an iv we can set it directly, otherwise use
* saved IV.
*/
if (iv == NULL && octx->iv_set)
iv = octx->iv;
if (iv)
{
if(CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen) != 1)
return 0;
octx->iv_set = 1;
}
octx->key_set = 1;
}
else
{
/* If key set use IV, otherwise copy */
if (octx->key_set)
CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
else
memcpy(octx->iv, iv, octx->ivlen);
octx->iv_set = 1;
}
return 1;
}
static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t len)
{
unsigned char *buf;
int *buf_len;
int written_len = 0;
size_t trailing_len;
EVP_AES_OCB_CTX *octx = ctx->cipher_data;
/* If IV or Key not set then return error */
if (!octx->iv_set)
return -1;
if (!octx->key_set)
return -1;
if (in)
{
/* Need to ensure we are only passing full blocks to low level OCB
* routines. We do it here rather than in EVP_EncryptUpdate/
* EVP_DecryptUpdate because we need to pass full blocks of AAD too
* and those routines don't support that
*/
/* Are we dealing with AAD or normal data here? */
if (out == NULL)
{
buf = octx->aad_buf;
buf_len = &(octx->aad_buf_len);
}
else
{
buf = octx->data_buf;
buf_len = &(octx->data_buf_len);
}
/* If we've got a partially filled buffer from a previous call then use
* that data first
*/
if(*buf_len)
{
unsigned int remaining;
remaining = 16 - (*buf_len);
if(remaining > len)
{
memcpy(buf+(*buf_len), in, len);
*(buf_len)+=len;
return 0;
}
memcpy(buf+(*buf_len), in, remaining);
/* If we get here we've filled the buffer, so process it */
len -= remaining;
in += remaining;
if (out == NULL)
{
if(!CRYPTO_ocb128_aad(&octx->ocb, buf, 16))
return -1;
}
else if (ctx->encrypt)
{
if(!CRYPTO_ocb128_encrypt(&octx->ocb, buf, out, 16))
return -1;
}
else
{
if(!CRYPTO_ocb128_decrypt(&octx->ocb, buf, out, 16))
return -1;
}
written_len = 16;
*buf_len = 0;
}
/* Do we have a partial block to handle at the end? */
trailing_len = len % 16;
/* If we've got some full blocks to handle, then process these first */
if(len != trailing_len)
{
if (out == NULL)
{
if(!CRYPTO_ocb128_aad(&octx->ocb, in, len-trailing_len))
return -1;
}
else if (ctx->encrypt)
{
if(!CRYPTO_ocb128_encrypt(&octx->ocb, in, out, len-trailing_len))
return -1;
}
else
{
if(!CRYPTO_ocb128_decrypt(&octx->ocb, in, out, len-trailing_len))
return -1;
}
written_len += len-trailing_len;
in += len-trailing_len;
}
/* Handle any trailing partial block */
if(trailing_len)
{
memcpy(buf, in, trailing_len);
*buf_len = trailing_len;
}
return written_len;
}
else
{
/* First of all empty the buffer of any partial block that we might
* have been provided - both for data and AAD
*/
if(octx->data_buf_len)
{
if (ctx->encrypt)
{
if(!CRYPTO_ocb128_encrypt(&octx->ocb, octx->data_buf, out,
octx->data_buf_len))
return -1;
}
else
{
if(!CRYPTO_ocb128_decrypt(&octx->ocb, octx->data_buf, out,
octx->data_buf_len))
return -1;
}
written_len = octx->data_buf_len;
octx->data_buf_len = 0;
}
if(octx->aad_buf_len)
{
if(!CRYPTO_ocb128_aad(&octx->ocb, octx->aad_buf, octx->aad_buf_len))
return -1;
octx->aad_buf_len = 0;
}
/* If decrypting then verify */
if (!ctx->encrypt)
{
if (octx->taglen < 0)
return -1;
if (CRYPTO_ocb128_finish(&octx->ocb,
octx->tag, octx->taglen) != 0)
return -1;
octx->iv_set = 0;
return written_len;
}
/* If encrypting then just get the tag */
if(CRYPTO_ocb128_tag(&octx->ocb, octx->tag, 16) != 1)
return -1;
/* Don't reuse the IV */
octx->iv_set = 0;
return written_len;
}
}
static int aes_ocb_cleanup(EVP_CIPHER_CTX *c)
{
EVP_AES_OCB_CTX *octx = c->cipher_data;
CRYPTO_ocb128_cleanup(&octx->ocb);
return 1;
}
BLOCK_CIPHER_custom(NID_aes,128,16,12,ocb,OCB,CUSTOM_FLAGS)
BLOCK_CIPHER_custom(NID_aes,192,16,12,ocb,OCB,CUSTOM_FLAGS)
BLOCK_CIPHER_custom(NID_aes,256,16,12,ocb,OCB,CUSTOM_FLAGS)
#endif
......@@ -340,6 +340,7 @@ struct evp_cipher_st
#define EVP_CIPH_CCM_MODE 0x7
#define EVP_CIPH_XTS_MODE 0x10001
#define EVP_CIPH_WRAP_MODE 0x10002
#define EVP_CIPH_OCB_MODE 0x10003
#define EVP_CIPH_MODE 0xF0007
/* Set if variable length cipher */
#define EVP_CIPH_VARIABLE_LENGTH 0x8
......@@ -422,6 +423,12 @@ typedef struct {
unsigned int interleave;
} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM;
#define EVP_CTRL_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN
#define EVP_CTRL_GET_TAG EVP_CTRL_GCM_GET_TAG
#define EVP_CTRL_SET_TAG EVP_CTRL_GCM_SET_TAG
#define EVP_CTRL_OCB_SET_TAGLEN 0x1c
/* GCM TLS constants */
/* Length of fixed part of IV derived from PRF */
#define EVP_GCM_TLS_FIXED_IV_LEN 4
......@@ -850,6 +857,7 @@ const EVP_CIPHER *EVP_aes_128_gcm(void);
const EVP_CIPHER *EVP_aes_128_xts(void);
const EVP_CIPHER *EVP_aes_128_wrap(void);
const EVP_CIPHER *EVP_aes_128_wrap_pad(void);
const EVP_CIPHER *EVP_aes_128_ocb(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);
......@@ -862,6 +870,7 @@ const EVP_CIPHER *EVP_aes_192_ccm(void);
const EVP_CIPHER *EVP_aes_192_gcm(void);
const EVP_CIPHER *EVP_aes_192_wrap(void);
const EVP_CIPHER *EVP_aes_192_wrap_pad(void);
const EVP_CIPHER *EVP_aes_192_ocb(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);
......@@ -875,6 +884,7 @@ const EVP_CIPHER *EVP_aes_256_gcm(void);
const EVP_CIPHER *EVP_aes_256_xts(void);
const EVP_CIPHER *EVP_aes_256_wrap(void);
const EVP_CIPHER *EVP_aes_256_wrap_pad(void);
const EVP_CIPHER *EVP_aes_256_ocb(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);
......
......@@ -62,9 +62,9 @@
* [including the GNU Public Licence.]
*/
#define NUM_NID 958
#define NUM_SN 951
#define NUM_LN 951
#define NUM_NID 961
#define NUM_SN 954
#define NUM_LN 954
#define NUM_OBJ 890
static const unsigned char lvalues[6255]={
......@@ -2514,6 +2514,9 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={
NID_jurisdictionStateOrProvinceName,11,&(lvalues[6232]),0},
{"jurisdictionC","jurisdictionCountryName",
NID_jurisdictionCountryName,11,&(lvalues[6243]),0},
{"AES-128-OCB","aes-128-ocb",NID_aes_128_ocb,0,NULL,0},
{"AES-192-OCB","aes-192-ocb",NID_aes_192_ocb,0,NULL,0},
{"AES-256-OCB","aes-256-ocb",NID_aes_256_ocb,0,NULL,0},
};
static const unsigned int sn_objs[NUM_SN]={
......@@ -2526,6 +2529,7 @@ static const unsigned int sn_objs[NUM_SN]={
653, /* "AES-128-CFB8" */
904, /* "AES-128-CTR" */
418, /* "AES-128-ECB" */
958, /* "AES-128-OCB" */
420, /* "AES-128-OFB" */
913, /* "AES-128-XTS" */
423, /* "AES-192-CBC" */
......@@ -2536,6 +2540,7 @@ static const unsigned int sn_objs[NUM_SN]={
654, /* "AES-192-CFB8" */
905, /* "AES-192-CTR" */
422, /* "AES-192-ECB" */
959, /* "AES-192-OCB" */
424, /* "AES-192-OFB" */
427, /* "AES-256-CBC" */
918, /* "AES-256-CBC-HMAC-SHA1" */
......@@ -2545,6 +2550,7 @@ static const unsigned int sn_objs[NUM_SN]={
655, /* "AES-256-CFB8" */
906, /* "AES-256-CTR" */
426, /* "AES-256-ECB" */
960, /* "AES-256-OCB" */
428, /* "AES-256-OFB" */
914, /* "AES-256-XTS" */
91, /* "BF-CBC" */
......@@ -3629,6 +3635,7 @@ static const unsigned int ln_objs[NUM_LN]={
904, /* "aes-128-ctr" */
418, /* "aes-128-ecb" */
895, /* "aes-128-gcm" */
958, /* "aes-128-ocb" */
420, /* "aes-128-ofb" */
913, /* "aes-128-xts" */
423, /* "aes-192-cbc" */
......@@ -3641,6 +3648,7 @@ static const unsigned int ln_objs[NUM_LN]={
905, /* "aes-192-ctr" */
422, /* "aes-192-ecb" */
898, /* "aes-192-gcm" */
959, /* "aes-192-ocb" */
424, /* "aes-192-ofb" */
427, /* "aes-256-cbc" */
918, /* "aes-256-cbc-hmac-sha1" */
......@@ -3652,6 +3660,7 @@ static const unsigned int ln_objs[NUM_LN]={
906, /* "aes-256-ctr" */
426, /* "aes-256-ecb" */
901, /* "aes-256-gcm" */
960, /* "aes-256-ocb" */
428, /* "aes-256-ofb" */
914, /* "aes-256-xts" */
376, /* "algorithm" */
......
......@@ -2745,6 +2745,18 @@
#define LN_aes_256_ctr "aes-256-ctr"
#define NID_aes_256_ctr 906
#define SN_aes_128_ocb "AES-128-OCB"
#define LN_aes_128_ocb "aes-128-ocb"
#define NID_aes_128_ocb 958
#define SN_aes_192_ocb "AES-192-OCB"
#define LN_aes_192_ocb "aes-192-ocb"
#define NID_aes_192_ocb 959
#define SN_aes_256_ocb "AES-256-OCB"
#define LN_aes_256_ocb "aes-256-ocb"
#define NID_aes_256_ocb 960
#define SN_aes_128_xts "AES-128-XTS"
#define LN_aes_128_xts "aes-128-xts"
#define NID_aes_128_xts 913
......
......@@ -955,3 +955,6 @@ ct_cert_scts 954
jurisdictionLocalityName 955
jurisdictionStateOrProvinceName 956
jurisdictionCountryName 957
aes_128_ocb 958
aes_192_ocb 959
aes_256_ocb 960
......@@ -894,6 +894,9 @@ aes 48 : id-aes256-wrap-pad
: AES-128-CTR : aes-128-ctr
: AES-192-CTR : aes-192-ctr
: AES-256-CTR : aes-256-ctr
: AES-128-OCB : aes-128-ocb
: AES-192-OCB : aes-192-ocb
: AES-256-OCB : aes-256-ocb
: AES-128-XTS : aes-128-xts
: AES-256-XTS : aes-256-xts
: DES-CFB1 : des-cfb1
......
......@@ -4514,3 +4514,15 @@ i2s_ASN1_IA5STRING 4874 EXIST::FUNCTION:
s2i_ASN1_IA5STRING 4875 EXIST::FUNCTION:
FIPS_dsa_sign_ctx 4876 EXIST:OPENSSL_FIPS:FUNCTION:DSA
FIPS_ecdsa_sign 4877 EXIST:OPENSSL_FIPS:FUNCTION:ECDSA
CRYPTO_ocb128_release 4878 EXIST::FUNCTION:
CRYPTO_ocb128_new 4879 EXIST::FUNCTION:
CRYPTO_ocb128_finish 4880 EXIST::FUNCTION:
EVP_aes_256_ocb 4881 EXIST::FUNCTION:AES
CRYPTO_ocb128_setiv 4882 EXIST::FUNCTION:
CRYPTO_ocb128_aad 4883 EXIST::FUNCTION:
CRYPTO_ocb128_decrypt 4884 EXIST::FUNCTION:
CRYPTO_ocb128_tag 4885 EXIST::FUNCTION:
EVP_aes_192_ocb 4886 EXIST::FUNCTION:AES
EVP_aes_128_ocb 4887 EXIST::FUNCTION:AES
CRYPTO_ocb128_init 4888 EXIST::FUNCTION:
CRYPTO_ocb128_encrypt 4889 EXIST::FUNCTION:
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册