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

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)
        !            69: #pragma optimize( "s", on )
        !            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)
        !           190: #pragma optimize( "t", on )
        !           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.