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