00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "aesopt.h"
00046
00047 #if defined(__cplusplus)
00048 extern "C"
00049 {
00050 #endif
00051
00052 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
00053 #define so(y,x,c) word_out(y, c, s(x,c))
00054
00055 #if defined(ARRAYS)
00056 #define locals(y,x) x[4],y[4]
00057 #else
00058 #define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
00059 #endif
00060
00061 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
00062 s(y,2) = s(x,2); s(y,3) = s(x,3);
00063 #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)
00064 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
00065 #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)
00066
00067 #if defined(ENCRYPTION) && !defined(AES_ASM)
00068
00069
00070
00071
00072
00073
00074 #if defined(_MSC_VER)
00075 #pragma optimize( "s", on )
00076 #endif
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 #define fwd_var(x,r,c)\
00090 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
00091 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
00092 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
00093 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
00094
00095 #if defined(FT4_SET)
00096 #undef dec_fmvars
00097 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
00098 #elif defined(FT1_SET)
00099 #undef dec_fmvars
00100 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
00101 #else
00102 #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)))
00103 #endif
00104
00105 #if defined(FL4_SET)
00106 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
00107 #elif defined(FL1_SET)
00108 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
00109 #else
00110 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
00111 #endif
00112
00113 aes_rval aes_encrypt(const void *in_blk, void *out_blk, const aes_encrypt_ctx cx[1])
00114 { aes_32t locals(b0, b1);
00115 const aes_32t *kp = cx->ks;
00116 #ifdef dec_fmvars
00117 dec_fmvars;
00118 #endif
00119
00120 aes_32t nr = (kp[45] ^ kp[52] ^ kp[53] ? kp[52] : 14);
00121
00122 #ifdef AES_ERR_CHK
00123 if( (nr != 10 || !(kp[0] | kp[3] | kp[4]))
00124 && (nr != 12 || !(kp[0] | kp[5] | kp[6]))
00125 && (nr != 14 || !(kp[0] | kp[7] | kp[8])) )
00126 return aes_error;
00127 #endif
00128
00129 state_in(b0, in_blk, kp);
00130
00131 #if (ENC_UNROLL == FULL)
00132
00133 switch(nr)
00134 {
00135 case 14:
00136 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
00137 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
00138 kp += 2 * N_COLS;
00139 case 12:
00140 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
00141 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
00142 kp += 2 * N_COLS;
00143 case 10:
00144 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
00145 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
00146 round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
00147 round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
00148 round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
00149 round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
00150 round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
00151 round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
00152 round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
00153 round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
00154 }
00155
00156 #else
00157
00158 #if (ENC_UNROLL == PARTIAL)
00159 { aes_32t rnd;
00160 for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd)
00161 {
00162 kp += N_COLS;
00163 round(fwd_rnd, b1, b0, kp);
00164 kp += N_COLS;
00165 round(fwd_rnd, b0, b1, kp);
00166 }
00167 kp += N_COLS;
00168 round(fwd_rnd, b1, b0, kp);
00169 #else
00170 { aes_32t rnd;
00171 for(rnd = 0; rnd < nr - 1; ++rnd)
00172 {
00173 kp += N_COLS;
00174 round(fwd_rnd, b1, b0, kp);
00175 l_copy(b0, b1);
00176 }
00177 #endif
00178 kp += N_COLS;
00179 round(fwd_lrnd, b0, b1, kp);
00180 }
00181 #endif
00182
00183 state_out(out_blk, b0);
00184 #ifdef AES_ERR_CHK
00185 return aes_good;
00186 #endif
00187 }
00188
00189 #endif
00190
00191 #if defined(DECRYPTION) && !defined(AES_ASM)
00192
00193
00194
00195
00196
00197
00198 #if defined(_MSC_VER)
00199 #pragma optimize( "t", on )
00200 #endif
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 #define inv_var(x,r,c)\
00214 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
00215 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
00216 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
00217 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
00218
00219 #if defined(IT4_SET)
00220 #undef dec_imvars
00221 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
00222 #elif defined(IT1_SET)
00223 #undef dec_imvars
00224 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
00225 #else
00226 #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)))
00227 #endif
00228
00229 #if defined(IL4_SET)
00230 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
00231 #elif defined(IL1_SET)
00232 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
00233 #else
00234 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
00235 #endif
00236
00237 aes_rval aes_decrypt(const void *in_blk, void *out_blk, const aes_decrypt_ctx cx[1])
00238 { aes_32t locals(b0, b1);
00239 #ifdef dec_imvars
00240 dec_imvars;
00241 #endif
00242
00243 aes_32t nr = (cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] ? cx->ks[52] : 14);
00244 const aes_32t *kp = cx->ks + nr * N_COLS;
00245
00246 #ifdef AES_ERR_CHK
00247 if( (nr != 10 || !(cx->ks[0] | cx->ks[3] | cx->ks[4]))
00248 && (nr != 12 || !(cx->ks[0] | cx->ks[5] | cx->ks[6]))
00249 && (nr != 14 || !(cx->ks[0] | cx->ks[7] | cx->ks[8])) )
00250 return aes_error;
00251 #endif
00252
00253 state_in(b0, in_blk, kp);
00254
00255 #if (DEC_UNROLL == FULL)
00256
00257 switch(nr)
00258 {
00259 case 14:
00260 round(inv_rnd, b1, b0, kp - 1 * N_COLS);
00261 round(inv_rnd, b0, b1, kp - 2 * N_COLS);
00262 kp -= 2 * N_COLS;
00263 case 12:
00264 round(inv_rnd, b1, b0, kp - 1 * N_COLS);
00265 round(inv_rnd, b0, b1, kp - 2 * N_COLS);
00266 kp -= 2 * N_COLS;
00267 case 10:
00268 round(inv_rnd, b1, b0, kp - 1 * N_COLS);
00269 round(inv_rnd, b0, b1, kp - 2 * N_COLS);
00270 round(inv_rnd, b1, b0, kp - 3 * N_COLS);
00271 round(inv_rnd, b0, b1, kp - 4 * N_COLS);
00272 round(inv_rnd, b1, b0, kp - 5 * N_COLS);
00273 round(inv_rnd, b0, b1, kp - 6 * N_COLS);
00274 round(inv_rnd, b1, b0, kp - 7 * N_COLS);
00275 round(inv_rnd, b0, b1, kp - 8 * N_COLS);
00276 round(inv_rnd, b1, b0, kp - 9 * N_COLS);
00277 round(inv_lrnd, b0, b1, kp - 10 * N_COLS);
00278 }
00279
00280 #else
00281
00282 #if (DEC_UNROLL == PARTIAL)
00283 { aes_32t rnd;
00284 for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd)
00285 {
00286 kp -= N_COLS;
00287 round(inv_rnd, b1, b0, kp);
00288 kp -= N_COLS;
00289 round(inv_rnd, b0, b1, kp);
00290 }
00291 kp -= N_COLS;
00292 round(inv_rnd, b1, b0, kp);
00293 #else
00294 { aes_32t rnd;
00295 for(rnd = 0; rnd < nr - 1; ++rnd)
00296 {
00297 kp -= N_COLS;
00298 round(inv_rnd, b1, b0, kp);
00299 l_copy(b0, b1);
00300 }
00301 #endif
00302 kp -= N_COLS;
00303 round(inv_lrnd, b0, b1, kp);
00304 }
00305 #endif
00306
00307 state_out(out_blk, b0);
00308 #ifdef AES_ERR_CHK
00309 return aes_good;
00310 #endif
00311 }
00312
00313 #endif
00314
00315 #if defined(__cplusplus)
00316 }
00317 #endif