source: trunk/src/rijndael-alg-fst.c@ 350

Last change on this file since 350 was 291, checked in by katerina, 14 years ago

Fix for ticket #219 (miscompiled on SLES 11)

File size: 14.0 KB
Line 
1/*
2 * rijndael-alg-fst.c v2.3 April '2000
3 *
4 * Optimised ANSI C code
5 *
6 * authors: v1.0: Antoon Bosselaers
7 * v2.0: Vincent Rijmen
8 * v2.3: Paulo Barreto
9 *
10 * This code is placed in the public domain.
11 */
12
13#include "config_xor.h"
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#ifdef SH_ENCRYPT
20
21#include "rijndael-alg-fst.h"
22
23#include "rijndael-boxes-fst.h"
24
25int rijndaelKeySched(word8 k[MAXKC][4], word8 W[MAXROUNDS+1][4][4], int ROUNDS) {
26 /* Calculate the necessary round keys
27 * The number of calculations depends on keyBits and blockBits
28 */
29 int j, r, t, rconpointer = 0;
30 word8 tk[MAXKC][4];
31 int KC = ROUNDS - 6;
32 word32 tmp;
33
34 for (j = KC-1; j >= 0; j--) {
35 memmove( &(tk[j]), &(k[j]), sizeof(word32));
36 }
37 r = 0;
38 t = 0;
39
40 /* copy values into round key array */
41 for (j = 0; (j < KC) && (r < ROUNDS + 1); ) {
42 for (; (j < KC) && (t < 4); j++, t++) {
43 memmove( &(W[r][t]), &(tk[j]), sizeof(word32));
44 }
45 if (t == 4) {
46 r++;
47 t = 0;
48 }
49 }
50
51 while (r < ROUNDS + 1) { /* while not enough round key material calculated */
52 /* calculate new values */
53 tk[0][0] ^= S[tk[KC-1][1]];
54 tk[0][1] ^= S[tk[KC-1][2]];
55 tk[0][2] ^= S[tk[KC-1][3]];
56 tk[0][3] ^= S[tk[KC-1][0]];
57 tk[0][0] ^= rcon[rconpointer++];
58
59 if (KC != 8) {
60 for (j = 1; j < KC; j++) {
61 tmp = *((word32*)tk[j-1]);
62 *((word32*)tk[j]) ^= tmp;
63 }
64 } else {
65 for (j = 1; j < KC/2; j++) {
66 tmp = *((word32*)tk[j-1]);
67 *((word32*)tk[j]) ^= tmp;
68 }
69 tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
70 tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
71 tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
72 tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
73 for (j = KC/2 + 1; j < KC; j++) {
74 tmp = *((word32*)tk[j-1]);
75 *((word32*)tk[j]) ^= tmp;
76 }
77 }
78 /* copy values into round key array */
79 for (j = 0; (j < KC) && (r < ROUNDS + 1); ) {
80 for (; (j < KC) && (t < 4); j++, t++) {
81 memmove( &(W[r][t]), &(tk[j]), sizeof(word32));
82 }
83 if (t == 4) {
84 r++;
85 t = 0;
86 }
87 }
88 }
89 return 0;
90}
91
92int rijndaelKeyEncToDec(word8 W[MAXROUNDS+1][4][4], int ROUNDS) {
93 int r;
94 word8 *w;
95
96 for (r = 1; r < ROUNDS; r++) {
97 w = W[r][0];
98 *((word32*)w) =
99 *((word32*)U1[w[0]])
100 ^ *((word32*)U2[w[1]])
101 ^ *((word32*)U3[w[2]])
102 ^ *((word32*)U4[w[3]]);
103
104 w = W[r][1];
105 *((word32*)w) =
106 *((word32*)U1[w[0]])
107 ^ *((word32*)U2[w[1]])
108 ^ *((word32*)U3[w[2]])
109 ^ *((word32*)U4[w[3]]);
110
111 w = W[r][2];
112 *((word32*)w) =
113 *((word32*)U1[w[0]])
114 ^ *((word32*)U2[w[1]])
115 ^ *((word32*)U3[w[2]])
116 ^ *((word32*)U4[w[3]]);
117
118 w = W[r][3];
119 *((word32*)w) =
120 *((word32*)U1[w[0]])
121 ^ *((word32*)U2[w[1]])
122 ^ *((word32*)U3[w[2]])
123 ^ *((word32*)U4[w[3]]);
124 }
125 return 0;
126}
127
128/**
129 * Encrypt a single block.
130 */
131int rijndaelEncrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) {
132 int r;
133 union {
134 word32 tem4[4];
135 word8 temp[4][4];
136 } tmpU;
137 tmpU.tem4[0] = tmpU.tem4[1] = tmpU.tem4[2] = tmpU.tem4[3] = 0;
138
139 tmpU.tem4[0] = *((word32*)(a )) ^ *((word32*)rk[0][0]);
140 tmpU.tem4[1] = *((word32*)(a+ 4)) ^ *((word32*)rk[0][1]);
141 tmpU.tem4[2] = *((word32*)(a+ 8)) ^ *((word32*)rk[0][2]);
142 tmpU.tem4[3] = *((word32*)(a+12)) ^ *((word32*)rk[0][3]);
143 *((word32*)(b )) = *((word32*)T1[tmpU.temp[0][0]])
144 ^ *((word32*)T2[tmpU.temp[1][1]])
145 ^ *((word32*)T3[tmpU.temp[2][2]])
146 ^ *((word32*)T4[tmpU.temp[3][3]]);
147 *((word32*)(b + 4)) = *((word32*)T1[tmpU.temp[1][0]])
148 ^ *((word32*)T2[tmpU.temp[2][1]])
149 ^ *((word32*)T3[tmpU.temp[3][2]])
150 ^ *((word32*)T4[tmpU.temp[0][3]]);
151 *((word32*)(b + 8)) = *((word32*)T1[tmpU.temp[2][0]])
152 ^ *((word32*)T2[tmpU.temp[3][1]])
153 ^ *((word32*)T3[tmpU.temp[0][2]])
154 ^ *((word32*)T4[tmpU.temp[1][3]]);
155 *((word32*)(b +12)) = *((word32*)T1[tmpU.temp[3][0]])
156 ^ *((word32*)T2[tmpU.temp[0][1]])
157 ^ *((word32*)T3[tmpU.temp[1][2]])
158 ^ *((word32*)T4[tmpU.temp[2][3]]);
159 for (r = 1; r < ROUNDS-1; r++) {
160 tmpU.tem4[0] = *((word32*)(b )) ^ *((word32*)rk[r][0]);
161 tmpU.tem4[1] = *((word32*)(b+ 4)) ^ *((word32*)rk[r][1]);
162 tmpU.tem4[2] = *((word32*)(b+ 8)) ^ *((word32*)rk[r][2]);
163 tmpU.tem4[3] = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
164
165 *((word32*)(b )) = *((word32*)T1[tmpU.temp[0][0]])
166 ^ *((word32*)T2[tmpU.temp[1][1]])
167 ^ *((word32*)T3[tmpU.temp[2][2]])
168 ^ *((word32*)T4[tmpU.temp[3][3]]);
169 *((word32*)(b + 4)) = *((word32*)T1[tmpU.temp[1][0]])
170 ^ *((word32*)T2[tmpU.temp[2][1]])
171 ^ *((word32*)T3[tmpU.temp[3][2]])
172 ^ *((word32*)T4[tmpU.temp[0][3]]);
173 *((word32*)(b + 8)) = *((word32*)T1[tmpU.temp[2][0]])
174 ^ *((word32*)T2[tmpU.temp[3][1]])
175 ^ *((word32*)T3[tmpU.temp[0][2]])
176 ^ *((word32*)T4[tmpU.temp[1][3]]);
177 *((word32*)(b +12)) = *((word32*)T1[tmpU.temp[3][0]])
178 ^ *((word32*)T2[tmpU.temp[0][1]])
179 ^ *((word32*)T3[tmpU.temp[1][2]])
180 ^ *((word32*)T4[tmpU.temp[2][3]]);
181 }
182 /* last round is special */
183 tmpU.tem4[0] = *((word32*)(b )) ^ *((word32*)rk[ROUNDS-1][0]);
184 tmpU.tem4[1] = *((word32*)(b+ 4)) ^ *((word32*)rk[ROUNDS-1][1]);
185 tmpU.tem4[2] = *((word32*)(b+ 8)) ^ *((word32*)rk[ROUNDS-1][2]);
186 tmpU.tem4[3] = *((word32*)(b+12)) ^ *((word32*)rk[ROUNDS-1][3]);
187 b[ 0] = T1[tmpU.temp[0][0]][1];
188 b[ 1] = T1[tmpU.temp[1][1]][1];
189 b[ 2] = T1[tmpU.temp[2][2]][1];
190 b[ 3] = T1[tmpU.temp[3][3]][1];
191 b[ 4] = T1[tmpU.temp[1][0]][1];
192 b[ 5] = T1[tmpU.temp[2][1]][1];
193 b[ 6] = T1[tmpU.temp[3][2]][1];
194 b[ 7] = T1[tmpU.temp[0][3]][1];
195 b[ 8] = T1[tmpU.temp[2][0]][1];
196 b[ 9] = T1[tmpU.temp[3][1]][1];
197 b[10] = T1[tmpU.temp[0][2]][1];
198 b[11] = T1[tmpU.temp[1][3]][1];
199 b[12] = T1[tmpU.temp[3][0]][1];
200 b[13] = T1[tmpU.temp[0][1]][1];
201 b[14] = T1[tmpU.temp[1][2]][1];
202 b[15] = T1[tmpU.temp[2][3]][1];
203 *((word32*)(b )) ^= *((word32*)rk[ROUNDS][0]);
204 *((word32*)(b+ 4)) ^= *((word32*)rk[ROUNDS][1]);
205 *((word32*)(b+ 8)) ^= *((word32*)rk[ROUNDS][2]);
206 *((word32*)(b+12)) ^= *((word32*)rk[ROUNDS][3]);
207
208 return 0;
209}
210
211/**
212 * Decrypt a single block.
213 */
214int rijndaelDecrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) {
215 int r;
216 union {
217 word32 tem4[4];
218 word8 temp[4][4];
219 } tmpU;
220 tmpU.tem4[0] = tmpU.tem4[1] = tmpU.tem4[2] = tmpU.tem4[3] = 0;
221
222 tmpU.tem4[0] = *((word32*)(a )) ^ *((word32*)rk[ROUNDS][0]);
223 tmpU.tem4[1] = *((word32*)(a+ 4)) ^ *((word32*)rk[ROUNDS][1]);
224 tmpU.tem4[2] = *((word32*)(a+ 8)) ^ *((word32*)rk[ROUNDS][2]);
225 tmpU.tem4[3] = *((word32*)(a+12)) ^ *((word32*)rk[ROUNDS][3]);
226
227 *((word32*)(b )) = *((word32*)T5[tmpU.temp[0][0]])
228 ^ *((word32*)T6[tmpU.temp[3][1]])
229 ^ *((word32*)T7[tmpU.temp[2][2]])
230 ^ *((word32*)T8[tmpU.temp[1][3]]);
231 *((word32*)(b+ 4)) = *((word32*)T5[tmpU.temp[1][0]])
232 ^ *((word32*)T6[tmpU.temp[0][1]])
233 ^ *((word32*)T7[tmpU.temp[3][2]])
234 ^ *((word32*)T8[tmpU.temp[2][3]]);
235 *((word32*)(b+ 8)) = *((word32*)T5[tmpU.temp[2][0]])
236 ^ *((word32*)T6[tmpU.temp[1][1]])
237 ^ *((word32*)T7[tmpU.temp[0][2]])
238 ^ *((word32*)T8[tmpU.temp[3][3]]);
239 *((word32*)(b+12)) = *((word32*)T5[tmpU.temp[3][0]])
240 ^ *((word32*)T6[tmpU.temp[2][1]])
241 ^ *((word32*)T7[tmpU.temp[1][2]])
242 ^ *((word32*)T8[tmpU.temp[0][3]]);
243 for (r = ROUNDS-1; r > 1; r--) {
244 tmpU.tem4[0] = *((word32*)(b )) ^ *((word32*)rk[r][0]);
245 tmpU.tem4[1] = *((word32*)(b+ 4)) ^ *((word32*)rk[r][1]);
246 tmpU.tem4[2] = *((word32*)(b+ 8)) ^ *((word32*)rk[r][2]);
247 tmpU.tem4[3] = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
248 *((word32*)(b )) = *((word32*)T5[tmpU.temp[0][0]])
249 ^ *((word32*)T6[tmpU.temp[3][1]])
250 ^ *((word32*)T7[tmpU.temp[2][2]])
251 ^ *((word32*)T8[tmpU.temp[1][3]]);
252 *((word32*)(b+ 4)) = *((word32*)T5[tmpU.temp[1][0]])
253 ^ *((word32*)T6[tmpU.temp[0][1]])
254 ^ *((word32*)T7[tmpU.temp[3][2]])
255 ^ *((word32*)T8[tmpU.temp[2][3]]);
256 *((word32*)(b+ 8)) = *((word32*)T5[tmpU.temp[2][0]])
257 ^ *((word32*)T6[tmpU.temp[1][1]])
258 ^ *((word32*)T7[tmpU.temp[0][2]])
259 ^ *((word32*)T8[tmpU.temp[3][3]]);
260 *((word32*)(b+12)) = *((word32*)T5[tmpU.temp[3][0]])
261 ^ *((word32*)T6[tmpU.temp[2][1]])
262 ^ *((word32*)T7[tmpU.temp[1][2]])
263 ^ *((word32*)T8[tmpU.temp[0][3]]);
264 }
265 /* last round is special */
266 tmpU.tem4[0] = *((word32*)(b )) ^ *((word32*)rk[1][0]);
267 tmpU.tem4[1] = *((word32*)(b+ 4)) ^ *((word32*)rk[1][1]);
268 tmpU.tem4[2] = *((word32*)(b+ 8)) ^ *((word32*)rk[1][2]);
269 tmpU.tem4[3] = *((word32*)(b+12)) ^ *((word32*)rk[1][3]);
270 b[ 0] = S5[tmpU.temp[0][0]];
271 b[ 1] = S5[tmpU.temp[3][1]];
272 b[ 2] = S5[tmpU.temp[2][2]];
273 b[ 3] = S5[tmpU.temp[1][3]];
274 b[ 4] = S5[tmpU.temp[1][0]];
275 b[ 5] = S5[tmpU.temp[0][1]];
276 b[ 6] = S5[tmpU.temp[3][2]];
277 b[ 7] = S5[tmpU.temp[2][3]];
278 b[ 8] = S5[tmpU.temp[2][0]];
279 b[ 9] = S5[tmpU.temp[1][1]];
280 b[10] = S5[tmpU.temp[0][2]];
281 b[11] = S5[tmpU.temp[3][3]];
282 b[12] = S5[tmpU.temp[3][0]];
283 b[13] = S5[tmpU.temp[2][1]];
284 b[14] = S5[tmpU.temp[1][2]];
285 b[15] = S5[tmpU.temp[0][3]];
286 *((word32*)(b )) ^= *((word32*)rk[0][0]);
287 *((word32*)(b+ 4)) ^= *((word32*)rk[0][1]);
288 *((word32*)(b+ 8)) ^= *((word32*)rk[0][2]);
289 *((word32*)(b+12)) ^= *((word32*)rk[0][3]);
290
291 return 0;
292}
293
294#ifdef INTERMEDIATE_VALUE_KAT
295/**
296 * Encrypt only a certain number of rounds.
297 * Only used in the Intermediate Value Known Answer Test.
298 */
299int rijndaelEncryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds) {
300 int r;
301 word8 temp[4][4];
302
303 /* make number of rounds sane */
304 if (rounds > ROUNDS) {
305 rounds = ROUNDS;
306 }
307
308 *((word32*)a[0]) = *((word32*)a[0]) ^ *((word32*)rk[0][0]);
309 *((word32*)a[1]) = *((word32*)a[1]) ^ *((word32*)rk[0][1]);
310 *((word32*)a[2]) = *((word32*)a[2]) ^ *((word32*)rk[0][2]);
311 *((word32*)a[3]) = *((word32*)a[3]) ^ *((word32*)rk[0][3]);
312
313 for (r = 1; (r <= rounds) && (r < ROUNDS); r++) {
314 *((word32*)temp[0]) = *((word32*)T1[a[0][0]])
315 ^ *((word32*)T2[a[1][1]])
316 ^ *((word32*)T3[a[2][2]])
317 ^ *((word32*)T4[a[3][3]]);
318 *((word32*)temp[1]) = *((word32*)T1[a[1][0]])
319 ^ *((word32*)T2[a[2][1]])
320 ^ *((word32*)T3[a[3][2]])
321 ^ *((word32*)T4[a[0][3]]);
322 *((word32*)temp[2]) = *((word32*)T1[a[2][0]])
323 ^ *((word32*)T2[a[3][1]])
324 ^ *((word32*)T3[a[0][2]])
325 ^ *((word32*)T4[a[1][3]]);
326 *((word32*)temp[3]) = *((word32*)T1[a[3][0]])
327 ^ *((word32*)T2[a[0][1]])
328 ^ *((word32*)T3[a[1][2]])
329 ^ *((word32*)T4[a[2][3]]);
330 *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[r][0]);
331 *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[r][1]);
332 *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[r][2]);
333 *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[r][3]);
334 }
335 if (rounds == ROUNDS) {
336 /* last round is special */
337 temp[0][0] = T1[a[0][0]][1];
338 temp[0][1] = T1[a[1][1]][1];
339 temp[0][2] = T1[a[2][2]][1];
340 temp[0][3] = T1[a[3][3]][1];
341 temp[1][0] = T1[a[1][0]][1];
342 temp[1][1] = T1[a[2][1]][1];
343 temp[1][2] = T1[a[3][2]][1];
344 temp[1][3] = T1[a[0][3]][1];
345 temp[2][0] = T1[a[2][0]][1];
346 temp[2][1] = T1[a[3][1]][1];
347 temp[2][2] = T1[a[0][2]][1];
348 temp[2][3] = T1[a[1][3]][1];
349 temp[3][0] = T1[a[3][0]][1];
350 temp[3][1] = T1[a[0][1]][1];
351 temp[3][2] = T1[a[1][2]][1];
352 temp[3][3] = T1[a[2][3]][1];
353 *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[ROUNDS][0]);
354 *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[ROUNDS][1]);
355 *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[ROUNDS][2]);
356 *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[ROUNDS][3]);
357 }
358
359 return 0;
360}
361#endif /* INTERMEDIATE_VALUE_KAT */
362
363#ifdef INTERMEDIATE_VALUE_KAT
364/**
365 * Decrypt only a certain number of rounds.
366 * Only used in the Intermediate Value Known Answer Test.
367 * Operations rearranged such that the intermediate values
368 * of decryption correspond with the intermediate values
369 * of encryption.
370 */
371int rijndaelDecryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds) {
372 int r, i;
373 word8 temp[4], shift;
374
375 /* make number of rounds sane */
376 if (rounds > ROUNDS) {
377 rounds = ROUNDS;
378 }
379 /* first round is special: */
380 *(word32 *)a[0] ^= *(word32 *)rk[ROUNDS][0];
381 *(word32 *)a[1] ^= *(word32 *)rk[ROUNDS][1];
382 *(word32 *)a[2] ^= *(word32 *)rk[ROUNDS][2];
383 *(word32 *)a[3] ^= *(word32 *)rk[ROUNDS][3];
384 for (i = 0; i < 4; i++) {
385 a[i][0] = Si[a[i][0]];
386 a[i][1] = Si[a[i][1]];
387 a[i][2] = Si[a[i][2]];
388 a[i][3] = Si[a[i][3]];
389 }
390 for (i = 1; i < 4; i++) {
391 shift = (4 - i) & 3;
392 temp[0] = a[(0 + shift) & 3][i];
393 temp[1] = a[(1 + shift) & 3][i];
394 temp[2] = a[(2 + shift) & 3][i];
395 temp[3] = a[(3 + shift) & 3][i];
396 a[0][i] = temp[0];
397 a[1][i] = temp[1];
398 a[2][i] = temp[2];
399 a[3][i] = temp[3];
400 }
401 /* ROUNDS-1 ordinary rounds */
402 for (r = ROUNDS-1; r > rounds; r--) {
403 *(word32 *)a[0] ^= *(word32 *)rk[r][0];
404 *(word32 *)a[1] ^= *(word32 *)rk[r][1];
405 *(word32 *)a[2] ^= *(word32 *)rk[r][2];
406 *(word32 *)a[3] ^= *(word32 *)rk[r][3];
407
408 *((word32*)a[0]) =
409 *((word32*)U1[a[0][0]])
410 ^ *((word32*)U2[a[0][1]])
411 ^ *((word32*)U3[a[0][2]])
412 ^ *((word32*)U4[a[0][3]]);
413
414 *((word32*)a[1]) =
415 *((word32*)U1[a[1][0]])
416 ^ *((word32*)U2[a[1][1]])
417 ^ *((word32*)U3[a[1][2]])
418 ^ *((word32*)U4[a[1][3]]);
419
420 *((word32*)a[2]) =
421 *((word32*)U1[a[2][0]])
422 ^ *((word32*)U2[a[2][1]])
423 ^ *((word32*)U3[a[2][2]])
424 ^ *((word32*)U4[a[2][3]]);
425
426 *((word32*)a[3]) =
427 *((word32*)U1[a[3][0]])
428 ^ *((word32*)U2[a[3][1]])
429 ^ *((word32*)U3[a[3][2]])
430 ^ *((word32*)U4[a[3][3]]);
431 for (i = 0; i < 4; i++) {
432 a[i][0] = Si[a[i][0]];
433 a[i][1] = Si[a[i][1]];
434 a[i][2] = Si[a[i][2]];
435 a[i][3] = Si[a[i][3]];
436 }
437 for (i = 1; i < 4; i++) {
438 shift = (4 - i) & 3;
439 temp[0] = a[(0 + shift) & 3][i];
440 temp[1] = a[(1 + shift) & 3][i];
441 temp[2] = a[(2 + shift) & 3][i];
442 temp[3] = a[(3 + shift) & 3][i];
443 a[0][i] = temp[0];
444 a[1][i] = temp[1];
445 a[2][i] = temp[2];
446 a[3][i] = temp[3];
447 }
448 }
449 if (rounds == 0) {
450 /* End with the extra key addition */
451 *(word32 *)a[0] ^= *(word32 *)rk[0][0];
452 *(word32 *)a[1] ^= *(word32 *)rk[0][1];
453 *(word32 *)a[2] ^= *(word32 *)rk[0][2];
454 *(word32 *)a[3] ^= *(word32 *)rk[0][3];
455 }
456 return 0;
457}
458#endif /* INTERMEDIATE_VALUE_KAT */
459#endif
Note: See TracBrowser for help on using the repository browser.