⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cwc.c

📁 加密认证联合模式的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        }
    }
    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 + -