build: Fix build with !HAVE_PTHREAD
[libgcrypt.git] / cipher / serpent.c
1 /* serpent.c - Implementation of the Serpent encryption algorithm.
2  *      Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.
20  */
21
22 #include <config.h>
23
24 #include <string.h>
25 #include <stdio.h>
26
27 #include "types.h"
28 #include "g10lib.h"
29 #include "cipher.h"
30 #include "bithelp.h"
31 #include "bufhelp.h"
32 #include "cipher-internal.h"
33 #include "cipher-selftest.h"
34
35
36 /* USE_SSE2 indicates whether to compile with AMD64 SSE2 code. */
37 #undef USE_SSE2
38 #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
39     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
40 # define USE_SSE2 1
41 #endif
42
43 /* USE_AVX2 indicates whether to compile with AMD64 AVX2 code. */
44 #undef USE_AVX2
45 #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
46     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
47 # if defined(ENABLE_AVX2_SUPPORT)
48 #  define USE_AVX2 1
49 # endif
50 #endif
51
52 /* USE_NEON indicates whether to enable ARM NEON assembly code. */
53 #undef USE_NEON
54 #ifdef ENABLE_NEON_SUPPORT
55 # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
56      && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
57      && defined(HAVE_GCC_INLINE_ASM_NEON)
58 #  define USE_NEON 1
59 # endif
60 #endif /*ENABLE_NEON_SUPPORT*/
61
62 /* Number of rounds per Serpent encrypt/decrypt operation.  */
63 #define ROUNDS 32
64
65 /* Magic number, used during generating of the subkeys.  */
66 #define PHI 0x9E3779B9
67
68 /* Serpent works on 128 bit blocks.  */
69 typedef u32 serpent_block_t[4];
70
71 /* Serpent key, provided by the user.  If the original key is shorter
72    than 256 bits, it is padded.  */
73 typedef u32 serpent_key_t[8];
74
75 /* The key schedule consists of 33 128 bit subkeys.  */
76 typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
77
78 /* A Serpent context.  */
79 typedef struct serpent_context
80 {
81   serpent_subkeys_t keys;       /* Generated subkeys.  */
82
83 #ifdef USE_AVX2
84   int use_avx2;
85 #endif
86 #ifdef USE_NEON
87   int use_neon;
88 #endif
89 } serpent_context_t;
90
91
92 /* Assembly implementations use SystemV ABI, ABI conversion and additional
93  * stack to store XMM6-XMM15 needed on Win64. */
94 #undef ASM_FUNC_ABI
95 #if defined(USE_SSE2) || defined(USE_AVX2)
96 # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
97 #  define ASM_FUNC_ABI __attribute__((sysv_abi))
98 # else
99 #  define ASM_FUNC_ABI
100 # endif
101 #endif
102
103
104 #ifdef USE_SSE2
105 /* Assembler implementations of Serpent using SSE2.  Process 8 block in
106    parallel.
107  */
108 extern void _gcry_serpent_sse2_ctr_enc(serpent_context_t *ctx,
109                                        unsigned char *out,
110                                        const unsigned char *in,
111                                        unsigned char *ctr) ASM_FUNC_ABI;
112
113 extern void _gcry_serpent_sse2_cbc_dec(serpent_context_t *ctx,
114                                        unsigned char *out,
115                                        const unsigned char *in,
116                                        unsigned char *iv) ASM_FUNC_ABI;
117
118 extern void _gcry_serpent_sse2_cfb_dec(serpent_context_t *ctx,
119                                        unsigned char *out,
120                                        const unsigned char *in,
121                                        unsigned char *iv) ASM_FUNC_ABI;
122
123 extern void _gcry_serpent_sse2_ocb_enc(serpent_context_t *ctx,
124                                        unsigned char *out,
125                                        const unsigned char *in,
126                                        unsigned char *offset,
127                                        unsigned char *checksum,
128                                        const u64 Ls[8]) ASM_FUNC_ABI;
129
130 extern void _gcry_serpent_sse2_ocb_dec(serpent_context_t *ctx,
131                                        unsigned char *out,
132                                        const unsigned char *in,
133                                        unsigned char *offset,
134                                        unsigned char *checksum,
135                                        const u64 Ls[8]) ASM_FUNC_ABI;
136
137 extern void _gcry_serpent_sse2_ocb_auth(serpent_context_t *ctx,
138                                         const unsigned char *abuf,
139                                         unsigned char *offset,
140                                         unsigned char *checksum,
141                                         const u64 Ls[8]) ASM_FUNC_ABI;
142 #endif
143
144 #ifdef USE_AVX2
145 /* Assembler implementations of Serpent using AVX2.  Process 16 block in
146    parallel.
147  */
148 extern void _gcry_serpent_avx2_ctr_enc(serpent_context_t *ctx,
149                                        unsigned char *out,
150                                        const unsigned char *in,
151                                        unsigned char *ctr) ASM_FUNC_ABI;
152
153 extern void _gcry_serpent_avx2_cbc_dec(serpent_context_t *ctx,
154                                        unsigned char *out,
155                                        const unsigned char *in,
156                                        unsigned char *iv) ASM_FUNC_ABI;
157
158 extern void _gcry_serpent_avx2_cfb_dec(serpent_context_t *ctx,
159                                        unsigned char *out,
160                                        const unsigned char *in,
161                                        unsigned char *iv) ASM_FUNC_ABI;
162
163 extern void _gcry_serpent_avx2_ocb_enc(serpent_context_t *ctx,
164                                        unsigned char *out,
165                                        const unsigned char *in,
166                                        unsigned char *offset,
167                                        unsigned char *checksum,
168                                        const u64 Ls[16]) ASM_FUNC_ABI;
169
170 extern void _gcry_serpent_avx2_ocb_dec(serpent_context_t *ctx,
171                                        unsigned char *out,
172                                        const unsigned char *in,
173                                        unsigned char *offset,
174                                        unsigned char *checksum,
175                                        const u64 Ls[16]) ASM_FUNC_ABI;
176
177 extern void _gcry_serpent_avx2_ocb_auth(serpent_context_t *ctx,
178                                         const unsigned char *abuf,
179                                         unsigned char *offset,
180                                         unsigned char *checksum,
181                                         const u64 Ls[16]) ASM_FUNC_ABI;
182 #endif
183
184 #ifdef USE_NEON
185 /* Assembler implementations of Serpent using ARM NEON.  Process 8 block in
186    parallel.
187  */
188 extern void _gcry_serpent_neon_ctr_enc(serpent_context_t *ctx,
189                                        unsigned char *out,
190                                        const unsigned char *in,
191                                        unsigned char *ctr);
192
193 extern void _gcry_serpent_neon_cbc_dec(serpent_context_t *ctx,
194                                        unsigned char *out,
195                                        const unsigned char *in,
196                                        unsigned char *iv);
197
198 extern void _gcry_serpent_neon_cfb_dec(serpent_context_t *ctx,
199                                        unsigned char *out,
200                                        const unsigned char *in,
201                                        unsigned char *iv);
202
203 extern void _gcry_serpent_neon_ocb_enc(serpent_context_t *ctx,
204                                        unsigned char *out,
205                                        const unsigned char *in,
206                                        unsigned char *offset,
207                                        unsigned char *checksum,
208                                        const void *Ls[8]);
209
210 extern void _gcry_serpent_neon_ocb_dec(serpent_context_t *ctx,
211                                        unsigned char *out,
212                                        const unsigned char *in,
213                                        unsigned char *offset,
214                                        unsigned char *checksum,
215                                        const void *Ls[8]);
216
217 extern void _gcry_serpent_neon_ocb_auth(serpent_context_t *ctx,
218                                         const unsigned char *abuf,
219                                         unsigned char *offset,
220                                         unsigned char *checksum,
221                                         const void *Ls[8]);
222 #endif
223
224
225 /* A prototype.  */
226 static const char *serpent_test (void);
227
228
229 /*
230  * These are the S-Boxes of Serpent from following research paper.
231  *
232  *  D. A. Osvik, “Speeding up Serpent,” in Third AES Candidate Conference,
233  *   (New York, New York, USA), p. 317–329, National Institute of Standards and
234  *   Technology, 2000.
235  *
236  * Paper is also available at: http://www.ii.uib.no/~osvik/pub/aes3.pdf
237  *
238  */
239
240 #define SBOX0(r0, r1, r2, r3, w, x, y, z) \
241   { \
242     u32 r4; \
243     \
244     r3 ^= r0; r4 =  r1; \
245     r1 &= r3; r4 ^= r2; \
246     r1 ^= r0; r0 |= r3; \
247     r0 ^= r4; r4 ^= r3; \
248     r3 ^= r2; r2 |= r1; \
249     r2 ^= r4; r4 = ~r4; \
250     r4 |= r1; r1 ^= r3; \
251     r1 ^= r4; r3 |= r0; \
252     r1 ^= r3; r4 ^= r3; \
253     \
254     w = r1; x = r4; y = r2; z = r0; \
255   }
256
257 #define SBOX0_INVERSE(r0, r1, r2, r3, w, x, y, z) \
258   { \
259     u32 r4; \
260     \
261     r2 = ~r2; r4 =  r1; \
262     r1 |= r0; r4 = ~r4; \
263     r1 ^= r2; r2 |= r4; \
264     r1 ^= r3; r0 ^= r4; \
265     r2 ^= r0; r0 &= r3; \
266     r4 ^= r0; r0 |= r1; \
267     r0 ^= r2; r3 ^= r4; \
268     r2 ^= r1; r3 ^= r0; \
269     r3 ^= r1; \
270     r2 &= r3; \
271     r4 ^= r2; \
272     \
273     w = r0; x = r4; y = r1; z = r3; \
274   }
275
276 #define SBOX1(r0, r1, r2, r3, w, x, y, z) \
277   { \
278     u32 r4; \
279     \
280     r0 = ~r0; r2 = ~r2; \
281     r4 =  r0; r0 &= r1; \
282     r2 ^= r0; r0 |= r3; \
283     r3 ^= r2; r1 ^= r0; \
284     r0 ^= r4; r4 |= r1; \
285     r1 ^= r3; r2 |= r0; \
286     r2 &= r4; r0 ^= r1; \
287     r1 &= r2; \
288     r1 ^= r0; r0 &= r2; \
289     r0 ^= r4; \
290     \
291     w = r2; x = r0; y = r3; z = r1; \
292   }
293
294 #define SBOX1_INVERSE(r0, r1, r2, r3, w, x, y, z) \
295   { \
296     u32 r4; \
297     \
298     r4 =  r1; r1 ^= r3; \
299     r3 &= r1; r4 ^= r2; \
300     r3 ^= r0; r0 |= r1; \
301     r2 ^= r3; r0 ^= r4; \
302     r0 |= r2; r1 ^= r3; \
303     r0 ^= r1; r1 |= r3; \
304     r1 ^= r0; r4 = ~r4; \
305     r4 ^= r1; r1 |= r0; \
306     r1 ^= r0; \
307     r1 |= r4; \
308     r3 ^= r1; \
309     \
310     w = r4; x = r0; y = r3; z = r2; \
311   }
312
313 #define SBOX2(r0, r1, r2, r3, w, x, y, z) \
314   { \
315     u32 r4; \
316     \
317     r4 =  r0; r0 &= r2; \
318     r0 ^= r3; r2 ^= r1; \
319     r2 ^= r0; r3 |= r4; \
320     r3 ^= r1; r4 ^= r2; \
321     r1 =  r3; r3 |= r4; \
322     r3 ^= r0; r0 &= r1; \
323     r4 ^= r0; r1 ^= r3; \
324     r1 ^= r4; r4 = ~r4; \
325     \
326     w = r2; x = r3; y = r1; z = r4; \
327   }
328
329 #define SBOX2_INVERSE(r0, r1, r2, r3, w, x, y, z) \
330   { \
331     u32 r4; \
332     \
333     r2 ^= r3; r3 ^= r0; \
334     r4 =  r3; r3 &= r2; \
335     r3 ^= r1; r1 |= r2; \
336     r1 ^= r4; r4 &= r3; \
337     r2 ^= r3; r4 &= r0; \
338     r4 ^= r2; r2 &= r1; \
339     r2 |= r0; r3 = ~r3; \
340     r2 ^= r3; r0 ^= r3; \
341     r0 &= r1; r3 ^= r4; \
342     r3 ^= r0; \
343     \
344     w = r1; x = r4; y = r2; z = r3; \
345   }
346
347 #define SBOX3(r0, r1, r2, r3, w, x, y, z) \
348   { \
349     u32 r4; \
350     \
351     r4 =  r0; r0 |= r3; \
352     r3 ^= r1; r1 &= r4; \
353     r4 ^= r2; r2 ^= r3; \
354     r3 &= r0; r4 |= r1; \
355     r3 ^= r4; r0 ^= r1; \
356     r4 &= r0; r1 ^= r3; \
357     r4 ^= r2; r1 |= r0; \
358     r1 ^= r2; r0 ^= r3; \
359     r2 =  r1; r1 |= r3; \
360     r1 ^= r0; \
361     \
362     w = r1; x = r2; y = r3; z = r4; \
363   }
364
365 #define SBOX3_INVERSE(r0, r1, r2, r3, w, x, y, z) \
366   { \
367     u32 r4; \
368     \
369     r4 =  r2; r2 ^= r1; \
370     r0 ^= r2; r4 &= r2; \
371     r4 ^= r0; r0 &= r1; \
372     r1 ^= r3; r3 |= r4; \
373     r2 ^= r3; r0 ^= r3; \
374     r1 ^= r4; r3 &= r2; \
375     r3 ^= r1; r1 ^= r0; \
376     r1 |= r2; r0 ^= r3; \
377     r1 ^= r4; \
378     r0 ^= r1; \
379     \
380     w = r2; x = r1; y = r3; z = r0; \
381   }
382
383 #define SBOX4(r0, r1, r2, r3, w, x, y, z) \
384   { \
385     u32 r4; \
386     \
387     r1 ^= r3; r3 = ~r3; \
388     r2 ^= r3; r3 ^= r0; \
389     r4 =  r1; r1 &= r3; \
390     r1 ^= r2; r4 ^= r3; \
391     r0 ^= r4; r2 &= r4; \
392     r2 ^= r0; r0 &= r1; \
393     r3 ^= r0; r4 |= r1; \
394     r4 ^= r0; r0 |= r3; \
395     r0 ^= r2; r2 &= r3; \
396     r0 = ~r0; r4 ^= r2; \
397     \
398     w = r1; x = r4; y = r0; z = r3; \
399   }
400
401 #define SBOX4_INVERSE(r0, r1, r2, r3, w, x, y, z) \
402   { \
403     u32 r4; \
404     \
405     r4 =  r2; r2 &= r3; \
406     r2 ^= r1; r1 |= r3; \
407     r1 &= r0; r4 ^= r2; \
408     r4 ^= r1; r1 &= r2; \
409     r0 = ~r0; r3 ^= r4; \
410     r1 ^= r3; r3 &= r0; \
411     r3 ^= r2; r0 ^= r1; \
412     r2 &= r0; r3 ^= r0; \
413     r2 ^= r4; \
414     r2 |= r3; r3 ^= r0; \
415     r2 ^= r1; \
416     \
417     w = r0; x = r3; y = r2; z = r4; \
418   }
419
420 #define SBOX5(r0, r1, r2, r3, w, x, y, z) \
421   { \
422     u32 r4; \
423     \
424     r0 ^= r1; r1 ^= r3; \
425     r3 = ~r3; r4 =  r1; \
426     r1 &= r0; r2 ^= r3; \
427     r1 ^= r2; r2 |= r4; \
428     r4 ^= r3; r3 &= r1; \
429     r3 ^= r0; r4 ^= r1; \
430     r4 ^= r2; r2 ^= r0; \
431     r0 &= r3; r2 = ~r2; \
432     r0 ^= r4; r4 |= r3; \
433     r2 ^= r4; \
434     \
435     w = r1; x = r3; y = r0; z = r2; \
436   }
437
438 #define SBOX5_INVERSE(r0, r1, r2, r3, w, x, y, z) \
439   { \
440     u32 r4; \
441     \
442     r1 = ~r1; r4 =  r3; \
443     r2 ^= r1; r3 |= r0; \
444     r3 ^= r2; r2 |= r1; \
445     r2 &= r0; r4 ^= r3; \
446     r2 ^= r4; r4 |= r0; \
447     r4 ^= r1; r1 &= r2; \
448     r1 ^= r3; r4 ^= r2; \
449     r3 &= r4; r4 ^= r1; \
450     r3 ^= r4; r4 = ~r4; \
451     r3 ^= r0; \
452     \
453     w = r1; x = r4; y = r3; z = r2; \
454   }
455
456 #define SBOX6(r0, r1, r2, r3, w, x, y, z) \
457   { \
458     u32 r4; \
459     \
460     r2 = ~r2; r4 =  r3; \
461     r3 &= r0; r0 ^= r4; \
462     r3 ^= r2; r2 |= r4; \
463     r1 ^= r3; r2 ^= r0; \
464     r0 |= r1; r2 ^= r1; \
465     r4 ^= r0; r0 |= r3; \
466     r0 ^= r2; r4 ^= r3; \
467     r4 ^= r0; r3 = ~r3; \
468     r2 &= r4; \
469     r2 ^= r3; \
470     \
471     w = r0; x = r1; y = r4; z = r2; \
472   }
473
474 #define SBOX6_INVERSE(r0, r1, r2, r3, w, x, y, z) \
475   { \
476     u32 r4; \
477     \
478     r0 ^= r2; r4 =  r2; \
479     r2 &= r0; r4 ^= r3; \
480     r2 = ~r2; r3 ^= r1; \
481     r2 ^= r3; r4 |= r0; \
482     r0 ^= r2; r3 ^= r4; \
483     r4 ^= r1; r1 &= r3; \
484     r1 ^= r0; r0 ^= r3; \
485     r0 |= r2; r3 ^= r1; \
486     r4 ^= r0; \
487     \
488     w = r1; x = r2; y = r4; z = r3; \
489   }
490
491 #define SBOX7(r0, r1, r2, r3, w, x, y, z) \
492   { \
493     u32 r4; \
494     \
495     r4 =  r1; r1 |= r2; \
496     r1 ^= r3; r4 ^= r2; \
497     r2 ^= r1; r3 |= r4; \
498     r3 &= r0; r4 ^= r2; \
499     r3 ^= r1; r1 |= r4; \
500     r1 ^= r0; r0 |= r4; \
501     r0 ^= r2; r1 ^= r4; \
502     r2 ^= r1; r1 &= r0; \
503     r1 ^= r4; r2 = ~r2; \
504     r2 |= r0; \
505     r4 ^= r2; \
506     \
507     w = r4; x = r3; y = r1; z = r0; \
508   }
509
510 #define SBOX7_INVERSE(r0, r1, r2, r3, w, x, y, z) \
511   { \
512     u32 r4; \
513     \
514     r4 =  r2; r2 ^= r0; \
515     r0 &= r3; r4 |= r3; \
516     r2 = ~r2; r3 ^= r1; \
517     r1 |= r0; r0 ^= r2; \
518     r2 &= r4; r3 &= r4; \
519     r1 ^= r2; r2 ^= r0; \
520     r0 |= r2; r4 ^= r1; \
521     r0 ^= r3; r3 ^= r4; \
522     r4 |= r0; r3 ^= r2; \
523     r4 ^= r2; \
524     \
525     w = r3; x = r0; y = r1; z = r4; \
526   }
527
528 /* XOR BLOCK1 into BLOCK0.  */
529 #define BLOCK_XOR(block0, block1) \
530   {                               \
531     block0[0] ^= block1[0];       \
532     block0[1] ^= block1[1];       \
533     block0[2] ^= block1[2];       \
534     block0[3] ^= block1[3];       \
535   }
536
537 /* Copy BLOCK_SRC to BLOCK_DST.  */
538 #define BLOCK_COPY(block_dst, block_src) \
539   {                                      \
540     block_dst[0] = block_src[0];         \
541     block_dst[1] = block_src[1];         \
542     block_dst[2] = block_src[2];         \
543     block_dst[3] = block_src[3];         \
544   }
545
546 /* Apply SBOX number WHICH to to the block found in ARRAY0, writing
547    the output to the block found in ARRAY1.  */
548 #define SBOX(which, array0, array1)                         \
549   SBOX##which (array0[0], array0[1], array0[2], array0[3],  \
550                array1[0], array1[1], array1[2], array1[3]);
551
552 /* Apply inverse SBOX number WHICH to to the block found in ARRAY0, writing
553    the output to the block found in ARRAY1.  */
554 #define SBOX_INVERSE(which, array0, array1)                           \
555   SBOX##which##_INVERSE (array0[0], array0[1], array0[2], array0[3],  \
556                          array1[0], array1[1], array1[2], array1[3]);
557
558 /* Apply the linear transformation to BLOCK.  */
559 #define LINEAR_TRANSFORMATION(block)                  \
560   {                                                   \
561     block[0] = rol (block[0], 13);                    \
562     block[2] = rol (block[2], 3);                     \
563     block[1] = block[1] ^ block[0] ^ block[2];        \
564     block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
565     block[1] = rol (block[1], 1);                     \
566     block[3] = rol (block[3], 7);                     \
567     block[0] = block[0] ^ block[1] ^ block[3];        \
568     block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
569     block[0] = rol (block[0], 5);                     \
570     block[2] = rol (block[2], 22);                    \
571   }
572
573 /* Apply the inverse linear transformation to BLOCK.  */
574 #define LINEAR_TRANSFORMATION_INVERSE(block)          \
575   {                                                   \
576     block[2] = ror (block[2], 22);                    \
577     block[0] = ror (block[0] , 5);                    \
578     block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
579     block[0] = block[0] ^ block[1] ^ block[3];        \
580     block[3] = ror (block[3], 7);                     \
581     block[1] = ror (block[1], 1);                     \
582     block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
583     block[1] = block[1] ^ block[0] ^ block[2];        \
584     block[2] = ror (block[2], 3);                     \
585     block[0] = ror (block[0], 13);                    \
586   }
587
588 /* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
589    subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary storage.
590    This macro increments `round'.  */
591 #define ROUND(which, subkeys, block, block_tmp) \
592   {                                             \
593     BLOCK_XOR (block, subkeys[round]);          \
594     round++;                                    \
595     SBOX (which, block, block_tmp);             \
596     LINEAR_TRANSFORMATION (block_tmp);          \
597     BLOCK_COPY (block, block_tmp);              \
598   }
599
600 /* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
601    and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary
602    storage.  The result will be stored in BLOCK_TMP.  This macro
603    increments `round'.  */
604 #define ROUND_LAST(which, subkeys, block, block_tmp) \
605   {                                                  \
606     BLOCK_XOR (block, subkeys[round]);               \
607     round++;                                         \
608     SBOX (which, block, block_tmp);                  \
609     BLOCK_XOR (block_tmp, subkeys[round]);           \
610     round++;                                         \
611   }
612
613 /* Apply an inverse Serpent round to BLOCK, using the SBOX number
614    WHICH and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as
615    temporary storage.  This macro increments `round'.  */
616 #define ROUND_INVERSE(which, subkey, block, block_tmp) \
617   {                                                    \
618     LINEAR_TRANSFORMATION_INVERSE (block);             \
619     SBOX_INVERSE (which, block, block_tmp);            \
620     BLOCK_XOR (block_tmp, subkey[round]);              \
621     round--;                                           \
622     BLOCK_COPY (block, block_tmp);                     \
623   }
624
625 /* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
626    and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary
627    storage.  The result will be stored in BLOCK_TMP.  This macro
628    increments `round'.  */
629 #define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
630   {                                                           \
631     BLOCK_XOR (block, subkeys[round]);                        \
632     round--;                                                  \
633     SBOX_INVERSE (which, block, block_tmp);                   \
634     BLOCK_XOR (block_tmp, subkeys[round]);                    \
635     round--;                                                  \
636   }
637
638 /* Convert the user provided key KEY of KEY_LENGTH bytes into the
639    internally used format.  */
640 static void
641 serpent_key_prepare (const byte *key, unsigned int key_length,
642                      serpent_key_t key_prepared)
643 {
644   int i;
645
646   /* Copy key.  */
647   key_length /= 4;
648   for (i = 0; i < key_length; i++)
649     key_prepared[i] = buf_get_le32 (key + i * 4);
650
651   if (i < 8)
652     {
653       /* Key must be padded according to the Serpent
654          specification.  */
655       key_prepared[i] = 0x00000001;
656
657       for (i++; i < 8; i++)
658         key_prepared[i] = 0;
659     }
660 }
661
662 /* Derive the 33 subkeys from KEY and store them in SUBKEYS.  */
663 static void
664 serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
665 {
666   u32 w[8];             /* The `prekey'.  */
667   u32 ws[4];
668   u32 wt[4];
669
670   /* Initialize with key values.  */
671   w[0] = key[0];
672   w[1] = key[1];
673   w[2] = key[2];
674   w[3] = key[3];
675   w[4] = key[4];
676   w[5] = key[5];
677   w[6] = key[6];
678   w[7] = key[7];
679
680   /* Expand to intermediate key using the affine recurrence.  */
681 #define EXPAND_KEY4(wo, r)                                                     \
682   wo[0] = w[(r+0)%8] =                                                         \
683     rol (w[(r+0)%8] ^ w[(r+3)%8] ^ w[(r+5)%8] ^ w[(r+7)%8] ^ PHI ^ (r+0), 11); \
684   wo[1] = w[(r+1)%8] =                                                         \
685     rol (w[(r+1)%8] ^ w[(r+4)%8] ^ w[(r+6)%8] ^ w[(r+0)%8] ^ PHI ^ (r+1), 11); \
686   wo[2] = w[(r+2)%8] =                                                         \
687     rol (w[(r+2)%8] ^ w[(r+5)%8] ^ w[(r+7)%8] ^ w[(r+1)%8] ^ PHI ^ (r+2), 11); \
688   wo[3] = w[(r+3)%8] =                                                         \
689     rol (w[(r+3)%8] ^ w[(r+6)%8] ^ w[(r+0)%8] ^ w[(r+2)%8] ^ PHI ^ (r+3), 11);
690
691 #define EXPAND_KEY(r)       \
692   EXPAND_KEY4(ws, (r));     \
693   EXPAND_KEY4(wt, (r + 4));
694
695   /* Calculate subkeys via S-Boxes, in bitslice mode.  */
696   EXPAND_KEY (0); SBOX (3, ws, subkeys[0]); SBOX (2, wt, subkeys[1]);
697   EXPAND_KEY (8); SBOX (1, ws, subkeys[2]); SBOX (0, wt, subkeys[3]);
698   EXPAND_KEY (16); SBOX (7, ws, subkeys[4]); SBOX (6, wt, subkeys[5]);
699   EXPAND_KEY (24); SBOX (5, ws, subkeys[6]); SBOX (4, wt, subkeys[7]);
700   EXPAND_KEY (32); SBOX (3, ws, subkeys[8]); SBOX (2, wt, subkeys[9]);
701   EXPAND_KEY (40); SBOX (1, ws, subkeys[10]); SBOX (0, wt, subkeys[11]);
702   EXPAND_KEY (48); SBOX (7, ws, subkeys[12]); SBOX (6, wt, subkeys[13]);
703   EXPAND_KEY (56); SBOX (5, ws, subkeys[14]); SBOX (4, wt, subkeys[15]);
704   EXPAND_KEY (64); SBOX (3, ws, subkeys[16]); SBOX (2, wt, subkeys[17]);
705   EXPAND_KEY (72); SBOX (1, ws, subkeys[18]); SBOX (0, wt, subkeys[19]);
706   EXPAND_KEY (80); SBOX (7, ws, subkeys[20]); SBOX (6, wt, subkeys[21]);
707   EXPAND_KEY (88); SBOX (5, ws, subkeys[22]); SBOX (4, wt, subkeys[23]);
708   EXPAND_KEY (96); SBOX (3, ws, subkeys[24]); SBOX (2, wt, subkeys[25]);
709   EXPAND_KEY (104); SBOX (1, ws, subkeys[26]); SBOX (0, wt, subkeys[27]);
710   EXPAND_KEY (112); SBOX (7, ws, subkeys[28]); SBOX (6, wt, subkeys[29]);
711   EXPAND_KEY (120); SBOX (5, ws, subkeys[30]); SBOX (4, wt, subkeys[31]);
712   EXPAND_KEY4 (ws, 128); SBOX (3, ws, subkeys[32]);
713
714   wipememory (ws, sizeof (ws));
715   wipememory (wt, sizeof (wt));
716   wipememory (w, sizeof (w));
717 }
718
719 /* Initialize CONTEXT with the key KEY of KEY_LENGTH bits.  */
720 static void
721 serpent_setkey_internal (serpent_context_t *context,
722                          const byte *key, unsigned int key_length)
723 {
724   serpent_key_t key_prepared;
725
726   serpent_key_prepare (key, key_length, key_prepared);
727   serpent_subkeys_generate (key_prepared, context->keys);
728
729 #ifdef USE_AVX2
730   context->use_avx2 = 0;
731   if ((_gcry_get_hw_features () & HWF_INTEL_AVX2))
732     {
733       context->use_avx2 = 1;
734     }
735 #endif
736
737 #ifdef USE_NEON
738   context->use_neon = 0;
739   if ((_gcry_get_hw_features () & HWF_ARM_NEON))
740     {
741       context->use_neon = 1;
742     }
743 #endif
744
745   wipememory (key_prepared, sizeof(key_prepared));
746 }
747
748 /* Initialize CTX with the key KEY of KEY_LENGTH bytes.  */
749 static gcry_err_code_t
750 serpent_setkey (void *ctx,
751                 const byte *key, unsigned int key_length,
752                 gcry_cipher_hd_t hd)
753 {
754   serpent_context_t *context = ctx;
755   static const char *serpent_test_ret;
756   static int serpent_init_done;
757   gcry_err_code_t ret = GPG_ERR_NO_ERROR;
758
759   (void)hd;
760
761   if (! serpent_init_done)
762     {
763       /* Execute a self-test the first time, Serpent is used.  */
764       serpent_init_done = 1;
765       serpent_test_ret = serpent_test ();
766       if (serpent_test_ret)
767         log_error ("Serpent test failure: %s\n", serpent_test_ret);
768     }
769
770   if (serpent_test_ret)
771     ret = GPG_ERR_SELFTEST_FAILED;
772   else
773     serpent_setkey_internal (context, key, key_length);
774
775   return ret;
776 }
777
778 static void
779 serpent_encrypt_internal (serpent_context_t *context,
780                           const byte *input, byte *output)
781 {
782   serpent_block_t b, b_next;
783   int round = 0;
784
785   b[0] = buf_get_le32 (input + 0);
786   b[1] = buf_get_le32 (input + 4);
787   b[2] = buf_get_le32 (input + 8);
788   b[3] = buf_get_le32 (input + 12);
789
790   ROUND (0, context->keys, b, b_next);
791   ROUND (1, context->keys, b, b_next);
792   ROUND (2, context->keys, b, b_next);
793   ROUND (3, context->keys, b, b_next);
794   ROUND (4, context->keys, b, b_next);
795   ROUND (5, context->keys, b, b_next);
796   ROUND (6, context->keys, b, b_next);
797   ROUND (7, context->keys, b, b_next);
798   ROUND (0, context->keys, b, b_next);
799   ROUND (1, context->keys, b, b_next);
800   ROUND (2, context->keys, b, b_next);
801   ROUND (3, context->keys, b, b_next);
802   ROUND (4, context->keys, b, b_next);
803   ROUND (5, context->keys, b, b_next);
804   ROUND (6, context->keys, b, b_next);
805   ROUND (7, context->keys, b, b_next);
806   ROUND (0, context->keys, b, b_next);
807   ROUND (1, context->keys, b, b_next);
808   ROUND (2, context->keys, b, b_next);
809   ROUND (3, context->keys, b, b_next);
810   ROUND (4, context->keys, b, b_next);
811   ROUND (5, context->keys, b, b_next);
812   ROUND (6, context->keys, b, b_next);
813   ROUND (7, context->keys, b, b_next);
814   ROUND (0, context->keys, b, b_next);
815   ROUND (1, context->keys, b, b_next);
816   ROUND (2, context->keys, b, b_next);
817   ROUND (3, context->keys, b, b_next);
818   ROUND (4, context->keys, b, b_next);
819   ROUND (5, context->keys, b, b_next);
820   ROUND (6, context->keys, b, b_next);
821
822   ROUND_LAST (7, context->keys, b, b_next);
823
824   buf_put_le32 (output + 0, b_next[0]);
825   buf_put_le32 (output + 4, b_next[1]);
826   buf_put_le32 (output + 8, b_next[2]);
827   buf_put_le32 (output + 12, b_next[3]);
828 }
829
830 static void
831 serpent_decrypt_internal (serpent_context_t *context,
832                           const byte *input, byte *output)
833 {
834   serpent_block_t b, b_next;
835   int round = ROUNDS;
836
837   b_next[0] = buf_get_le32 (input + 0);
838   b_next[1] = buf_get_le32 (input + 4);
839   b_next[2] = buf_get_le32 (input + 8);
840   b_next[3] = buf_get_le32 (input + 12);
841
842   ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
843
844   ROUND_INVERSE (6, context->keys, b, b_next);
845   ROUND_INVERSE (5, context->keys, b, b_next);
846   ROUND_INVERSE (4, context->keys, b, b_next);
847   ROUND_INVERSE (3, context->keys, b, b_next);
848   ROUND_INVERSE (2, context->keys, b, b_next);
849   ROUND_INVERSE (1, context->keys, b, b_next);
850   ROUND_INVERSE (0, context->keys, b, b_next);
851   ROUND_INVERSE (7, context->keys, b, b_next);
852   ROUND_INVERSE (6, context->keys, b, b_next);
853   ROUND_INVERSE (5, context->keys, b, b_next);
854   ROUND_INVERSE (4, context->keys, b, b_next);
855   ROUND_INVERSE (3, context->keys, b, b_next);
856   ROUND_INVERSE (2, context->keys, b, b_next);
857   ROUND_INVERSE (1, context->keys, b, b_next);
858   ROUND_INVERSE (0, context->keys, b, b_next);
859   ROUND_INVERSE (7, context->keys, b, b_next);
860   ROUND_INVERSE (6, context->keys, b, b_next);
861   ROUND_INVERSE (5, context->keys, b, b_next);
862   ROUND_INVERSE (4, context->keys, b, b_next);
863   ROUND_INVERSE (3, context->keys, b, b_next);
864   ROUND_INVERSE (2, context->keys, b, b_next);
865   ROUND_INVERSE (1, context->keys, b, b_next);
866   ROUND_INVERSE (0, context->keys, b, b_next);
867   ROUND_INVERSE (7, context->keys, b, b_next);
868   ROUND_INVERSE (6, context->keys, b, b_next);
869   ROUND_INVERSE (5, context->keys, b, b_next);
870   ROUND_INVERSE (4, context->keys, b, b_next);
871   ROUND_INVERSE (3, context->keys, b, b_next);
872   ROUND_INVERSE (2, context->keys, b, b_next);
873   ROUND_INVERSE (1, context->keys, b, b_next);
874   ROUND_INVERSE (0, context->keys, b, b_next);
875
876   buf_put_le32 (output + 0, b_next[0]);
877   buf_put_le32 (output + 4, b_next[1]);
878   buf_put_le32 (output + 8, b_next[2]);
879   buf_put_le32 (output + 12, b_next[3]);
880 }
881
882 static unsigned int
883 serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
884 {
885   serpent_context_t *context = ctx;
886
887   serpent_encrypt_internal (context, buffer_in, buffer_out);
888   return /*burn_stack*/ (2 * sizeof (serpent_block_t));
889 }
890
891 static unsigned int
892 serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
893 {
894   serpent_context_t *context = ctx;
895
896   serpent_decrypt_internal (context, buffer_in, buffer_out);
897   return /*burn_stack*/ (2 * sizeof (serpent_block_t));
898 }
899
900 \f
901
902 /* Bulk encryption of complete blocks in CTR mode.  This function is only
903    intended for the bulk encryption feature of cipher.c.  CTR is expected to be
904    of size sizeof(serpent_block_t). */
905 void
906 _gcry_serpent_ctr_enc(void *context, unsigned char *ctr,
907                       void *outbuf_arg, const void *inbuf_arg,
908                       size_t nblocks)
909 {
910   serpent_context_t *ctx = context;
911   unsigned char *outbuf = outbuf_arg;
912   const unsigned char *inbuf = inbuf_arg;
913   unsigned char tmpbuf[sizeof(serpent_block_t)];
914   int burn_stack_depth = 2 * sizeof (serpent_block_t);
915
916 #ifdef USE_AVX2
917   if (ctx->use_avx2)
918     {
919       int did_use_avx2 = 0;
920
921       /* Process data in 16 block chunks. */
922       while (nblocks >= 16)
923         {
924           _gcry_serpent_avx2_ctr_enc(ctx, outbuf, inbuf, ctr);
925
926           nblocks -= 16;
927           outbuf += 16 * sizeof(serpent_block_t);
928           inbuf  += 16 * sizeof(serpent_block_t);
929           did_use_avx2 = 1;
930         }
931
932       if (did_use_avx2)
933         {
934           /* serpent-avx2 assembly code does not use stack */
935           if (nblocks == 0)
936             burn_stack_depth = 0;
937         }
938
939       /* Use generic/sse2 code to handle smaller chunks... */
940       /* TODO: use caching instead? */
941     }
942 #endif
943
944 #ifdef USE_SSE2
945   {
946     int did_use_sse2 = 0;
947
948     /* Process data in 8 block chunks. */
949     while (nblocks >= 8)
950       {
951         _gcry_serpent_sse2_ctr_enc(ctx, outbuf, inbuf, ctr);
952
953         nblocks -= 8;
954         outbuf += 8 * sizeof(serpent_block_t);
955         inbuf  += 8 * sizeof(serpent_block_t);
956         did_use_sse2 = 1;
957       }
958
959     if (did_use_sse2)
960       {
961         /* serpent-sse2 assembly code does not use stack */
962         if (nblocks == 0)
963           burn_stack_depth = 0;
964       }
965
966     /* Use generic code to handle smaller chunks... */
967     /* TODO: use caching instead? */
968   }
969 #endif
970
971 #ifdef USE_NEON
972   if (ctx->use_neon)
973     {
974       int did_use_neon = 0;
975
976       /* Process data in 8 block chunks. */
977       while (nblocks >= 8)
978         {
979           _gcry_serpent_neon_ctr_enc(ctx, outbuf, inbuf, ctr);
980
981           nblocks -= 8;
982           outbuf += 8 * sizeof(serpent_block_t);
983           inbuf  += 8 * sizeof(serpent_block_t);
984           did_use_neon = 1;
985         }
986
987       if (did_use_neon)
988         {
989           /* serpent-neon assembly code does not use stack */
990           if (nblocks == 0)
991             burn_stack_depth = 0;
992         }
993
994       /* Use generic code to handle smaller chunks... */
995       /* TODO: use caching instead? */
996     }
997 #endif
998
999   for ( ;nblocks; nblocks-- )
1000     {
1001       /* Encrypt the counter. */
1002       serpent_encrypt_internal(ctx, ctr, tmpbuf);
1003       /* XOR the input with the encrypted counter and store in output.  */
1004       cipher_block_xor(outbuf, tmpbuf, inbuf, sizeof(serpent_block_t));
1005       outbuf += sizeof(serpent_block_t);
1006       inbuf  += sizeof(serpent_block_t);
1007       /* Increment the counter.  */
1008       cipher_block_add(ctr, 1, sizeof(serpent_block_t));
1009     }
1010
1011   wipememory(tmpbuf, sizeof(tmpbuf));
1012   _gcry_burn_stack(burn_stack_depth);
1013 }
1014
1015 /* Bulk decryption of complete blocks in CBC mode.  This function is only
1016    intended for the bulk encryption feature of cipher.c. */
1017 void
1018 _gcry_serpent_cbc_dec(void *context, unsigned char *iv,
1019                       void *outbuf_arg, const void *inbuf_arg,
1020                       size_t nblocks)
1021 {
1022   serpent_context_t *ctx = context;
1023   unsigned char *outbuf = outbuf_arg;
1024   const unsigned char *inbuf = inbuf_arg;
1025   unsigned char savebuf[sizeof(serpent_block_t)];
1026   int burn_stack_depth = 2 * sizeof (serpent_block_t);
1027
1028 #ifdef USE_AVX2
1029   if (ctx->use_avx2)
1030     {
1031       int did_use_avx2 = 0;
1032
1033       /* Process data in 16 block chunks. */
1034       while (nblocks >= 16)
1035         {
1036           _gcry_serpent_avx2_cbc_dec(ctx, outbuf, inbuf, iv);
1037
1038           nblocks -= 16;
1039           outbuf += 16 * sizeof(serpent_block_t);
1040           inbuf  += 16 * sizeof(serpent_block_t);
1041           did_use_avx2 = 1;
1042         }
1043
1044       if (did_use_avx2)
1045         {
1046           /* serpent-avx2 assembly code does not use stack */
1047           if (nblocks == 0)
1048             burn_stack_depth = 0;
1049         }
1050
1051       /* Use generic/sse2 code to handle smaller chunks... */
1052     }
1053 #endif
1054
1055 #ifdef USE_SSE2
1056   {
1057     int did_use_sse2 = 0;
1058
1059     /* Process data in 8 block chunks. */
1060     while (nblocks >= 8)
1061       {
1062         _gcry_serpent_sse2_cbc_dec(ctx, outbuf, inbuf, iv);
1063
1064         nblocks -= 8;
1065         outbuf += 8 * sizeof(serpent_block_t);
1066         inbuf  += 8 * sizeof(serpent_block_t);
1067         did_use_sse2 = 1;
1068       }
1069
1070     if (did_use_sse2)
1071       {
1072         /* serpent-sse2 assembly code does not use stack */
1073         if (nblocks == 0)
1074           burn_stack_depth = 0;
1075       }
1076
1077     /* Use generic code to handle smaller chunks... */
1078   }
1079 #endif
1080
1081 #ifdef USE_NEON
1082   if (ctx->use_neon)
1083     {
1084       int did_use_neon = 0;
1085
1086       /* Process data in 8 block chunks. */
1087       while (nblocks >= 8)
1088         {
1089           _gcry_serpent_neon_cbc_dec(ctx, outbuf, inbuf, iv);
1090
1091           nblocks -= 8;
1092           outbuf += 8 * sizeof(serpent_block_t);
1093           inbuf  += 8 * sizeof(serpent_block_t);
1094           did_use_neon = 1;
1095         }
1096
1097       if (did_use_neon)
1098         {
1099           /* serpent-neon assembly code does not use stack */
1100           if (nblocks == 0)
1101             burn_stack_depth = 0;
1102         }
1103
1104       /* Use generic code to handle smaller chunks... */
1105     }
1106 #endif
1107
1108   for ( ;nblocks; nblocks-- )
1109     {
1110       /* INBUF is needed later and it may be identical to OUTBUF, so store
1111          the intermediate result to SAVEBUF.  */
1112       serpent_decrypt_internal (ctx, inbuf, savebuf);
1113
1114       cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf,
1115                                 sizeof(serpent_block_t));
1116       inbuf += sizeof(serpent_block_t);
1117       outbuf += sizeof(serpent_block_t);
1118     }
1119
1120   wipememory(savebuf, sizeof(savebuf));
1121   _gcry_burn_stack(burn_stack_depth);
1122 }
1123
1124 /* Bulk decryption of complete blocks in CFB mode.  This function is only
1125    intended for the bulk encryption feature of cipher.c. */
1126 void
1127 _gcry_serpent_cfb_dec(void *context, unsigned char *iv,
1128                       void *outbuf_arg, const void *inbuf_arg,
1129                       size_t nblocks)
1130 {
1131   serpent_context_t *ctx = context;
1132   unsigned char *outbuf = outbuf_arg;
1133   const unsigned char *inbuf = inbuf_arg;
1134   int burn_stack_depth = 2 * sizeof (serpent_block_t);
1135
1136 #ifdef USE_AVX2
1137   if (ctx->use_avx2)
1138     {
1139       int did_use_avx2 = 0;
1140
1141       /* Process data in 16 block chunks. */
1142       while (nblocks >= 16)
1143         {
1144           _gcry_serpent_avx2_cfb_dec(ctx, outbuf, inbuf, iv);
1145
1146           nblocks -= 16;
1147           outbuf += 16 * sizeof(serpent_block_t);
1148           inbuf  += 16 * sizeof(serpent_block_t);
1149           did_use_avx2 = 1;
1150         }
1151
1152       if (did_use_avx2)
1153         {
1154           /* serpent-avx2 assembly code does not use stack */
1155           if (nblocks == 0)
1156             burn_stack_depth = 0;
1157         }
1158
1159       /* Use generic/sse2 code to handle smaller chunks... */
1160     }
1161 #endif
1162
1163 #ifdef USE_SSE2
1164   {
1165     int did_use_sse2 = 0;
1166
1167     /* Process data in 8 block chunks. */
1168     while (nblocks >= 8)
1169       {
1170         _gcry_serpent_sse2_cfb_dec(ctx, outbuf, inbuf, iv);
1171
1172         nblocks -= 8;
1173         outbuf += 8 * sizeof(serpent_block_t);
1174         inbuf  += 8 * sizeof(serpent_block_t);
1175         did_use_sse2 = 1;
1176       }
1177
1178     if (did_use_sse2)
1179       {
1180         /* serpent-sse2 assembly code does not use stack */
1181         if (nblocks == 0)
1182           burn_stack_depth = 0;
1183       }
1184
1185     /* Use generic code to handle smaller chunks... */
1186   }
1187 #endif
1188
1189 #ifdef USE_NEON
1190   if (ctx->use_neon)
1191     {
1192       int did_use_neon = 0;
1193
1194       /* Process data in 8 block chunks. */
1195       while (nblocks >= 8)
1196         {
1197           _gcry_serpent_neon_cfb_dec(ctx, outbuf, inbuf, iv);
1198
1199           nblocks -= 8;
1200           outbuf += 8 * sizeof(serpent_block_t);
1201           inbuf  += 8 * sizeof(serpent_block_t);
1202           did_use_neon = 1;
1203         }
1204
1205       if (did_use_neon)
1206         {
1207           /* serpent-neon assembly code does not use stack */
1208           if (nblocks == 0)
1209             burn_stack_depth = 0;
1210         }
1211
1212       /* Use generic code to handle smaller chunks... */
1213     }
1214 #endif
1215
1216   for ( ;nblocks; nblocks-- )
1217     {
1218       serpent_encrypt_internal(ctx, iv, iv);
1219       cipher_block_xor_n_copy(outbuf, iv, inbuf, sizeof(serpent_block_t));
1220       outbuf += sizeof(serpent_block_t);
1221       inbuf  += sizeof(serpent_block_t);
1222     }
1223
1224   _gcry_burn_stack(burn_stack_depth);
1225 }
1226
1227 /* Bulk encryption/decryption of complete blocks in OCB mode. */
1228 size_t
1229 _gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
1230                         const void *inbuf_arg, size_t nblocks, int encrypt)
1231 {
1232 #if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
1233   serpent_context_t *ctx = (void *)&c->context.c;
1234   unsigned char *outbuf = outbuf_arg;
1235   const unsigned char *inbuf = inbuf_arg;
1236   int burn_stack_depth = 2 * sizeof (serpent_block_t);
1237   u64 blkn = c->u_mode.ocb.data_nblocks;
1238 #else
1239   (void)c;
1240   (void)outbuf_arg;
1241   (void)inbuf_arg;
1242   (void)encrypt;
1243 #endif
1244
1245 #ifdef USE_AVX2
1246   if (ctx->use_avx2)
1247     {
1248       int did_use_avx2 = 0;
1249       u64 Ls[16];
1250       unsigned int n = 16 - (blkn % 16);
1251       u64 *l;
1252       int i;
1253
1254       if (nblocks >= 16)
1255         {
1256           for (i = 0; i < 16; i += 8)
1257             {
1258               /* Use u64 to store pointers for x32 support (assembly function
1259                * assumes 64-bit pointers). */
1260               Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1261               Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
1262               Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1263               Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
1264               Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1265               Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
1266               Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1267             }
1268
1269           Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
1270           l = &Ls[(15 + n) % 16];
1271
1272           /* Process data in 16 block chunks. */
1273           while (nblocks >= 16)
1274             {
1275               blkn += 16;
1276               *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16);
1277
1278               if (encrypt)
1279                 _gcry_serpent_avx2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
1280                                           c->u_ctr.ctr, Ls);
1281               else
1282                 _gcry_serpent_avx2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
1283                                           c->u_ctr.ctr, Ls);
1284
1285               nblocks -= 16;
1286               outbuf += 16 * sizeof(serpent_block_t);
1287               inbuf  += 16 * sizeof(serpent_block_t);
1288               did_use_avx2 = 1;
1289             }
1290         }
1291
1292       if (did_use_avx2)
1293         {
1294           /* serpent-avx2 assembly code does not use stack */
1295           if (nblocks == 0)
1296             burn_stack_depth = 0;
1297         }
1298
1299       /* Use generic code to handle smaller chunks... */
1300     }
1301 #endif
1302
1303 #ifdef USE_SSE2
1304   {
1305     int did_use_sse2 = 0;
1306     u64 Ls[8];
1307     unsigned int n = 8 - (blkn % 8);
1308     u64 *l;
1309
1310     if (nblocks >= 8)
1311       {
1312         /* Use u64 to store pointers for x32 support (assembly function
1313           * assumes 64-bit pointers). */
1314         Ls[(0 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1315         Ls[(1 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
1316         Ls[(2 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1317         Ls[(3 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
1318         Ls[(4 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1319         Ls[(5 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
1320         Ls[(6 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1321         l = &Ls[(7 + n) % 8];
1322
1323         /* Process data in 8 block chunks. */
1324         while (nblocks >= 8)
1325           {
1326             blkn += 8;
1327             *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 8);
1328
1329             if (encrypt)
1330               _gcry_serpent_sse2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
1331                                           c->u_ctr.ctr, Ls);
1332             else
1333               _gcry_serpent_sse2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
1334                                           c->u_ctr.ctr, Ls);
1335
1336             nblocks -= 8;
1337             outbuf += 8 * sizeof(serpent_block_t);
1338             inbuf  += 8 * sizeof(serpent_block_t);
1339             did_use_sse2 = 1;
1340           }
1341       }
1342
1343     if (did_use_sse2)
1344       {
1345         /* serpent-sse2 assembly code does not use stack */
1346         if (nblocks == 0)
1347           burn_stack_depth = 0;
1348       }
1349
1350     /* Use generic code to handle smaller chunks... */
1351   }
1352 #endif
1353
1354 #ifdef USE_NEON
1355   if (ctx->use_neon)
1356     {
1357       int did_use_neon = 0;
1358       const void *Ls[8];
1359       unsigned int n = 8 - (blkn % 8);
1360       const void **l;
1361
1362       if (nblocks >= 8)
1363         {
1364           Ls[(0 + n) % 8] = c->u_mode.ocb.L[0];
1365           Ls[(1 + n) % 8] = c->u_mode.ocb.L[1];
1366           Ls[(2 + n) % 8] = c->u_mode.ocb.L[0];
1367           Ls[(3 + n) % 8] = c->u_mode.ocb.L[2];
1368           Ls[(4 + n) % 8] = c->u_mode.ocb.L[0];
1369           Ls[(5 + n) % 8] = c->u_mode.ocb.L[1];
1370           Ls[(6 + n) % 8] = c->u_mode.ocb.L[0];
1371           l = &Ls[(7 + n) % 8];
1372
1373           /* Process data in 8 block chunks. */
1374           while (nblocks >= 8)
1375             {
1376               blkn += 8;
1377               *l = ocb_get_l(c,  blkn - blkn % 8);
1378
1379               if (encrypt)
1380                 _gcry_serpent_neon_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
1381                                           c->u_ctr.ctr, Ls);
1382               else
1383                 _gcry_serpent_neon_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
1384                                           c->u_ctr.ctr, Ls);
1385
1386               nblocks -= 8;
1387               outbuf += 8 * sizeof(serpent_block_t);
1388               inbuf  += 8 * sizeof(serpent_block_t);
1389               did_use_neon = 1;
1390             }
1391         }
1392
1393       if (did_use_neon)
1394         {
1395           /* serpent-neon assembly code does not use stack */
1396           if (nblocks == 0)
1397             burn_stack_depth = 0;
1398         }
1399
1400       /* Use generic code to handle smaller chunks... */
1401     }
1402 #endif
1403
1404 #if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
1405   c->u_mode.ocb.data_nblocks = blkn;
1406
1407   if (burn_stack_depth)
1408     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
1409 #endif
1410
1411   return nblocks;
1412 }
1413
1414 /* Bulk authentication of complete blocks in OCB mode. */
1415 size_t
1416 _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
1417                         size_t nblocks)
1418 {
1419 #if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
1420   serpent_context_t *ctx = (void *)&c->context.c;
1421   const unsigned char *abuf = abuf_arg;
1422   int burn_stack_depth = 2 * sizeof(serpent_block_t);
1423   u64 blkn = c->u_mode.ocb.aad_nblocks;
1424 #else
1425   (void)c;
1426   (void)abuf_arg;
1427 #endif
1428
1429 #ifdef USE_AVX2
1430   if (ctx->use_avx2)
1431     {
1432       int did_use_avx2 = 0;
1433       u64 Ls[16];
1434       unsigned int n = 16 - (blkn % 16);
1435       u64 *l;
1436       int i;
1437
1438       if (nblocks >= 16)
1439         {
1440           for (i = 0; i < 16; i += 8)
1441             {
1442               /* Use u64 to store pointers for x32 support (assembly function
1443                * assumes 64-bit pointers). */
1444               Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1445               Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
1446               Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1447               Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
1448               Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1449               Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
1450               Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1451             }
1452
1453           Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
1454           l = &Ls[(15 + n) % 16];
1455
1456           /* Process data in 16 block chunks. */
1457           while (nblocks >= 16)
1458             {
1459               blkn += 16;
1460               *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16);
1461
1462               _gcry_serpent_avx2_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset,
1463                                           c->u_mode.ocb.aad_sum, Ls);
1464
1465               nblocks -= 16;
1466               abuf += 16 * sizeof(serpent_block_t);
1467               did_use_avx2 = 1;
1468             }
1469         }
1470
1471       if (did_use_avx2)
1472         {
1473           /* serpent-avx2 assembly code does not use stack */
1474           if (nblocks == 0)
1475             burn_stack_depth = 0;
1476         }
1477
1478       /* Use generic code to handle smaller chunks... */
1479     }
1480 #endif
1481
1482 #ifdef USE_SSE2
1483   {
1484     int did_use_sse2 = 0;
1485     u64 Ls[8];
1486     unsigned int n = 8 - (blkn % 8);
1487     u64 *l;
1488
1489     if (nblocks >= 8)
1490       {
1491         /* Use u64 to store pointers for x32 support (assembly function
1492         * assumes 64-bit pointers). */
1493         Ls[(0 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1494         Ls[(1 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
1495         Ls[(2 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1496         Ls[(3 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
1497         Ls[(4 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1498         Ls[(5 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
1499         Ls[(6 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
1500         l = &Ls[(7 + n) % 8];
1501
1502         /* Process data in 8 block chunks. */
1503         while (nblocks >= 8)
1504           {
1505             blkn += 8;
1506             *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 8);
1507
1508             _gcry_serpent_sse2_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset,
1509                                         c->u_mode.ocb.aad_sum, Ls);
1510
1511             nblocks -= 8;
1512             abuf += 8 * sizeof(serpent_block_t);
1513             did_use_sse2 = 1;
1514           }
1515       }
1516
1517     if (did_use_sse2)
1518       {
1519         /* serpent-avx2 assembly code does not use stack */
1520         if (nblocks == 0)
1521           burn_stack_depth = 0;
1522       }
1523
1524     /* Use generic code to handle smaller chunks... */
1525   }
1526 #endif
1527
1528 #ifdef USE_NEON
1529   if (ctx->use_neon)
1530     {
1531       int did_use_neon = 0;
1532       const void *Ls[8];
1533       unsigned int n = 8 - (blkn % 8);
1534       const void **l;
1535
1536       if (nblocks >= 8)
1537         {
1538           Ls[(0 + n) % 8] = c->u_mode.ocb.L[0];
1539           Ls[(1 + n) % 8] = c->u_mode.ocb.L[1];
1540           Ls[(2 + n) % 8] = c->u_mode.ocb.L[0];
1541           Ls[(3 + n) % 8] = c->u_mode.ocb.L[2];
1542           Ls[(4 + n) % 8] = c->u_mode.ocb.L[0];
1543           Ls[(5 + n) % 8] = c->u_mode.ocb.L[1];
1544           Ls[(6 + n) % 8] = c->u_mode.ocb.L[0];
1545           l = &Ls[(7 + n) % 8];
1546
1547           /* Process data in 8 block chunks. */
1548           while (nblocks >= 8)
1549             {
1550               blkn += 8;
1551               *l = ocb_get_l(c, blkn - blkn % 8);
1552
1553               _gcry_serpent_neon_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset,
1554                                           c->u_mode.ocb.aad_sum, Ls);
1555
1556               nblocks -= 8;
1557               abuf += 8 * sizeof(serpent_block_t);
1558               did_use_neon = 1;
1559             }
1560         }
1561
1562       if (did_use_neon)
1563         {
1564           /* serpent-neon assembly code does not use stack */
1565           if (nblocks == 0)
1566             burn_stack_depth = 0;
1567         }
1568
1569       /* Use generic code to handle smaller chunks... */
1570     }
1571 #endif
1572
1573 #if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
1574   c->u_mode.ocb.aad_nblocks = blkn;
1575
1576   if (burn_stack_depth)
1577     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
1578 #endif
1579
1580   return nblocks;
1581 }
1582
1583 \f
1584
1585 /* Run the self-tests for SERPENT-CTR-128, tests IV increment of bulk CTR
1586    encryption.  Returns NULL on success. */
1587 static const char*
1588 selftest_ctr_128 (void)
1589 {
1590   const int nblocks = 16+8+1;
1591   const int blocksize = sizeof(serpent_block_t);
1592   const int context_size = sizeof(serpent_context_t);
1593
1594   return _gcry_selftest_helper_ctr("SERPENT", &serpent_setkey,
1595            &serpent_encrypt, &_gcry_serpent_ctr_enc, nblocks, blocksize,
1596            context_size);
1597 }
1598
1599
1600 /* Run the self-tests for SERPENT-CBC-128, tests bulk CBC decryption.
1601    Returns NULL on success. */
1602 static const char*
1603 selftest_cbc_128 (void)
1604 {
1605   const int nblocks = 16+8+2;
1606   const int blocksize = sizeof(serpent_block_t);
1607   const int context_size = sizeof(serpent_context_t);
1608
1609   return _gcry_selftest_helper_cbc("SERPENT", &serpent_setkey,
1610            &serpent_encrypt, &_gcry_serpent_cbc_dec, nblocks, blocksize,
1611            context_size);
1612 }
1613
1614
1615 /* Run the self-tests for SERPENT-CBC-128, tests bulk CBC decryption.
1616    Returns NULL on success. */
1617 static const char*
1618 selftest_cfb_128 (void)
1619 {
1620   const int nblocks = 16+8+2;
1621   const int blocksize = sizeof(serpent_block_t);
1622   const int context_size = sizeof(serpent_context_t);
1623
1624   return _gcry_selftest_helper_cfb("SERPENT", &serpent_setkey,
1625            &serpent_encrypt, &_gcry_serpent_cfb_dec, nblocks, blocksize,
1626            context_size);
1627 }
1628
1629
1630 /* Serpent test.  */
1631
1632 static const char *
1633 serpent_test (void)
1634 {
1635   serpent_context_t context;
1636   unsigned char scratch[16];
1637   unsigned int i;
1638   const char *r;
1639
1640   static struct test
1641   {
1642     int key_length;
1643     unsigned char key[32];
1644     unsigned char text_plain[16];
1645     unsigned char text_cipher[16];
1646   } test_data[] =
1647     {
1648       {
1649         16,
1650         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
1651         "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
1652         "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
1653       },
1654       {
1655         24,
1656         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
1657         "\x00\x00\x00\x00\x00\x00\x00\x00",
1658         "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
1659         "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
1660       },
1661       {
1662         32,
1663         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
1664         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
1665         "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
1666         "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
1667       },
1668       {
1669         32,
1670         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
1671         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
1672         "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
1673         "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
1674       },
1675       {
1676         0
1677       },
1678     };
1679
1680   for (i = 0; test_data[i].key_length; i++)
1681     {
1682       serpent_setkey_internal (&context, test_data[i].key,
1683                                test_data[i].key_length);
1684       serpent_encrypt_internal (&context, test_data[i].text_plain, scratch);
1685
1686       if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
1687         switch (test_data[i].key_length)
1688           {
1689           case 16:
1690             return "Serpent-128 test encryption failed.";
1691           case  24:
1692             return "Serpent-192 test encryption failed.";
1693           case 32:
1694             return "Serpent-256 test encryption failed.";
1695           }
1696
1697     serpent_decrypt_internal (&context, test_data[i].text_cipher, scratch);
1698     if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
1699       switch (test_data[i].key_length)
1700         {
1701         case 16:
1702           return "Serpent-128 test decryption failed.";
1703         case  24:
1704           return "Serpent-192 test decryption failed.";
1705         case 32:
1706           return "Serpent-256 test decryption failed.";
1707         }
1708     }
1709
1710   if ( (r = selftest_ctr_128 ()) )
1711     return r;
1712
1713   if ( (r = selftest_cbc_128 ()) )
1714     return r;
1715
1716   if ( (r = selftest_cfb_128 ()) )
1717     return r;
1718
1719   return NULL;
1720 }
1721
1722 \f
1723 static gcry_cipher_oid_spec_t serpent128_oids[] =
1724   {
1725     {"1.3.6.1.4.1.11591.13.2.1", GCRY_CIPHER_MODE_ECB },
1726     {"1.3.6.1.4.1.11591.13.2.2", GCRY_CIPHER_MODE_CBC },
1727     {"1.3.6.1.4.1.11591.13.2.3", GCRY_CIPHER_MODE_OFB },
1728     {"1.3.6.1.4.1.11591.13.2.4", GCRY_CIPHER_MODE_CFB },
1729     { NULL }
1730   };
1731
1732 static gcry_cipher_oid_spec_t serpent192_oids[] =
1733   {
1734     {"1.3.6.1.4.1.11591.13.2.21", GCRY_CIPHER_MODE_ECB },
1735     {"1.3.6.1.4.1.11591.13.2.22", GCRY_CIPHER_MODE_CBC },
1736     {"1.3.6.1.4.1.11591.13.2.23", GCRY_CIPHER_MODE_OFB },
1737     {"1.3.6.1.4.1.11591.13.2.24", GCRY_CIPHER_MODE_CFB },
1738     { NULL }
1739   };
1740
1741 static gcry_cipher_oid_spec_t serpent256_oids[] =
1742   {
1743     {"1.3.6.1.4.1.11591.13.2.41", GCRY_CIPHER_MODE_ECB },
1744     {"1.3.6.1.4.1.11591.13.2.42", GCRY_CIPHER_MODE_CBC },
1745     {"1.3.6.1.4.1.11591.13.2.43", GCRY_CIPHER_MODE_OFB },
1746     {"1.3.6.1.4.1.11591.13.2.44", GCRY_CIPHER_MODE_CFB },
1747     { NULL }
1748   };
1749
1750 static const char *serpent128_aliases[] =
1751   {
1752     "SERPENT",
1753     "SERPENT-128",
1754     NULL
1755   };
1756 static const char *serpent192_aliases[] =
1757   {
1758     "SERPENT-192",
1759     NULL
1760   };
1761 static const char *serpent256_aliases[] =
1762   {
1763     "SERPENT-256",
1764     NULL
1765   };
1766
1767 gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
1768   {
1769     GCRY_CIPHER_SERPENT128, {0, 0},
1770     "SERPENT128", serpent128_aliases, serpent128_oids, 16, 128,
1771     sizeof (serpent_context_t),
1772     serpent_setkey, serpent_encrypt, serpent_decrypt
1773   };
1774
1775 gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
1776   {
1777     GCRY_CIPHER_SERPENT192, {0, 0},
1778     "SERPENT192", serpent192_aliases, serpent192_oids, 16, 192,
1779     sizeof (serpent_context_t),
1780     serpent_setkey, serpent_encrypt, serpent_decrypt
1781   };
1782
1783 gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
1784   {
1785     GCRY_CIPHER_SERPENT256, {0, 0},
1786     "SERPENT256", serpent256_aliases, serpent256_oids, 16, 256,
1787     sizeof (serpent_context_t),
1788     serpent_setkey, serpent_encrypt, serpent_decrypt
1789   };