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