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