Annotation of truecrypt/crypto/aescrypt.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  ---------------------------------------------------------------------------
                      3:  Copyright (c) 2003, Dr Brian Gladman, Worcester, UK.   All rights reserved.
                      4: 
                      5:  LICENSE TERMS
                      6: 
                      7:  The free distribution and use of this software in both source and binary
                      8:  form is allowed (with or without changes) provided that:
                      9: 
                     10:    1. distributions of this source code include the above copyright
                     11:       notice, this list of conditions and the following disclaimer;
                     12: 
                     13:    2. distributions in binary form include the above copyright
                     14:       notice, this list of conditions and the following disclaimer
                     15:       in the documentation and/or other associated materials;
                     16: 
                     17:    3. the copyright holder's name is not used to endorse products
                     18:       built using this software without specific written permission.
                     19: 
                     20:  ALTERNATIVELY, provided that this notice is retained in full, this product
                     21:  may be distributed under the terms of the GNU General Public License (GPL),
                     22:  in which case the provisions of the GPL apply INSTEAD OF those given above.
                     23: 
                     24:  DISCLAIMER
                     25: 
                     26:  This software is provided 'as is' with no explicit or implied warranties
                     27:  in respect of its properties, including, but not limited to, correctness
                     28:  and/or fitness for purpose.
                     29:  ---------------------------------------------------------------------------
                     30:  Issue 28/01/2004
                     31: 
                     32:  This file contains the code for implementing encryption and decryption
                     33:  for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
                     34:  can optionally be replaced by code written in assembler using NASM. For
                     35:  further details see the file aesopt.h
                     36: */
                     37: 
                     38: #include "aesopt.h"
                     39: #include "aestab.h"
                     40: 
                     41: #if defined(__cplusplus)
                     42: extern "C"
                     43: {
                     44: #endif
                     45: 
                     46: #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
                     47: #define so(y,x,c)   word_out(y, c, s(x,c))
                     48: 
                     49: #if defined(ARRAYS)
                     50: #define locals(y,x)     x[4],y[4]
                     51: #else
                     52: #define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
                     53: #endif
                     54: 
                     55: #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
                     56:                         s(y,2) = s(x,2); s(y,3) = s(x,3);
                     57: #define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
                     58: #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
                     59: #define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
                     60: 
                     61: #if defined(ENCRYPTION) && !defined(AES_ASM)
                     62: 
                     63: /* Visual C++ .Net v7.1 provides the fastest encryption code when using
                     64:    Pentium optimiation with small code but this is poor for decryption
                     65:    so we need to control this with the following VC++ pragmas
                     66: */
                     67: 
                     68: #if defined(_MSC_VER)
1.1.1.2 ! root       69: //#pragma optimize( "s", on )
1.1       root       70: #endif
                     71: 
                     72: /* Given the column (c) of the output state variable, the following
                     73:    macros give the input state variables which are needed in its
                     74:    computation for each row (r) of the state. All the alternative
                     75:    macros give the same end values but expand into different ways
                     76:    of calculating these values.  In particular the complex macro
                     77:    used for dynamically variable block sizes is designed to expand
                     78:    to a compile time constant whenever possible but will expand to
                     79:    conditional clauses on some branches (I am grateful to Frank
                     80:    Yellin for this construction)
                     81: */
                     82: 
                     83: #define fwd_var(x,r,c)\
                     84:  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
                     85:  : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
                     86:  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
                     87:  :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
                     88: 
                     89: #if defined(FT4_SET)
                     90: #undef  dec_fmvars
                     91: #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
                     92: #elif defined(FT1_SET)
                     93: #undef  dec_fmvars
                     94: #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
                     95: #else
                     96: #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
                     97: #endif
                     98: 
                     99: #if defined(FL4_SET)
                    100: #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
                    101: #elif defined(FL1_SET)
                    102: #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
                    103: #else
                    104: #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
                    105: #endif
                    106: 
                    107: aes_rval aes_encrypt(const unsigned char *in,
                    108:                         unsigned char *out, const aes_encrypt_ctx cx[1])
                    109: {   aes_32t         locals(b0, b1);
                    110:     const aes_32t   *kp = cx->ks;
                    111: #if defined( dec_fmvars )
                    112:     dec_fmvars; /* declare variables for fwd_mcol() if needed */
                    113: #endif
                    114: 
                    115: #if defined( AES_ERR_CHK )
                    116:     if( cx->rn != 10 && cx->rn != 12 && cx->rn != 14 )
                    117:         return aes_error;
                    118: #endif
                    119: 
                    120:     state_in(b0, in, kp);
                    121: 
                    122: #if (ENC_UNROLL == FULL)
                    123: 
                    124:     switch(cx->rn)
                    125:     {
                    126:     case 14:
                    127:         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
                    128:         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
                    129:         kp += 2 * N_COLS;
                    130:     case 12:
                    131:         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
                    132:         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
                    133:         kp += 2 * N_COLS;
                    134:     case 10:
                    135:         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
                    136:         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
                    137:         round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
                    138:         round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
                    139:         round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
                    140:         round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
                    141:         round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
                    142:         round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
                    143:         round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
                    144:         round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
                    145:     }
                    146: 
                    147: #else
                    148: 
                    149: #if (ENC_UNROLL == PARTIAL)
                    150:     {   aes_32t    rnd;
                    151:         for(rnd = 0; rnd < (cx->rn >> 1) - 1; ++rnd)
                    152:         {
                    153:             kp += N_COLS;
                    154:             round(fwd_rnd, b1, b0, kp);
                    155:             kp += N_COLS;
                    156:             round(fwd_rnd, b0, b1, kp);
                    157:         }
                    158:         kp += N_COLS;
                    159:         round(fwd_rnd,  b1, b0, kp);
                    160: #else
                    161:     {   aes_32t    rnd;
                    162:         for(rnd = 0; rnd < cx->rn - 1; ++rnd)
                    163:         {
                    164:             kp += N_COLS;
                    165:             round(fwd_rnd, b1, b0, kp);
                    166:             l_copy(b0, b1);
                    167:         }
                    168: #endif
                    169:         kp += N_COLS;
                    170:         round(fwd_lrnd, b0, b1, kp);
                    171:     }
                    172: #endif
                    173: 
                    174:     state_out(out, b0);
                    175: #if defined( AES_ERR_CHK )
                    176:     return aes_good;
                    177: #endif
                    178: }
                    179: 
                    180: #endif
                    181: 
                    182: #if defined(DECRYPTION) && !defined(AES_ASM)
                    183: 
                    184: /* Visual C++ .Net v7.1 provides the fastest encryption code when using
                    185:    Pentium optimiation with small code but this is poor for decryption
                    186:    so we need to control this with the following VC++ pragmas
                    187: */
                    188: 
                    189: #if defined(_MSC_VER)
1.1.1.2 ! root      190: //#pragma optimize( "t", on )
1.1       root      191: #endif
                    192: 
                    193: /* Given the column (c) of the output state variable, the following
                    194:    macros give the input state variables which are needed in its
                    195:    computation for each row (r) of the state. All the alternative
                    196:    macros give the same end values but expand into different ways
                    197:    of calculating these values.  In particular the complex macro
                    198:    used for dynamically variable block sizes is designed to expand
                    199:    to a compile time constant whenever possible but will expand to
                    200:    conditional clauses on some branches (I am grateful to Frank
                    201:    Yellin for this construction)
                    202: */
                    203: 
                    204: #define inv_var(x,r,c)\
                    205:  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
                    206:  : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
                    207:  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
                    208:  :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
                    209: 
                    210: #if defined(IT4_SET)
                    211: #undef  dec_imvars
                    212: #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
                    213: #elif defined(IT1_SET)
                    214: #undef  dec_imvars
                    215: #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
                    216: #else
                    217: #define inv_rnd(y,x,k,c)    (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
                    218: #endif
                    219: 
                    220: #if defined(IL4_SET)
                    221: #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
                    222: #elif defined(IL1_SET)
                    223: #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
                    224: #else
                    225: #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
                    226: #endif
                    227: 
                    228: aes_rval aes_decrypt(const unsigned char *in,
                    229:                         unsigned char *out, const aes_decrypt_ctx cx[1])
                    230: {   aes_32t        locals(b0, b1);
                    231: #if defined( dec_imvars )
                    232:     dec_imvars; /* declare variables for inv_mcol() if needed */
                    233: #endif
                    234:     const aes_32t *kp = cx->ks + cx->rn * N_COLS;
                    235: 
                    236: #if defined( AES_ERR_CHK )
                    237:     if( cx->rn != 10 && cx->rn != 12 && cx->rn != 14 )
                    238:         return aes_error;
                    239: #endif
                    240: 
                    241:     state_in(b0, in, kp);
                    242: 
                    243: #if (DEC_UNROLL == FULL)
                    244: 
                    245:     switch(cx->rn)
                    246:     {
                    247:     case 14:
                    248:         round(inv_rnd,  b1, b0, kp -  1 * N_COLS);
                    249:         round(inv_rnd,  b0, b1, kp -  2 * N_COLS);
                    250:         kp -= 2 * N_COLS;
                    251:     case 12:
                    252:         round(inv_rnd,  b1, b0, kp -  1 * N_COLS);
                    253:         round(inv_rnd,  b0, b1, kp -  2 * N_COLS);
                    254:         kp -= 2 * N_COLS;
                    255:     case 10:
                    256:         round(inv_rnd,  b1, b0, kp -  1 * N_COLS);
                    257:         round(inv_rnd,  b0, b1, kp -  2 * N_COLS);
                    258:         round(inv_rnd,  b1, b0, kp -  3 * N_COLS);
                    259:         round(inv_rnd,  b0, b1, kp -  4 * N_COLS);
                    260:         round(inv_rnd,  b1, b0, kp -  5 * N_COLS);
                    261:         round(inv_rnd,  b0, b1, kp -  6 * N_COLS);
                    262:         round(inv_rnd,  b1, b0, kp -  7 * N_COLS);
                    263:         round(inv_rnd,  b0, b1, kp -  8 * N_COLS);
                    264:         round(inv_rnd,  b1, b0, kp -  9 * N_COLS);
                    265:         round(inv_lrnd, b0, b1, kp - 10 * N_COLS);
                    266:     }
                    267: 
                    268: #else
                    269: 
                    270: #if (DEC_UNROLL == PARTIAL)
                    271:     {   aes_32t    rnd;
                    272:         for(rnd = 0; rnd < (cx->rn >> 1) - 1; ++rnd)
                    273:         {
                    274:             kp -= N_COLS;
                    275:             round(inv_rnd, b1, b0, kp);
                    276:             kp -= N_COLS;
                    277:             round(inv_rnd, b0, b1, kp);
                    278:         }
                    279:         kp -= N_COLS;
                    280:         round(inv_rnd, b1, b0, kp);
                    281: #else
                    282:     {   aes_32t    rnd;
                    283:         for(rnd = 0; rnd < cx->rn - 1; ++rnd)
                    284:         {
                    285:             kp -= N_COLS;
                    286:             round(inv_rnd, b1, b0, kp);
                    287:             l_copy(b0, b1);
                    288:         }
                    289: #endif
                    290:         kp -= N_COLS;
                    291:         round(inv_lrnd, b0, b1, kp);
                    292:     }
                    293: #endif
                    294: 
                    295:     state_out(out, b0);
                    296: #if defined( AES_ERR_CHK )
                    297:     return aes_good;
                    298: #endif
                    299: }
                    300: 
                    301: #endif
                    302: 
                    303: #if defined(__cplusplus)
                    304: }
                    305: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.