提交 23916810 编写于 作者: D Dr. Stephen Henson

Initial untested CCM support via EVP.

上级 6386b1b3
......@@ -4,6 +4,11 @@
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
*) Initial untested CCM support via EVP. Interface is very similar to GCM
case except we must supply all data in one chunk (i.e. no update, final)
and the message length must be supplied if AAD is used.
[Steve Henson]
*) Initial version of POST overhaul. Add POST callback to allow the status
of POST to be monitored and/or failures induced. Modify fips_test_suite
to use callback. Always run all selftests even if one fails.
......
......@@ -334,6 +334,7 @@ FIPS_EX_OBJ= ../crypto/aes/aes_cfb.o \
../crypto/evp/m_sha1.o \
../crypto/hmac/hmac.o \
../crypto/modes/cbc128.o \
../crypto/modes/ccm128.o \
../crypto/modes/cfb128.o \
../crypto/modes/ctr128.o \
../crypto/modes/gcm128.o \
......
......@@ -328,6 +328,7 @@ FIPS_EX_OBJ= ../crypto/aes/aes_cfb.o \
../crypto/evp/m_sha1.o \
../crypto/hmac/hmac.o \
../crypto/modes/cbc128.o \
../crypto/modes/ccm128.o \
../crypto/modes/cfb128.o \
../crypto/modes/ctr128.o \
../crypto/modes/gcm128.o \
......
......@@ -568,5 +568,215 @@ static const EVP_CIPHER aes_256_xts_cipher=
const EVP_CIPHER *EVP_aes_256_xts (void)
{ return &aes_256_xts_cipher; }
typedef struct
{
/* AES key schedule to use */
AES_KEY ks;
/* Set if key initialised */
int key_set;
/* Set if an iv is set */
int iv_set;
/* Set if tag is valid */
int tag_set;
/* Set if message length set */
int len_set;
/* L and M parameters from RFC3610 */
int L, M;
CCM128_CONTEXT ccm;
} EVP_AES_CCM_CTX;
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)
{
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->key_set = 1;
}
if (iv)
{
memcpy(ctx->iv, iv, 15 - cctx->L);
cctx->iv_set = 1;
}
return 1;
}
static int aes_ccm(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 (CRYPTO_ccm128_encrypt(ccm, in, out, len))
return -1;
cctx->tag_set = 1;
return len;
}
else
{
int rv = -1;
if (!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;
}
}
static const EVP_CIPHER aes_128_ccm_cipher=
{
NID_aes_128_ccm,1,16,12,
EVP_CIPH_CCM_MODE|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT,
aes_ccm_init_key,
aes_ccm,
0,
sizeof(EVP_AES_CCM_CTX),
NULL,
NULL,
aes_ccm_ctrl,
NULL
};
const EVP_CIPHER *EVP_aes_128_ccm (void)
{ return &aes_128_ccm_cipher; }
static const EVP_CIPHER aes_192_ccm_cipher=
{
NID_aes_128_ccm,1,24,12,
EVP_CIPH_CCM_MODE|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT,
aes_ccm_init_key,
aes_ccm,
0,
sizeof(EVP_AES_CCM_CTX),
NULL,
NULL,
aes_ccm_ctrl,
NULL
};
const EVP_CIPHER *EVP_aes_192_ccm (void)
{ return &aes_192_ccm_cipher; }
static const EVP_CIPHER aes_256_ccm_cipher=
{
NID_aes_128_ccm,1,32,12,
EVP_CIPH_CCM_MODE|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT,
aes_ccm_init_key,
aes_ccm,
0,
sizeof(EVP_AES_CCM_CTX),
NULL,
NULL,
aes_ccm_ctrl,
NULL
};
const EVP_CIPHER *EVP_aes_256_ccm (void)
{ return &aes_256_ccm_cipher; }
#endif
......@@ -378,6 +378,11 @@ struct evp_cipher_st
#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
typedef struct evp_cipher_info_st
{
......@@ -790,6 +795,7 @@ 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);
const EVP_CIPHER *EVP_aes_128_ctr(void);
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);
......@@ -800,6 +806,7 @@ 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);
const EVP_CIPHER *EVP_aes_192_ctr(void);
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);
......@@ -809,6 +816,7 @@ 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);
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);
#endif
......
......@@ -108,21 +108,18 @@ void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
typedef struct ccm128_context CCM128_CONTEXT;
void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
unsigned int M,unsigned int L,void *key,block128_f block);
unsigned int M, unsigned int L, void *key,block128_f block);
int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
const unsigned char *nonce,size_t nlen,size_t mlen);
const unsigned char *nonce, size_t nlen, size_t mlen);
void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
const unsigned char *aad,size_t alen);
const unsigned char *aad, size_t alen);
int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
const unsigned char *inp, unsigned char *out,
size_t len);
const unsigned char *inp, unsigned char *out, size_t len);
int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
const unsigned char *inp, unsigned char *out,
size_t len);
size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len);
const unsigned char *inp, unsigned char *out, size_t len);
size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
typedef struct xts128_context XTS128_CONTEXT;
int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char *iv,
const unsigned char *inp, unsigned char *out,
size_t len, int enc);
const unsigned char *inp, unsigned char *out, size_t len, int enc);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册