Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | /* |
2 | * FIPS-197 compliant AES implementation |
||
3 | * |
||
4 | * Copyright (C) 2006-2007 Christophe Devine |
||
5 | * |
||
6 | * Redistribution and use in source and binary forms, with or without |
||
7 | * modification, are permitted provided that the following conditions |
||
8 | * are met: |
||
9 | * |
||
10 | * * Redistributions of source code _must_ retain the above copyright |
||
11 | * notice, this list of conditions and the following disclaimer. |
||
12 | * * Redistributions in binary form may or may not reproduce the above |
||
13 | * copyright notice, this list of conditions and the following |
||
14 | * disclaimer in the documentation and/or other materials provided |
||
15 | * with the distribution. |
||
16 | * * Neither the name of XySSL nor the names of its contributors may be |
||
17 | * used to endorse or promote products derived from this software |
||
18 | * without specific prior written permission. |
||
19 | * |
||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
||
23 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
||
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
31 | */ |
||
32 | /* |
||
33 | * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. |
||
34 | * |
||
35 | * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf |
||
36 | * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf |
||
37 | */ |
||
38 | |||
39 | #include "fitz.h" |
||
40 | |||
41 | #define aes_context fz_aes |
||
42 | |||
43 | /* AES block cipher implementation from XYSSL */ |
||
44 | |||
45 | /* |
||
46 | * 32-bit integer manipulation macros (little endian) |
||
47 | */ |
||
48 | #ifndef GET_ULONG_LE |
||
49 | #define GET_ULONG_LE(n,b,i) \ |
||
50 | { \ |
||
51 | (n) = ( (unsigned long) (b)[(i)] ) \ |
||
52 | | ( (unsigned long) (b)[(i) + 1] << 8 ) \ |
||
53 | | ( (unsigned long) (b)[(i) + 2] << 16 ) \ |
||
54 | | ( (unsigned long) (b)[(i) + 3] << 24 ); \ |
||
55 | } |
||
56 | #endif |
||
57 | |||
58 | #ifndef PUT_ULONG_LE |
||
59 | #define PUT_ULONG_LE(n,b,i) \ |
||
60 | { \ |
||
61 | (b)[(i) ] = (unsigned char) ( (n) ); \ |
||
62 | (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ |
||
63 | (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ |
||
64 | (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ |
||
65 | } |
||
66 | #endif |
||
67 | |||
68 | /* |
||
69 | * Forward S-box & tables |
||
70 | */ |
||
71 | static unsigned char FSb[256]; |
||
72 | static unsigned long FT0[256]; |
||
73 | static unsigned long FT1[256]; |
||
74 | static unsigned long FT2[256]; |
||
75 | static unsigned long FT3[256]; |
||
76 | |||
77 | /* |
||
78 | * Reverse S-box & tables |
||
79 | */ |
||
80 | static unsigned char RSb[256]; |
||
81 | static unsigned long RT0[256]; |
||
82 | static unsigned long RT1[256]; |
||
83 | static unsigned long RT2[256]; |
||
84 | static unsigned long RT3[256]; |
||
85 | |||
86 | /* |
||
87 | * Round constants |
||
88 | */ |
||
89 | static unsigned long RCON[10]; |
||
90 | |||
91 | /* |
||
92 | * Tables generation code |
||
93 | */ |
||
94 | #define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) |
||
95 | #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) |
||
96 | #define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) |
||
97 | |||
98 | static int aes_init_done = 0; |
||
99 | |||
100 | static void aes_gen_tables( void ) |
||
101 | { |
||
102 | int i, x, y, z; |
||
103 | int pow[256]; |
||
104 | int log[256]; |
||
105 | |||
106 | /* |
||
107 | * compute pow and log tables over GF(2^8) |
||
108 | */ |
||
109 | for( i = 0, x = 1; i < 256; i++ ) |
||
110 | { |
||
111 | pow[i] = x; |
||
112 | log[x] = i; |
||
113 | x = ( x ^ XTIME( x ) ) & 0xFF; |
||
114 | } |
||
115 | |||
116 | /* |
||
117 | * calculate the round constants |
||
118 | */ |
||
119 | for( i = 0, x = 1; i < 10; i++ ) |
||
120 | { |
||
121 | RCON[i] = (unsigned long) x; |
||
122 | x = XTIME( x ) & 0xFF; |
||
123 | } |
||
124 | |||
125 | /* |
||
126 | * generate the forward and reverse S-boxes |
||
127 | */ |
||
128 | FSb[0x00] = 0x63; |
||
129 | RSb[0x63] = 0x00; |
||
130 | |||
131 | for( i = 1; i < 256; i++ ) |
||
132 | { |
||
133 | x = pow[255 - log[i]]; |
||
134 | |||
135 | y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF; |
||
136 | x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; |
||
137 | x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; |
||
138 | x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; |
||
139 | x ^= y ^ 0x63; |
||
140 | |||
141 | FSb[i] = (unsigned char) x; |
||
142 | RSb[x] = (unsigned char) i; |
||
143 | } |
||
144 | |||
145 | /* |
||
146 | * generate the forward and reverse tables |
||
147 | */ |
||
148 | for( i = 0; i < 256; i++ ) |
||
149 | { |
||
150 | x = FSb[i]; |
||
151 | y = XTIME( x ) & 0xFF; |
||
152 | z = ( y ^ x ) & 0xFF; |
||
153 | |||
154 | FT0[i] = ( (unsigned long) y ) ^ |
||
155 | ( (unsigned long) x << 8 ) ^ |
||
156 | ( (unsigned long) x << 16 ) ^ |
||
157 | ( (unsigned long) z << 24 ); |
||
158 | |||
159 | FT1[i] = ROTL8( FT0[i] ); |
||
160 | FT2[i] = ROTL8( FT1[i] ); |
||
161 | FT3[i] = ROTL8( FT2[i] ); |
||
162 | |||
163 | x = RSb[i]; |
||
164 | |||
165 | RT0[i] = ( (unsigned long) MUL( 0x0E, x ) ) ^ |
||
166 | ( (unsigned long) MUL( 0x09, x ) << 8 ) ^ |
||
167 | ( (unsigned long) MUL( 0x0D, x ) << 16 ) ^ |
||
168 | ( (unsigned long) MUL( 0x0B, x ) << 24 ); |
||
169 | |||
170 | RT1[i] = ROTL8( RT0[i] ); |
||
171 | RT2[i] = ROTL8( RT1[i] ); |
||
172 | RT3[i] = ROTL8( RT2[i] ); |
||
173 | } |
||
174 | } |
||
175 | |||
176 | /* |
||
177 | * AES key schedule (encryption) |
||
178 | */ |
||
179 | void aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize ) |
||
180 | { |
||
181 | int i; |
||
182 | unsigned long *RK; |
||
183 | |||
184 | #if !defined(XYSSL_AES_ROM_TABLES) |
||
185 | if( aes_init_done == 0 ) |
||
186 | { |
||
187 | aes_gen_tables(); |
||
188 | aes_init_done = 1; |
||
189 | } |
||
190 | #endif |
||
191 | |||
192 | switch( keysize ) |
||
193 | { |
||
194 | case 128: ctx->nr = 10; break; |
||
195 | case 192: ctx->nr = 12; break; |
||
196 | case 256: ctx->nr = 14; break; |
||
197 | default : return; |
||
198 | } |
||
199 | |||
200 | #if defined(PADLOCK_ALIGN16) |
||
201 | ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); |
||
202 | #else |
||
203 | ctx->rk = RK = ctx->buf; |
||
204 | #endif |
||
205 | |||
206 | for( i = 0; i < (keysize >> 5); i++ ) |
||
207 | { |
||
208 | GET_ULONG_LE( RK[i], key, i << 2 ); |
||
209 | } |
||
210 | |||
211 | switch( ctx->nr ) |
||
212 | { |
||
213 | case 10: |
||
214 | |||
215 | for( i = 0; i < 10; i++, RK += 4 ) |
||
216 | { |
||
217 | RK[4] = RK[0] ^ RCON[i] ^ |
||
218 | ( FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ |
||
219 | ( FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ |
||
220 | ( FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ |
||
221 | ( FSb[ ( RK[3] ) & 0xFF ] << 24 ); |
||
222 | |||
223 | RK[5] = RK[1] ^ RK[4]; |
||
224 | RK[6] = RK[2] ^ RK[5]; |
||
225 | RK[7] = RK[3] ^ RK[6]; |
||
226 | } |
||
227 | break; |
||
228 | |||
229 | case 12: |
||
230 | |||
231 | for( i = 0; i < 8; i++, RK += 6 ) |
||
232 | { |
||
233 | RK[6] = RK[0] ^ RCON[i] ^ |
||
234 | ( FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ |
||
235 | ( FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ |
||
236 | ( FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ |
||
237 | ( FSb[ ( RK[5] ) & 0xFF ] << 24 ); |
||
238 | |||
239 | RK[7] = RK[1] ^ RK[6]; |
||
240 | RK[8] = RK[2] ^ RK[7]; |
||
241 | RK[9] = RK[3] ^ RK[8]; |
||
242 | RK[10] = RK[4] ^ RK[9]; |
||
243 | RK[11] = RK[5] ^ RK[10]; |
||
244 | } |
||
245 | break; |
||
246 | |||
247 | case 14: |
||
248 | |||
249 | for( i = 0; i < 7; i++, RK += 8 ) |
||
250 | { |
||
251 | RK[8] = RK[0] ^ RCON[i] ^ |
||
252 | ( FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ |
||
253 | ( FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ |
||
254 | ( FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ |
||
255 | ( FSb[ ( RK[7] ) & 0xFF ] << 24 ); |
||
256 | |||
257 | RK[9] = RK[1] ^ RK[8]; |
||
258 | RK[10] = RK[2] ^ RK[9]; |
||
259 | RK[11] = RK[3] ^ RK[10]; |
||
260 | |||
261 | RK[12] = RK[4] ^ |
||
262 | ( FSb[ ( RK[11] ) & 0xFF ] ) ^ |
||
263 | ( FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ |
||
264 | ( FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ |
||
265 | ( FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); |
||
266 | |||
267 | RK[13] = RK[5] ^ RK[12]; |
||
268 | RK[14] = RK[6] ^ RK[13]; |
||
269 | RK[15] = RK[7] ^ RK[14]; |
||
270 | } |
||
271 | break; |
||
272 | |||
273 | default: |
||
274 | |||
275 | break; |
||
276 | } |
||
277 | } |
||
278 | |||
279 | /* |
||
280 | * AES key schedule (decryption) |
||
281 | */ |
||
282 | void aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize ) |
||
283 | { |
||
284 | int i, j; |
||
285 | aes_context cty; |
||
286 | unsigned long *RK; |
||
287 | unsigned long *SK; |
||
288 | |||
289 | switch( keysize ) |
||
290 | { |
||
291 | case 128: ctx->nr = 10; break; |
||
292 | case 192: ctx->nr = 12; break; |
||
293 | case 256: ctx->nr = 14; break; |
||
294 | default : return; |
||
295 | } |
||
296 | |||
297 | #if defined(PADLOCK_ALIGN16) |
||
298 | ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); |
||
299 | #else |
||
300 | ctx->rk = RK = ctx->buf; |
||
301 | #endif |
||
302 | |||
303 | aes_setkey_enc( &cty, key, keysize ); |
||
304 | SK = cty.rk + cty.nr * 4; |
||
305 | |||
306 | *RK++ = *SK++; |
||
307 | *RK++ = *SK++; |
||
308 | *RK++ = *SK++; |
||
309 | *RK++ = *SK++; |
||
310 | |||
311 | for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) |
||
312 | { |
||
313 | for( j = 0; j < 4; j++, SK++ ) |
||
314 | { |
||
315 | *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ |
||
316 | RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ |
||
317 | RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ |
||
318 | RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; |
||
319 | } |
||
320 | } |
||
321 | |||
322 | *RK++ = *SK++; |
||
323 | *RK++ = *SK++; |
||
324 | *RK++ = *SK++; |
||
325 | *RK++ = *SK++; |
||
326 | |||
327 | memset( &cty, 0, sizeof( aes_context ) ); |
||
328 | } |
||
329 | |||
330 | #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ |
||
331 | { \ |
||
332 | X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ |
||
333 | FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ |
||
334 | FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ |
||
335 | FT3[ ( Y3 >> 24 ) & 0xFF ]; \ |
||
336 | \ |
||
337 | X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ |
||
338 | FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ |
||
339 | FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ |
||
340 | FT3[ ( Y0 >> 24 ) & 0xFF ]; \ |
||
341 | \ |
||
342 | X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ |
||
343 | FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ |
||
344 | FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ |
||
345 | FT3[ ( Y1 >> 24 ) & 0xFF ]; \ |
||
346 | \ |
||
347 | X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ |
||
348 | FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ |
||
349 | FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ |
||
350 | FT3[ ( Y2 >> 24 ) & 0xFF ]; \ |
||
351 | } |
||
352 | |||
353 | #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ |
||
354 | { \ |
||
355 | X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ |
||
356 | RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ |
||
357 | RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ |
||
358 | RT3[ ( Y1 >> 24 ) & 0xFF ]; \ |
||
359 | \ |
||
360 | X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ |
||
361 | RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ |
||
362 | RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ |
||
363 | RT3[ ( Y2 >> 24 ) & 0xFF ]; \ |
||
364 | \ |
||
365 | X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ |
||
366 | RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ |
||
367 | RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ |
||
368 | RT3[ ( Y3 >> 24 ) & 0xFF ]; \ |
||
369 | \ |
||
370 | X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ |
||
371 | RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ |
||
372 | RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ |
||
373 | RT3[ ( Y0 >> 24 ) & 0xFF ]; \ |
||
374 | } |
||
375 | |||
376 | /* |
||
377 | * AES-ECB block encryption/decryption |
||
378 | */ |
||
379 | void aes_crypt_ecb( aes_context *ctx, |
||
380 | int mode, |
||
381 | const unsigned char input[16], |
||
382 | unsigned char output[16] ) |
||
383 | { |
||
384 | int i; |
||
385 | unsigned long *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; |
||
386 | |||
387 | #if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86) |
||
388 | if( padlock_supports( PADLOCK_ACE ) ) |
||
389 | { |
||
390 | if( padlock_xcryptecb( ctx, mode, input, output ) == 0 ) |
||
391 | return; |
||
392 | } |
||
393 | #endif |
||
394 | |||
395 | RK = ctx->rk; |
||
396 | |||
397 | GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++; |
||
398 | GET_ULONG_LE( X1, input, 4 ); X1 ^= *RK++; |
||
399 | GET_ULONG_LE( X2, input, 8 ); X2 ^= *RK++; |
||
400 | GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++; |
||
401 | |||
402 | if( mode == AES_DECRYPT ) |
||
403 | { |
||
404 | for( i = (ctx->nr >> 1) - 1; i > 0; i-- ) |
||
405 | { |
||
406 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); |
||
407 | AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); |
||
408 | } |
||
409 | |||
410 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); |
||
411 | |||
412 | X0 = *RK++ ^ ( RSb[ ( Y0 ) & 0xFF ] ) ^ |
||
413 | ( RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ |
||
414 | ( RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ |
||
415 | ( RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); |
||
416 | |||
417 | X1 = *RK++ ^ ( RSb[ ( Y1 ) & 0xFF ] ) ^ |
||
418 | ( RSb[ ( Y0 >>8 ) & 0xFF ] << 8 ) ^ |
||
419 | ( RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ |
||
420 | ( RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); |
||
421 | |||
422 | X2 = *RK++ ^ ( RSb[ ( Y2 ) & 0xFF ] ) ^ |
||
423 | ( RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ |
||
424 | ( RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ |
||
425 | ( RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); |
||
426 | |||
427 | X3 = *RK++ ^ ( RSb[ ( Y3 ) & 0xFF ] ) ^ |
||
428 | ( RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ |
||
429 | ( RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ |
||
430 | ( RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); |
||
431 | } |
||
432 | else /* AES_ENCRYPT */ |
||
433 | { |
||
434 | for( i = (ctx->nr >> 1) - 1; i > 0; i-- ) |
||
435 | { |
||
436 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); |
||
437 | AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); |
||
438 | } |
||
439 | |||
440 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); |
||
441 | |||
442 | X0 = *RK++ ^ ( FSb[ ( Y0 ) & 0xFF ] ) ^ |
||
443 | ( FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ |
||
444 | ( FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ |
||
445 | ( FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); |
||
446 | |||
447 | X1 = *RK++ ^ ( FSb[ ( Y1 ) & 0xFF ] ) ^ |
||
448 | ( FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ |
||
449 | ( FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ |
||
450 | ( FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); |
||
451 | |||
452 | X2 = *RK++ ^ ( FSb[ ( Y2 ) & 0xFF ] ) ^ |
||
453 | ( FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ |
||
454 | ( FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ |
||
455 | ( FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); |
||
456 | |||
457 | X3 = *RK++ ^ ( FSb[ ( Y3 ) & 0xFF ] ) ^ |
||
458 | ( FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ |
||
459 | ( FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ |
||
460 | ( FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); |
||
461 | } |
||
462 | |||
463 | PUT_ULONG_LE( X0, output, 0 ); |
||
464 | PUT_ULONG_LE( X1, output, 4 ); |
||
465 | PUT_ULONG_LE( X2, output, 8 ); |
||
466 | PUT_ULONG_LE( X3, output, 12 ); |
||
467 | } |
||
468 | |||
469 | /* |
||
470 | * AES-CBC buffer encryption/decryption |
||
471 | */ |
||
472 | void aes_crypt_cbc( aes_context *ctx, |
||
473 | int mode, |
||
474 | int length, |
||
475 | unsigned char iv[16], |
||
476 | const unsigned char *input, |
||
477 | unsigned char *output ) |
||
478 | { |
||
479 | int i; |
||
480 | unsigned char temp[16]; |
||
481 | |||
482 | #if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86) |
||
483 | if( padlock_supports( PADLOCK_ACE ) ) |
||
484 | { |
||
485 | if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) |
||
486 | return; |
||
487 | } |
||
488 | #endif |
||
489 | |||
490 | if( mode == AES_DECRYPT ) |
||
491 | { |
||
492 | while( length > 0 ) |
||
493 | { |
||
494 | memcpy( temp, input, 16 ); |
||
495 | aes_crypt_ecb( ctx, mode, input, output ); |
||
496 | |||
497 | for( i = 0; i < 16; i++ ) |
||
498 | output[i] = (unsigned char)( output[i] ^ iv[i] ); |
||
499 | |||
500 | memcpy( iv, temp, 16 ); |
||
501 | |||
502 | input += 16; |
||
503 | output += 16; |
||
504 | length -= 16; |
||
505 | } |
||
506 | } |
||
507 | else |
||
508 | { |
||
509 | while( length > 0 ) |
||
510 | { |
||
511 | for( i = 0; i < 16; i++ ) |
||
512 | output[i] = (unsigned char)( input[i] ^ iv[i] ); |
||
513 | |||
514 | aes_crypt_ecb( ctx, mode, output, output ); |
||
515 | memcpy( iv, output, 16 ); |
||
516 | |||
517 | input += 16; |
||
518 | output += 16; |
||
519 | length -= 16; |
||
520 | } |
||
521 | } |
||
522 | } |
||
523 | |||
524 | /* |
||
525 | * AES-CFB buffer encryption/decryption |
||
526 | */ |
||
527 | void aes_crypt_cfb( aes_context *ctx, |
||
528 | int mode, |
||
529 | int length, |
||
530 | int *iv_off, |
||
531 | unsigned char iv[16], |
||
532 | const unsigned char *input, |
||
533 | unsigned char *output ) |
||
534 | { |
||
535 | int c, n = *iv_off; |
||
536 | |||
537 | if( mode == AES_DECRYPT ) |
||
538 | { |
||
539 | while( length-- ) |
||
540 | { |
||
541 | if( n == 0 ) |
||
542 | aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); |
||
543 | |||
544 | c = *input++; |
||
545 | *output++ = (unsigned char)( c ^ iv[n] ); |
||
546 | iv[n] = (unsigned char) c; |
||
547 | |||
548 | n = (n + 1) & 0x0F; |
||
549 | } |
||
550 | } |
||
551 | else |
||
552 | { |
||
553 | while( length-- ) |
||
554 | { |
||
555 | if( n == 0 ) |
||
556 | aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); |
||
557 | |||
558 | iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); |
||
559 | |||
560 | n = (n + 1) & 0x0F; |
||
561 | } |
||
562 | } |
||
563 | |||
564 | *iv_off = n; |
||
565 | }>>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>>><>><>><>><>><>><>>><>><>><>>><>><>><>>><>>><>><>><>><>><>><>>><>><>><>><>>>>><>><>><>><>><> |