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

📄 cwc.c

📁 加密认证联合模式的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

    v = a[5] * ctx->zval[4]
      + a[4] * ctx->zval[5];    /* add in r[9] term  */
    f = (v + tp59) - tp59;
    p = ctx->hash[3] + tp17 * (v - f);
    v = (p + tp76) - tp76;
    ctx->hash[3] = p - v;
    ctx->hash[4] += tm07 * f + tm24 * v;

    f = (ctx->hash[4] + tp76) - tp76;
    ctx->hash[4] -= f;
    ctx->hash[5] += tm24 * f;
    reset_FPU;
}

#else

void do_cwc(uint_32t in[], cwc_ctx ctx[1])
{   uint_32t   data[3];
    double  a[6], v, f;

    /* set FPU to operate in 53 bit precision and   */
    /* in truncate to zero mode                     */
    set_FPU;

    data[2] = bswap_32(in[2]);
    data[1] = bswap_32(in[1]);
    data[0] = bswap_32(in[0]);

    /* split input data into 24 bit double values   */
    a[0] =  data[2] & 0x00ffffff;
    a[1] = (data[2] >> 24) | ((data[1] & 0x0000ffff) << 8);
    a[2] = (data[1] >> 16) | ((data[0] & 0x000000ff) << 16);
    a[3] =  data[0] >> 8;

    /* add into the running hash value              */
    a[0] += ctx->hash[0]; a[1] += ctx->hash[1];
    a[2] += ctx->hash[2]; a[3] += ctx->hash[3];
    a[4] = ctx->hash[4]; a[5] = ctx->hash[5];

    /* calculate the low five terms of the product  */
    ctx->hash[0] = a[0] * ctx->zval[0];
    ctx->hash[1] = a[1] * ctx->zval[0]
                 + a[0] * ctx->zval[1];
    ctx->hash[2] = a[2] * ctx->zval[0]
                 + a[1] * ctx->zval[1]
                 + a[0] * ctx->zval[2];
    ctx->hash[3] = a[3] * ctx->zval[0]
                 + a[2] * ctx->zval[1]
                 + a[1] * ctx->zval[2]
                 + a[0] * ctx->zval[3];
    ctx->hash[4] = a[4] * ctx->zval[0]
                 + a[3] * ctx->zval[1]
                 + a[2] * ctx->zval[2]
                 + a[1] * ctx->zval[3]
                 + a[0] * ctx->zval[4];
    ctx->hash[5] = a[5] * ctx->zval[0]
                 + a[4] * ctx->zval[1]
                 + a[3] * ctx->zval[2]
                 + a[2] * ctx->zval[3]
                 + a[1] * ctx->zval[4]
                 + a[0] * ctx->zval[5];

    v = a[5] * ctx->zval[5];    /* add in r[10] term */
    f = (v + tp59) - tp59;
    ctx->hash[4] += tp17 * (v - f);
    ctx->hash[5] += tm07 * f;

    /* do a modular reduction step  */
    f = (ctx->hash[5] + tp59) - tp59;
    ctx->hash[5] -= f;
    ctx->hash[0] += tm07 * f;

    v = a[5] * ctx->zval[1]
      + a[4] * ctx->zval[2]
      + a[3] * ctx->zval[3]
      + a[2] * ctx->zval[4]
      + a[1] * ctx->zval[5];    /* add in r[6] term  */
    f = (v + tp59) - tp59;
    ctx->hash[0] += tp17 * (v - f);
    ctx->hash[1] += tm07 * f;

    v = a[5] * ctx->zval[2]
      + a[4] * ctx->zval[3]
      + a[3] * ctx->zval[4]
      + a[2] * ctx->zval[5];    /* add in r[7] term  */
    f = (v + tp59) - tp59;
    ctx->hash[1] += tp17 * (v - f);
    ctx->hash[2] += tm07 * f;

    v = a[5] * ctx->zval[3]
      + a[4] * ctx->zval[4]
      + a[3] * ctx->zval[5];    /* add in r[8] term  */
    f = (v + tp59) - tp59;
    ctx->hash[2] += tp17 * (v - f);
    ctx->hash[3] += tm07 * f;

    v = a[5] * ctx->zval[4]
      + a[4] * ctx->zval[5];    /* add in r[9] term  */
    f = (v + tp59) - tp59;
    ctx->hash[3] += tp17 * (v - f);
    ctx->hash[4] += tm07 * f;

    /* ripple the carries           */
    f = (ctx->hash[0] + tp76) - tp76;
    ctx->hash[0] -= f;
    ctx->hash[1] += tm24 * f;

    f = (ctx->hash[1] + tp76) - tp76;
    ctx->hash[1] -= f;
    ctx->hash[2] += tm24 * f;

    f = (ctx->hash[2] + tp76) - tp76;
    ctx->hash[2] -= f;
    ctx->hash[3] += tm24 * f;

    f = (ctx->hash[3] + tp76) - tp76;
    ctx->hash[3] -= f;
    ctx->hash[4] += tm24 * f;

    f = (ctx->hash[4] + tp76) - tp76;
    ctx->hash[4] -= f;
    ctx->hash[5] += tm24 * f;

    /* do a modular reduction step  */
    f = (ctx->hash[5] + tp59) - tp59;
    ctx->hash[5] -= f;
    ctx->hash[0] += tm07 * f;
    reset_FPU;
}

#endif

#else

/* add multiple length unsigned values in big endian form   */
/* little endian long words in big endian word order        */

void add_4(uint_32t l[], uint_32t r[])
{   uint_32t   ss, cc;

    ss = l[3] + r[3];
    cc = (ss < l[3] ? 1 : 0);
    l[3] = ss;

    ss = l[2] + r[2] + cc;
    cc = (ss < l[2] ? 1 : ss > l[2] ? 0 : cc);
    l[2] = ss;

    ss = l[1] + r[1] + cc;
    cc = (ss < l[1] ? 1 : ss > l[1] ? 0 : cc);
    l[1] = ss;

    l[0] += r[0] + cc;
}

/* multiply multiple length unsigned values in big endian form  */
/* little endian long words in big endian word order            */

void mlt_4(uint_32t r[], const uint_32t a[], const uint_32t b[])
{   uint_64t ch, cl, sm;
    int     i, j, k;

    for(i = 0, cl = 0; i < 8; ++i)
    {
        /* number of terms in sum   */
        k = (i < 3 ? 0 : i - 3);

        for(j = k, ch = 0; j <= i - k; ++j)
        {
            sm = (uint_64t)a[3 - j] * b[3 - i + j];
            cl += (uint_32t)sm;
            ch += (sm >> 32);
        }

        r[7 - i] = (uint_32t)cl;
        cl = (cl >> 32) + ch;
    }
}

/* Carter-Wegman hash iteration on 12 bytes of data */

void do_cwc(uint_32t in[], cwc_ctx ctx[1])
{   uint_32t   *pt = ctx->hash + (CWC_CBLK_SIZE >> 2), data[4];

    /* put big endian 32-bit items into little endian order     */
    data[3] = bswap_32(in[2]);
    data[2] = bswap_32(in[1]);
    data[1] = bswap_32(in[0]);
    data[0] = 0;

    /* add current hash value into the current data block   */
    add_4(data, ctx->hash);

    /* multiply by the hash key in Z                        */
    mlt_4(ctx->hash, data, ctx->zval);

    /* we now want to find the remainder when divided by    */
    /* (2^127 - 1).  If hash = 2^128 * hi + lo, we can see  */
    /* that hash = (2^127 - 1) * 2 * hi + 2 * hi + lo, so   */
    /* we can set the 128 bit remainder as 2 * hi + lo      */

    add_4(ctx->hash, ctx->hash);/* 2 * hi - if top bit = 1  */
    if(*pt & 0x80000000)    /* another 2^127-1 has to be    */
    {                       /* subtracted from the result   */
        *pt &= 0x7fffffff;
        *(pt - 1) += 1;
    }

    add_4(ctx->hash, pt);       /* 2 * hi + lo - adjust the */
    if(*ctx->hash & 0x80000000) /* result again (as above)  */
    {
        *ctx->hash &= 0x7fffffff;
        be_inc((uint_32t*)ctx->hash, 0);
    }
}

#endif

ret_type cwc_init_and_key(                      /* initialise mode and set key  */
            const unsigned char key[],          /* the key value                */
            unsigned long key_len,              /* and its length in bytes      */
            cwc_ctx ctx[1])                     /* the mode context             */
{
    uint_32t zv[CWC_CBLK_SIZE >> 2];

    if(key_len != 16 && key_len != 24 && key_len != 32)
        return RETURN_ERROR;

    /* set all bytes in the context to zero     */
    memset(ctx, 0, sizeof(cwc_ctx));

    /* set up encryption context                */
    aes_encrypt_key(key, key_len, ctx->enc_ctx);

    /* initialise cwc z value                   */
    memset(zv, 0, (CWC_CBLK_SIZE >> 2) * sizeof(uint_32t));
    ((unsigned char*)zv)[0] = 0xc0;
    aes_encrypt((unsigned char*)zv, (unsigned char*)zv, ctx->enc_ctx);
    ((unsigned char*)zv)[0] &= 0x7f;
#if PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN
    bswap32_block(zv, zv, 4);
#endif

#if defined( USE_FLOATS )
    /* set up the z value in 24 bit doubles     */
    ctx->zval[0] =  zv[3] & 0x00ffffff;
    ctx->zval[1] = (zv[3] >> 24) | ((zv[2] & 0x0000ffff) << 8);
    ctx->zval[2] = (zv[2] >> 16) | ((zv[1] & 0x000000ff) << 16);
    ctx->zval[3] =  zv[1] >> 8;
    ctx->zval[4] =  zv[0] & 0x00ffffff;
    ctx->zval[5] =  zv[0] >> 24;
#endif

#if defined(USE_LONGS )
    memcpy(ctx->zval, zv, CWC_CBLK_SIZE);
#endif

    return RETURN_OK;
}

ret_type cwc_init_message(                      /* initialise a new message     */
            const unsigned char iv[],           /* the initialisation vector    */
            unsigned long iv_len,               /* and its length in bytes      */
            cwc_ctx ctx[1])                     /* the mode context             */
{   uint_32t i;

    /* set up the initial iv in the context  */
    ui8_ptr(ctx->ctr_val)[0] = 0x80;
    for(i = 0; i < 11; ++i)
        ui8_ptr(ctx->ctr_val)[i + 1] = iv[i];

    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] = 1;
    memset(ctx->cwc_buf, 0, sizeof(ctx->cwc_buf));
    ctx->hdr_cnt = 0;
    ctx->txt_acnt = 0;
    ctx->txt_ccnt = 0;

#if defined( USE_FLOATS )
    ctx->hash[0] = 0; ctx->hash[1] = 0;
    ctx->hash[2] = 0; ctx->hash[3] = 0;
    ctx->hash[4] = 0; ctx->hash[5] = 0;
#endif

#if defined( USE_LONGS )
    memset(ctx->hash, 0, sizeof(ctx->hash));
#endif

    return RETURN_OK;
}

ret_type cwc_auth_header(                       /* authenticate the header      */
            const unsigned char hdr[],          /* the header buffer            */
            unsigned long hdr_len,              /* and its length in bytes      */
            cwc_ctx ctx[1])                     /* the mode context             */
{   uint_32t cnt = 0, b_pos = ctx->hdr_cnt;

    if(!hdr_len)
        return RETURN_OK;

    b_pos -= (b_pos / ABLK_LEN) * ABLK_LEN;

    while(cnt < hdr_len && (b_pos & BUF_ADRMASK))
        ui8_ptr(ctx->cwc_buf)[b_pos++] = hdr[cnt++];

    if(!(b_pos & BUF_ADRMASK) && !((hdr + cnt - ui8_ptr(ctx->cwc_buf)) & BUF_ADRMASK))
    {
        while(cnt + BUF_INC <= hdr_len && b_pos <= ABLK_LEN - BUF_INC)
        {
            *unit_ptr(ui8_ptr(ctx->cwc_buf) + b_pos) = *unit_ptr(hdr + cnt);
            cnt += BUF_INC; b_pos += BUF_INC;
        }

        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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -