"Fossies" - the Fresh Open Source Software Archive

Member "src/Crypto/Aescrypt.c" (10 Oct 2018, 10138 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Aescrypt.c" see the Fossies "Dox" file reference documentation.

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