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