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 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 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 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 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 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 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 603 void serpent_done(symmetric_key *skey) 604 { 605 LTC_UNUSED_PARAM(skey); 606 } 607 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 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