]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/aesVect/rijndael.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / aesVect / rijndael.c
1
2
3
4 /* This is an independent implementation of the encryption algorithm: */
5 /* */
6 /* RIJNDAEL by Joan Daemen and Vincent Rijmen */
7 /* */
8 /* which is a candidate algorithm in the Advanced Encryption Standard */
9 /* programme of the US National Institute of Standards and Technology. */
10 /* */
11 /* Copyright in this implementation is held by Dr B R Gladman but I */
12 /* hereby give permission for its free direct or derivative use subject */
13 /* to acknowledgment of its origin and compliance with any conditions */
14 /* that the originators of the algorithm place on its exploitation. */
15 /* */
16 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
17
18 /* Timing data for Rijndael (rijndael.c)
19
20 Algorithm: rijndael (rijndael.c)
21
22 128 bit key:
23 Key Setup: 305/1389 cycles (encrypt/decrypt)
24 Encrypt: 374 cycles = 68.4 mbits/sec
25 Decrypt: 352 cycles = 72.7 mbits/sec
26 Mean: 363 cycles = 70.5 mbits/sec
27
28 192 bit key:
29 Key Setup: 277/1595 cycles (encrypt/decrypt)
30 Encrypt: 439 cycles = 58.3 mbits/sec
31 Decrypt: 425 cycles = 60.2 mbits/sec
32 Mean: 432 cycles = 59.3 mbits/sec
33
34 256 bit key:
35 Key Setup: 374/1960 cycles (encrypt/decrypt)
36 Encrypt: 502 cycles = 51.0 mbits/sec
37 Decrypt: 498 cycles = 51.4 mbits/sec
38 Mean: 500 cycles = 51.2 mbits/sec
39
40 */
41
42 #include "std_defs.h"
43
44 /* enable of block/word/byte swapping macros */
45 #define USE_SWAP_MACROS 1
46
47 static char *alg_name[] = { (char *)"rijndael", (char *)"rijndael.c", (char *)"rijndael" };
48
49 char **cipher_name()
50 {
51 return alg_name;
52 }
53
54 #define LARGE_TABLES
55
56 u1byte pow_tab[256];
57 u1byte log_tab[256];
58 u1byte sbx_tab[256];
59 u1byte isb_tab[256];
60 u4byte rco_tab[ 10];
61 u4byte ft_tab[4][256];
62 u4byte it_tab[4][256];
63
64 #ifdef LARGE_TABLES
65 u4byte fl_tab[4][256];
66 u4byte il_tab[4][256];
67 #endif
68
69 u4byte tab_gen = 0;
70
71 u4byte k_len;
72 u4byte e_key[64];
73 u4byte d_key[64];
74
75 #define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
76
77 #define f_rn(bo, bi, n, k) \
78 bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
79 ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
80 ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
81 ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
82
83 #define i_rn(bo, bi, n, k) \
84 bo[n] = it_tab[0][byte(bi[n],0)] ^ \
85 it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
86 it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
87 it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
88
89 #ifdef LARGE_TABLES
90
91 #define ls_box(x) \
92 ( fl_tab[0][byte(x, 0)] ^ \
93 fl_tab[1][byte(x, 1)] ^ \
94 fl_tab[2][byte(x, 2)] ^ \
95 fl_tab[3][byte(x, 3)] )
96
97 #define f_rl(bo, bi, n, k) \
98 bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
99 fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
100 fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
101 fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
102
103 #define i_rl(bo, bi, n, k) \
104 bo[n] = il_tab[0][byte(bi[n],0)] ^ \
105 il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
106 il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
107 il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
108
109 #else
110
111 #define ls_box(x) \
112 ((u4byte)sbx_tab[byte(x, 0)] << 0) ^ \
113 ((u4byte)sbx_tab[byte(x, 1)] << 8) ^ \
114 ((u4byte)sbx_tab[byte(x, 2)] << 16) ^ \
115 ((u4byte)sbx_tab[byte(x, 3)] << 24)
116
117 #define f_rl(bo, bi, n, k) \
118 bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^ \
119 rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]), 8) ^ \
120 rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \
121 rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n)
122
123 #define i_rl(bo, bi, n, k) \
124 bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^ \
125 rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]), 8) ^ \
126 rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \
127 rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n)
128
129 #endif
130
131 void gen_tabs(void)
132 { u4byte i, t;
133 u1byte p, q;
134
135 /* log and power tables for GF(2**8) finite field with */
136 /* 0x11b as modular polynomial - the simplest prmitive */
137 /* root is 0x11, used here to generate the tables */
138
139 for(i = 0,p = 1; i < 256; ++i)
140 {
141 pow_tab[i] = (u1byte)p; log_tab[p] = (u1byte)i;
142
143 p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);
144 }
145
146 log_tab[1] = 0; p = 1;
147
148 for(i = 0; i < 10; ++i)
149 {
150 rco_tab[i] = p;
151
152 p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
153 }
154
155 /* note that the affine byte transformation matrix in */
156 /* rijndael specification is in big endian format with */
157 /* bit 0 as the most significant bit. In the remainder */
158 /* of the specification the bits are numbered from the */
159 /* least significant end of a byte. */
160
161 for(i = 0; i < 256; ++i)
162 {
163 p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p;
164 q = (q >> 7) | (q << 1); p ^= q;
165 q = (q >> 7) | (q << 1); p ^= q;
166 q = (q >> 7) | (q << 1); p ^= q;
167 q = (q >> 7) | (q << 1); p ^= q ^ 0x63;
168 sbx_tab[i] = (u1byte)p; isb_tab[p] = (u1byte)i;
169 }
170
171 for(i = 0; i < 256; ++i)
172 {
173 p = sbx_tab[i];
174
175 #ifdef LARGE_TABLES
176
177 t = p; fl_tab[0][i] = t;
178 fl_tab[1][i] = rotl(t, 8);
179 fl_tab[2][i] = rotl(t, 16);
180 fl_tab[3][i] = rotl(t, 24);
181 #endif
182 t = ((u4byte)ff_mult(2, p)) |
183 ((u4byte)p << 8) |
184 ((u4byte)p << 16) |
185 ((u4byte)ff_mult(3, p) << 24);
186
187 ft_tab[0][i] = t;
188 ft_tab[1][i] = rotl(t, 8);
189 ft_tab[2][i] = rotl(t, 16);
190 ft_tab[3][i] = rotl(t, 24);
191
192 p = isb_tab[i];
193
194 #ifdef LARGE_TABLES
195
196 t = p; il_tab[0][i] = t;
197 il_tab[1][i] = rotl(t, 8);
198 il_tab[2][i] = rotl(t, 16);
199 il_tab[3][i] = rotl(t, 24);
200 #endif
201 t = ((u4byte)ff_mult(14, p)) |
202 ((u4byte)ff_mult( 9, p) << 8) |
203 ((u4byte)ff_mult(13, p) << 16) |
204 ((u4byte)ff_mult(11, p) << 24);
205
206 it_tab[0][i] = t;
207 it_tab[1][i] = rotl(t, 8);
208 it_tab[2][i] = rotl(t, 16);
209 it_tab[3][i] = rotl(t, 24);
210 }
211
212 tab_gen = 1;
213 };
214
215 #define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
216
217 #define imix_col(y,x) \
218 u = star_x(x); \
219 v = star_x(u); \
220 w = star_x(v); \
221 t = w ^ (x); \
222 (y) = u ^ v ^ w; \
223 (y) ^= rotr(u ^ t, 8) ^ \
224 rotr(v ^ t, 16) ^ \
225 rotr(t,24)
226
227 /* initialise the key schedule from the user supplied key */
228
229 #define loop4(i) \
230 { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
231 t ^= e_key[4 * i]; e_key[4 * i + 4] = t; \
232 t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t; \
233 t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t; \
234 t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t; \
235 }
236
237 #define loop6(i) \
238 { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
239 t ^= e_key[6 * i]; e_key[6 * i + 6] = t; \
240 t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t; \
241 t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t; \
242 t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t; \
243 t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t; \
244 t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t; \
245 }
246
247 #define loop8(i) \
248 { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
249 t ^= e_key[8 * i]; e_key[8 * i + 8] = t; \
250 t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t; \
251 t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t; \
252 t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t; \
253 t = e_key[8 * i + 4] ^ ls_box(t); \
254 e_key[8 * i + 12] = t; \
255 t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t; \
256 t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t; \
257 t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t; \
258 }
259
260 u4byte *set_key(const u4byte in_key[], const u4byte key_len)
261 { u4byte i, t, u, v, w;
262
263 if(!tab_gen)
264
265 gen_tabs();
266
267 k_len = (key_len + 31) / 32;
268
269 #if USE_SWAP_MACROS
270 get_key(e_key, key_len);
271 #else
272 e_key[0] = in_key[0]; e_key[1] = in_key[1];
273 e_key[2] = in_key[2]; e_key[3] = in_key[3];
274 #endif
275
276 switch(k_len)
277 {
278 case 4: t = e_key[3];
279 for(i = 0; i < 10; ++i)
280 loop4(i);
281 break;
282
283 case 6:
284 #if USE_SWAP_MACROS
285 t = e_key[5];
286 #else
287 /* done in get_key macros in USE_SWAP_MACROS case */
288 e_key[4] = in_key[4]; t = e_key[5] = in_key[5];
289 #endif
290 for(i = 0; i < 8; ++i)
291 loop6(i);
292 break;
293
294 case 8:
295 #if USE_SWAP_MACROS
296 t = e_key[7];
297 #else
298 e_key[4] = in_key[4]; e_key[5] = in_key[5];
299 e_key[6] = in_key[6]; t = e_key[7] = in_key[7];
300 #endif
301 for(i = 0; i < 7; ++i)
302 loop8(i);
303 break;
304 }
305
306 d_key[0] = e_key[0]; d_key[1] = e_key[1];
307 d_key[2] = e_key[2]; d_key[3] = e_key[3];
308
309 for(i = 4; i < 4 * k_len + 24; ++i)
310 {
311 imix_col(d_key[i], e_key[i]);
312 }
313
314 return e_key;
315 };
316
317 /* encrypt a block of text */
318
319 #define f_nround(bo, bi, k) \
320 f_rn(bo, bi, 0, k); \
321 f_rn(bo, bi, 1, k); \
322 f_rn(bo, bi, 2, k); \
323 f_rn(bo, bi, 3, k); \
324 k += 4
325
326 #define f_lround(bo, bi, k) \
327 f_rl(bo, bi, 0, k); \
328 f_rl(bo, bi, 1, k); \
329 f_rl(bo, bi, 2, k); \
330 f_rl(bo, bi, 3, k)
331
332 void rEncrypt(const u4byte in_blk[4], u4byte out_blk[4])
333 { u4byte b0[4], b1[4], *kp;
334
335 #if USE_SWAP_MACROS
336 u4byte swap_block[4];
337 get_block(swap_block);
338 b0[0] = swap_block[0] ^ e_key[0]; b0[1] = swap_block[1] ^ e_key[1];
339 b0[2] = swap_block[2] ^ e_key[2]; b0[3] = swap_block[3] ^ e_key[3];
340 #else
341 b0[0] = in_blk[0] ^ e_key[0]; b0[1] = in_blk[1] ^ e_key[1];
342 b0[2] = in_blk[2] ^ e_key[2]; b0[3] = in_blk[3] ^ e_key[3];
343 #endif
344
345 kp = e_key + 4;
346
347 if(k_len > 6)
348 {
349 f_nround(b1, b0, kp); f_nround(b0, b1, kp);
350 }
351
352 if(k_len > 4)
353 {
354 f_nround(b1, b0, kp); f_nround(b0, b1, kp);
355 }
356
357 f_nround(b1, b0, kp); f_nround(b0, b1, kp);
358 f_nround(b1, b0, kp); f_nround(b0, b1, kp);
359 f_nround(b1, b0, kp); f_nround(b0, b1, kp);
360 f_nround(b1, b0, kp); f_nround(b0, b1, kp);
361 f_nround(b1, b0, kp); f_lround(b0, b1, kp);
362
363 #if USE_SWAP_MACROS
364 put_block(b0);
365 #else
366 out_blk[0] = b0[0]; out_blk[1] = b0[1];
367 out_blk[2] = b0[2]; out_blk[3] = b0[3];
368 #endif
369 };
370
371 /* decrypt a block of text */
372
373 #define i_nround(bo, bi, k) \
374 i_rn(bo, bi, 0, k); \
375 i_rn(bo, bi, 1, k); \
376 i_rn(bo, bi, 2, k); \
377 i_rn(bo, bi, 3, k); \
378 k -= 4
379
380 #define i_lround(bo, bi, k) \
381 i_rl(bo, bi, 0, k); \
382 i_rl(bo, bi, 1, k); \
383 i_rl(bo, bi, 2, k); \
384 i_rl(bo, bi, 3, k)
385
386 void rDecrypt(const u4byte in_blk[4], u4byte out_blk[4])
387 { u4byte b0[4], b1[4], *kp;
388
389 #if USE_SWAP_MACROS
390 u4byte swap_block[4];
391 get_block(swap_block);
392 b0[0] = swap_block[0] ^ e_key[4 * k_len + 24];
393 b0[1] = swap_block[1] ^ e_key[4 * k_len + 25];
394 b0[2] = swap_block[2] ^ e_key[4 * k_len + 26];
395 b0[3] = swap_block[3] ^ e_key[4 * k_len + 27];
396 #else
397 b0[0] = in_blk[0] ^ e_key[4 * k_len + 24];
398 b0[1] = in_blk[1] ^ e_key[4 * k_len + 25];
399 b0[2] = in_blk[2] ^ e_key[4 * k_len + 26];
400 b0[3] = in_blk[3] ^ e_key[4 * k_len + 27];
401 #endif
402
403 kp = d_key + 4 * (k_len + 5);
404
405 if(k_len > 6)
406 {
407 i_nround(b1, b0, kp); i_nround(b0, b1, kp);
408 }
409
410 if(k_len > 4)
411 {
412 i_nround(b1, b0, kp); i_nround(b0, b1, kp);
413 }
414
415 i_nround(b1, b0, kp); i_nround(b0, b1, kp);
416 i_nround(b1, b0, kp); i_nround(b0, b1, kp);
417 i_nround(b1, b0, kp); i_nround(b0, b1, kp);
418 i_nround(b1, b0, kp); i_nround(b0, b1, kp);
419 i_nround(b1, b0, kp); i_lround(b0, b1, kp);
420
421 #if USE_SWAP_MACROS
422 put_block(b0);
423 #else
424 out_blk[0] = b0[0]; out_blk[1] = b0[1];
425 out_blk[2] = b0[2]; out_blk[3] = b0[3];
426 #endif
427 };