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.  */
39typedef 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.  */
43typedef u32 serpent_key_t[8];
44
45/* The key schedule consists of 33 128 bit subkeys.  */
46typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
47
48/* A Serpent context.  */
49typedef struct serpent_context
50{
51  serpent_subkeys_t keys;	/* Generated subkeys.  */
52} serpent_context_t;
53
54
55/* A prototype.  */
56static 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.  */
581static void
582serpent_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.  */
609static void
610serpent_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.  */
667static void
668serpent_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.  */
679static gcry_err_code_t
680serpent_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
708static void
709serpent_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
774static void
775serpent_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
841static void
842serpent_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
851static void
852serpent_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
863
864/* Serpent test.  */
865
866static const char *
867serpent_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
951
952/* "SERPENT" is an alias for "SERPENT128".  */
953static const char *cipher_spec_serpent128_aliases[] =
954  {
955    "SERPENT",
956    NULL
957  };
958
959gcry_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
966gcry_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
973gcry_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  };
979