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 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 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 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 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 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 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 610 void serpent_done(symmetric_key *skey) 611 { 612 LTC_UNUSED_PARAM(skey); 613 } 614 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 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