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

📄 gcm.c

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

        while(cnt + BLOCK_SIZE <= data_len)
        {
            gf_mul_hh(ui8_ptr(ctx->txt_ghv), ctx, scratch);
            xor_block(ctx->txt_ghv, data + cnt);
            cnt += BLOCK_SIZE;
        }
    }

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

    ctx->txt_acnt += cnt;
    return RETURN_OK;
}

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

    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->txt_ccnt += cnt;
    return RETURN_OK;
}

ret_type gcm_compute_tag(                       /* compute authentication tag   */
            unsigned char tag[],                /* the buffer for the tag       */
            unsigned long tag_len,              /* and its length in bytes      */
            gcm_ctx ctx[1])                     /* the mode context             */
{   uint_32t i, ln, scratch[GF_BYTE_LEN >> 2];
    uint_8t tbuf[BLOCK_SIZE];

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

    gf_mul_hh(ui8_ptr(ctx->hdr_ghv), ctx, scratch);
    gf_mul_hh(ui8_ptr(ctx->txt_ghv), ctx, scratch);

#if 1   /* alternative versions of the exponentiation operation */
    if(ctx->hdr_cnt && (ln = (uint_32t)((ctx->txt_acnt + BLOCK_SIZE - 1) / BLOCK_SIZE)))
    {
        memcpy(tbuf, ctx->ghash_h, BLOCK_SIZE);
        for( ; ; )
        {
            if(ln & 1) gf_mul(ui8_ptr(ctx->hdr_ghv), tbuf);
            if(!(ln >>= 1)) break;
            gf_mul(tbuf, tbuf);
        }
    }
#else   /* this one seems slower on x86 and x86_64 :-( */
    if(ctx->hdr_cnt && (ln = (uint_32t)((ctx->txt_acnt + BLOCK_SIZE - 1) / BLOCK_SIZE)))
    {
        i = ln | ln >> 1; i |= i >> 2; i |= i >> 4;
        i |= i >> 8; i |= i >> 16; i = i & ~(i >> 1);
        memset(tbuf, 0, BLOCK_SIZE);
        tbuf[0] = 0x80;
        while(i)
        {
            gf_mul(tbuf, tbuf);
            if(i & ln)
                gf_mul_hh(tbuf, ctx, scratch);
            i >>= 1;
        }
        gf_mul(ui8_ptr(ctx->hdr_ghv), tbuf);
    }
#endif
    i = BLOCK_SIZE; ln = (uint_32t)(ctx->txt_acnt << 3);
    while(i-- > 0)
    {
        ui8_ptr(ctx->hdr_ghv)[i] ^= ui8_ptr(ctx->txt_ghv)[i] ^ (unsigned char)ln;
        ln = (i == 8 ? (uint_32t)(ctx->hdr_cnt << 3) : ln >> 8);
    }

    gf_mul_hh(ui8_ptr(ctx->hdr_ghv), ctx, scratch);

    *ui32_ptr(ui8_ptr(ctx->ctr_val) + CTR_POS) = ctx->y0_val;
    aes_encrypt(ui8_ptr(ctx->ctr_val), ui8_ptr(ctx->enc_ctr), ctx->aes);
    for(i = 0; i < (unsigned int)tag_len; ++i)
        tag[i] = ui8_ptr(ctx->hdr_ghv)[i] ^ ui8_ptr(ctx->enc_ctr)[i];

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

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

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

    gcm_crypt_data(data, data_len, ctx);
    gcm_auth_data(data, data_len, ctx);
    return RETURN_OK;
}

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

ret_type gcm_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      */
            gcm_ctx ctx[1])                     /* the mode context             */
{
    gcm_init_message(iv, iv_len, ctx);
    gcm_auth_header(hdr, hdr_len, ctx);
    gcm_encrypt(msg, msg_len, ctx);
    return gcm_compute_tag(tag, tag_len, ctx) ? RETURN_ERROR : RETURN_OK;
}

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

    gcm_init_message(iv, iv_len, ctx);
    gcm_auth_header(hdr, hdr_len, ctx);
    gcm_decrypt(msg, msg_len, ctx);
    rr = gcm_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 + -