~ubuntu-branches/ubuntu/trusty/grub2/trusty-updates

« back to all changes in this revision

Viewing changes to lib/libgcrypt/cipher/serpent.c

Tags: upstream-1.99~20101122
ImportĀ upstreamĀ versionĀ 1.99~20101122

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
 
  };