]>
Commit | Line | Data |
---|---|---|
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 | }; |