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

📄 aes.c

📁 加密解密,安全工具!很有意思的代码
💻 C
📖 第 1 页 / 共 3 页
字号:

// I retain copyright in this code but I encourage its free use provided
// that I don't carry any responsibility for the results. I am especially 
// happy to see it used in free and open source software. If you do use 
// it I would appreciate an acknowledgement of its origin in the code or
// the product that results and I would also appreciate knowing a liitle
// about the use to which it is being put.
//
// Dr B. R. Gladman <brg@gladman.uk.net> 23rd January 2001.

// This is an implementation of the AES encryption algorithm (Rijndael)
// designed by Joan Daemen and Vincent Rijmen. This version is designed
// to provide both fixed and dynamic block and key lengths and can also 
// run with either big or little endian internal byte order (see aes.h). 
// It inputs block and key lengths in bytes with the legal values being 
// 16, 24 and 32.

// CONFIGURATION OPTIONS (see also aes.h)
// 1. define COMPACT for a compact but slow version of the cipher (the 
//    other options below do not apply to the compact version)
// 2. define UNROLL for loop unrolling in encrypt and decrypt
// 3. define FIXED_TABLES for static tables built within the executable
//    image - otherwise tables are built dynamically on first use
// 4. define FOUR_TABLES for high speed but increased memory use (uses four
//    tables in place of one to reduce inner loop instruction counts)
// 5. define LAST_ROUND_TABLES for ultimate speed but still more memory use
//    (this uses tables for the last round)
// 6. define SMALL_PTABLE for slower field multiply but smaller table

//#define COMPACT
#define UNROLL
#define FIXED_TABLES
#define FOUR_TABLES
#define LAST_ROUND_TABLES
//#define SMALL_PTABLE

// End of configuration options

#include "aes.h"

#if !defined(AES_DLL) || !defined(TEST)

// the finite field modular polynomial and elements

    #define ff_poly 0x011b
    #define ff_hi   0x80
    #define ff_02   0x02
    #define ff_03   0x03
    #define ff_09   0x09
    #define ff_0b   0x0b
    #define ff_0d   0x0d
    #define ff_0e   0x0e

// finite field multiply of a and b

    #if defined(SMALL_PTABLE)
        #define FFmul(a, b) (a && b ? \
        FFpow[(u = FFlog[a], v = FFlog[b] + u, v + (v < u ? 1 : 0))] : 0)
    #else
        #define FFmul(a, b) (a && b ? FFpow[FFlog[a] + FFlog[b]] : 0)
    #endif

// multiply four bytes in GF(2^8) by 'x' {02} in parallel

    #define m1  0x80808080
    #define m2  0x7f7f7f7f
    #define m3  0x1b1b1b1b
    #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m3)

// perform column mix operation on four bytes in parallel

    #define mix_col(x) (f2 = FFmulX(x), f2 ^ rot3(x ^ f2) ^ rot2(x) ^ rot1(x))

// perform inverse column mix operation on four bytes in parallel

    #define inv_mix_col(x) (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, f2 ^ f4 ^ f8 ^ rot3(f2 ^ f9) ^ rot2(f4 ^ f9) ^ rot1(f9))

    #if defined(FIXED_TABLES) || defined(COMPACT)

        #include "aes_tab.h"

    #else

        #if defined(SMALL_PTABLE)
static byte  FFpow[256];        // powers of generator (0x03) in GF(2^8)
        #else
static byte  FFpow[512];
        #endif
static byte  FFlog[256];        // log: map element to power of generator

static byte  s_box[256];        // the S box
static byte  inv_s_box[256];    // the inverse S box
static word  rcon_tab[30];      // table of round constants (can be reduced
                                // to a length of 10 for 128-bit blocks)
        #if defined(FOUR_TABLES)
static word  ft_tab[4][256];
static word  it_tab[4][256];
        #else
static word  ft_tab[256];
static word  it_tab[256];
        #endif

        #if defined(LAST_ROUND_TABLES)
            #if defined(FOUR_TABLES)
static word  fl_tab[4][256];
static word  il_tab[4][256];
            #else
static word  fl_tab[256];
static word  il_tab[256];
            #endif
        #endif

static void gen_tabs(void)
{
    word  i, w;
    byte  b;
#if defined(SMALL_PTABLE)
    byte  u, v;
#endif


    // log and power tables for GF(2^8) finite field with
    // 0x011b as modular polynomial - the simplest primitive
    // root is 0x03, used here to generate the tables

    i = 0; w = 1; 
    do
    {
        FFpow[i] = (byte)w;
#if !defined(SMALL_PTABLE)
        FFpow[i + 255] = (byte)w;
#endif
        FFlog[w] = (byte)i++;
        w ^=  (w << 1) ^ (w & ff_hi ? ff_poly : 0);
    }
    while ( w != 1 );

    FFpow[255] = 1;

    for ( i = 0, w = 1; i < 28; ++i )
    {
        rcon_tab[i] = bytes2word(w, 0, 0, 0);
        w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
    }

    for ( i = w = 0; i < 256; ++i )
    {
        w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
        w ^= 0x63 ^ (w >> 8);
        s_box[i] = (byte)w;
        inv_s_box[(byte)w] = (byte)i;
        w = FFpow[255 - FFlog[i + 1]];
    }

    for ( i = 0; i < 256; ++i )
    {
        b = s_box[i];
#if defined(LAST_ROUND_TABLES)
        w = bytes2word(b, 0, 0, 0);
#if defined(FOUR_TABLES)
        fl_tab[0][i] = w;
        fl_tab[1][i] = rot1(w);
        fl_tab[2][i] = rot2(w);
        fl_tab[3][i] = rot3(w);
#else
        fl_tab[i] = w;
#endif
#endif
        w = bytes2word(FFmul(ff_02, b), b, b, FFmul(ff_03, b));
#if defined(FOUR_TABLES)
        ft_tab[0][i] = w;
        ft_tab[1][i] = rot1(w);
        ft_tab[2][i] = rot2(w);
        ft_tab[3][i] = rot3(w);
#else
        ft_tab[i] = w;
#endif
        b = inv_s_box[i];
#if defined(LAST_ROUND_TABLES)
        w = bytes2word(b, 0, 0, 0);
#if defined(FOUR_TABLES)
        il_tab[0][i] = w;
        il_tab[1][i] = rot1(w);
        il_tab[2][i] = rot2(w);
        il_tab[3][i] = rot3(w);
#else
        il_tab[i] = w;
#endif
#endif
        w = bytes2word(FFmul(ff_0e, b), FFmul(ff_09, b),
                       FFmul(ff_0d, b), FFmul(ff_0b, b));
#if defined(FOUR_TABLES)
        it_tab[0][i] = w;
        it_tab[1][i] = rot1(w);
        it_tab[2][i] = rot2(w);
        it_tab[3][i] = rot3(w);
#else
        it_tab[i] = w;
#endif
    }
}

    #endif  // !FIXED_TABLES && !COMPACT

    #if defined(COMPACT) || !defined(LAST_ROUND_TABLES)

        #define ls_box(x) bytes2word(           \
    s_box[byte0(x)], s_box[byte1(x)],   \
    s_box[byte2(x)], s_box[byte3(x)])

    #elif defined(FOUR_TABLES)

        #define ls_box(x) (  fl_tab[0][byte0(x)] ^ fl_tab[1][byte1(x)] ^ fl_tab[2][byte2(x)] ^ fl_tab[3][byte3(x)] )

    #else

        #define ls_box(x)           \
 (  fl_tab[byte0(x)]        \
  ^ rot1(fl_tab[byte1(x)])  \
  ^ rot2(fl_tab[byte2(x)])  \
  ^ rot3(fl_tab[byte3(x)]) )

    #endif

// Subroutne to set the block size (if variable) in bytes, legal
// values being 16, 24 and 32.

    #if defined(BLOCK_SIZE_R)
        #define n_col   (Ncol)
        #define fr_sh(n,r)  (((n) + Shr##r) % n_col)
        #define ir_sh(n,r)  (((n) + n_col - Shr##r) % n_col)
    #else
        #define n_col       (f_dat(cx,Ncol))
        #define sh(x)       (f_dat(cx,Shr)[x])
        #define fr_sh(n,r)  (f_dat(cx,shf##r)[n])
        #define ir_sh(n,r)  (f_dat(cx,shr##r)[n])

        #if defined(AES_IN_CPP)
rval aes::set_blk(const word n_bytes)
        #else
cf_dec set_blk(const word n_bytes, aes *cx)     
        #endif
{
    word    i, j;

    if ( n_bytes != 16 && n_bytes != 24 && n_bytes != 32 )

        return(n_bytes ? aes_bad : (rval)n_col);

#if !defined(FIXED_TABLES)
    if ( !(f_dat(cx,mode) & 0x08) )
    {
        gen_tabs(); mode = 0x08;
    }
#endif

    f_dat(cx,mode) |= 0x04;

    n_col = n_bytes >> 2;

    for ( i = 0; i < 8; ++i )
    {
        j = 1;
        f_dat(cx,shf1)[i] = (byte)((i + j) % n_col);
        f_dat(cx,shr1)[i] = (byte)((n_col + i - j) % n_col);
        j = (n_col == 8 ? 3 : 2);
        f_dat(cx,shf2)[i] = (byte)((i + j) % n_col);
        f_dat(cx,shr2)[i] = (byte)((n_col + i - j) % n_col);
        ++j;
        f_dat(cx,shf3)[i] = (byte)((i + j) % n_col);
        f_dat(cx,shr3)[i] = (byte)((n_col + i - j) % n_col);
    }

    return aes_good;
}
    #endif

// Initialise the key schedule from the user supplied key. The key
// length is now specified in bytes - 16, 24 or 32 as appropriate.
// This corresponds to bit lengths of 128, 192 and 256 bits, and
// to Nk values of 4, 6 and 8 respectively.

    #define mx(t,f)     *t++ = inv_mix_col(*f++);

    #if !defined(BLOCK_SIZE_R)

        #define cpy(t,f)                        \
switch(n_col)                           \
{   case 8: *t++ = *f++; *t++ = *f++;   \
    case 6: *t++ = *f++; *t++ = *f++;   \
    case 4: *t++ = *f++; *t++ = *f++;   \
            *t++ = *f++; *t++ = *f++;   \
}

        #define mix(t,f)                \
switch(n_col)                   \
{   case 8: mx(t,f); mx(t,f);   \
    case 6: mx(t,f); mx(t,f);   \
    case 4: mx(t,f); mx(t,f);   \
            mx(t,f); mx(t,f);   \
}

    #elif   BLOCK_SIZE_R == 16
        #define cpy(t,f)    *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++
        #define mix(t,f)    {   mx(t,f); mx(t,f); mx(t,f); mx(t,f); }
    #elif BLOCK_SIZE_R == 24
        #define cpy(t,f)    *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; \
                    *t++ = *f++; *t++ = *f++
        #define mix(t,f)    {   mx(t,f); mx(t,f); mx(t,f); mx(t,f); \
                        mx(t,f); mx(t,f); }
    #elif BLOCK_SIZE_R == 32
        #define cpy(t,f)    *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; \
                    *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++
        #define mix(t,f)    {   mx(t,f); mx(t,f); mx(t,f); mx(t,f); \
                        mx(t,f); mx(t,f); mx(t,f); mx(t,f); }
    #endif

    #if defined(AES_IN_CPP)
rval aes::set_key(const byte in_key[], const word n_bytes, const enum aes_key f)
    #else
cf_dec set_key(const byte in_key[], const word n_bytes, const enum aes_key f, aes *cx)
    #endif
{
    word    t, *k1, *kt, *rcp;

    if ( n_bytes != 16 && n_bytes != 24 && n_bytes != 32 ) return aes_bad;

#if !defined(FIXED_TABLES)
    if ( !(f_dat(cx,mode) & 0x08) )
    {

⌨️ 快捷键说明

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