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