moved alg-serpent and alg-twofish scenarios to gcrypt-ikev1
[strongswan.git] / src / libstrongswan / plugins / serpent / serpent.c
1 /* Optimized implementation of the Serpent AES candidate algorithm
2 * Designed by Anderson, Biham and Knudsen and Implemented by
3 * Gisle Sælensminde 2000.
4 *
5 * The implementation is based on the pentium optimised sboxes of
6 * Dag Arne Osvik. Even these sboxes are designed to be optimal for x86
7 * processors they are efficient on other processors as well, but the speedup
8 * isn't so impressive compared to other implementations.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public License
12 * as published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 */
15
16 #ifdef __KERNEL__
17 #include <linux/init.h>
18 #include <linux/types.h>
19
20 #include <asm/byteorder.h>
21 #else
22 #include <sys/types.h>
23 #include <asm/byteorder.h>
24 #endif
25
26 #include "serpent.h"
27
28 #define rotl(reg, val) ((reg << val) | (reg >> (32 - val)))
29 #define rotr(reg, val) ((reg >> val) | (reg << (32 - val)))
30
31 #ifdef __cpu_to_be32
32 #define BLOCK_SWAP
33 #define io_swap(x) __cpu_to_be32(x)
34 #else
35 #undef BLOCK_SWAP
36 #endif
37
38 /* The sbox functions. The first four parameters is the input bits, and
39 * the last is a tempoary. These parameters are also used for output, but
40 * the bit order is permuted. The output bit order from S0 is
41 * (1 4 2 0 3), where 3 is the (now useless) tempoary.
42 */
43
44 #define S0(r0,r1,r2,r3,r4) \
45 r3 = r3 ^ r0; \
46 r4 = r1; \
47 r1 = r1 & r3; \
48 r4 = r4 ^ r2; \
49 r1 = r1 ^ r0; \
50 r0 = r0 | r3; \
51 r0 = r0 ^ r4; \
52 r4 = r4 ^ r3; \
53 r3 = r3 ^ r2; \
54 r2 = r2 | r1; \
55 r2 = r2 ^ r4; \
56 r4 = -1 ^ r4; \
57 r4 = r4 | r1; \
58 r1 = r1 ^ r3; \
59 r1 = r1 ^ r4; \
60 r3 = r3 | r0; \
61 r1 = r1 ^ r3; \
62 r4 = r4 ^ r3;
63
64 #define S1(r0,r1,r2,r3,r4) \
65 r1 = -1 ^ r1; \
66 r4 = r0; \
67 r0 = r0 ^ r1; \
68 r4 = r4 | r1; \
69 r4 = r4 ^ r3; \
70 r3 = r3 & r0; \
71 r2 = r2 ^ r4; \
72 r3 = r3 ^ r1; \
73 r3 = r3 | r2; \
74 r0 = r0 ^ r4; \
75 r3 = r3 ^ r0; \
76 r1 = r1 & r2; \
77 r0 = r0 | r1; \
78 r1 = r1 ^ r4; \
79 r0 = r0 ^ r2; \
80 r4 = r4 | r3; \
81 r0 = r0 ^ r4; \
82 r4 = -1 ^ r4; \
83 r1 = r1 ^ r3; \
84 r4 = r4 & r2; \
85 r1 = -1 ^ r1; \
86 r4 = r4 ^ r0; \
87 r1 = r1 ^ r4;
88
89 #define S2(r0,r1,r2,r3,r4) \
90 r4 = r0; \
91 r0 = r0 & r2; \
92 r0 = r0 ^ r3; \
93 r2 = r2 ^ r1; \
94 r2 = r2 ^ r0; \
95 r3 = r3 | r4; \
96 r3 = r3 ^ r1; \
97 r4 = r4 ^ r2; \
98 r1 = r3; \
99 r3 = r3 | r4; \
100 r3 = r3 ^ r0; \
101 r0 = r0 & r1; \
102 r4 = r4 ^ r0; \
103 r1 = r1 ^ r3; \
104 r1 = r1 ^ r4; \
105 r4 = -1 ^ r4;
106
107 #define S3(r0,r1,r2,r3,r4) \
108 r4 = r0 ; \
109 r0 = r0 | r3; \
110 r3 = r3 ^ r1; \
111 r1 = r1 & r4; \
112 r4 = r4 ^ r2; \
113 r2 = r2 ^ r3; \
114 r3 = r3 & r0; \
115 r4 = r4 | r1; \
116 r3 = r3 ^ r4; \
117 r0 = r0 ^ r1; \
118 r4 = r4 & r0; \
119 r1 = r1 ^ r3; \
120 r4 = r4 ^ r2; \
121 r1 = r1 | r0; \
122 r1 = r1 ^ r2; \
123 r0 = r0 ^ r3; \
124 r2 = r1; \
125 r1 = r1 | r3; \
126 r1 = r1 ^ r0;
127
128 #define S4(r0,r1,r2,r3,r4) \
129 r1 = r1 ^ r3; \
130 r3 = -1 ^ r3; \
131 r2 = r2 ^ r3; \
132 r3 = r3 ^ r0; \
133 r4 = r1; \
134 r1 = r1 & r3; \
135 r1 = r1 ^ r2; \
136 r4 = r4 ^ r3; \
137 r0 = r0 ^ r4; \
138 r2 = r2 & r4; \
139 r2 = r2 ^ r0; \
140 r0 = r0 & r1; \
141 r3 = r3 ^ r0; \
142 r4 = r4 | r1; \
143 r4 = r4 ^ r0; \
144 r0 = r0 | r3; \
145 r0 = r0 ^ r2; \
146 r2 = r2 & r3; \
147 r0 = -1 ^ r0; \
148 r4 = r4 ^ r2;
149
150 #define S5(r0,r1,r2,r3,r4) \
151 r0 = r0 ^ r1; \
152 r1 = r1 ^ r3; \
153 r3 = -1 ^ r3; \
154 r4 = r1; \
155 r1 = r1 & r0; \
156 r2 = r2 ^ r3; \
157 r1 = r1 ^ r2; \
158 r2 = r2 | r4; \
159 r4 = r4 ^ r3; \
160 r3 = r3 & r1; \
161 r3 = r3 ^ r0; \
162 r4 = r4 ^ r1; \
163 r4 = r4 ^ r2; \
164 r2 = r2 ^ r0; \
165 r0 = r0 & r3; \
166 r2 = -1 ^ r2; \
167 r0 = r0 ^ r4; \
168 r4 = r4 | r3; \
169 r2 = r2 ^ r4;
170
171 #define S6(r0,r1,r2,r3,r4) \
172 r2 = -1 ^ r2; \
173 r4 = r3; \
174 r3 = r3 & r0; \
175 r0 = r0 ^ r4; \
176 r3 = r3 ^ r2; \
177 r2 = r2 | r4; \
178 r1 = r1 ^ r3; \
179 r2 = r2 ^ r0; \
180 r0 = r0 | r1; \
181 r2 = r2 ^ r1; \
182 r4 = r4 ^ r0; \
183 r0 = r0 | r3; \
184 r0 = r0 ^ r2; \
185 r4 = r4 ^ r3; \
186 r4 = r4 ^ r0; \
187 r3 = -1 ^ r3; \
188 r2 = r2 & r4; \
189 r2 = r2 ^ r3;
190
191 #define S7(r0,r1,r2,r3,r4) \
192 r4 = r2; \
193 r2 = r2 & r1; \
194 r2 = r2 ^ r3; \
195 r3 = r3 & r1; \
196 r4 = r4 ^ r2; \
197 r2 = r2 ^ r1; \
198 r1 = r1 ^ r0; \
199 r0 = r0 | r4; \
200 r0 = r0 ^ r2; \
201 r3 = r3 ^ r1; \
202 r2 = r2 ^ r3; \
203 r3 = r3 & r0; \
204 r3 = r3 ^ r4; \
205 r4 = r4 ^ r2; \
206 r2 = r2 & r0; \
207 r4 = -1 ^ r4; \
208 r2 = r2 ^ r4; \
209 r4 = r4 & r0; \
210 r1 = r1 ^ r3; \
211 r4 = r4 ^ r1;
212
213 /* The inverse sboxes */
214
215 #define I0(r0,r1,r2,r3,r4) \
216 r2 = r2 ^ -1; \
217 r4 = r1; \
218 r1 = r1 | r0; \
219 r4 = r4 ^ -1; \
220 r1 = r1 ^ r2; \
221 r2 = r2 | r4; \
222 r1 = r1 ^ r3; \
223 r0 = r0 ^ r4; \
224 r2 = r2 ^ r0; \
225 r0 = r0 & r3; \
226 r4 = r4 ^ r0; \
227 r0 = r0 | r1; \
228 r0 = r0 ^ r2; \
229 r3 = r3 ^ r4; \
230 r2 = r2 ^ r1; \
231 r3 = r3 ^ r0; \
232 r3 = r3 ^ r1; \
233 r2 = r2 & r3; \
234 r4 = r4 ^ r2;
235
236 #define I1(r0,r1,r2,r3,r4) \
237 r4 = r1; \
238 r1 = r1 ^ r3; \
239 r3 = r3 & r1; \
240 r4 = r4 ^ r2; \
241 r3 = r3 ^ r0; \
242 r0 = r0 | r1; \
243 r2 = r2 ^ r3; \
244 r0 = r0 ^ r4; \
245 r0 = r0 | r2; \
246 r1 = r1 ^ r3; \
247 r0 = r0 ^ r1; \
248 r1 = r1 | r3; \
249 r1 = r1 ^ r0; \
250 r4 = r4 ^ -1; \
251 r4 = r4 ^ r1; \
252 r1 = r1 | r0; \
253 r1 = r1 ^ r0; \
254 r1 = r1 | r4; \
255 r3 = r3 ^ r1;
256
257 #define I2(r0,r1,r2,r3,r4) \
258 r2 = r2 ^ r3; \
259 r3 = r3 ^ r0; \
260 r4 = r3; \
261 r3 = r3 & r2; \
262 r3 = r3 ^ r1; \
263 r1 = r1 | r2; \
264 r1 = r1 ^ r4; \
265 r4 = r4 & r3; \
266 r2 = r2 ^ r3; \
267 r4 = r4 & r0; \
268 r4 = r4 ^ r2; \
269 r2 = r2 & r1; \
270 r2 = r2 | r0; \
271 r3 = r3 ^ -1; \
272 r2 = r2 ^ r3; \
273 r0 = r0 ^ r3; \
274 r0 = r0 & r1; \
275 r3 = r3 ^ r4; \
276 r3 = r3 ^ r0;
277
278 #define I3(r0,r1,r2,r3,r4) \
279 r4 = r2; \
280 r2 = r2 ^ r1; \
281 r0 = r0 ^ r2; \
282 r4 = r4 & r2; \
283 r4 = r4 ^ r0; \
284 r0 = r0 & r1; \
285 r1 = r1 ^ r3; \
286 r3 = r3 | r4; \
287 r2 = r2 ^ r3; \
288 r0 = r0 ^ r3; \
289 r1 = r1 ^ r4; \
290 r3 = r3 & r2; \
291 r3 = r3 ^ r1; \
292 r1 = r1 ^ r0; \
293 r1 = r1 | r2; \
294 r0 = r0 ^ r3; \
295 r1 = r1 ^ r4; \
296 r0 = r0 ^ r1;
297
298 #define I4(r0,r1,r2,r3,r4) \
299 r4 = r2; \
300 r2 = r2 & r3; \
301 r2 = r2 ^ r1; \
302 r1 = r1 | r3; \
303 r1 = r1 & r0; \
304 r4 = r4 ^ r2; \
305 r4 = r4 ^ r1; \
306 r1 = r1 & r2; \
307 r0 = r0 ^ -1; \
308 r3 = r3 ^ r4; \
309 r1 = r1 ^ r3; \
310 r3 = r3 & r0; \
311 r3 = r3 ^ r2; \
312 r0 = r0 ^ r1; \
313 r2 = r2 & r0; \
314 r3 = r3 ^ r0; \
315 r2 = r2 ^ r4; \
316 r2 = r2 | r3; \
317 r3 = r3 ^ r0; \
318 r2 = r2 ^ r1;
319
320 #define I5(r0,r1,r2,r3,r4) \
321 r1 = r1 ^ -1; \
322 r4 = r3; \
323 r2 = r2 ^ r1; \
324 r3 = r3 | r0; \
325 r3 = r3 ^ r2; \
326 r2 = r2 | r1; \
327 r2 = r2 & r0; \
328 r4 = r4 ^ r3; \
329 r2 = r2 ^ r4; \
330 r4 = r4 | r0; \
331 r4 = r4 ^ r1; \
332 r1 = r1 & r2; \
333 r1 = r1 ^ r3; \
334 r4 = r4 ^ r2; \
335 r3 = r3 & r4; \
336 r4 = r4 ^ r1; \
337 r3 = r3 ^ r0; \
338 r3 = r3 ^ r4; \
339 r4 = r4 ^ -1;
340
341
342 #define I6(r0,r1,r2,r3,r4) \
343 r0 = r0 ^ r2; \
344 r4 = r2; \
345 r2 = r2 & r0; \
346 r4 = r4 ^ r3; \
347 r2 = r2 ^ -1; \
348 r3 = r3 ^ r1; \
349 r2 = r2 ^ r3; \
350 r4 = r4 | r0; \
351 r0 = r0 ^ r2; \
352 r3 = r3 ^ r4; \
353 r4 = r4 ^ r1; \
354 r1 = r1 & r3; \
355 r1 = r1 ^ r0; \
356 r0 = r0 ^ r3; \
357 r0 = r0 | r2; \
358 r3 = r3 ^ r1; \
359 r4 = r4 ^ r0;
360
361 #define I7(r0,r1,r2,r3,r4) \
362 r4 = r2; \
363 r2 = r2 ^ r0; \
364 r0 = r0 & r3; \
365 r4 = r4 | r3; \
366 r2 = r2 ^ -1; \
367 r3 = r3 ^ r1; \
368 r1 = r1 | r0; \
369 r0 = r0 ^ r2; \
370 r2 = r2 & r4; \
371 r3 = r3 & r4; \
372 r1 = r1 ^ r2; \
373 r2 = r2 ^ r0; \
374 r0 = r0 | r2; \
375 r4 = r4 ^ r1; \
376 r0 = r0 ^ r3; \
377 r3 = r3 ^ r4; \
378 r4 = r4 | r0; \
379 r3 = r3 ^ r2; \
380 r4 = r4 ^ r2;
381
382 /* forward and inverse linear transformations */
383
384 #define LINTRANS(r0,r1,r2,r3,r4) \
385 r0 = rotl(r0, 13); \
386 r2 = rotl(r2, 3); \
387 r3 = r3 ^ r2; \
388 r4 = r0 << 3; \
389 r1 = r1 ^ r0; \
390 r3 = r3 ^ r4; \
391 r1 = r1 ^ r2; \
392 r3 = rotl(r3, 7); \
393 r1 = rotl(r1, 1); \
394 r2 = r2 ^ r3; \
395 r4 = r1 << 7; \
396 r0 = r0 ^ r1; \
397 r2 = r2 ^ r4; \
398 r0 = r0 ^ r3; \
399 r2 = rotl(r2, 22); \
400 r0 = rotl(r0, 5);
401
402 #define ILINTRANS(r0,r1,r2,r3,r4) \
403 r2 = rotr(r2, 22); \
404 r0 = rotr(r0, 5); \
405 r2 = r2 ^ r3; \
406 r4 = r1 << 7; \
407 r0 = r0 ^ r1; \
408 r2 = r2 ^ r4; \
409 r0 = r0 ^ r3; \
410 r3 = rotr(r3, 7); \
411 r1 = rotr(r1, 1); \
412 r3 = r3 ^ r2; \
413 r4 = r0 << 3; \
414 r1 = r1 ^ r0; \
415 r3 = r3 ^ r4; \
416 r1 = r1 ^ r2; \
417 r2 = rotr(r2, 3); \
418 r0 = rotr(r0, 13);
419
420
421 #define KEYMIX(r0,r1,r2,r3,r4,IN) \
422 r0 = r0 ^ l_key[IN+8]; \
423 r1 = r1 ^ l_key[IN+9]; \
424 r2 = r2 ^ l_key[IN+10]; \
425 r3 = r3 ^ l_key[IN+11];
426
427 #define GETKEY(r0, r1, r2, r3, IN) \
428 r0 = l_key[IN+8]; \
429 r1 = l_key[IN+9]; \
430 r2 = l_key[IN+10]; \
431 r3 = l_key[IN+11];
432
433 #define SETKEY(r0, r1, r2, r3, IN) \
434 l_key[IN+8] = r0; \
435 l_key[IN+9] = r1; \
436 l_key[IN+10] = r2; \
437 l_key[IN+11] = r3;
438
439 /* initialise the key schedule from the user supplied key */
440
441 int serpent_set_key(serpent_context *cx, const unsigned char *key, int key_len)
442 { const u32 *in_key = (const u32 *)key;
443 /* l_key - storage for the key schedule */
444 u32 *l_key = cx->keyinfo;
445 u32 i,lk,r0,r1,r2,r3,r4;
446
447 if (key_len != 16 && key_len != 24 && key_len != 32)
448 return -1; /* unsupported key length */
449
450 key_len *= 8;
451
452 i = 0; lk = (key_len + 31) / 32;
453
454 while(i < lk)
455 {
456 #ifdef BLOCK_SWAP
457 l_key[i] = io_swap(in_key[lk - i - 1]);
458 #else
459 l_key[i] = in_key[i];
460 #endif
461 i++;
462 }
463
464 if (key_len < 256)
465 {
466 while(i < 8)
467
468 l_key[i++] = 0;
469
470 i = key_len / 32; lk = 1 << key_len % 32;
471
472 l_key[i] &= lk - 1;
473 l_key[i] |= lk;
474 }
475
476 for(i = 0; i < 132; ++i)
477 {
478 lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5]
479 ^ l_key[i + 7] ^ 0x9e3779b9 ^ i;
480
481 l_key[i + 8] = (lk << 11) | (lk >> 21);
482 }
483
484 GETKEY(r0, r1, r2, r3, 0);
485 S3(r0,r1,r2,r3,r4);
486 SETKEY(r1, r2, r3, r4, 0)
487
488 GETKEY(r0, r1, r2, r3, 4);
489 S2(r0,r1,r2,r3,r4);
490 SETKEY(r2, r3, r1, r4, 4)
491
492 GETKEY(r0, r1, r2, r3, 8);
493 S1(r0,r1,r2,r3,r4);
494 SETKEY(r3, r1, r2, r0, 8)
495
496 GETKEY(r0, r1, r2, r3, 12);
497 S0(r0,r1,r2,r3,r4);
498 SETKEY(r1, r4, r2, r0, 12)
499
500 GETKEY(r0, r1, r2, r3, 16);
501 S7(r0,r1,r2,r3,r4);
502 SETKEY(r2, r4, r3, r0, 16)
503
504 GETKEY(r0, r1, r2, r3, 20);
505 S6(r0,r1,r2,r3,r4)
506 SETKEY(r0, r1, r4, r2, 20)
507
508 GETKEY(r0, r1, r2, r3, 24);
509 S5(r0,r1,r2,r3,r4);
510 SETKEY(r1, r3, r0, r2, 24)
511
512 GETKEY(r0, r1, r2, r3, 28);
513 S4(r0,r1,r2,r3,r4)
514 SETKEY(r1, r4, r0, r3, 28)
515
516 GETKEY(r0, r1, r2, r3, 32);
517 S3(r0,r1,r2,r3,r4);
518 SETKEY(r1, r2, r3, r4, 32)
519
520 GETKEY(r0, r1, r2, r3, 36);
521 S2(r0,r1,r2,r3,r4);
522 SETKEY(r2, r3, r1, r4, 36)
523
524 GETKEY(r0, r1, r2, r3, 40);
525 S1(r0,r1,r2,r3,r4);
526 SETKEY(r3, r1, r2, r0, 40)
527
528 GETKEY(r0, r1, r2, r3, 44);
529 S0(r0,r1,r2,r3,r4);
530 SETKEY(r1, r4, r2, r0, 44)
531
532 GETKEY(r0, r1, r2, r3, 48);
533 S7(r0,r1,r2,r3,r4);
534 SETKEY(r2, r4, r3, r0, 48)
535
536 GETKEY(r0, r1, r2, r3, 52);
537 S6(r0,r1,r2,r3,r4)
538 SETKEY(r0, r1, r4, r2, 52)
539
540 GETKEY(r0, r1, r2, r3, 56);
541 S5(r0,r1,r2,r3,r4);
542 SETKEY(r1, r3, r0, r2, 56)
543
544 GETKEY(r0, r1, r2, r3, 60);
545 S4(r0,r1,r2,r3,r4)
546 SETKEY(r1, r4, r0, r3, 60)
547
548 GETKEY(r0, r1, r2, r3, 64);
549 S3(r0,r1,r2,r3,r4);
550 SETKEY(r1, r2, r3, r4, 64)
551
552 GETKEY(r0, r1, r2, r3, 68);
553 S2(r0,r1,r2,r3,r4);
554 SETKEY(r2, r3, r1, r4, 68)
555
556 GETKEY(r0, r1, r2, r3, 72);
557 S1(r0,r1,r2,r3,r4);
558 SETKEY(r3, r1, r2, r0, 72)
559
560 GETKEY(r0, r1, r2, r3, 76);
561 S0(r0,r1,r2,r3,r4);
562 SETKEY(r1, r4, r2, r0, 76)
563
564 GETKEY(r0, r1, r2, r3, 80);
565 S7(r0,r1,r2,r3,r4);
566 SETKEY(r2, r4, r3, r0, 80)
567
568 GETKEY(r0, r1, r2, r3, 84);
569 S6(r0,r1,r2,r3,r4)
570 SETKEY(r0, r1, r4, r2, 84)
571
572 GETKEY(r0, r1, r2, r3, 88);
573 S5(r0,r1,r2,r3,r4);
574 SETKEY(r1, r3, r0, r2, 88)
575
576 GETKEY(r0, r1, r2, r3, 92);
577 S4(r0,r1,r2,r3,r4)
578 SETKEY(r1, r4, r0, r3, 92)
579
580 GETKEY(r0, r1, r2, r3, 96);
581 S3(r0,r1,r2,r3,r4);
582 SETKEY(r1, r2, r3, r4, 96)
583
584 GETKEY(r0, r1, r2, r3, 100);
585 S2(r0,r1,r2,r3,r4);
586 SETKEY(r2, r3, r1, r4, 100)
587
588 GETKEY(r0, r1, r2, r3, 104);
589 S1(r0,r1,r2,r3,r4);
590 SETKEY(r3, r1, r2, r0, 104)
591
592 GETKEY(r0, r1, r2, r3, 108);
593 S0(r0,r1,r2,r3,r4);
594 SETKEY(r1, r4, r2, r0, 108)
595
596 GETKEY(r0, r1, r2, r3, 112);
597 S7(r0,r1,r2,r3,r4);
598 SETKEY(r2, r4, r3, r0, 112)
599
600 GETKEY(r0, r1, r2, r3, 116);
601 S6(r0,r1,r2,r3,r4)
602 SETKEY(r0, r1, r4, r2, 116)
603
604 GETKEY(r0, r1, r2, r3, 120);
605 S5(r0,r1,r2,r3,r4);
606 SETKEY(r1, r3, r0, r2, 120)
607
608 GETKEY(r0, r1, r2, r3, 124);
609 S4(r0,r1,r2,r3,r4)
610 SETKEY(r1, r4, r0, r3, 124)
611
612 GETKEY(r0, r1, r2, r3, 128);
613 S3(r0,r1,r2,r3,r4);
614 SETKEY(r1, r2, r3, r4, 128)
615
616 return 0;
617 };
618
619 /* Encryption and decryption functions. The rounds are fully inlined.
620 * The sboxes alters the bit order of the output, and the altered
621 * bit ordrer is used progressivly. */
622
623 /* encrypt a block of text */
624
625 int serpent_encrypt(serpent_context *cx, const u8 *in,
626 u8 *out)
627 { u32 *l_key = cx->keyinfo;
628 const u32 *in_blk = (const u32 *) in;
629 u32 *out_blk = (u32 *) out;
630 u32 r0,r1,r2,r3,r4;
631
632 #ifdef BLOCK_SWAP
633 r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]);
634 r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]);
635 #else
636 r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3];
637 #endif
638
639 /* round 1 */
640 KEYMIX(r0,r1,r2,r3,r4,0);
641 S0(r0,r1,r2,r3,r4);
642 LINTRANS(r1,r4,r2,r0,r3);
643
644 /* round 2 */
645 KEYMIX(r1,r4,r2,r0,r3,4);
646 S1(r1,r4,r2,r0,r3);
647 LINTRANS(r0,r4,r2,r1,r3);
648
649 /* round 3 */
650 KEYMIX(r0,r4,r2,r1,r3,8);
651 S2(r0,r4,r2,r1,r3);
652 LINTRANS(r2,r1,r4,r3,r0);
653
654 /* round 4 */
655 KEYMIX(r2,r1,r4,r3,r0,12);
656 S3(r2,r1,r4,r3,r0);
657 LINTRANS(r1,r4,r3,r0,r2);
658
659 /* round 5 */
660 KEYMIX(r1,r4,r3,r0,r2,16);
661 S4(r1,r4,r3,r0,r2)
662 LINTRANS(r4,r2,r1,r0,r3);
663
664 /* round 6 */
665 KEYMIX(r4,r2,r1,r0,r3,20);
666 S5(r4,r2,r1,r0,r3);
667 LINTRANS(r2,r0,r4,r1,r3);
668
669 /* round 7 */
670 KEYMIX(r2,r0,r4,r1,r3,24);
671 S6(r2,r0,r4,r1,r3)
672 LINTRANS(r2,r0,r3,r4,r1);
673
674 /* round 8 */
675 KEYMIX(r2,r0,r3,r4,r1,28);
676 S7(r2,r0,r3,r4,r1);
677 LINTRANS(r3,r1,r4,r2,r0);
678
679 /* round 9 */
680 KEYMIX(r3,r1,r4,r2,r0,32);
681 S0(r3,r1,r4,r2,r0);
682 LINTRANS(r1,r0,r4,r3,r2);
683
684 /* round 10 */
685 KEYMIX(r1,r0,r4,r3,r2,36);
686 S1(r1,r0,r4,r3,r2);
687 LINTRANS(r3,r0,r4,r1,r2);
688
689 /* round 11 */
690 KEYMIX(r3,r0,r4,r1,r2,40);
691 S2(r3,r0,r4,r1,r2);
692 LINTRANS(r4,r1,r0,r2,r3);
693
694 /* round 12 */
695 KEYMIX(r4,r1,r0,r2,r3,44);
696 S3(r4,r1,r0,r2,r3);
697 LINTRANS(r1,r0,r2,r3,r4);
698
699 /* round 13 */
700 KEYMIX(r1,r0,r2,r3,r4,48);
701 S4(r1,r0,r2,r3,r4)
702 LINTRANS(r0,r4,r1,r3,r2);
703
704 /* round 14 */
705 KEYMIX(r0,r4,r1,r3,r2,52);
706 S5(r0,r4,r1,r3,r2);
707 LINTRANS(r4,r3,r0,r1,r2);
708
709 /* round 15 */
710 KEYMIX(r4,r3,r0,r1,r2,56);
711 S6(r4,r3,r0,r1,r2)
712 LINTRANS(r4,r3,r2,r0,r1);
713
714 /* round 16 */
715 KEYMIX(r4,r3,r2,r0,r1,60);
716 S7(r4,r3,r2,r0,r1);
717 LINTRANS(r2,r1,r0,r4,r3);
718
719 /* round 17 */
720 KEYMIX(r2,r1,r0,r4,r3,64);
721 S0(r2,r1,r0,r4,r3);
722 LINTRANS(r1,r3,r0,r2,r4);
723
724 /* round 18 */
725 KEYMIX(r1,r3,r0,r2,r4,68);
726 S1(r1,r3,r0,r2,r4);
727 LINTRANS(r2,r3,r0,r1,r4);
728
729 /* round 19 */
730 KEYMIX(r2,r3,r0,r1,r4,72);
731 S2(r2,r3,r0,r1,r4);
732 LINTRANS(r0,r1,r3,r4,r2);
733
734 /* round 20 */
735 KEYMIX(r0,r1,r3,r4,r2,76);
736 S3(r0,r1,r3,r4,r2);
737 LINTRANS(r1,r3,r4,r2,r0);
738
739 /* round 21 */
740 KEYMIX(r1,r3,r4,r2,r0,80);
741 S4(r1,r3,r4,r2,r0)
742 LINTRANS(r3,r0,r1,r2,r4);
743
744 /* round 22 */
745 KEYMIX(r3,r0,r1,r2,r4,84);
746 S5(r3,r0,r1,r2,r4);
747 LINTRANS(r0,r2,r3,r1,r4);
748
749 /* round 23 */
750 KEYMIX(r0,r2,r3,r1,r4,88);
751 S6(r0,r2,r3,r1,r4)
752 LINTRANS(r0,r2,r4,r3,r1);
753
754 /* round 24 */
755 KEYMIX(r0,r2,r4,r3,r1,92);
756 S7(r0,r2,r4,r3,r1);
757 LINTRANS(r4,r1,r3,r0,r2);
758
759 /* round 25 */
760 KEYMIX(r4,r1,r3,r0,r2,96);
761 S0(r4,r1,r3,r0,r2);
762 LINTRANS(r1,r2,r3,r4,r0);
763
764 /* round 26 */
765 KEYMIX(r1,r2,r3,r4,r0,100);
766 S1(r1,r2,r3,r4,r0);
767 LINTRANS(r4,r2,r3,r1,r0);
768
769 /* round 27 */
770 KEYMIX(r4,r2,r3,r1,r0,104);
771 S2(r4,r2,r3,r1,r0);
772 LINTRANS(r3,r1,r2,r0,r4);
773
774 /* round 28 */
775 KEYMIX(r3,r1,r2,r0,r4,108);
776 S3(r3,r1,r2,r0,r4);
777 LINTRANS(r1,r2,r0,r4,r3);
778
779 /* round 29 */
780 KEYMIX(r1,r2,r0,r4,r3,112);
781 S4(r1,r2,r0,r4,r3)
782 LINTRANS(r2,r3,r1,r4,r0);
783
784 /* round 30 */
785 KEYMIX(r2,r3,r1,r4,r0,116);
786 S5(r2,r3,r1,r4,r0);
787 LINTRANS(r3,r4,r2,r1,r0);
788
789 /* round 31 */
790 KEYMIX(r3,r4,r2,r1,r0,120);
791 S6(r3,r4,r2,r1,r0)
792 LINTRANS(r3,r4,r0,r2,r1);
793
794 /* round 32 */
795 KEYMIX(r3,r4,r0,r2,r1,124);
796 S7(r3,r4,r0,r2,r1);
797 KEYMIX(r0,r1,r2,r3,r4,128);
798
799
800 #ifdef BLOCK_SWAP
801 out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1);
802 out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3);
803 #else
804 out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3;
805 #endif
806 return 0;
807 };
808
809 /* decrypt a block of text */
810
811 int serpent_decrypt(serpent_context *cx, const u8 *in,
812 u8 *out)
813 { u32 *l_key = cx->keyinfo;
814 const u32 *in_blk = (const u32 *)in;
815 u32 *out_blk = (u32 *)out;
816 u32 r0,r1,r2,r3,r4;
817
818 #ifdef BLOCK_SWAP
819 r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]);
820 r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]);
821 #else
822 r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3];
823 #endif
824
825 /* round 1 */
826 KEYMIX(r0,r1,r2,r3,r4,128);
827 I7(r0,r1,r2,r3,r4);
828 KEYMIX(r3,r0,r1,r4,r2,124);
829
830 /* round 2 */
831 ILINTRANS(r3,r0,r1,r4,r2);
832 I6(r3,r0,r1,r4,r2);
833 KEYMIX(r0,r1,r2,r4,r3,120);
834
835 /* round 3 */
836 ILINTRANS(r0,r1,r2,r4,r3);
837 I5(r0,r1,r2,r4,r3);
838 KEYMIX(r1,r3,r4,r2,r0,116);
839
840 /* round 4 */
841 ILINTRANS(r1,r3,r4,r2,r0);
842 I4(r1,r3,r4,r2,r0);
843 KEYMIX(r1,r2,r4,r0,r3,112);
844
845 /* round 5 */
846 ILINTRANS(r1,r2,r4,r0,r3);
847 I3(r1,r2,r4,r0,r3);
848 KEYMIX(r4,r2,r0,r1,r3,108);
849
850 /* round 6 */
851 ILINTRANS(r4,r2,r0,r1,r3);
852 I2(r4,r2,r0,r1,r3);
853 KEYMIX(r2,r3,r0,r1,r4,104);
854
855 /* round 7 */
856 ILINTRANS(r2,r3,r0,r1,r4);
857 I1(r2,r3,r0,r1,r4);
858 KEYMIX(r4,r2,r1,r0,r3,100);
859
860 /* round 8 */
861 ILINTRANS(r4,r2,r1,r0,r3);
862 I0(r4,r2,r1,r0,r3);
863 KEYMIX(r4,r3,r2,r0,r1,96);
864
865 /* round 9 */
866 ILINTRANS(r4,r3,r2,r0,r1);
867 I7(r4,r3,r2,r0,r1);
868 KEYMIX(r0,r4,r3,r1,r2,92);
869
870 /* round 10 */
871 ILINTRANS(r0,r4,r3,r1,r2);
872 I6(r0,r4,r3,r1,r2);
873 KEYMIX(r4,r3,r2,r1,r0,88);
874
875 /* round 11 */
876 ILINTRANS(r4,r3,r2,r1,r0);
877 I5(r4,r3,r2,r1,r0);
878 KEYMIX(r3,r0,r1,r2,r4,84);
879
880 /* round 12 */
881 ILINTRANS(r3,r0,r1,r2,r4);
882 I4(r3,r0,r1,r2,r4);
883 KEYMIX(r3,r2,r1,r4,r0,80);
884
885 /* round 13 */
886 ILINTRANS(r3,r2,r1,r4,r0);
887 I3(r3,r2,r1,r4,r0);
888 KEYMIX(r1,r2,r4,r3,r0,76);
889
890 /* round 14 */
891 ILINTRANS(r1,r2,r4,r3,r0);
892 I2(r1,r2,r4,r3,r0);
893 KEYMIX(r2,r0,r4,r3,r1,72);
894
895 /* round 15 */
896 ILINTRANS(r2,r0,r4,r3,r1);
897 I1(r2,r0,r4,r3,r1);
898 KEYMIX(r1,r2,r3,r4,r0,68);
899
900 /* round 16 */
901 ILINTRANS(r1,r2,r3,r4,r0);
902 I0(r1,r2,r3,r4,r0);
903 KEYMIX(r1,r0,r2,r4,r3,64);
904
905 /* round 17 */
906 ILINTRANS(r1,r0,r2,r4,r3);
907 I7(r1,r0,r2,r4,r3);
908 KEYMIX(r4,r1,r0,r3,r2,60);
909
910 /* round 18 */
911 ILINTRANS(r4,r1,r0,r3,r2);
912 I6(r4,r1,r0,r3,r2);
913 KEYMIX(r1,r0,r2,r3,r4,56);
914
915 /* round 19 */
916 ILINTRANS(r1,r0,r2,r3,r4);
917 I5(r1,r0,r2,r3,r4);
918 KEYMIX(r0,r4,r3,r2,r1,52);
919
920 /* round 20 */
921 ILINTRANS(r0,r4,r3,r2,r1);
922 I4(r0,r4,r3,r2,r1);
923 KEYMIX(r0,r2,r3,r1,r4,48);
924
925 /* round 21 */
926 ILINTRANS(r0,r2,r3,r1,r4);
927 I3(r0,r2,r3,r1,r4);
928 KEYMIX(r3,r2,r1,r0,r4,44);
929
930 /* round 22 */
931 ILINTRANS(r3,r2,r1,r0,r4);
932 I2(r3,r2,r1,r0,r4);
933 KEYMIX(r2,r4,r1,r0,r3,40);
934
935 /* round 23 */
936 ILINTRANS(r2,r4,r1,r0,r3);
937 I1(r2,r4,r1,r0,r3);
938 KEYMIX(r3,r2,r0,r1,r4,36);
939
940 /* round 24 */
941 ILINTRANS(r3,r2,r0,r1,r4);
942 I0(r3,r2,r0,r1,r4);
943 KEYMIX(r3,r4,r2,r1,r0,32);
944
945 /* round 25 */
946 ILINTRANS(r3,r4,r2,r1,r0);
947 I7(r3,r4,r2,r1,r0);
948 KEYMIX(r1,r3,r4,r0,r2,28);
949
950 /* round 26 */
951 ILINTRANS(r1,r3,r4,r0,r2);
952 I6(r1,r3,r4,r0,r2);
953 KEYMIX(r3,r4,r2,r0,r1,24);
954
955 /* round 27 */
956 ILINTRANS(r3,r4,r2,r0,r1);
957 I5(r3,r4,r2,r0,r1);
958 KEYMIX(r4,r1,r0,r2,r3,20);
959
960 /* round 28 */
961 ILINTRANS(r4,r1,r0,r2,r3);
962 I4(r4,r1,r0,r2,r3);
963 KEYMIX(r4,r2,r0,r3,r1,16);
964
965 /* round 29 */
966 ILINTRANS(r4,r2,r0,r3,r1);
967 I3(r4,r2,r0,r3,r1);
968 KEYMIX(r0,r2,r3,r4,r1,12);
969
970 /* round 30 */
971 ILINTRANS(r0,r2,r3,r4,r1);
972 I2(r0,r2,r3,r4,r1);
973 KEYMIX(r2,r1,r3,r4,r0,8);
974
975 /* round 31 */
976 ILINTRANS(r2,r1,r3,r4,r0);
977 I1(r2,r1,r3,r4,r0);
978 KEYMIX(r0,r2,r4,r3,r1,4);
979
980 /* round 32 */
981 ILINTRANS(r0,r2,r4,r3,r1);
982 I0(r0,r2,r4,r3,r1);
983 KEYMIX(r0,r1,r2,r3,r4,0);
984
985 #ifdef BLOCK_SWAP
986 out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1);
987 out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3);
988 #else
989 out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3;
990 #endif
991 return 0;
992 };
993