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

📄 eax.c

📁 加密认证联合模式的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        while(cnt + BUF_INC <= data_len && b_pos <= BLOCK_SIZE - BUF_INC)
        {
            *unit_ptr(ui8_ptr(ctx->txt_cbc) + b_pos) ^= *unit_ptr(data + cnt);
            cnt += BUF_INC; b_pos += BUF_INC;
        }

        while(cnt + BLOCK_SIZE <= data_len)
        {
            aes_encrypt(ui8_ptr(ctx->txt_cbc), ui8_ptr(ctx->txt_cbc), ctx->aes);
            xor_block_aligned(ctx->txt_cbc, data + cnt);
            cnt += BLOCK_SIZE;
        }
    }
    else
    {
        while(cnt < data_len && b_pos < BLOCK_SIZE)
           ui8_ptr(ctx->txt_cbc)[b_pos++] ^= data[cnt++];

        while(cnt + BLOCK_SIZE <= data_len)
        {
            aes_encrypt(ui8_ptr(ctx->txt_cbc), ui8_ptr(ctx->txt_cbc), ctx->aes);
            xor_block(ctx->txt_cbc, data + cnt);
            cnt += BLOCK_SIZE;
        }
    }

    while(cnt < data_len)
    {
        if(b_pos == BLOCK_SIZE)
        {
            aes_encrypt(ui8_ptr(ctx->txt_cbc), ui8_ptr(ctx->txt_cbc), ctx->aes);
            b_pos = 0;
        }
        ui8_ptr(ctx->txt_cbc)[b_pos++] ^= data[cnt++];
    }

    ctx->txt_acnt = b_pos;
    return RETURN_OK;
}

ret_type eax_crypt_data(                        /* encrypt or decrypt data      */
            unsigned char data[],               /* the data buffer              */
            unsigned long data_len,             /* and its length in bytes      */
            eax_ctx ctx[1])                     /* the mode context             */
{   uint_32t cnt = 0, b_pos = ctx->txt_ccnt;

    if(!data_len)
        return RETURN_OK;

    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);
            b_pos = 0;
            inc_ctr(ctx->ctr_val);
        }
        data[cnt++] ^= ui8_ptr(ctx->enc_ctr)[b_pos++];
    }

    ctx->txt_ccnt = b_pos;
    return RETURN_OK;
}

ret_type eax_compute_tag(                       /* compute authentication tag   */
            unsigned char tag[],                /* the buffer for the tag       */
            unsigned long tag_len,              /* and its length in bytes      */
            eax_ctx ctx[1])                     /* the mode context             */
{   uint_32t i;
    uint_8t *p;

    if(ctx->txt_acnt != ctx->txt_ccnt && ctx->txt_ccnt > 0)
        return RETURN_ERROR;

    /* complete OMAC* for header value      */
    p = ui8_ptr(ctx->pad_xvv);
    if(ctx->hdr_cnt < BLOCK_SIZE)
    {
        ui8_ptr(ctx->hdr_cbc)[ctx->hdr_cnt] ^= 0x80;
        p += 16;
    }

    for(i = 0; i < EAX_BLOCK_SIZE; ++i)
        ui8_ptr(ctx->hdr_cbc)[i] ^= p[i];

    aes_encrypt(ui8_ptr(ctx->hdr_cbc), ui8_ptr(ctx->hdr_cbc), ctx->aes);

    /* complete OMAC* for ciphertext value  */
    p = ui8_ptr(ctx->pad_xvv);
    if(ctx->txt_acnt < BLOCK_SIZE)
    {
        ui8_ptr(ctx->txt_cbc)[ctx->txt_acnt] ^= 0x80;
        p += 16;
    }

    for(i = 0; i < EAX_BLOCK_SIZE; ++i)
        ui8_ptr(ctx->txt_cbc)[i] ^= p[i];

    aes_encrypt(ui8_ptr(ctx->txt_cbc), ui8_ptr(ctx->txt_cbc), ctx->aes);

    /* compute final authentication tag     */
    for(i = 0; i < (unsigned int)tag_len; ++i)
        tag[i] = ui8_ptr(ctx->nce_cbc)[i] ^ ui8_ptr(ctx->txt_cbc)[i] ^ ui8_ptr(ctx->hdr_cbc)[i];

    return (ctx->txt_ccnt == ctx->txt_acnt ? RETURN_OK : RETURN_WARN);
}

ret_type eax_end(                               /* clean up and end operation   */
            eax_ctx ctx[1])                     /* the mode context             */
{
    memset(ctx, 0, sizeof(eax_ctx));
    return RETURN_OK;
}

ret_type eax_encrypt(                           /* encrypt & authenticate data  */
            unsigned char data[],               /* the data buffer              */
            unsigned long data_len,             /* and its length in bytes      */
            eax_ctx ctx[1])                     /* the mode context             */
{

    eax_crypt_data(data, data_len, ctx);
    eax_auth_data(data, data_len, ctx);
    return RETURN_OK;
}

ret_type eax_decrypt(                           /* authenticate & decrypt data  */
            unsigned char data[],               /* the data buffer              */
            unsigned long data_len,             /* and its length in bytes      */
            eax_ctx ctx[1])                     /* the mode context             */
{
    eax_auth_data(data, data_len, ctx);
    eax_crypt_data(data, data_len, ctx);
    return RETURN_OK;
}

ret_type eax_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      */
            eax_ctx ctx[1])                     /* the mode context             */
{
    eax_init_message(iv, iv_len, ctx);
    eax_auth_header(hdr, hdr_len, ctx);
    eax_encrypt(msg, msg_len, ctx);
    return eax_compute_tag(tag, tag_len, ctx) ? RETURN_ERROR : RETURN_OK;
}

ret_type eax_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      */
            eax_ctx ctx[1])                     /* the mode context             */
{   uint_8t local_tag[BLOCK_SIZE];
    ret_type rr;

    eax_init_message(iv, iv_len, ctx);
    eax_auth_header(hdr, hdr_len, ctx);
    eax_decrypt(msg, msg_len, ctx);
    rr = eax_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 + -