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