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

1.1       root        1: /*
                      2:  ---------------------------------------------------------------------------
1.1.1.5 ! root        3:  Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
1.1       root        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:  ---------------------------------------------------------------------------
1.1.1.5 ! root       30:  Issue 09/09/2006
1.1       root       31: */
                     32: 
1.1.1.3   root       33: #include "Aesopt.h"
                     34: #include "Aestab.h"
1.1       root       35: 
                     36: #if defined(__cplusplus)
                     37: extern "C"
                     38: {
                     39: #endif
                     40: 
                     41: #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
                     42: #define so(y,x,c)   word_out(y, c, s(x,c))
                     43: 
                     44: #if defined(ARRAYS)
                     45: #define locals(y,x)     x[4],y[4]
                     46: #else
                     47: #define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
                     48: #endif
                     49: 
                     50: #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
                     51:                         s(y,2) = s(x,2); s(y,3) = s(x,3);
                     52: #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)
                     53: #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
                     54: #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)
                     55: 
1.1.1.5 ! root       56: #if ( FUNCS_IN_C & ENCRYPTION_IN_C )
1.1       root       57: 
                     58: /* Visual C++ .Net v7.1 provides the fastest encryption code when using
                     59:    Pentium optimiation with small code but this is poor for decryption
                     60:    so we need to control this with the following VC++ pragmas
                     61: */
                     62: 
1.1.1.5 ! root       63: #if defined( _MSC_VER ) && !defined( _WIN64 )
1.1.1.4   root       64: #pragma optimize( "s", on )
1.1       root       65: #endif
                     66: 
                     67: /* Given the column (c) of the output state variable, the following
                     68:    macros give the input state variables which are needed in its
                     69:    computation for each row (r) of the state. All the alternative
                     70:    macros give the same end values but expand into different ways
                     71:    of calculating these values.  In particular the complex macro
                     72:    used for dynamically variable block sizes is designed to expand
                     73:    to a compile time constant whenever possible but will expand to
                     74:    conditional clauses on some branches (I am grateful to Frank
                     75:    Yellin for this construction)
                     76: */
                     77: 
                     78: #define fwd_var(x,r,c)\
                     79:  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
                     80:  : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
                     81:  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
                     82:  :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
                     83: 
                     84: #if defined(FT4_SET)
                     85: #undef  dec_fmvars
                     86: #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
                     87: #elif defined(FT1_SET)
                     88: #undef  dec_fmvars
                     89: #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
                     90: #else
                     91: #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)))
                     92: #endif
                     93: 
                     94: #if defined(FL4_SET)
                     95: #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
                     96: #elif defined(FL1_SET)
                     97: #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
                     98: #else
                     99: #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
                    100: #endif
                    101: 
1.1.1.5 ! root      102: AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
1.1.1.4   root      103: {   uint_32t         locals(b0, b1);
                    104:     const uint_32t   *kp;
1.1       root      105: #if defined( dec_fmvars )
                    106:     dec_fmvars; /* declare variables for fwd_mcol() if needed */
                    107: #endif
                    108: 
                    109: #if defined( AES_ERR_CHK )
1.1.1.4   root      110:     if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
                    111:         return EXIT_FAILURE;
1.1       root      112: #endif
                    113: 
1.1.1.4   root      114:     kp = cx->ks;
1.1       root      115:     state_in(b0, in, kp);
                    116: 
                    117: #if (ENC_UNROLL == FULL)
                    118: 
1.1.1.4   root      119:     switch(cx->inf.b[0])
1.1       root      120:     {
1.1.1.4   root      121:     case 14 * 16:
1.1       root      122:         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
                    123:         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
                    124:         kp += 2 * N_COLS;
1.1.1.4   root      125:     case 12 * 16:
1.1       root      126:         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
                    127:         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
                    128:         kp += 2 * N_COLS;
1.1.1.4   root      129:     case 10 * 16:
1.1       root      130:         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
                    131:         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
                    132:         round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
                    133:         round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
                    134:         round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
                    135:         round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
                    136:         round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
                    137:         round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
                    138:         round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
                    139:         round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
                    140:     }
                    141: 
                    142: #else
                    143: 
                    144: #if (ENC_UNROLL == PARTIAL)
1.1.1.4   root      145:     {   uint_32t    rnd;
                    146:         for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
1.1       root      147:         {
                    148:             kp += N_COLS;
                    149:             round(fwd_rnd, b1, b0, kp);
                    150:             kp += N_COLS;
                    151:             round(fwd_rnd, b0, b1, kp);
                    152:         }
                    153:         kp += N_COLS;
                    154:         round(fwd_rnd,  b1, b0, kp);
                    155: #else
1.1.1.4   root      156:     {   uint_32t    rnd;
                    157:         for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
1.1       root      158:         {
                    159:             kp += N_COLS;
                    160:             round(fwd_rnd, b1, b0, kp);
                    161:             l_copy(b0, b1);
                    162:         }
                    163: #endif
                    164:         kp += N_COLS;
                    165:         round(fwd_lrnd, b0, b1, kp);
                    166:     }
                    167: #endif
                    168: 
                    169:     state_out(out, b0);
1.1.1.4   root      170: 
1.1       root      171: #if defined( AES_ERR_CHK )
1.1.1.4   root      172:     return EXIT_SUCCESS;
1.1       root      173: #endif
                    174: }
                    175: 
                    176: #endif
                    177: 
1.1.1.4   root      178: #if ( FUNCS_IN_C & DECRYPTION_IN_C)
1.1       root      179: 
                    180: /* Visual C++ .Net v7.1 provides the fastest encryption code when using
                    181:    Pentium optimiation with small code but this is poor for decryption
                    182:    so we need to control this with the following VC++ pragmas
                    183: */
                    184: 
1.1.1.5 ! root      185: #if defined( _MSC_VER ) && !defined( _WIN64 )
1.1.1.4   root      186: #pragma optimize( "t", on )
1.1       root      187: #endif
                    188: 
                    189: /* Given the column (c) of the output state variable, the following
                    190:    macros give the input state variables which are needed in its
                    191:    computation for each row (r) of the state. All the alternative
                    192:    macros give the same end values but expand into different ways
                    193:    of calculating these values.  In particular the complex macro
                    194:    used for dynamically variable block sizes is designed to expand
                    195:    to a compile time constant whenever possible but will expand to
                    196:    conditional clauses on some branches (I am grateful to Frank
                    197:    Yellin for this construction)
                    198: */
                    199: 
                    200: #define inv_var(x,r,c)\
                    201:  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
                    202:  : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
                    203:  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
                    204:  :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
                    205: 
                    206: #if defined(IT4_SET)
                    207: #undef  dec_imvars
                    208: #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
                    209: #elif defined(IT1_SET)
                    210: #undef  dec_imvars
                    211: #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
                    212: #else
                    213: #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)))
                    214: #endif
                    215: 
                    216: #if defined(IL4_SET)
                    217: #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
                    218: #elif defined(IL1_SET)
                    219: #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
                    220: #else
                    221: #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
                    222: #endif
                    223: 
1.1.1.4   root      224: /* This code can work with the decryption key schedule in the   */
                    225: /* order that is used for encrytpion (where the 1st decryption  */
                    226: /* round key is at the high end ot the schedule) or with a key  */
                    227: /* schedule that has been reversed to put the 1st decryption    */
                    228: /* round key at the low end of the schedule in memory (when     */
                    229: /* AES_REV_DKS is defined)                                      */
                    230: 
                    231: #ifdef AES_REV_DKS
                    232: #define key_ofs     0
                    233: #define rnd_key(n)  (kp + n * N_COLS)
                    234: #else
                    235: #define key_ofs     1
                    236: #define rnd_key(n)  (kp - n * N_COLS)
                    237: #endif
                    238: 
1.1.1.5 ! root      239: AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
1.1.1.4   root      240: {   uint_32t        locals(b0, b1);
1.1       root      241: #if defined( dec_imvars )
                    242:     dec_imvars; /* declare variables for inv_mcol() if needed */
                    243: #endif
1.1.1.4   root      244:     const uint_32t *kp;
1.1       root      245: 
                    246: #if defined( AES_ERR_CHK )
1.1.1.4   root      247:     if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
                    248:         return EXIT_FAILURE;
1.1       root      249: #endif
                    250: 
1.1.1.4   root      251:     kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
1.1       root      252:     state_in(b0, in, kp);
                    253: 
                    254: #if (DEC_UNROLL == FULL)
                    255: 
1.1.1.4   root      256:     kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
                    257:     switch(cx->inf.b[0])
1.1       root      258:     {
1.1.1.4   root      259:     case 14 * 16:
                    260:         round(inv_rnd,  b1, b0, rnd_key(-13));
                    261:         round(inv_rnd,  b0, b1, rnd_key(-12));
                    262:     case 12 * 16:
                    263:         round(inv_rnd,  b1, b0, rnd_key(-11));
                    264:         round(inv_rnd,  b0, b1, rnd_key(-10));
                    265:     case 10 * 16:
                    266:         round(inv_rnd,  b1, b0, rnd_key(-9));
                    267:         round(inv_rnd,  b0, b1, rnd_key(-8));
                    268:         round(inv_rnd,  b1, b0, rnd_key(-7));
                    269:         round(inv_rnd,  b0, b1, rnd_key(-6));
                    270:         round(inv_rnd,  b1, b0, rnd_key(-5));
                    271:         round(inv_rnd,  b0, b1, rnd_key(-4));
                    272:         round(inv_rnd,  b1, b0, rnd_key(-3));
                    273:         round(inv_rnd,  b0, b1, rnd_key(-2));
                    274:         round(inv_rnd,  b1, b0, rnd_key(-1));
                    275:         round(inv_lrnd, b0, b1, rnd_key( 0));
1.1       root      276:     }
                    277: 
                    278: #else
                    279: 
                    280: #if (DEC_UNROLL == PARTIAL)
1.1.1.4   root      281:     {   uint_32t    rnd;
                    282:         for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
1.1       root      283:         {
1.1.1.4   root      284:             kp = rnd_key(1);
1.1       root      285:             round(inv_rnd, b1, b0, kp);
1.1.1.4   root      286:             kp = rnd_key(1);
1.1       root      287:             round(inv_rnd, b0, b1, kp);
                    288:         }
1.1.1.4   root      289:         kp = rnd_key(1);
1.1       root      290:         round(inv_rnd, b1, b0, kp);
                    291: #else
1.1.1.4   root      292:     {   uint_32t    rnd;
                    293:         for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
1.1       root      294:         {
1.1.1.4   root      295:             kp = rnd_key(1);
1.1       root      296:             round(inv_rnd, b1, b0, kp);
                    297:             l_copy(b0, b1);
                    298:         }
                    299: #endif
1.1.1.4   root      300:         kp = rnd_key(1);
1.1       root      301:         round(inv_lrnd, b0, b1, kp);
1.1.1.4   root      302:         }
1.1       root      303: #endif
                    304: 
                    305:     state_out(out, b0);
1.1.1.4   root      306: 
1.1       root      307: #if defined( AES_ERR_CHK )
1.1.1.4   root      308:     return EXIT_SUCCESS;
1.1       root      309: #endif
                    310: }
                    311: 
                    312: #endif
                    313: 
                    314: #if defined(__cplusplus)
                    315: }
                    316: #endif

unix.superglobalmegacorp.com

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