~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to grub-core/lib/libgcrypt/cipher/serpent.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Robert Millan, Updated translations
  • Date: 2010-11-22 12:24:56 UTC
  • mfrom: (1.26.4 upstream) (17.3.36 sid)
  • mto: (17.3.43 sid)
  • mto: This revision was merged to the branch mainline in revision 89.
  • Revision ID: james.westby@ubuntu.com-20101122122456-y82z3sfb7k4zfdcc
Tags: 1.99~20101122-1
[ Colin Watson ]
* New Bazaar snapshot.  Too many changes to list in full, but some of the
  more user-visible ones are as follows:
  - GRUB script:
    + Function parameters, "break", "continue", "shift", "setparams",
      "return", and "!".
    + "export" command supports multiple variable names.
    + Multi-line quoted strings support.
    + Wildcard expansion.
  - sendkey support.
  - USB hotunplugging and USB serial support.
  - Rename CD-ROM to cd on BIOS.
  - Add new --boot-directory option to grub-install, grub-reboot, and
    grub-set-default; the old --root-directory option is still accepted
    but was often confusing.
  - Basic btrfs detection/UUID support (but no file reading yet).
  - bash-completion for utilities.
  - If a device is listed in device.map, always assume that it is
    BIOS-visible rather than using extra layers such as LVM or RAID.
  - Add grub-mknetdir script (closes: #550658).
  - Remove deprecated "root" command.
  - Handle RAID devices containing virtio components.
  - GRUB Legacy configuration file support (via grub-menulst2cfg).
  - Keyboard layout support (via grub-mklayout and grub-kbdcomp).
  - Check generated grub.cfg for syntax errors before saving.
  - Pause execution for at most ten seconds if any errors are displayed,
    so that the user has a chance to see them.
  - Support submenus.
  - Write embedding zone using Reed-Solomon, so that it's robust against
    being partially overwritten (closes: #550702, #591416, #593347).
  - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged
    into a single GRUB_DISABLE_RECOVERY variable.
  - Fix loader memory allocation failure (closes: #551627).
  - Don't call savedefault on recovery entries (closes: #589325).
  - Support triple-indirect blocks on ext2 (closes: #543924).
  - Recognise DDF1 fake RAID (closes: #603354).

[ Robert Millan ]
* Use dpkg architecture wildcards.

[ Updated translations ]
* Slovenian (Vanja Cvelbar).  Closes: #604003
* Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
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
 
 
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
  };