📄 ccm.c
字号:
if(ctx->cnt == ctx->hdr_lim)
{
ctx->state = MSG_STATE;
ctx->cnt = 0;
ctx->txt_acnt = 0;
}
return RETURN_OK;
}
ret_type ccm_auth_data( /* authenticate the plaintext */
const unsigned char data[], /* the data buffer */
unsigned long data_len, /* and its length in bytes */
ccm_ctx ctx[1]) /* the mode context */
{ uint_32t cnt = 0, b_pos = ((uint_32t)ctx->txt_acnt) & BLK_ADR_MASK;
if(ctx->state < 0)
return ctx->state;
if(ctx->state == AUTH_STATE)
return (ctx->state = CCM_AUTH_LENGTH_ERROR);
if(ctx->txt_acnt + data_len > ctx->msg_len)
return (ctx->state = CCM_MSG_LENGTH_ERROR);
while(cnt < data_len && (b_pos & BUF_ADRMASK))
ui8_ptr(ctx->cbc_buf)[b_pos++] ^= data[cnt++];
if(!(b_pos & BUF_ADRMASK) && !((data + cnt - ui8_ptr(ctx->cbc_buf)) & BUF_ADRMASK))
{
while(cnt + BUF_INC <= data_len && b_pos <= BLOCK_SIZE - BUF_INC)
{
*unit_ptr(ui8_ptr(ctx->cbc_buf) + b_pos) ^= *unit_ptr(data + cnt);
cnt += BUF_INC; b_pos += BUF_INC;
}
while(cnt + BLOCK_SIZE <= data_len)
{
aes_encrypt(ui8_ptr(ctx->cbc_buf), ui8_ptr(ctx->cbc_buf), ctx->aes);
xor_block_aligned(ctx->cbc_buf, data + cnt);
cnt += BLOCK_SIZE;
}
}
else
{
while(cnt < data_len && b_pos < BLOCK_SIZE)
ui8_ptr(ctx->cbc_buf)[b_pos++] ^= data[cnt++];
while(cnt + BLOCK_SIZE <= data_len)
{
aes_encrypt(ui8_ptr(ctx->cbc_buf), ui8_ptr(ctx->cbc_buf), ctx->aes);
xor_block(ctx->cbc_buf, data + cnt);
cnt += BLOCK_SIZE;
}
}
while(cnt < data_len)
{
if(b_pos == BLOCK_SIZE)
aes_encrypt(ui8_ptr(ctx->cbc_buf), ui8_ptr(ctx->cbc_buf), ctx->aes), b_pos = 0;
ui8_ptr(ctx->cbc_buf)[b_pos++] ^= data[cnt++];
}
if(b_pos == BLOCK_SIZE)
aes_encrypt(ui8_ptr(ctx->cbc_buf), ui8_ptr(ctx->cbc_buf), ctx->aes);
ctx->txt_acnt += cnt;
return RETURN_OK;
}
ret_type ccm_crypt_data( /* encrypt or decrypt data */
unsigned char data[], /* the data buffer */
unsigned long data_len, /* and its length in bytes */
ccm_ctx ctx[1]) /* the mode context */
{ uint_32t cnt = 0, b_pos = ((uint_32t)ctx->cnt) & BLK_ADR_MASK;
if(ctx->state < 0)
return ctx->state;
if(ctx->state == AUTH_STATE)
return (ctx->state = CCM_AUTH_LENGTH_ERROR);
if(ctx->cnt + data_len > ctx->msg_len)
return (ctx->state = CCM_MSG_LENGTH_ERROR);
if(!data_len)
return RETURN_OK;
if(b_pos == 0)
{
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->aes);
inc_ctr(ctx->ctr_val);
}
while(cnt < data_len && (b_pos & BUF_ADRMASK))
data[cnt++] ^= ui8_ptr(ctx->enc_ctr)[b_pos++];
if(!(b_pos & BUF_ADRMASK) && !((data + cnt - ui8_ptr(ctx->enc_ctr)) & BUF_ADRMASK))
{
while(cnt + BUF_INC <= data_len && b_pos <= BLOCK_SIZE - BUF_INC)
{
*unit_ptr(data + cnt) ^= *unit_ptr(ui8_ptr(ctx->enc_ctr) + b_pos);
cnt += BUF_INC; b_pos += BUF_INC;
}
while(cnt + BLOCK_SIZE <= data_len)
{
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->aes);
inc_ctr(ctx->ctr_val);
xor_block_aligned(data + cnt, ctx->enc_ctr);
cnt += BLOCK_SIZE;
}
}
else
{
while(cnt < data_len && b_pos < BLOCK_SIZE)
data[cnt++] ^= ui8_ptr(ctx->enc_ctr)[b_pos++];
while(cnt + BLOCK_SIZE <= data_len)
{
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->aes);
inc_ctr(ctx->ctr_val);
xor_block(data + cnt, ctx->enc_ctr);
cnt += BLOCK_SIZE;
}
}
while(cnt < data_len)
{
if(b_pos == BLOCK_SIZE)
{
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->aes);
inc_ctr(ctx->ctr_val);
b_pos = 0;
}
data[cnt++] ^= ui8_ptr(ctx->enc_ctr)[b_pos++];
}
ctx->cnt += cnt;
return RETURN_OK;
}
ret_type ccm_compute_tag( /* compute authentication tag */
unsigned char tag[], /* the buffer for the tag */
unsigned long tag_len, /* and its length in bytes */
ccm_ctx ctx[1]) /* the mode context */
{ uint_32t cnt, pos;
if(ctx->state < 0)
return ctx->state;
if( tag_len != ctx->tag_len
|| ctx->state == INIT_STATE && ctx->hdr_lim
|| ctx->state == AUTH_STATE)
return (ctx->state = CCM_AUTH_LENGTH_ERROR);
if(ctx->txt_acnt != ctx->cnt && ctx->cnt > 0)
return RETURN_ERROR;
if( ctx->cnt < ctx->msg_len
|| ctx->cnt + tag_len > ctx->msg_len + ctx->tag_len)
return (ctx->state = CCM_MSG_LENGTH_ERROR);
/* if at the start of the authentication field */
if(tag_len > 0 && ctx->cnt == ctx->msg_len)
{
if(ctx->cnt & BLK_ADR_MASK)
aes_encrypt(ui8_ptr(ctx->cbc_buf), ui8_ptr(ctx->cbc_buf), ctx->aes);
set_ctr(ctx, 0);
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->aes);
}
cnt = 0;
pos = (uint_32t)(ctx->cnt - ctx->msg_len);
while(cnt < tag_len)
{
tag[cnt++] = ui8_ptr(ctx->cbc_buf)[pos] ^ ui8_ptr(ctx->enc_ctr)[pos];
++pos;
}
return (ctx->cnt == ctx->txt_acnt ? RETURN_OK : RETURN_WARN);
}
ret_type ccm_end( /* clean up and end operation */
ccm_ctx ctx[1]) /* the mode context */
{
memset(ctx, 0, sizeof(ccm_ctx));
return RETURN_OK;
}
ret_type ccm_encrypt( /* authenticate & encrypt data */
unsigned char data[], /* the data buffer */
unsigned long data_len, /* and its length in bytes */
ccm_ctx ctx[1]) /* the mode context */
{
ccm_auth_data(data, data_len, ctx);
ccm_crypt_data(data, data_len, ctx);
return RETURN_OK;
}
ret_type ccm_decrypt( /* decrypt & authenticate data */
unsigned char data[], /* the data buffer */
unsigned long data_len, /* and its length in bytes */
ccm_ctx ctx[1]) /* the mode context */
{
ccm_crypt_data(data, data_len, ctx);
ccm_auth_data(data, data_len, ctx);
return RETURN_OK;
}
ret_type ccm_encrypt_message( /* encrypt an entire message */
const unsigned char iv[], /* the initialisation vector */
unsigned long iv_len, /* and its length in bytes */
const unsigned char hdr[], /* the header buffer */
unsigned long hdr_len, /* and its length in bytes */
unsigned char msg[], /* the message buffer */
unsigned long msg_len, /* and its length in bytes */
unsigned char tag[], /* the buffer for the tag */
unsigned long tag_len, /* and its length in bytes */
ccm_ctx ctx[1]) /* the mode context */
{
ccm_init_message(iv, iv_len, hdr_len, msg_len, tag_len, ctx);
ccm_auth_header(hdr, hdr_len, ctx);
ccm_encrypt(msg, msg_len, ctx);
return ccm_compute_tag(tag, tag_len, ctx) ? RETURN_ERROR : RETURN_OK;
}
ret_type ccm_decrypt_message( /* decrypt an entire message */
const unsigned char iv[], /* the initialisation vector */
unsigned long iv_len, /* and its length in bytes */
const unsigned char hdr[], /* the header buffer */
unsigned long hdr_len, /* and its length in bytes */
unsigned char msg[], /* the message buffer */
unsigned long msg_len, /* and its length in bytes */
const unsigned char tag[], /* the buffer for the tag */
unsigned long tag_len, /* and its length in bytes */
ccm_ctx ctx[1]) /* the mode context */
{ uint_8t local_tag[BLOCK_SIZE];
ret_type rr;
ccm_init_message(iv, iv_len, hdr_len, msg_len, tag_len, ctx);
ccm_auth_header(hdr, hdr_len, ctx);
ccm_decrypt(msg, msg_len, ctx);
rr = ccm_compute_tag(local_tag, tag_len, ctx);
return (rr != RETURN_OK || memcmp(tag, local_tag, tag_len)) ? RETURN_ERROR : RETURN_OK;
}
#if defined(__cplusplus)
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -