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