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

📄 eax.c

📁 加密认证联合模式的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 ---------------------------------------------------------------------------
 Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.

 LICENSE TERMS

 The free distribution and use of this software in both source and binary
 form is allowed (with or without changes) provided that:

   1. distributions of this source code include the above copyright
      notice, this list of conditions and the following disclaimer;

   2. distributions in binary form include the above copyright
      notice, this list of conditions and the following disclaimer
      in the documentation and/or other associated materials;

   3. the copyright holder's name is not used to endorse products
      built using this software without specific written permission.

 ALTERNATIVELY, provided that this notice is retained in full, this product
 may be distributed under the terms of the GNU General Public License (GPL),
 in which case the provisions of the GPL apply INSTEAD OF those given above.

 DISCLAIMER

 This software is provided 'as is' with no explicit or implied warranties
 in respect of its properties, including, but not limited to, correctness
 and/or fitness for purpose.
 ---------------------------------------------------------------------------
 Issue Date: 13/06/2006

 This code implements the EAX combined encryption and authentication mode
 specified M. Bellare, P. Rogaway and D. Wagner.

 This is a byte oriented version in which the nonce is of limited length
*/

#include "eax.h"
#include "mode_hdr.h"

#if defined(__cplusplus)
extern "C"
{
#endif

#define BLOCK_SIZE      AES_BLOCK_SIZE      /* block length                 */
#define BLK_ADR_MASK    (BLOCK_SIZE - 1)    /* mask for 'in block' address  */

#define inc_ctr(x)  \
    {   int i = BLOCK_SIZE; while(i-- > 0 && !++(ui8_ptr(x)[i])) ; }

ret_type eax_init_and_key(                       /* initialise mode and set key */
            const unsigned char key[],          /* the key value                */
            unsigned long key_len,              /* and its length in bytes      */
            eax_ctx ctx[1])                     /* the mode context             */
{   static uint_8t x_t[4] = { 0x00, 0x87, 0x0e, 0x87 ^ 0x0e };
    uint_8t t, *p;
    uint_32t i;

    /* set the context to all zeroes            */
    memset(ctx, 0, sizeof(eax_ctx));

    /* set the AES key                          */
    aes_encrypt_key(key, key_len, ctx->aes);

    /* compute E(0) (needed for the pad values) */
    aes_encrypt(ui8_ptr(ctx->pad_xvv), ui8_ptr(ctx->pad_xvv), ctx->aes);

    /* compute {02} * {E(0)} and {04} * {E(0)}  */
    /* GF(2^128) mod x^128 + x^7 + x^2 + x + 1  */
    for(i = 0, p = ui8_ptr(ctx->pad_xvv), t = *p >> 6; i < EAX_BLOCK_SIZE - 1; ++i, ++p)
    {
        *(p + 16) = (*p << 2) | (*(p + 1) >> 6);
        *p = (*p << 1) | (*(p + 1) >> 7);
    }
    *(p + 16) = (*p << 2) ^ x_t[t];
    *(p + 15) ^= (t >>= 1);
    *p = (*p << 1) ^ x_t[t];

    return RETURN_OK;
}

ret_type eax_init_message(                      /* initialise a new message     */
            const unsigned char iv[],           /* the initialisation vector    */
            unsigned long iv_len,               /* and its length in bytes      */
            eax_ctx ctx[1])                     /* the mode context             */
{   uint_32t i = 0, n_pos = 0;
    uint_8t *p;

    memset(ctx->nce_cbc, 0, EAX_BLOCK_SIZE);
    memset(ctx->hdr_cbc, 0, EAX_BLOCK_SIZE);
    memset(ctx->txt_cbc, 0, EAX_BLOCK_SIZE);

    /* set the header CBC start value           */
    ui8_ptr(ctx->hdr_cbc)[EAX_BLOCK_SIZE - 1] = 1;
    ctx->hdr_cnt = 16;

    /* set the ciphertext CBC start value       */
    ui8_ptr(ctx->txt_cbc)[EAX_BLOCK_SIZE - 1] = 2;
    ctx->txt_ccnt = 16; /* encryption count     */
    ctx->txt_acnt = 16; /* authentication count */

    /* if the nonce length is zero, the OMAC    */
    /* message is a block of zeroes which gives */
    /* the pre-encrypted tag as the Lu value    */
    if(iv_len)
    {
        n_pos = 16;

        /* compile the OMAC value for the nonce     */
        i = 0;
        while(i < iv_len)
        {
            if(n_pos == EAX_BLOCK_SIZE)
            {
                aes_encrypt(ui8_ptr(ctx->nce_cbc), ui8_ptr(ctx->nce_cbc), ctx->aes);
                n_pos = 0;
            }
            ui8_ptr(ctx->nce_cbc)[n_pos++] ^= iv[i++];
        }

        /* do the OMAC padding for the nonce        */
        p = ui8_ptr(ctx->pad_xvv);
        if(n_pos < EAX_BLOCK_SIZE)
        {
            ui8_ptr(ctx->nce_cbc)[n_pos] ^= 0x80; p += 16;
        }

        for(i = 0; i < EAX_BLOCK_SIZE; ++i)
            ui8_ptr(ctx->nce_cbc)[i] ^= p[i];
    }
    else
        memcpy(ctx->nce_cbc, ctx->pad_xvv, EAX_BLOCK_SIZE);

    /* compute the OMAC*(nonce) value           */
    aes_encrypt(ui8_ptr(ctx->nce_cbc), ui8_ptr(ctx->nce_cbc), ctx->aes);

    /* copy value into counter for CTR          */
    memcpy(ctx->ctr_val, ctx->nce_cbc, EAX_BLOCK_SIZE);
    return RETURN_OK;
}

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

    if(!hdr_len)
        return RETURN_OK;

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

    if(!(b_pos & BUF_ADRMASK) && !((hdr + cnt - ui8_ptr(ctx->hdr_cbc)) & BUF_ADRMASK))
    {
        while(cnt + BUF_INC <= hdr_len && b_pos <= BLOCK_SIZE - BUF_INC)
        {
            *unit_ptr(ui8_ptr(ctx->hdr_cbc) + b_pos) ^= *unit_ptr(hdr + cnt);
            cnt += BUF_INC; b_pos += BUF_INC;
        }
        
        while(cnt + BLOCK_SIZE <= hdr_len)
        {
            aes_encrypt(ui8_ptr(ctx->hdr_cbc), ui8_ptr(ctx->hdr_cbc), ctx->aes);
            xor_block_aligned(ctx->hdr_cbc, hdr + cnt);
            cnt += BLOCK_SIZE;
        }
    }
    else
    {
        while(cnt < hdr_len && b_pos < BLOCK_SIZE)
            ui8_ptr(ctx->hdr_cbc)[b_pos++] ^= hdr[cnt++];
        
        while(cnt + BLOCK_SIZE <= hdr_len)
        {
            aes_encrypt(ui8_ptr(ctx->hdr_cbc), ui8_ptr(ctx->hdr_cbc), ctx->aes);
            xor_block(ctx->hdr_cbc, hdr + cnt);
            cnt += BLOCK_SIZE;
        }
    }

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

    ctx->hdr_cnt = b_pos;
    return RETURN_OK;
}

ret_type eax_auth_data(                         /* authenticate ciphertext data */
            const 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_acnt;

    if(!data_len)
        return RETURN_OK;

    while(cnt < data_len && (b_pos & BUF_ADRMASK))
       ui8_ptr(ctx->txt_cbc)[b_pos++] ^= data[cnt++];

    if(!(b_pos & BUF_ADRMASK) && !((data + cnt - ui8_ptr(ctx->txt_cbc)) & BUF_ADRMASK))
    {

⌨️ 快捷键说明

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