]>
git.saurik.com Git - apple/security.git/blob - AppleCSP/AES/rijndaelGladman.c
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 * rijndaelGladman.c - Gladman AES/Rijndael implementation.
21 * Based on rijndael.c written by Dr. Brian Gladman.
26 /* This is an independent implementation of the encryption algorithm: */
28 /* RIJNDAEL by Joan Daemen and Vincent Rijmen */
30 /* which is a candidate algorithm in the Advanced Encryption Standard */
31 /* programme of the US National Institute of Standards and Technology. */
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. */
38 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
40 #include "rijndaelGladman.h"
42 /* enable of block/word/byte swapping macros */
43 #define USE_SWAP_MACROS 1
46 /* original static declarations */
52 u4byte ft_tab
[4][256];
53 u4byte it_tab
[4][256];
56 u4byte fl_tab
[4][256];
57 u4byte il_tab
[4][256];
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
];
68 u4byte (*fl_tab
)[FL_TAB_SIZE_LS
];
69 u4byte (*il_tab
)[IL_TAB_SIZE_LS
];
70 #endif /* LARGE_TABLES */
73 #define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
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)
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)
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)] )
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)
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)
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)
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)
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)
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 */
137 for(i
= 0,p
= 1; i
< 256; ++i
)
139 pow_tab
[i
] = (u1byte
)p
; log_tab
[p
] = (u1byte
)i
;
141 p
= p
^ (p
<< 1) ^ (p
& 0x80 ? 0x01b : 0);
144 log_tab
[1] = 0; p
= 1;
146 for(i
= 0; i
< 10; ++i
)
150 p
= (p
<< 1) ^ (p
& 0x80 ? 0x1b : 0);
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. */
159 for(i
= 0; i
< 256; ++i
)
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
;
169 for(i
= 0; i
< 256; ++i
)
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);
180 t
= ((u4byte
)ff_mult(2, p
)) |
183 ((u4byte
)ff_mult(3, p
) << 24);
186 ft_tab
[1][i
] = rotl(t
, 8);
187 ft_tab
[2][i
] = rotl(t
, 16);
188 ft_tab
[3][i
] = rotl(t
, 24);
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);
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);
205 it_tab
[1][i
] = rotl(t
, 8);
206 it_tab
[2][i
] = rotl(t
, 16);
207 it_tab
[3][i
] = rotl(t
, 24);
211 #define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
213 #define imix_col(y,x) \
219 (y) ^= rotr(u ^ t, 8) ^ \
223 /* initialise the key schedule from the user supplied key */
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; \
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; \
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; \
257 const u4byte in_key
[],
258 const u4byte key_len
,
260 { u4byte i
, t
, u
, v
, w
;
261 u4byte
*e_key
= aesKey
->e_key
;
262 u4byte
*d_key
= aesKey
->d_key
;
264 aesKey
->k_len
= (key_len
+ 31) / 32;
267 get_key(e_key
, key_len
);
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];
273 switch(aesKey
->k_len
)
275 case 4: t
= e_key
[3];
276 for(i
= 0; i
< 10; ++i
)
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];
287 for(i
= 0; i
< 8; ++i
)
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];
298 for(i
= 0; i
< 7; ++i
)
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];
306 for(i
= 4; i
< 4 * aesKey
->k_len
+ 24; ++i
)
308 imix_col(d_key
[i
], e_key
[i
]);
314 /* encrypt a block of text */
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); \
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); \
330 const u4byte in_blk
[4],
332 const GAesKey
*aesKey
)
334 u4byte b0
[4], b1
[4], *kp
;
335 u4byte
*e_key
= aesKey
->e_key
;
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];
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];
349 if(aesKey
->k_len
> 6)
351 f_nround(b1
, b0
, kp
); f_nround(b0
, b1
, kp
);
354 if(aesKey
->k_len
> 4)
356 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_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
);
368 out_blk
[0] = b0
[0]; out_blk
[1] = b0
[1];
369 out_blk
[2] = b0
[2]; out_blk
[3] = b0
[3];
373 /* decrypt a block of text */
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); \
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); \
389 const u4byte in_blk
[4],
391 const GAesKey
*aesKey
)
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
;
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];
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];
412 kp
= d_key
+ 4 * (k_len
+ 5);
416 i_nround(b1
, b0
, kp
); i_nround(b0
, b1
, kp
);
421 i_nround(b1
, b0
, kp
); i_nround(b0
, b1
, kp
);
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
);
433 out_blk
[0] = b0
[0]; out_blk
[1] = b0
[1];
434 out_blk
[2] = b0
[2]; out_blk
[3] = b0
[3];