1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 
11 /* Based on serpent.cpp - originally written and placed in the public domain by Wei Dai
12    https://github.com/weidai11/cryptopp/blob/master/serpent.cpp
13 
14    On 2017-10-16 wikipedia says:
15    "The Serpent cipher algorithm is in the public domain and has not been patented."
16    https://en.wikipedia.org/wiki/Serpent_(cipher)
17  */
18 
19 #include "tomcrypt_private.h"
20 
21 #ifdef LTC_SERPENT
22 
23 const struct ltc_cipher_descriptor serpent_desc = {
24    "serpent",
25    25,                  /* cipher_ID */
26    16, 32, 16, 32,      /* min_key_len, max_key_len, block_len, default_rounds */
27    &serpent_setup,
28    &serpent_ecb_encrypt,
29    &serpent_ecb_decrypt,
30    &serpent_test,
31    &serpent_done,
32    &serpent_keysize,
33    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
34 };
35 
36 /* linear transformation */
37 #define _LT(i,a,b,c,d,e)  {                                 \
38                             a = ROLc(a, 13);                \
39                             c = ROLc(c, 3);                 \
40                             d = ROLc(d ^ c ^ (a << 3), 7);  \
41                             b = ROLc(b ^ a ^ c, 1);         \
42                             a = ROLc(a ^ b ^ d, 5);         \
43                             c = ROLc(c ^ d ^ (b << 7), 22); \
44                           }
45 
46 /* inverse linear transformation */
47 #define _ILT(i,a,b,c,d,e) {                                 \
48                             c = RORc(c, 22);                \
49                             a = RORc(a, 5);                 \
50                             c ^= d ^ (b << 7);              \
51                             a ^= b ^ d;                     \
52                             b = RORc(b, 1);                 \
53                             d = RORc(d, 7) ^ c ^ (a << 3);  \
54                             b ^= a ^ c;                     \
55                             c = RORc(c, 3);                 \
56                             a = RORc(a, 13);                \
57                           }
58 
59 /* order of output from S-box functions */
60 #define _beforeS0(f) f(0,a,b,c,d,e)
61 #define _afterS0(f)  f(1,b,e,c,a,d)
62 #define _afterS1(f)  f(2,c,b,a,e,d)
63 #define _afterS2(f)  f(3,a,e,b,d,c)
64 #define _afterS3(f)  f(4,e,b,d,c,a)
65 #define _afterS4(f)  f(5,b,a,e,c,d)
66 #define _afterS5(f)  f(6,a,c,b,e,d)
67 #define _afterS6(f)  f(7,a,c,d,b,e)
68 #define _afterS7(f)  f(8,d,e,b,a,c)
69 
70 /* order of output from inverse S-box functions */
71 #define _beforeI7(f) f(8,a,b,c,d,e)
72 #define _afterI7(f)  f(7,d,a,b,e,c)
73 #define _afterI6(f)  f(6,a,b,c,e,d)
74 #define _afterI5(f)  f(5,b,d,e,c,a)
75 #define _afterI4(f)  f(4,b,c,e,a,d)
76 #define _afterI3(f)  f(3,a,b,e,c,d)
77 #define _afterI2(f)  f(2,b,d,e,c,a)
78 #define _afterI1(f)  f(1,a,b,c,e,d)
79 #define _afterI0(f)  f(0,a,d,b,e,c)
80 
81 /* The instruction sequences for the S-box functions
82  * come from Dag Arne Osvik's paper "Speeding up Serpent".
83  */
84 
85 #define _S0(i, r0, r1, r2, r3, r4) { \
86    r3 ^= r0;   \
87    r4 = r1;    \
88    r1 &= r3;   \
89    r4 ^= r2;   \
90    r1 ^= r0;   \
91    r0 |= r3;   \
92    r0 ^= r4;   \
93    r4 ^= r3;   \
94    r3 ^= r2;   \
95    r2 |= r1;   \
96    r2 ^= r4;   \
97    r4 = ~r4;   \
98    r4 |= r1;   \
99    r1 ^= r3;   \
100    r1 ^= r4;   \
101    r3 |= r0;   \
102    r1 ^= r3;   \
103    r4 ^= r3;   \
104 }
105 
106 #define _I0(i, r0, r1, r2, r3, r4) { \
107    r2 = ~r2;   \
108    r4 = r1;    \
109    r1 |= r0;   \
110    r4 = ~r4;   \
111    r1 ^= r2;   \
112    r2 |= r4;   \
113    r1 ^= r3;   \
114    r0 ^= r4;   \
115    r2 ^= r0;   \
116    r0 &= r3;   \
117    r4 ^= r0;   \
118    r0 |= r1;   \
119    r0 ^= r2;   \
120    r3 ^= r4;   \
121    r2 ^= r1;   \
122    r3 ^= r0;   \
123    r3 ^= r1;   \
124    r2 &= r3;   \
125    r4 ^= r2;   \
126 }
127 
128 #define _S1(i, r0, r1, r2, r3, r4) { \
129    r0 = ~r0;   \
130    r2 = ~r2;   \
131    r4 = r0;    \
132    r0 &= r1;   \
133    r2 ^= r0;   \
134    r0 |= r3;   \
135    r3 ^= r2;   \
136    r1 ^= r0;   \
137    r0 ^= r4;   \
138    r4 |= r1;   \
139    r1 ^= r3;   \
140    r2 |= r0;   \
141    r2 &= r4;   \
142    r0 ^= r1;   \
143    r1 &= r2;   \
144    r1 ^= r0;   \
145    r0 &= r2;   \
146    r0 ^= r4;   \
147 }
148 
149 #define _I1(i, r0, r1, r2, r3, r4) { \
150    r4 = r1;    \
151    r1 ^= r3;   \
152    r3 &= r1;   \
153    r4 ^= r2;   \
154    r3 ^= r0;   \
155    r0 |= r1;   \
156    r2 ^= r3;   \
157    r0 ^= r4;   \
158    r0 |= r2;   \
159    r1 ^= r3;   \
160    r0 ^= r1;   \
161    r1 |= r3;   \
162    r1 ^= r0;   \
163    r4 = ~r4;   \
164    r4 ^= r1;   \
165    r1 |= r0;   \
166    r1 ^= r0;   \
167    r1 |= r4;   \
168    r3 ^= r1;   \
169 }
170 
171 #define _S2(i, r0, r1, r2, r3, r4) { \
172    r4 = r0;    \
173    r0 &= r2;   \
174    r0 ^= r3;   \
175    r2 ^= r1;   \
176    r2 ^= r0;   \
177    r3 |= r4;   \
178    r3 ^= r1;   \
179    r4 ^= r2;   \
180    r1 = r3;    \
181    r3 |= r4;   \
182    r3 ^= r0;   \
183    r0 &= r1;   \
184    r4 ^= r0;   \
185    r1 ^= r3;   \
186    r1 ^= r4;   \
187    r4 = ~r4;   \
188 }
189 
190 #define _I2(i, r0, r1, r2, r3, r4) { \
191    r2 ^= r3;   \
192    r3 ^= r0;   \
193    r4 = r3;    \
194    r3 &= r2;   \
195    r3 ^= r1;   \
196    r1 |= r2;   \
197    r1 ^= r4;   \
198    r4 &= r3;   \
199    r2 ^= r3;   \
200    r4 &= r0;   \
201    r4 ^= r2;   \
202    r2 &= r1;   \
203    r2 |= r0;   \
204    r3 = ~r3;   \
205    r2 ^= r3;   \
206    r0 ^= r3;   \
207    r0 &= r1;   \
208    r3 ^= r4;   \
209    r3 ^= r0;   \
210 }
211 
212 #define _S3(i, r0, r1, r2, r3, r4) { \
213    r4 = r0;    \
214    r0 |= r3;   \
215    r3 ^= r1;   \
216    r1 &= r4;   \
217    r4 ^= r2;   \
218    r2 ^= r3;   \
219    r3 &= r0;   \
220    r4 |= r1;   \
221    r3 ^= r4;   \
222    r0 ^= r1;   \
223    r4 &= r0;   \
224    r1 ^= r3;   \
225    r4 ^= r2;   \
226    r1 |= r0;   \
227    r1 ^= r2;   \
228    r0 ^= r3;   \
229    r2 = r1;    \
230    r1 |= r3;   \
231    r1 ^= r0;   \
232 }
233 
234 #define _I3(i, r0, r1, r2, r3, r4) { \
235    r4 = r2;    \
236    r2 ^= r1;   \
237    r1 &= r2;   \
238    r1 ^= r0;   \
239    r0 &= r4;   \
240    r4 ^= r3;   \
241    r3 |= r1;   \
242    r3 ^= r2;   \
243    r0 ^= r4;   \
244    r2 ^= r0;   \
245    r0 |= r3;   \
246    r0 ^= r1;   \
247    r4 ^= r2;   \
248    r2 &= r3;   \
249    r1 |= r3;   \
250    r1 ^= r2;   \
251    r4 ^= r0;   \
252    r2 ^= r4;   \
253 }
254 
255 #define _S4(i, r0, r1, r2, r3, r4) { \
256    r1 ^= r3;   \
257    r3 = ~r3;   \
258    r2 ^= r3;   \
259    r3 ^= r0;   \
260    r4 = r1;    \
261    r1 &= r3;   \
262    r1 ^= r2;   \
263    r4 ^= r3;   \
264    r0 ^= r4;   \
265    r2 &= r4;   \
266    r2 ^= r0;   \
267    r0 &= r1;   \
268    r3 ^= r0;   \
269    r4 |= r1;   \
270    r4 ^= r0;   \
271    r0 |= r3;   \
272    r0 ^= r2;   \
273    r2 &= r3;   \
274    r0 = ~r0;   \
275    r4 ^= r2;   \
276 }
277 
278 #define _I4(i, r0, r1, r2, r3, r4) { \
279    r4 = r2;    \
280    r2 &= r3;   \
281    r2 ^= r1;   \
282    r1 |= r3;   \
283    r1 &= r0;   \
284    r4 ^= r2;   \
285    r4 ^= r1;   \
286    r1 &= r2;   \
287    r0 = ~r0;   \
288    r3 ^= r4;   \
289    r1 ^= r3;   \
290    r3 &= r0;   \
291    r3 ^= r2;   \
292    r0 ^= r1;   \
293    r2 &= r0;   \
294    r3 ^= r0;   \
295    r2 ^= r4;   \
296    r2 |= r3;   \
297    r3 ^= r0;   \
298    r2 ^= r1;   \
299 }
300 
301 #define _S5(i, r0, r1, r2, r3, r4) { \
302    r0 ^= r1;   \
303    r1 ^= r3;   \
304    r3 = ~r3;   \
305    r4 = r1;    \
306    r1 &= r0;   \
307    r2 ^= r3;   \
308    r1 ^= r2;   \
309    r2 |= r4;   \
310    r4 ^= r3;   \
311    r3 &= r1;   \
312    r3 ^= r0;   \
313    r4 ^= r1;   \
314    r4 ^= r2;   \
315    r2 ^= r0;   \
316    r0 &= r3;   \
317    r2 = ~r2;   \
318    r0 ^= r4;   \
319    r4 |= r3;   \
320    r2 ^= r4;   \
321 }
322 
323 #define _I5(i, r0, r1, r2, r3, r4) { \
324    r1 = ~r1;   \
325    r4 = r3;    \
326    r2 ^= r1;   \
327    r3 |= r0;   \
328    r3 ^= r2;   \
329    r2 |= r1;   \
330    r2 &= r0;   \
331    r4 ^= r3;   \
332    r2 ^= r4;   \
333    r4 |= r0;   \
334    r4 ^= r1;   \
335    r1 &= r2;   \
336    r1 ^= r3;   \
337    r4 ^= r2;   \
338    r3 &= r4;   \
339    r4 ^= r1;   \
340    r3 ^= r0;   \
341    r3 ^= r4;   \
342    r4 = ~r4;   \
343 }
344 
345 #define _S6(i, r0, r1, r2, r3, r4) { \
346    r2 = ~r2;   \
347    r4 = r3;    \
348    r3 &= r0;   \
349    r0 ^= r4;   \
350    r3 ^= r2;   \
351    r2 |= r4;   \
352    r1 ^= r3;   \
353    r2 ^= r0;   \
354    r0 |= r1;   \
355    r2 ^= r1;   \
356    r4 ^= r0;   \
357    r0 |= r3;   \
358    r0 ^= r2;   \
359    r4 ^= r3;   \
360    r4 ^= r0;   \
361    r3 = ~r3;   \
362    r2 &= r4;   \
363    r2 ^= r3;   \
364 }
365 
366 #define _I6(i, r0, r1, r2, r3, r4) { \
367    r0 ^= r2;   \
368    r4 = r2;    \
369    r2 &= r0;   \
370    r4 ^= r3;   \
371    r2 = ~r2;   \
372    r3 ^= r1;   \
373    r2 ^= r3;   \
374    r4 |= r0;   \
375    r0 ^= r2;   \
376    r3 ^= r4;   \
377    r4 ^= r1;   \
378    r1 &= r3;   \
379    r1 ^= r0;   \
380    r0 ^= r3;   \
381    r0 |= r2;   \
382    r3 ^= r1;   \
383    r4 ^= r0;   \
384 }
385 
386 #define _S7(i, r0, r1, r2, r3, r4) { \
387    r4 = r2;    \
388    r2 &= r1;   \
389    r2 ^= r3;   \
390    r3 &= r1;   \
391    r4 ^= r2;   \
392    r2 ^= r1;   \
393    r1 ^= r0;   \
394    r0 |= r4;   \
395    r0 ^= r2;   \
396    r3 ^= r1;   \
397    r2 ^= r3;   \
398    r3 &= r0;   \
399    r3 ^= r4;   \
400    r4 ^= r2;   \
401    r2 &= r0;   \
402    r4 = ~r4;   \
403    r2 ^= r4;   \
404    r4 &= r0;   \
405    r1 ^= r3;   \
406    r4 ^= r1;   \
407 }
408 
409 #define _I7(i, r0, r1, r2, r3, r4) { \
410    r4 = r2;    \
411    r2 ^= r0;   \
412    r0 &= r3;   \
413    r2 = ~r2;   \
414    r4 |= r3;   \
415    r3 ^= r1;   \
416    r1 |= r0;   \
417    r0 ^= r2;   \
418    r2 &= r4;   \
419    r1 ^= r2;   \
420    r2 ^= r0;   \
421    r0 |= r2;   \
422    r3 &= r4;   \
423    r0 ^= r3;   \
424    r4 ^= r1;   \
425    r3 ^= r4;   \
426    r4 |= r0;   \
427    r3 ^= r2;   \
428    r4 ^= r2;   \
429 }
430 
431 /* key xor */
432 #define _KX(r, a, b, c, d, e) { \
433    a ^= k[4 * r + 0];   \
434    b ^= k[4 * r + 1];   \
435    c ^= k[4 * r + 2];   \
436    d ^= k[4 * r + 3];   \
437 }
438 
439 #define _LK(r, a, b, c, d, e) { \
440    a = k[(8-r)*4 + 0];  \
441    b = k[(8-r)*4 + 1];  \
442    c = k[(8-r)*4 + 2];  \
443    d = k[(8-r)*4 + 3];  \
444 }
445 
446 #define _SK(r, a, b, c, d, e) { \
447    k[(8-r)*4 + 4] = a;  \
448    k[(8-r)*4 + 5] = b;  \
449    k[(8-r)*4 + 6] = c;  \
450    k[(8-r)*4 + 7] = d;  \
451 }
452 
_setup_key(const unsigned char * key,int keylen,int rounds,ulong32 * k)453 static int _setup_key(const unsigned char *key, int keylen, int rounds, ulong32 *k)
454 {
455    int i;
456    ulong32 t;
457    ulong32 k0[8] = { 0 }; /* zero-initialize */
458    ulong32 a, b, c, d, e;
459 
460    for (i = 0; i < 8 && i < keylen/4; ++i) {
461       LOAD32L(k0[i], key + i * 4);
462    }
463    if (keylen < 32) {
464       k0[keylen/4] |= (ulong32)1 << ((keylen%4)*8);
465     }
466 
467    t = k0[7];
468    for (i = 0; i < 8; ++i) {
469       k[i] = k0[i] = t = ROLc(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11);
470    }
471    for (i = 8; i < 4*(rounds+1); ++i) {
472       k[i] = t = ROLc(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
473    }
474    k -= 20;
475 
476    for (i = 0; i < rounds/8; i++) {
477       _afterS2(_LK);  _afterS2(_S3);  _afterS3(_SK);
478       _afterS1(_LK);  _afterS1(_S2);  _afterS2(_SK);
479       _afterS0(_LK);  _afterS0(_S1);  _afterS1(_SK);
480       _beforeS0(_LK); _beforeS0(_S0); _afterS0(_SK);
481       k += 8*4;
482       _afterS6(_LK); _afterS6(_S7); _afterS7(_SK);
483       _afterS5(_LK); _afterS5(_S6); _afterS6(_SK);
484       _afterS4(_LK); _afterS4(_S5); _afterS5(_SK);
485       _afterS3(_LK); _afterS3(_S4); _afterS4(_SK);
486    }
487    _afterS2(_LK); _afterS2(_S3); _afterS3(_SK);
488 
489    return CRYPT_OK;
490 }
491 
_enc_block(const unsigned char * in,unsigned char * out,const ulong32 * k)492 static int _enc_block(const unsigned char *in, unsigned char *out, const ulong32 *k)
493 {
494    ulong32 a, b, c, d, e;
495    unsigned int i = 1;
496 
497    LOAD32L(a, in + 0);
498    LOAD32L(b, in + 4);
499    LOAD32L(c, in + 8);
500    LOAD32L(d, in + 12);
501 
502    do {
503       _beforeS0(_KX); _beforeS0(_S0); _afterS0(_LT);
504       _afterS0(_KX);  _afterS0(_S1);  _afterS1(_LT);
505       _afterS1(_KX);  _afterS1(_S2);  _afterS2(_LT);
506       _afterS2(_KX);  _afterS2(_S3);  _afterS3(_LT);
507       _afterS3(_KX);  _afterS3(_S4);  _afterS4(_LT);
508       _afterS4(_KX);  _afterS4(_S5);  _afterS5(_LT);
509       _afterS5(_KX);  _afterS5(_S6);  _afterS6(_LT);
510       _afterS6(_KX);  _afterS6(_S7);
511 
512       if (i == 4) break;
513 
514       ++i;
515       c = b;
516       b = e;
517       e = d;
518       d = a;
519       a = e;
520       k += 32;
521       _beforeS0(_LT);
522    } while (1);
523 
524    _afterS7(_KX);
525 
526    STORE32L(d, out + 0);
527    STORE32L(e, out + 4);
528    STORE32L(b, out + 8);
529    STORE32L(a, out + 12);
530 
531    return CRYPT_OK;
532 }
533 
_dec_block(const unsigned char * in,unsigned char * out,const ulong32 * k)534 static int _dec_block(const unsigned char *in, unsigned char *out, const ulong32 *k)
535 {
536    ulong32 a, b, c, d, e;
537    unsigned int i;
538 
539    LOAD32L(a, in + 0);
540    LOAD32L(b, in + 4);
541    LOAD32L(c, in + 8);
542    LOAD32L(d, in + 12);
543    e = 0; LTC_UNUSED_PARAM(e); /* avoid scan-build warning */
544    i = 4;
545    k += 96;
546 
547    _beforeI7(_KX);
548    goto start;
549 
550    do {
551       c = b;
552       b = d;
553       d = e;
554       k -= 32;
555       _beforeI7(_ILT);
556 start:
557                       _beforeI7(_I7); _afterI7(_KX);
558       _afterI7(_ILT); _afterI7(_I6);  _afterI6(_KX);
559       _afterI6(_ILT); _afterI6(_I5);  _afterI5(_KX);
560       _afterI5(_ILT); _afterI5(_I4);  _afterI4(_KX);
561       _afterI4(_ILT); _afterI4(_I3);  _afterI3(_KX);
562       _afterI3(_ILT); _afterI3(_I2);  _afterI2(_KX);
563       _afterI2(_ILT); _afterI2(_I1);  _afterI1(_KX);
564       _afterI1(_ILT); _afterI1(_I0);  _afterI0(_KX);
565    } while (--i != 0);
566 
567    STORE32L(a, out + 0);
568    STORE32L(d, out + 4);
569    STORE32L(b, out + 8);
570    STORE32L(e, out + 12);
571 
572    return CRYPT_OK;
573 }
574 
serpent_setup(const unsigned char * key,int keylen,int num_rounds,symmetric_key * skey)575 int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
576 {
577    int err;
578 
579    LTC_ARGCHK(key  != NULL);
580    LTC_ARGCHK(skey != NULL);
581 
582    if (num_rounds != 0 && num_rounds != 32) return CRYPT_INVALID_ROUNDS;
583    if (keylen != 16 && keylen != 24 && keylen != 32) return CRYPT_INVALID_KEYSIZE;
584 
585    err = _setup_key(key, keylen, 32, skey->serpent.k);
586 #ifdef LTC_CLEAN_STACK
587    burn_stack(sizeof(ulong32) * 14 + sizeof(int));
588 #endif
589    return err;
590 }
591 
serpent_ecb_encrypt(const unsigned char * pt,unsigned char * ct,const symmetric_key * skey)592 int serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
593 {
594    int err = _enc_block(pt, ct, skey->serpent.k);
595 #ifdef LTC_CLEAN_STACK
596    burn_stack(sizeof(ulong32) * 5 + sizeof(int));
597 #endif
598    return err;
599 }
600 
serpent_ecb_decrypt(const unsigned char * ct,unsigned char * pt,const symmetric_key * skey)601 int serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
602 {
603    int err = _dec_block(ct, pt, skey->serpent.k);
604 #ifdef LTC_CLEAN_STACK
605    burn_stack(sizeof(ulong32) * 5 + sizeof(int));
606 #endif
607    return err;
608 }
609 
serpent_done(symmetric_key * skey)610 void serpent_done(symmetric_key *skey)
611 {
612    LTC_UNUSED_PARAM(skey);
613 }
614 
serpent_keysize(int * keysize)615 int serpent_keysize(int *keysize)
616 {
617    LTC_ARGCHK(keysize != NULL);
618 
619    if (*keysize >= 32) { *keysize = 32; }
620    else if (*keysize >= 24) { *keysize = 24; }
621    else if (*keysize >= 16) { *keysize = 16; }
622    else return CRYPT_INVALID_KEYSIZE;
623    return CRYPT_OK;
624 }
625 
serpent_test(void)626 int serpent_test(void)
627 {
628 #ifndef LTC_TEST
629    return CRYPT_NOP;
630 #else
631    static const struct {
632       unsigned char key[32];
633       int keylen;
634       unsigned char pt[16], ct[16];
635    } tests[] = {
636       {
637       /* key */    {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
638                     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
639       /* keylen */ 32,
640       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
641       /* ct */     {0xA2,0x23,0xAA,0x12,0x88,0x46,0x3C,0x0E,0x2B,0xE3,0x8E,0xBD,0x82,0x56,0x16,0xC0}
642       },
643       {
644       /* key */    {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
645                     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
646       /* keylen */ 32,
647       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
648       /* ct */     {0xEA,0xE1,0xD4,0x05,0x57,0x01,0x74,0xDF,0x7D,0xF2,0xF9,0x96,0x6D,0x50,0x91,0x59}
649       },
650       {
651       /* key */    {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
652                     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
653       /* keylen */ 32,
654       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
655       /* ct */     {0x65,0xF3,0x76,0x84,0x47,0x1E,0x92,0x1D,0xC8,0xA3,0x0F,0x45,0xB4,0x3C,0x44,0x99}
656       },
657       {
658       /* key */    {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
659                     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
660       /* keylen */ 24,
661       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
662       /* ct */     {0x9E,0x27,0x4E,0xAD,0x9B,0x73,0x7B,0xB2,0x1E,0xFC,0xFC,0xA5,0x48,0x60,0x26,0x89}
663       },
664       {
665       /* key */    {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
666                     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
667       /* keylen */ 24,
668       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
669       /* ct */     {0x92,0xFC,0x8E,0x51,0x03,0x99,0xE4,0x6A,0x04,0x1B,0xF3,0x65,0xE7,0xB3,0xAE,0x82}
670       },
671       {
672       /* key */    {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
673                     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
674       /* keylen */ 24,
675       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
676       /* ct */     {0x5E,0x0D,0xA3,0x86,0xC4,0x6A,0xD4,0x93,0xDE,0xA2,0x03,0xFD,0xC6,0xF5,0x7D,0x70}
677       },
678       {
679       /* key */    {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
680       /* keylen */ 16,
681       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
682       /* ct */     {0x26,0x4E,0x54,0x81,0xEF,0xF4,0x2A,0x46,0x06,0xAB,0xDA,0x06,0xC0,0xBF,0xDA,0x3D}
683       },
684       {
685       /* key */    {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
686       /* keylen */ 16,
687       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
688       /* ct */     {0x4A,0x23,0x1B,0x3B,0xC7,0x27,0x99,0x34,0x07,0xAC,0x6E,0xC8,0x35,0x0E,0x85,0x24}
689       },
690       {
691       /* key */    {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
692       /* keylen */ 16,
693       /* pt */     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
694       /* ct */     {0xE0,0x32,0x69,0xF9,0xE9,0xFD,0x85,0x3C,0x7D,0x81,0x56,0xDF,0x14,0xB9,0x8D,0x56}
695       }
696    };
697 
698    unsigned char buf[2][16];
699    symmetric_key key;
700    int err, x;
701 
702    for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
703       if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
704         return err;
705       }
706       if ((err = serpent_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
707         return err;
708       }
709       if (compare_testvector(buf[0], 16, tests[x].ct, 16, "SERPENT Encrypt", x)) {
710         return CRYPT_FAIL_TESTVECTOR;
711       }
712       if ((err = serpent_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
713         return err;
714       }
715       if (compare_testvector(buf[1], 16, tests[x].pt, 16, "SERPENT Decrypt", x)) {
716         return CRYPT_FAIL_TESTVECTOR;
717       }
718    }
719 
720    return CRYPT_OK;
721 #endif
722 }
723 
724 #endif
725 
726 /* ref:         $Format:%D$ */
727 /* git commit:  $Format:%H$ */
728 /* commit time: $Format:%ai$ */
729