📄 cwc.c
字号:
}
}
else
{
while(cnt < hdr_len && b_pos < ABLK_LEN)
ui8_ptr(ctx->cwc_buf)[b_pos++] = hdr[cnt++];
while(cnt + ABLK_LEN <= hdr_len)
{
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
memcpy(ctx->cwc_buf, hdr + cnt, ABLK_LEN);
cnt += ABLK_LEN;
}
}
while(cnt < hdr_len)
{
if(b_pos == ABLK_LEN)
{
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
b_pos = 0;
}
ui8_ptr(ctx->cwc_buf)[b_pos++] = hdr[cnt++];
}
if(b_pos) /* if bytes remain in the buffer */
{
while(b_pos < ABLK_LEN)
ui8_ptr(ctx->cwc_buf)[b_pos++] = 0;
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
}
ctx->hdr_cnt += hdr_len;
return RETURN_OK;
}
ret_type cwc_auth_data( /* authenticate ciphertext */
const unsigned char data[], /* the data buffer */
unsigned long data_len, /* and its length in bytes */
cwc_ctx ctx[1]) /* the mode context */
{ uint_32t cnt = 0, b_pos = ctx->txt_acnt;
if(!data_len)
return RETURN_OK;
b_pos -= (b_pos / ABLK_LEN) * ABLK_LEN;
while(cnt < data_len && (b_pos & BUF_ADRMASK))
ui8_ptr(ctx->cwc_buf)[b_pos++] = data[cnt++];
if(!(b_pos & BUF_ADRMASK) && !((data + cnt - ui8_ptr(ctx->cwc_buf)) & BUF_ADRMASK))
{
while(cnt + BUF_INC <= data_len && b_pos <= ABLK_LEN - BUF_INC)
{
*unit_ptr(ui8_ptr(ctx->cwc_buf) + b_pos) = *unit_ptr(data + cnt);
cnt += BUF_INC; b_pos += BUF_INC;
}
while(cnt + ABLK_LEN <= data_len)
{
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
memcpy(ctx->cwc_buf, data + cnt, ABLK_LEN);
cnt += ABLK_LEN;
}
}
else
{
while(cnt < data_len && b_pos < ABLK_LEN)
ui8_ptr(ctx->cwc_buf)[b_pos++] = data[cnt++];
while(cnt + ABLK_LEN <= data_len)
{
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
memcpy(ctx->cwc_buf, data + cnt, ABLK_LEN);
cnt += ABLK_LEN;
}
}
while(cnt < data_len)
{
if(b_pos == ABLK_LEN)
{
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
b_pos = 0;
}
ui8_ptr(ctx->cwc_buf)[b_pos++] = data[cnt++];
}
if(b_pos == ABLK_LEN)
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
ctx->txt_acnt += data_len;
return RETURN_OK;
}
ret_type cwc_crypt_data( /* encrypt or decrypt data */
unsigned char data[], /* the data buffer */
unsigned long data_len, /* and its length in bytes */
cwc_ctx ctx[1]) /* the mode context */
{ uint_32t cnt = 0, b_pos = ctx->txt_ccnt;
if(!data_len)
return RETURN_OK;
if(b_pos == 0)
{
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->enc_ctx);
be_inc(ui8_ptr(ctx->ctr_val), 12);
}
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 <= CBLK_LEN - BUF_INC)
{
*unit_ptr(data + cnt) ^= *unit_ptr(ui8_ptr(ctx->enc_ctr) + b_pos);
cnt += BUF_INC; b_pos += BUF_INC;
}
while(cnt + CBLK_LEN <= data_len)
{
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->enc_ctx);
be_inc(ui8_ptr(ctx->ctr_val), 12);
xor_block_aligned(data + cnt, ctx->enc_ctr);
cnt += CBLK_LEN;
}
}
else
{
while(cnt < data_len && b_pos < CBLK_LEN)
data[cnt++] ^= ui8_ptr(ctx->enc_ctr)[b_pos++];
while(cnt + CBLK_LEN <= data_len)
{
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->enc_ctx);
be_inc(ui8_ptr(ctx->ctr_val), 12);
xor_block(data + cnt, ctx->enc_ctr);
cnt += CBLK_LEN;
}
}
while(cnt < data_len)
{
if(b_pos == CBLK_LEN)
{
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->enc_ctx);
be_inc(ui8_ptr(ctx->ctr_val), 12);
b_pos = 0;
}
data[cnt++] ^= ui8_ptr(ctx->enc_ctr)[b_pos++];
}
ctx->txt_ccnt += data_len;
return RETURN_OK;
}
ret_type cwc_compute_tag( /* compute authentication tag */
unsigned char tag[], /* the buffer for the tag */
unsigned long tag_len, /* and its length in bytes */
cwc_ctx ctx[1]) /* the mode context */
{ uint_32t pos, hh[4];
if(ctx->txt_acnt != ctx->txt_ccnt && ctx->txt_ccnt > 0)
return RETURN_ERROR;
pos = ctx->txt_acnt;
pos -= (pos / ABLK_LEN) * ABLK_LEN;
if(pos)
{
while(pos < ABLK_LEN)
ui8_ptr(ctx->cwc_buf)[pos++] = 0;
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
}
#if defined( USE_FLOATS )
/* For 64-bit data lengths:
ctx->hash[0] += (ctx->txt_ccnt & 0xffffffff);
ctx->hash[1] += 256.0 * (ctx->txt_ccnt >> 32);
ctx->hash[2] += 65536.0 * (ctx->hdr_cnt & 0xffffffff);
ctx->hash[4] += (ctx->hdr_cnt >> 32);
*/
/* set FPU to operate in 53 bit precision */
/* and in truncate to zero mode */
set_FPU;
ctx->hash[0] += ctx->txt_ccnt;
ctx->hash[2] += 65536.0 * ctx->hdr_cnt;
freeze(ctx->hash, 1);
hh[0] = ((uint_32t)ctx->hash[4])
| (((uint_32t)ctx->hash[5]) << 24);
hh[1] = (((uint_32t)ctx->hash[2]) >> 16)
| (((uint_32t)ctx->hash[3]) << 8);
hh[2] = (((uint_32t)ctx->hash[1]) >> 8)
| ((((uint_32t)ctx->hash[2]) & 0x0000ffff) << 16);
hh[3] = ((uint_32t)ctx->hash[0])
| (((uint_32t)ctx->hash[1]) << 24);
reset_FPU;
#endif
#if defined( USE_LONGS )
/* For 64-bit data lengths:
hh[0] = (ctx->hdr_cnt >> 32);
hh[1] = (ctx->hdr_cnt & 0xffffffff);
hh[2] = (ctx->txt_ccnt >> 32);
hh[3] = (ctx->txt_ccnt & 0xffffffff);
*/
hh[0] = 0;
hh[1] = ctx->hdr_cnt;
hh[2] = 0;
hh[3] = ctx->txt_ccnt;
add_4(ctx->hash, hh);
if(ctx->hash[0] & 0x80000000)
{
ctx->hash[0] &= 0x7fffffff;
be_inc(ctx->hash, 0);
}
hh[0] = ctx->hash[0];
hh[1] = ctx->hash[1];
hh[2] = ctx->hash[2];
hh[3] = ctx->hash[3];
#endif
#if PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN
bswap32_block(hh, hh, 4);
#endif
aes_encrypt((unsigned char*)hh, (unsigned char*)hh, ctx->enc_ctx);
ui8_ptr(ctx->ctr_val)[12] = 0; ui8_ptr(ctx->ctr_val)[13] = 0;
ui8_ptr(ctx->ctr_val)[14] = 0; ui8_ptr(ctx->ctr_val)[15] = 0;
aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->enc_ctx);
for(pos = 0; pos < tag_len; ++pos)
tag[pos] = ((unsigned char*)hh)[pos] ^ ui8_ptr(ctx->enc_ctr)[pos];
return (ctx->txt_ccnt == ctx->txt_acnt ? RETURN_OK : RETURN_WARN);
}
ret_type cwc_end( /* clean up and end operation */
cwc_ctx ctx[1]) /* the mode context */
{
memset(ctx, 0, sizeof(cwc_ctx));
return RETURN_OK;
}
ret_type cwc_encrypt( /* encrypt & authenticate data */
unsigned char data[], /* the data buffer */
unsigned long data_len, /* and its length in bytes */
cwc_ctx ctx[1]) /* the mode context */
{
cwc_crypt_data(data, data_len, ctx);
cwc_auth_data(data, data_len, ctx);
return RETURN_OK;
}
ret_type cwc_decrypt( /* authenticate & decrypt data */
unsigned char data[], /* the data buffer */
unsigned long data_len, /* and its length in bytes */
cwc_ctx ctx[1]) /* the mode context */
{
cwc_auth_data(data, data_len, ctx);
cwc_crypt_data(data, data_len, ctx);
return RETURN_OK;
}
ret_type cwc_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 */
cwc_ctx ctx[1]) /* the mode context */
{
cwc_init_message(iv, iv_len, ctx);
cwc_auth_header(hdr, hdr_len, ctx);
cwc_encrypt(msg, msg_len, ctx);
return cwc_compute_tag(tag, tag_len, ctx) ? RETURN_ERROR : RETURN_OK;
}
ret_type cwc_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 */
cwc_ctx ctx[1]) /* the mode context */
{ uint_8t local_tag[CBLK_LEN];
ret_type rr;
cwc_init_message(iv, iv_len, ctx);
cwc_auth_header(hdr, hdr_len, ctx);
cwc_decrypt(msg, msg_len, ctx);
rr = cwc_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 + -