A lot of cleanups as well as minor API changes.
[libgcrypt.git] / cipher / serpent.c
1 /* serpent.c - Implementation of the Serpent encryption algorithm.
2  *      Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.
20  */
21
22 #include <config.h>
23
24 #include <string.h>
25 #include <stdio.h>
26
27 #include "types.h"
28 #include "g10lib.h"
29 #include "cipher.h"
30 #include "bithelp.h"
31
32 /* Number of rounds per Serpent encrypt/decrypt operation.  */
33 #define ROUNDS 32
34
35 /* Magic number, used during generating of the subkeys.  */
36 #define PHI 0x9E3779B9
37
38 /* Serpent works on 128 bit blocks.  */
39 typedef u32 serpent_block_t[4];
40
41 /* Serpent key, provided by the user.  If the original key is shorter
42    than 256 bits, it is padded.  */
43 typedef u32 serpent_key_t[8];
44
45 /* The key schedule consists of 33 128 bit subkeys.  */
46 typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
47
48 /* A Serpent context.  */
49 typedef struct serpent_context
50 {
51   serpent_subkeys_t keys;       /* Generated subkeys.  */
52 } serpent_context_t;
53
54
55 /* A prototype.  */
56 static const char *serpent_test (void);
57       
58
59 #define byte_swap_32(x) \
60   (0 \
61    | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) \
62    | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
63
64 /* These are the S-Boxes of Serpent.  They are copied from Serpents
65    reference implementation (the optimized one, contained in
66    `floppy2') and are therefore:
67
68      Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
69
70   To quote the Serpent homepage
71   (http://www.cl.cam.ac.uk/~rja14/serpent.html):
72
73   "Serpent is now completely in the public domain, and we impose no
74    restrictions on its use.  This was announced on the 21st August at
75    the First AES Candidate Conference. The optimised implementations
76    in the submission package are now under the GNU PUBLIC LICENSE
77    (GPL), although some comments in the code still say otherwise. You
78    are welcome to use Serpent for any application."  */
79
80 #define SBOX0(a, b, c, d, w, x, y, z) \
81   { \
82     u32 t02, t03, t05, t06, t07, t08, t09; \
83     u32 t11, t12, t13, t14, t15, t17, t01; \
84     t01 = b   ^ c  ; \
85     t02 = a   | d  ; \
86     t03 = a   ^ b  ; \
87     z   = t02 ^ t01; \
88     t05 = c   | z  ; \
89     t06 = a   ^ d  ; \
90     t07 = b   | c  ; \
91     t08 = d   & t05; \
92     t09 = t03 & t07; \
93     y   = t09 ^ t08; \
94     t11 = t09 & y  ; \
95     t12 = c   ^ d  ; \
96     t13 = t07 ^ t11; \
97     t14 = b   & t06; \
98     t15 = t06 ^ t13; \
99     w   =     ~ t15; \
100     t17 = w   ^ t14; \
101     x   = t12 ^ t17; \
102   }
103
104 #define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
105   { \
106     u32 t02, t03, t04, t05, t06, t08, t09, t10; \
107     u32 t12, t13, t14, t15, t17, t18, t01; \
108     t01 = c   ^ d  ; \
109     t02 = a   | b  ; \
110     t03 = b   | c  ; \
111     t04 = c   & t01; \
112     t05 = t02 ^ t01; \
113     t06 = a   | t04; \
114     y   =     ~ t05; \
115     t08 = b   ^ d  ; \
116     t09 = t03 & t08; \
117     t10 = d   | y  ; \
118     x   = t09 ^ t06; \
119     t12 = a   | t05; \
120     t13 = x   ^ t12; \
121     t14 = t03 ^ t10; \
122     t15 = a   ^ c  ; \
123     z   = t14 ^ t13; \
124     t17 = t05 & t13; \
125     t18 = t14 | t17; \
126     w   = t15 ^ t18; \
127   }
128
129 #define SBOX1(a, b, c, d, w, x, y, z) \
130   { \
131     u32 t02, t03, t04, t05, t06, t07, t08; \
132     u32 t10, t11, t12, t13, t16, t17, t01; \
133     t01 = a   | d  ; \
134     t02 = c   ^ d  ; \
135     t03 =     ~ b  ; \
136     t04 = a   ^ c  ; \
137     t05 = a   | t03; \
138     t06 = d   & t04; \
139     t07 = t01 & t02; \
140     t08 = b   | t06; \
141     y   = t02 ^ t05; \
142     t10 = t07 ^ t08; \
143     t11 = t01 ^ t10; \
144     t12 = y   ^ t11; \
145     t13 = b   & d  ; \
146     z   =     ~ t10; \
147     x   = t13 ^ t12; \
148     t16 = t10 | x  ; \
149     t17 = t05 & t16; \
150     w   = c   ^ t17; \
151   }
152
153 #define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
154   { \
155     u32 t02, t03, t04, t05, t06, t07, t08; \
156     u32 t09, t10, t11, t14, t15, t17, t01; \
157     t01 = a   ^ b  ; \
158     t02 = b   | d  ; \
159     t03 = a   & c  ; \
160     t04 = c   ^ t02; \
161     t05 = a   | t04; \
162     t06 = t01 & t05; \
163     t07 = d   | t03; \
164     t08 = b   ^ t06; \
165     t09 = t07 ^ t06; \
166     t10 = t04 | t03; \
167     t11 = d   & t08; \
168     y   =     ~ t09; \
169     x   = t10 ^ t11; \
170     t14 = a   | y  ; \
171     t15 = t06 ^ x  ; \
172     z   = t01 ^ t04; \
173     t17 = c   ^ t15; \
174     w   = t14 ^ t17; \
175   }
176
177 #define SBOX2(a, b, c, d, w, x, y, z) \
178   { \
179     u32 t02, t03, t05, t06, t07, t08; \
180     u32 t09, t10, t12, t13, t14, t01; \
181     t01 = a   | c  ; \
182     t02 = a   ^ b  ; \
183     t03 = d   ^ t01; \
184     w   = t02 ^ t03; \
185     t05 = c   ^ w  ; \
186     t06 = b   ^ t05; \
187     t07 = b   | t05; \
188     t08 = t01 & t06; \
189     t09 = t03 ^ t07; \
190     t10 = t02 | t09; \
191     x   = t10 ^ t08; \
192     t12 = a   | d  ; \
193     t13 = t09 ^ x  ; \
194     t14 = b   ^ t13; \
195     z   =     ~ t09; \
196     y   = t12 ^ t14; \
197   }
198
199 #define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
200   { \
201     u32 t02, t03, t04, t06, t07, t08, t09; \
202     u32 t10, t11, t12, t15, t16, t17, t01; \
203     t01 = a   ^ d  ; \
204     t02 = c   ^ d  ; \
205     t03 = a   & c  ; \
206     t04 = b   | t02; \
207     w   = t01 ^ t04; \
208     t06 = a   | c  ; \
209     t07 = d   | w  ; \
210     t08 =     ~ d  ; \
211     t09 = b   & t06; \
212     t10 = t08 | t03; \
213     t11 = b   & t07; \
214     t12 = t06 & t02; \
215     z   = t09 ^ t10; \
216     x   = t12 ^ t11; \
217     t15 = c   & z  ; \
218     t16 = w   ^ x  ; \
219     t17 = t10 ^ t15; \
220     y   = t16 ^ t17; \
221   }
222
223 #define SBOX3(a, b, c, d, w, x, y, z) \
224   { \
225     u32 t02, t03, t04, t05, t06, t07, t08; \
226     u32 t09, t10, t11, t13, t14, t15, t01; \
227     t01 = a   ^ c  ; \
228     t02 = a   | d  ; \
229     t03 = a   & d  ; \
230     t04 = t01 & t02; \
231     t05 = b   | t03; \
232     t06 = a   & b  ; \
233     t07 = d   ^ t04; \
234     t08 = c   | t06; \
235     t09 = b   ^ t07; \
236     t10 = d   & t05; \
237     t11 = t02 ^ t10; \
238     z   = t08 ^ t09; \
239     t13 = d   | z  ; \
240     t14 = a   | t07; \
241     t15 = b   & t13; \
242     y   = t08 ^ t11; \
243     w   = t14 ^ t15; \
244     x   = t05 ^ t04; \
245   }
246
247 #define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
248   { \
249     u32 t02, t03, t04, t05, t06, t07, t09; \
250     u32 t11, t12, t13, t14, t16, t01; \
251     t01 = c   | d  ; \
252     t02 = a   | d  ; \
253     t03 = c   ^ t02; \
254     t04 = b   ^ t02; \
255     t05 = a   ^ d  ; \
256     t06 = t04 & t03; \
257     t07 = b   & t01; \
258     y   = t05 ^ t06; \
259     t09 = a   ^ t03; \
260     w   = t07 ^ t03; \
261     t11 = w   | t05; \
262     t12 = t09 & t11; \
263     t13 = a   & y  ; \
264     t14 = t01 ^ t05; \
265     x   = b   ^ t12; \
266     t16 = b   | t13; \
267     z   = t14 ^ t16; \
268   }
269
270 #define SBOX4(a, b, c, d, w, x, y, z) \
271   { \
272     u32 t02, t03, t04, t05, t06, t08, t09; \
273     u32 t10, t11, t12, t13, t14, t15, t16, t01; \
274     t01 = a   | b  ; \
275     t02 = b   | c  ; \
276     t03 = a   ^ t02; \
277     t04 = b   ^ d  ; \
278     t05 = d   | t03; \
279     t06 = d   & t01; \
280     z   = t03 ^ t06; \
281     t08 = z   & t04; \
282     t09 = t04 & t05; \
283     t10 = c   ^ t06; \
284     t11 = b   & c  ; \
285     t12 = t04 ^ t08; \
286     t13 = t11 | t03; \
287     t14 = t10 ^ t09; \
288     t15 = a   & t05; \
289     t16 = t11 | t12; \
290     y   = t13 ^ t08; \
291     x   = t15 ^ t16; \
292     w   =     ~ t14; \
293   }
294
295 #define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
296   { \
297     u32 t02, t03, t04, t05, t06, t07, t09; \
298     u32 t10, t11, t12, t13, t15, t01; \
299     t01 = b   | d  ; \
300     t02 = c   | d  ; \
301     t03 = a   & t01; \
302     t04 = b   ^ t02; \
303     t05 = c   ^ d  ; \
304     t06 =     ~ t03; \
305     t07 = a   & t04; \
306     x   = t05 ^ t07; \
307     t09 = x   | t06; \
308     t10 = a   ^ t07; \
309     t11 = t01 ^ t09; \
310     t12 = d   ^ t04; \
311     t13 = c   | t10; \
312     z   = t03 ^ t12; \
313     t15 = a   ^ t04; \
314     y   = t11 ^ t13; \
315     w   = t15 ^ t09; \
316   }
317
318 #define SBOX5(a, b, c, d, w, x, y, z) \
319   { \
320     u32 t02, t03, t04, t05, t07, t08, t09; \
321     u32 t10, t11, t12, t13, t14, t01; \
322     t01 = b   ^ d  ; \
323     t02 = b   | d  ; \
324     t03 = a   & t01; \
325     t04 = c   ^ t02; \
326     t05 = t03 ^ t04; \
327     w   =     ~ t05; \
328     t07 = a   ^ t01; \
329     t08 = d   | w  ; \
330     t09 = b   | t05; \
331     t10 = d   ^ t08; \
332     t11 = b   | t07; \
333     t12 = t03 | w  ; \
334     t13 = t07 | t10; \
335     t14 = t01 ^ t11; \
336     y   = t09 ^ t13; \
337     x   = t07 ^ t08; \
338     z   = t12 ^ t14; \
339   }
340
341 #define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
342   { \
343     u32 t02, t03, t04, t05, t07, t08, t09; \
344     u32 t10, t12, t13, t15, t16, t01; \
345     t01 = a   & d  ; \
346     t02 = c   ^ t01; \
347     t03 = a   ^ d  ; \
348     t04 = b   & t02; \
349     t05 = a   & c  ; \
350     w   = t03 ^ t04; \
351     t07 = a   & w  ; \
352     t08 = t01 ^ w  ; \
353     t09 = b   | t05; \
354     t10 =     ~ b  ; \
355     x   = t08 ^ t09; \
356     t12 = t10 | t07; \
357     t13 = w   | x  ; \
358     z   = t02 ^ t12; \
359     t15 = t02 ^ t13; \
360     t16 = b   ^ d  ; \
361     y   = t16 ^ t15; \
362   }
363
364 #define SBOX6(a, b, c, d, w, x, y, z) \
365   { \
366     u32 t02, t03, t04, t05, t07, t08, t09, t10; \
367     u32 t11, t12, t13, t15, t17, t18, t01; \
368     t01 = a   & d  ; \
369     t02 = b   ^ c  ; \
370     t03 = a   ^ d  ; \
371     t04 = t01 ^ t02; \
372     t05 = b   | c  ; \
373     x   =     ~ t04; \
374     t07 = t03 & t05; \
375     t08 = b   & x  ; \
376     t09 = a   | c  ; \
377     t10 = t07 ^ t08; \
378     t11 = b   | d  ; \
379     t12 = c   ^ t11; \
380     t13 = t09 ^ t10; \
381     y   =     ~ t13; \
382     t15 = x   & t03; \
383     z   = t12 ^ t07; \
384     t17 = a   ^ b  ; \
385     t18 = y   ^ t15; \
386     w   = t17 ^ t18; \
387   }
388
389 #define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
390   { \
391     u32 t02, t03, t04, t05, t06, t07, t08, t09; \
392     u32 t12, t13, t14, t15, t16, t17, t01; \
393     t01 = a   ^ c  ; \
394     t02 =     ~ c  ; \
395     t03 = b   & t01; \
396     t04 = b   | t02; \
397     t05 = d   | t03; \
398     t06 = b   ^ d  ; \
399     t07 = a   & t04; \
400     t08 = a   | t02; \
401     t09 = t07 ^ t05; \
402     x   = t06 ^ t08; \
403     w   =     ~ t09; \
404     t12 = b   & w  ; \
405     t13 = t01 & t05; \
406     t14 = t01 ^ t12; \
407     t15 = t07 ^ t13; \
408     t16 = d   | t02; \
409     t17 = a   ^ x  ; \
410     z   = t17 ^ t15; \
411     y   = t16 ^ t14; \
412   }
413
414 #define SBOX7(a, b, c, d, w, x, y, z) \
415   { \
416     u32 t02, t03, t04, t05, t06, t08, t09, t10; \
417     u32 t11, t13, t14, t15, t16, t17, t01; \
418     t01 = a   & c  ; \
419     t02 =     ~ d  ; \
420     t03 = a   & t02; \
421     t04 = b   | t01; \
422     t05 = a   & b  ; \
423     t06 = c   ^ t04; \
424     z   = t03 ^ t06; \
425     t08 = c   | z  ; \
426     t09 = d   | t05; \
427     t10 = a   ^ t08; \
428     t11 = t04 & z  ; \
429     x   = t09 ^ t10; \
430     t13 = b   ^ x  ; \
431     t14 = t01 ^ x  ; \
432     t15 = c   ^ t05; \
433     t16 = t11 | t13; \
434     t17 = t02 | t14; \
435     w   = t15 ^ t17; \
436     y   = a   ^ t16; \
437   }
438
439 #define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
440   { \
441     u32 t02, t03, t04, t06, t07, t08, t09; \
442     u32 t10, t11, t13, t14, t15, t16, t01; \
443     t01 = a   & b  ; \
444     t02 = a   | b  ; \
445     t03 = c   | t01; \
446     t04 = d   & t02; \
447     z   = t03 ^ t04; \
448     t06 = b   ^ t04; \
449     t07 = d   ^ z  ; \
450     t08 =     ~ t07; \
451     t09 = t06 | t08; \
452     t10 = b   ^ d  ; \
453     t11 = a   | d  ; \
454     x   = a   ^ t09; \
455     t13 = c   ^ t06; \
456     t14 = c   & t11; \
457     t15 = d   | x  ; \
458     t16 = t01 | t10; \
459     w   = t13 ^ t15; \
460     y   = t14 ^ t16; \
461   }
462
463 /* XOR BLOCK1 into BLOCK0.  */
464 #define BLOCK_XOR(block0, block1) \
465   {                               \
466     block0[0] ^= block1[0];       \
467     block0[1] ^= block1[1];       \
468     block0[2] ^= block1[2];       \
469     block0[3] ^= block1[3];       \
470   }
471
472 /* Copy BLOCK_SRC to BLOCK_DST.  */
473 #define BLOCK_COPY(block_dst, block_src) \
474   {                                      \
475     block_dst[0] = block_src[0];         \
476     block_dst[1] = block_src[1];         \
477     block_dst[2] = block_src[2];         \
478     block_dst[3] = block_src[3];         \
479   }
480
481 /* Apply SBOX number WHICH to to the block found in ARRAY0 at index
482    INDEX, writing the output to the block found in ARRAY1 at index
483    INDEX.  */
484 #define SBOX(which, array0, array1, index)            \
485   SBOX##which (array0[index + 0], array0[index + 1],  \
486                array0[index + 2], array0[index + 3],  \
487                array1[index + 0], array1[index + 1],  \
488                array1[index + 2], array1[index + 3]);
489
490 /* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
491    index INDEX, writing the output to the block found in ARRAY1 at
492    index INDEX.  */
493 #define SBOX_INVERSE(which, array0, array1, index)              \
494   SBOX##which##_INVERSE (array0[index + 0], array0[index + 1],  \
495                          array0[index + 2], array0[index + 3],  \
496                          array1[index + 0], array1[index + 1],  \
497                          array1[index + 2], array1[index + 3]);
498
499 /* Apply the linear transformation to BLOCK.  */
500 #define LINEAR_TRANSFORMATION(block)                  \
501   {                                                   \
502     block[0] = rol (block[0], 13);                    \
503     block[2] = rol (block[2], 3);                     \
504     block[1] = block[1] ^ block[0] ^ block[2];        \
505     block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
506     block[1] = rol (block[1], 1);                     \
507     block[3] = rol (block[3], 7);                     \
508     block[0] = block[0] ^ block[1] ^ block[3];        \
509     block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
510     block[0] = rol (block[0], 5);                     \
511     block[2] = rol (block[2], 22);                    \
512   }
513
514 /* Apply the inverse linear transformation to BLOCK.  */
515 #define LINEAR_TRANSFORMATION_INVERSE(block)          \
516   {                                                   \
517     block[2] = ror (block[2], 22);                    \
518     block[0] = ror (block[0] , 5);                    \
519     block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
520     block[0] = block[0] ^ block[1] ^ block[3];        \
521     block[3] = ror (block[3], 7);                     \
522     block[1] = ror (block[1], 1);                     \
523     block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
524     block[1] = block[1] ^ block[0] ^ block[2];        \
525     block[2] = ror (block[2], 3);                     \
526     block[0] = ror (block[0], 13);                    \
527   }
528
529 /* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
530    subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary storage.
531    This macro increments `round'.  */
532 #define ROUND(which, subkeys, block, block_tmp) \
533   {                                             \
534     BLOCK_XOR (block, subkeys[round]);          \
535     round++;                                    \
536     SBOX (which, block, block_tmp, 0);          \
537     LINEAR_TRANSFORMATION (block_tmp);          \
538     BLOCK_COPY (block, block_tmp);              \
539   }
540
541 /* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
542    and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary
543    storage.  The result will be stored in BLOCK_TMP.  This macro
544    increments `round'.  */
545 #define ROUND_LAST(which, subkeys, block, block_tmp) \
546   {                                                  \
547     BLOCK_XOR (block, subkeys[round]);               \
548     round++;                                         \
549     SBOX (which, block, block_tmp, 0);               \
550     BLOCK_XOR (block_tmp, subkeys[round]);           \
551     round++;                                         \
552   }
553
554 /* Apply an inverse Serpent round to BLOCK, using the SBOX number
555    WHICH and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as
556    temporary storage.  This macro increments `round'.  */
557 #define ROUND_INVERSE(which, subkey, block, block_tmp) \
558   {                                                    \
559     LINEAR_TRANSFORMATION_INVERSE (block);             \
560     SBOX_INVERSE (which, block, block_tmp, 0);         \
561     BLOCK_XOR (block_tmp, subkey[round]);              \
562     round--;                                           \
563     BLOCK_COPY (block, block_tmp);                     \
564   }
565
566 /* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
567    and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary
568    storage.  The result will be stored in BLOCK_TMP.  This macro
569    increments `round'.  */
570 #define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
571   {                                                           \
572     BLOCK_XOR (block, subkeys[round]);                        \
573     round--;                                                  \
574     SBOX_INVERSE (which, block, block_tmp, 0);                \
575     BLOCK_XOR (block_tmp, subkeys[round]);                    \
576     round--;                                                  \
577   }
578
579 /* Convert the user provided key KEY of KEY_LENGTH bytes into the
580    internally used format.  */
581 static void
582 serpent_key_prepare (const byte *key, unsigned int key_length,
583                      serpent_key_t key_prepared)
584 {
585   int i;
586
587   /* Copy key.  */
588   for (i = 0; i < key_length / 4; i++)
589     {
590 #ifdef WORDS_BIGENDIAN
591       key_prepared[i] = byte_swap_32 (((u32 *) key)[i]);
592 #else
593       key_prepared[i] = ((u32 *) key)[i];
594 #endif
595     }
596
597   if (i < 8)
598     {
599       /* Key must be padded according to the Serpent
600          specification.  */
601       key_prepared[i] = 0x00000001;
602
603       for (i++; i < 8; i++)
604         key_prepared[i] = 0;
605     }
606 }
607
608 /* Derive the 33 subkeys from KEY and store them in SUBKEYS.  */
609 static void
610 serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
611 {
612   u32 w_real[140];              /* The `prekey'.  */
613   u32 k[132];
614   u32 *w = &w_real[8];
615   int i, j;
616
617   /* Initialize with key values.  */
618   for (i = 0; i < 8; i++)
619     w[i - 8] = key[i];
620
621   /* Expand to intermediate key using the affine recurrence.  */
622   for (i = 0; i < 132; i++)
623     w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
624
625   /* Calculate subkeys via S-Boxes, in bitslice mode.  */
626   SBOX (3, w, k,   0);
627   SBOX (2, w, k,   4);
628   SBOX (1, w, k,   8);
629   SBOX (0, w, k,  12);
630   SBOX (7, w, k,  16);
631   SBOX (6, w, k,  20);
632   SBOX (5, w, k,  24);
633   SBOX (4, w, k,  28);
634   SBOX (3, w, k,  32);
635   SBOX (2, w, k,  36);
636   SBOX (1, w, k,  40);
637   SBOX (0, w, k,  44);
638   SBOX (7, w, k,  48);
639   SBOX (6, w, k,  52);
640   SBOX (5, w, k,  56);
641   SBOX (4, w, k,  60);
642   SBOX (3, w, k,  64);
643   SBOX (2, w, k,  68);
644   SBOX (1, w, k,  72);
645   SBOX (0, w, k,  76);
646   SBOX (7, w, k,  80);
647   SBOX (6, w, k,  84);
648   SBOX (5, w, k,  88);
649   SBOX (4, w, k,  92);
650   SBOX (3, w, k,  96);
651   SBOX (2, w, k, 100);
652   SBOX (1, w, k, 104);
653   SBOX (0, w, k, 108);
654   SBOX (7, w, k, 112);
655   SBOX (6, w, k, 116);
656   SBOX (5, w, k, 120);
657   SBOX (4, w, k, 124);
658   SBOX (3, w, k, 128);
659
660   /* Renumber subkeys.  */
661   for (i = 0; i < ROUNDS + 1; i++)
662     for (j = 0; j < 4; j++)
663       subkeys[i][j] = k[4 * i + j];
664 }
665
666 /* Initialize CONTEXT with the key KEY of KEY_LENGTH bits.  */
667 static void
668 serpent_setkey_internal (serpent_context_t *context,
669                          const byte *key, unsigned int key_length)
670 {
671   serpent_key_t key_prepared;
672
673   serpent_key_prepare (key, key_length, key_prepared);
674   serpent_subkeys_generate (key_prepared, context->keys);
675   _gcry_burn_stack (272 * sizeof (u32));
676 }
677
678 /* Initialize CTX with the key KEY of KEY_LENGTH bytes.  */
679 static gcry_err_code_t
680 serpent_setkey (void *ctx,
681                 const byte *key, unsigned int key_length)
682 {
683   serpent_context_t *context = ctx;
684   static const char *serpent_test_ret;
685   static int serpent_init_done;
686   gcry_err_code_t ret = GPG_ERR_NO_ERROR;
687   
688   if (! serpent_init_done)
689     {
690       /* Execute a self-test the first time, Serpent is used.  */
691       serpent_test_ret = serpent_test ();
692       if (serpent_test_ret)
693         log_error ("Serpent test failure: %s\n", serpent_test_ret);
694       serpent_init_done = 1;
695     }
696
697   if (serpent_test_ret)
698     ret = GPG_ERR_SELFTEST_FAILED;
699   else
700     {
701       serpent_setkey_internal (context, key, key_length);
702       _gcry_burn_stack (sizeof (serpent_key_t));
703     }
704
705   return ret;
706 }
707
708 static void
709 serpent_encrypt_internal (serpent_context_t *context,
710                           const serpent_block_t input, serpent_block_t output)
711 {
712   serpent_block_t b, b_next;
713   int round = 0;
714
715 #ifdef WORDS_BIGENDIAN
716   b[0] = byte_swap_32 (input[0]);
717   b[1] = byte_swap_32 (input[1]);
718   b[2] = byte_swap_32 (input[2]);
719   b[3] = byte_swap_32 (input[3]);
720 #else
721   b[0] = input[0];
722   b[1] = input[1];
723   b[2] = input[2];
724   b[3] = input[3];
725 #endif
726
727   ROUND (0, context->keys, b, b_next);
728   ROUND (1, context->keys, b, b_next);
729   ROUND (2, context->keys, b, b_next);
730   ROUND (3, context->keys, b, b_next);
731   ROUND (4, context->keys, b, b_next);
732   ROUND (5, context->keys, b, b_next);
733   ROUND (6, context->keys, b, b_next);
734   ROUND (7, context->keys, b, b_next);
735   ROUND (0, context->keys, b, b_next);
736   ROUND (1, context->keys, b, b_next);
737   ROUND (2, context->keys, b, b_next);
738   ROUND (3, context->keys, b, b_next);
739   ROUND (4, context->keys, b, b_next);
740   ROUND (5, context->keys, b, b_next);
741   ROUND (6, context->keys, b, b_next);
742   ROUND (7, context->keys, b, b_next);
743   ROUND (0, context->keys, b, b_next);
744   ROUND (1, context->keys, b, b_next);
745   ROUND (2, context->keys, b, b_next);
746   ROUND (3, context->keys, b, b_next);
747   ROUND (4, context->keys, b, b_next);
748   ROUND (5, context->keys, b, b_next);
749   ROUND (6, context->keys, b, b_next);
750   ROUND (7, context->keys, b, b_next);
751   ROUND (0, context->keys, b, b_next);
752   ROUND (1, context->keys, b, b_next);
753   ROUND (2, context->keys, b, b_next);
754   ROUND (3, context->keys, b, b_next);
755   ROUND (4, context->keys, b, b_next);
756   ROUND (5, context->keys, b, b_next);
757   ROUND (6, context->keys, b, b_next);
758
759   ROUND_LAST (7, context->keys, b, b_next);
760
761 #ifdef WORDS_BIGENDIAN
762   output[0] = byte_swap_32 (b_next[0]);
763   output[1] = byte_swap_32 (b_next[1]);
764   output[2] = byte_swap_32 (b_next[2]);
765   output[3] = byte_swap_32 (b_next[3]);
766 #else
767   output[0] = b_next[0];
768   output[1] = b_next[1];
769   output[2] = b_next[2];
770   output[3] = b_next[3];
771 #endif
772 }
773
774 static void
775 serpent_decrypt_internal (serpent_context_t *context,
776                           const serpent_block_t input, serpent_block_t output)
777 {
778   serpent_block_t b, b_next;
779   int round = ROUNDS;
780
781 #ifdef WORDS_BIGENDIAN
782   b_next[0] = byte_swap_32 (input[0]);
783   b_next[1] = byte_swap_32 (input[1]);
784   b_next[2] = byte_swap_32 (input[2]);
785   b_next[3] = byte_swap_32 (input[3]);
786 #else
787   b_next[0] = input[0];
788   b_next[1] = input[1];
789   b_next[2] = input[2];
790   b_next[3] = input[3];
791 #endif
792
793   ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
794
795   ROUND_INVERSE (6, context->keys, b, b_next);
796   ROUND_INVERSE (5, context->keys, b, b_next);
797   ROUND_INVERSE (4, context->keys, b, b_next);
798   ROUND_INVERSE (3, context->keys, b, b_next);
799   ROUND_INVERSE (2, context->keys, b, b_next);
800   ROUND_INVERSE (1, context->keys, b, b_next);
801   ROUND_INVERSE (0, context->keys, b, b_next);
802   ROUND_INVERSE (7, context->keys, b, b_next);
803   ROUND_INVERSE (6, context->keys, b, b_next);
804   ROUND_INVERSE (5, context->keys, b, b_next);
805   ROUND_INVERSE (4, context->keys, b, b_next);
806   ROUND_INVERSE (3, context->keys, b, b_next);
807   ROUND_INVERSE (2, context->keys, b, b_next);
808   ROUND_INVERSE (1, context->keys, b, b_next);
809   ROUND_INVERSE (0, context->keys, b, b_next);
810   ROUND_INVERSE (7, context->keys, b, b_next);
811   ROUND_INVERSE (6, context->keys, b, b_next);
812   ROUND_INVERSE (5, context->keys, b, b_next);
813   ROUND_INVERSE (4, context->keys, b, b_next);
814   ROUND_INVERSE (3, context->keys, b, b_next);
815   ROUND_INVERSE (2, context->keys, b, b_next);
816   ROUND_INVERSE (1, context->keys, b, b_next);
817   ROUND_INVERSE (0, context->keys, b, b_next);
818   ROUND_INVERSE (7, context->keys, b, b_next);
819   ROUND_INVERSE (6, context->keys, b, b_next);
820   ROUND_INVERSE (5, context->keys, b, b_next);
821   ROUND_INVERSE (4, context->keys, b, b_next);
822   ROUND_INVERSE (3, context->keys, b, b_next);
823   ROUND_INVERSE (2, context->keys, b, b_next);
824   ROUND_INVERSE (1, context->keys, b, b_next);
825   ROUND_INVERSE (0, context->keys, b, b_next);
826
827
828 #ifdef WORDS_BIGENDIAN
829   output[0] = byte_swap_32 (b_next[0]);
830   output[1] = byte_swap_32 (b_next[1]);
831   output[2] = byte_swap_32 (b_next[2]);
832   output[3] = byte_swap_32 (b_next[3]);
833 #else
834   output[0] = b_next[0];
835   output[1] = b_next[1];
836   output[2] = b_next[2];
837   output[3] = b_next[3];
838 #endif
839 }
840
841 static void
842 serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
843 {
844   serpent_context_t *context = ctx;
845
846   serpent_encrypt_internal (context,
847                             (const u32 *) buffer_in, (u32 *) buffer_out);
848   _gcry_burn_stack (2 * sizeof (serpent_block_t));
849 }
850
851 static void
852 serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
853 {
854   serpent_context_t *context = ctx;
855
856   serpent_decrypt_internal (context,
857                             (const u32 *) buffer_in,
858                             (u32 *) buffer_out);
859   _gcry_burn_stack (2 * sizeof (serpent_block_t));
860 }
861
862 \f
863
864 /* Serpent test.  */
865
866 static const char *
867 serpent_test (void)
868 {
869   serpent_context_t context;
870   unsigned char scratch[16];
871   unsigned int i;
872
873   static struct test
874   {
875     int key_length;
876     unsigned char key[32];
877     unsigned char text_plain[16];
878     unsigned char text_cipher[16];
879   } test_data[] =
880     {
881       {
882         16,
883         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
884         "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
885         "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
886       },
887       {
888         24,
889         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
890         "\x00\x00\x00\x00\x00\x00\x00\x00",
891         "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
892         "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
893       },
894       {
895         32,
896         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
897         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
898         "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
899         "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
900       },
901       {
902         32,
903         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
904         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
905         "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
906         "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
907       },
908       {
909         0
910       },
911     };
912
913   for (i = 0; test_data[i].key_length; i++)
914     {
915       serpent_setkey_internal (&context, test_data[i].key,
916                                test_data[i].key_length);
917       serpent_encrypt_internal (&context,
918                                 (const u32 *) test_data[i].text_plain,
919                                 (u32 *) scratch);
920
921       if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
922         switch (test_data[i].key_length)
923           {
924           case 16:
925             return "Serpent-128 test encryption failed.";
926           case  24:
927             return "Serpent-192 test encryption failed.";
928           case 32:
929             return "Serpent-256 test encryption failed.";
930           }
931
932     serpent_decrypt_internal (&context,
933                               (const u32 *) test_data[i].text_cipher,
934                               (u32 *) scratch);
935     if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
936       switch (test_data[i].key_length)
937         {
938         case 16:
939           return "Serpent-128 test decryption failed.";
940         case  24:
941           return "Serpent-192 test decryption failed.";
942         case 32:
943           return "Serpent-256 test decryption failed.";
944         }
945     }
946
947   return NULL;
948 }
949
950 \f
951
952 /* "SERPENT" is an alias for "SERPENT128".  */
953 static const char *cipher_spec_serpent128_aliases[] =
954   {
955     "SERPENT",
956     NULL
957   };
958
959 gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
960   {
961     "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
962     sizeof (serpent_context_t),
963     serpent_setkey, serpent_encrypt, serpent_decrypt
964   };
965
966 gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
967   {
968     "SERPENT192", NULL, NULL, 16, 192,
969     sizeof (serpent_context_t),
970     serpent_setkey, serpent_encrypt, serpent_decrypt
971   };
972
973 gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
974   {
975     "SERPENT256", NULL, NULL, 16, 256,
976     sizeof (serpent_context_t),
977     serpent_setkey, serpent_encrypt, serpent_decrypt
978   };