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