1/* serpent.c - Implementation of the Serpent encryption algorithm. 2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 3 * 4 * This file is part of Libgcrypt. 5 * 6 * Libgcrypt is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser general Public License as 8 * published by the Free Software Foundation; either version 2.1 of 9 * the License, or (at your option) any later version. 10 * 11 * Libgcrypt is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 * 02111-1307, USA. 20 */ 21 22#include <config.h> 23 24#include <string.h> 25#include <stdio.h> 26 27#include "types.h" 28#include "g10lib.h" 29#include "cipher.h" 30#include "bithelp.h" 31 32/* Number of rounds per Serpent encrypt/decrypt operation. */ 33#define ROUNDS 32 34 35/* Magic number, used during generating of the subkeys. */ 36#define PHI 0x9E3779B9 37 38/* Serpent works on 128 bit blocks. */ 39typedef u32 serpent_block_t[4]; 40 41/* Serpent key, provided by the user. If the original key is shorter 42 than 256 bits, it is padded. */ 43typedef u32 serpent_key_t[8]; 44 45/* The key schedule consists of 33 128 bit subkeys. */ 46typedef u32 serpent_subkeys_t[ROUNDS + 1][4]; 47 48/* A Serpent context. */ 49typedef struct serpent_context 50{ 51 serpent_subkeys_t keys; /* Generated subkeys. */ 52} serpent_context_t; 53 54 55/* A prototype. */ 56static const char *serpent_test (void); 57 58 59#define byte_swap_32(x) \ 60 (0 \ 61 | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \ 62 | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) 63 64/* These are the S-Boxes of Serpent. They are copied from Serpents 65 reference implementation (the optimized one, contained in 66 `floppy2') and are therefore: 67 68 Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen. 69 70 To quote the Serpent homepage 71 (http://www.cl.cam.ac.uk/~rja14/serpent.html): 72 73 "Serpent is now completely in the public domain, and we impose no 74 restrictions on its use. This was announced on the 21st August at 75 the First AES Candidate Conference. The optimised implementations 76 in the submission package are now under the GNU PUBLIC LICENSE 77 (GPL), although some comments in the code still say otherwise. You 78 are welcome to use Serpent for any application." */ 79 80#define SBOX0(a, b, c, d, w, x, y, z) \ 81 { \ 82 u32 t02, t03, t05, t06, t07, t08, t09; \ 83 u32 t11, t12, t13, t14, t15, t17, t01; \ 84 t01 = b ^ c ; \ 85 t02 = a | d ; \ 86 t03 = a ^ b ; \ 87 z = t02 ^ t01; \ 88 t05 = c | z ; \ 89 t06 = a ^ d ; \ 90 t07 = b | c ; \ 91 t08 = d & t05; \ 92 t09 = t03 & t07; \ 93 y = t09 ^ t08; \ 94 t11 = t09 & y ; \ 95 t12 = c ^ d ; \ 96 t13 = t07 ^ t11; \ 97 t14 = b & t06; \ 98 t15 = t06 ^ t13; \ 99 w = ~ t15; \ 100 t17 = w ^ t14; \ 101 x = t12 ^ t17; \ 102 } 103 104#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \ 105 { \ 106 u32 t02, t03, t04, t05, t06, t08, t09, t10; \ 107 u32 t12, t13, t14, t15, t17, t18, t01; \ 108 t01 = c ^ d ; \ 109 t02 = a | b ; \ 110 t03 = b | c ; \ 111 t04 = c & t01; \ 112 t05 = t02 ^ t01; \ 113 t06 = a | t04; \ 114 y = ~ t05; \ 115 t08 = b ^ d ; \ 116 t09 = t03 & t08; \ 117 t10 = d | y ; \ 118 x = t09 ^ t06; \ 119 t12 = a | t05; \ 120 t13 = x ^ t12; \ 121 t14 = t03 ^ t10; \ 122 t15 = a ^ c ; \ 123 z = t14 ^ t13; \ 124 t17 = t05 & t13; \ 125 t18 = t14 | t17; \ 126 w = t15 ^ t18; \ 127 } 128 129#define SBOX1(a, b, c, d, w, x, y, z) \ 130 { \ 131 u32 t02, t03, t04, t05, t06, t07, t08; \ 132 u32 t10, t11, t12, t13, t16, t17, t01; \ 133 t01 = a | d ; \ 134 t02 = c ^ d ; \ 135 t03 = ~ b ; \ 136 t04 = a ^ c ; \ 137 t05 = a | t03; \ 138 t06 = d & t04; \ 139 t07 = t01 & t02; \ 140 t08 = b | t06; \ 141 y = t02 ^ t05; \ 142 t10 = t07 ^ t08; \ 143 t11 = t01 ^ t10; \ 144 t12 = y ^ t11; \ 145 t13 = b & d ; \ 146 z = ~ t10; \ 147 x = t13 ^ t12; \ 148 t16 = t10 | x ; \ 149 t17 = t05 & t16; \ 150 w = c ^ t17; \ 151 } 152 153#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \ 154 { \ 155 u32 t02, t03, t04, t05, t06, t07, t08; \ 156 u32 t09, t10, t11, t14, t15, t17, t01; \ 157 t01 = a ^ b ; \ 158 t02 = b | d ; \ 159 t03 = a & c ; \ 160 t04 = c ^ t02; \ 161 t05 = a | t04; \ 162 t06 = t01 & t05; \ 163 t07 = d | t03; \ 164 t08 = b ^ t06; \ 165 t09 = t07 ^ t06; \ 166 t10 = t04 | t03; \ 167 t11 = d & t08; \ 168 y = ~ t09; \ 169 x = t10 ^ t11; \ 170 t14 = a | y ; \ 171 t15 = t06 ^ x ; \ 172 z = t01 ^ t04; \ 173 t17 = c ^ t15; \ 174 w = t14 ^ t17; \ 175 } 176 177#define SBOX2(a, b, c, d, w, x, y, z) \ 178 { \ 179 u32 t02, t03, t05, t06, t07, t08; \ 180 u32 t09, t10, t12, t13, t14, t01; \ 181 t01 = a | c ; \ 182 t02 = a ^ b ; \ 183 t03 = d ^ t01; \ 184 w = t02 ^ t03; \ 185 t05 = c ^ w ; \ 186 t06 = b ^ t05; \ 187 t07 = b | t05; \ 188 t08 = t01 & t06; \ 189 t09 = t03 ^ t07; \ 190 t10 = t02 | t09; \ 191 x = t10 ^ t08; \ 192 t12 = a | d ; \ 193 t13 = t09 ^ x ; \ 194 t14 = b ^ t13; \ 195 z = ~ t09; \ 196 y = t12 ^ t14; \ 197 } 198 199#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \ 200 { \ 201 u32 t02, t03, t04, t06, t07, t08, t09; \ 202 u32 t10, t11, t12, t15, t16, t17, t01; \ 203 t01 = a ^ d ; \ 204 t02 = c ^ d ; \ 205 t03 = a & c ; \ 206 t04 = b | t02; \ 207 w = t01 ^ t04; \ 208 t06 = a | c ; \ 209 t07 = d | w ; \ 210 t08 = ~ d ; \ 211 t09 = b & t06; \ 212 t10 = t08 | t03; \ 213 t11 = b & t07; \ 214 t12 = t06 & t02; \ 215 z = t09 ^ t10; \ 216 x = t12 ^ t11; \ 217 t15 = c & z ; \ 218 t16 = w ^ x ; \ 219 t17 = t10 ^ t15; \ 220 y = t16 ^ t17; \ 221 } 222 223#define SBOX3(a, b, c, d, w, x, y, z) \ 224 { \ 225 u32 t02, t03, t04, t05, t06, t07, t08; \ 226 u32 t09, t10, t11, t13, t14, t15, t01; \ 227 t01 = a ^ c ; \ 228 t02 = a | d ; \ 229 t03 = a & d ; \ 230 t04 = t01 & t02; \ 231 t05 = b | t03; \ 232 t06 = a & b ; \ 233 t07 = d ^ t04; \ 234 t08 = c | t06; \ 235 t09 = b ^ t07; \ 236 t10 = d & t05; \ 237 t11 = t02 ^ t10; \ 238 z = t08 ^ t09; \ 239 t13 = d | z ; \ 240 t14 = a | t07; \ 241 t15 = b & t13; \ 242 y = t08 ^ t11; \ 243 w = t14 ^ t15; \ 244 x = t05 ^ t04; \ 245 } 246 247#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \ 248 { \ 249 u32 t02, t03, t04, t05, t06, t07, t09; \ 250 u32 t11, t12, t13, t14, t16, t01; \ 251 t01 = c | d ; \ 252 t02 = a | d ; \ 253 t03 = c ^ t02; \ 254 t04 = b ^ t02; \ 255 t05 = a ^ d ; \ 256 t06 = t04 & t03; \ 257 t07 = b & t01; \ 258 y = t05 ^ t06; \ 259 t09 = a ^ t03; \ 260 w = t07 ^ t03; \ 261 t11 = w | t05; \ 262 t12 = t09 & t11; \ 263 t13 = a & y ; \ 264 t14 = t01 ^ t05; \ 265 x = b ^ t12; \ 266 t16 = b | t13; \ 267 z = t14 ^ t16; \ 268 } 269 270#define SBOX4(a, b, c, d, w, x, y, z) \ 271 { \ 272 u32 t02, t03, t04, t05, t06, t08, t09; \ 273 u32 t10, t11, t12, t13, t14, t15, t16, t01; \ 274 t01 = a | b ; \ 275 t02 = b | c ; \ 276 t03 = a ^ t02; \ 277 t04 = b ^ d ; \ 278 t05 = d | t03; \ 279 t06 = d & t01; \ 280 z = t03 ^ t06; \ 281 t08 = z & t04; \ 282 t09 = t04 & t05; \ 283 t10 = c ^ t06; \ 284 t11 = b & c ; \ 285 t12 = t04 ^ t08; \ 286 t13 = t11 | t03; \ 287 t14 = t10 ^ t09; \ 288 t15 = a & t05; \ 289 t16 = t11 | t12; \ 290 y = t13 ^ t08; \ 291 x = t15 ^ t16; \ 292 w = ~ t14; \ 293 } 294 295#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \ 296 { \ 297 u32 t02, t03, t04, t05, t06, t07, t09; \ 298 u32 t10, t11, t12, t13, t15, t01; \ 299 t01 = b | d ; \ 300 t02 = c | d ; \ 301 t03 = a & t01; \ 302 t04 = b ^ t02; \ 303 t05 = c ^ d ; \ 304 t06 = ~ t03; \ 305 t07 = a & t04; \ 306 x = t05 ^ t07; \ 307 t09 = x | t06; \ 308 t10 = a ^ t07; \ 309 t11 = t01 ^ t09; \ 310 t12 = d ^ t04; \ 311 t13 = c | t10; \ 312 z = t03 ^ t12; \ 313 t15 = a ^ t04; \ 314 y = t11 ^ t13; \ 315 w = t15 ^ t09; \ 316 } 317 318#define SBOX5(a, b, c, d, w, x, y, z) \ 319 { \ 320 u32 t02, t03, t04, t05, t07, t08, t09; \ 321 u32 t10, t11, t12, t13, t14, t01; \ 322 t01 = b ^ d ; \ 323 t02 = b | d ; \ 324 t03 = a & t01; \ 325 t04 = c ^ t02; \ 326 t05 = t03 ^ t04; \ 327 w = ~ t05; \ 328 t07 = a ^ t01; \ 329 t08 = d | w ; \ 330 t09 = b | t05; \ 331 t10 = d ^ t08; \ 332 t11 = b | t07; \ 333 t12 = t03 | w ; \ 334 t13 = t07 | t10; \ 335 t14 = t01 ^ t11; \ 336 y = t09 ^ t13; \ 337 x = t07 ^ t08; \ 338 z = t12 ^ t14; \ 339 } 340 341#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \ 342 { \ 343 u32 t02, t03, t04, t05, t07, t08, t09; \ 344 u32 t10, t12, t13, t15, t16, t01; \ 345 t01 = a & d ; \ 346 t02 = c ^ t01; \ 347 t03 = a ^ d ; \ 348 t04 = b & t02; \ 349 t05 = a & c ; \ 350 w = t03 ^ t04; \ 351 t07 = a & w ; \ 352 t08 = t01 ^ w ; \ 353 t09 = b | t05; \ 354 t10 = ~ b ; \ 355 x = t08 ^ t09; \ 356 t12 = t10 | t07; \ 357 t13 = w | x ; \ 358 z = t02 ^ t12; \ 359 t15 = t02 ^ t13; \ 360 t16 = b ^ d ; \ 361 y = t16 ^ t15; \ 362 } 363 364#define SBOX6(a, b, c, d, w, x, y, z) \ 365 { \ 366 u32 t02, t03, t04, t05, t07, t08, t09, t10; \ 367 u32 t11, t12, t13, t15, t17, t18, t01; \ 368 t01 = a & d ; \ 369 t02 = b ^ c ; \ 370 t03 = a ^ d ; \ 371 t04 = t01 ^ t02; \ 372 t05 = b | c ; \ 373 x = ~ t04; \ 374 t07 = t03 & t05; \ 375 t08 = b & x ; \ 376 t09 = a | c ; \ 377 t10 = t07 ^ t08; \ 378 t11 = b | d ; \ 379 t12 = c ^ t11; \ 380 t13 = t09 ^ t10; \ 381 y = ~ t13; \ 382 t15 = x & t03; \ 383 z = t12 ^ t07; \ 384 t17 = a ^ b ; \ 385 t18 = y ^ t15; \ 386 w = t17 ^ t18; \ 387 } 388 389#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \ 390 { \ 391 u32 t02, t03, t04, t05, t06, t07, t08, t09; \ 392 u32 t12, t13, t14, t15, t16, t17, t01; \ 393 t01 = a ^ c ; \ 394 t02 = ~ c ; \ 395 t03 = b & t01; \ 396 t04 = b | t02; \ 397 t05 = d | t03; \ 398 t06 = b ^ d ; \ 399 t07 = a & t04; \ 400 t08 = a | t02; \ 401 t09 = t07 ^ t05; \ 402 x = t06 ^ t08; \ 403 w = ~ t09; \ 404 t12 = b & w ; \ 405 t13 = t01 & t05; \ 406 t14 = t01 ^ t12; \ 407 t15 = t07 ^ t13; \ 408 t16 = d | t02; \ 409 t17 = a ^ x ; \ 410 z = t17 ^ t15; \ 411 y = t16 ^ t14; \ 412 } 413 414#define SBOX7(a, b, c, d, w, x, y, z) \ 415 { \ 416 u32 t02, t03, t04, t05, t06, t08, t09, t10; \ 417 u32 t11, t13, t14, t15, t16, t17, t01; \ 418 t01 = a & c ; \ 419 t02 = ~ d ; \ 420 t03 = a & t02; \ 421 t04 = b | t01; \ 422 t05 = a & b ; \ 423 t06 = c ^ t04; \ 424 z = t03 ^ t06; \ 425 t08 = c | z ; \ 426 t09 = d | t05; \ 427 t10 = a ^ t08; \ 428 t11 = t04 & z ; \ 429 x = t09 ^ t10; \ 430 t13 = b ^ x ; \ 431 t14 = t01 ^ x ; \ 432 t15 = c ^ t05; \ 433 t16 = t11 | t13; \ 434 t17 = t02 | t14; \ 435 w = t15 ^ t17; \ 436 y = a ^ t16; \ 437 } 438 439#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \ 440 { \ 441 u32 t02, t03, t04, t06, t07, t08, t09; \ 442 u32 t10, t11, t13, t14, t15, t16, t01; \ 443 t01 = a & b ; \ 444 t02 = a | b ; \ 445 t03 = c | t01; \ 446 t04 = d & t02; \ 447 z = t03 ^ t04; \ 448 t06 = b ^ t04; \ 449 t07 = d ^ z ; \ 450 t08 = ~ t07; \ 451 t09 = t06 | t08; \ 452 t10 = b ^ d ; \ 453 t11 = a | d ; \ 454 x = a ^ t09; \ 455 t13 = c ^ t06; \ 456 t14 = c & t11; \ 457 t15 = d | x ; \ 458 t16 = t01 | t10; \ 459 w = t13 ^ t15; \ 460 y = t14 ^ t16; \ 461 } 462 463/* XOR BLOCK1 into BLOCK0. */ 464#define BLOCK_XOR(block0, block1) \ 465 { \ 466 block0[0] ^= block1[0]; \ 467 block0[1] ^= block1[1]; \ 468 block0[2] ^= block1[2]; \ 469 block0[3] ^= block1[3]; \ 470 } 471 472/* Copy BLOCK_SRC to BLOCK_DST. */ 473#define BLOCK_COPY(block_dst, block_src) \ 474 { \ 475 block_dst[0] = block_src[0]; \ 476 block_dst[1] = block_src[1]; \ 477 block_dst[2] = block_src[2]; \ 478 block_dst[3] = block_src[3]; \ 479 } 480 481/* Apply SBOX number WHICH to to the block found in ARRAY0 at index 482 INDEX, writing the output to the block found in ARRAY1 at index 483 INDEX. */ 484#define SBOX(which, array0, array1, index) \ 485 SBOX##which (array0[index + 0], array0[index + 1], \ 486 array0[index + 2], array0[index + 3], \ 487 array1[index + 0], array1[index + 1], \ 488 array1[index + 2], array1[index + 3]); 489 490/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at 491 index INDEX, writing the output to the block found in ARRAY1 at 492 index INDEX. */ 493#define SBOX_INVERSE(which, array0, array1, index) \ 494 SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \ 495 array0[index + 2], array0[index + 3], \ 496 array1[index + 0], array1[index + 1], \ 497 array1[index + 2], array1[index + 3]); 498 499/* Apply the linear transformation to BLOCK. */ 500#define LINEAR_TRANSFORMATION(block) \ 501 { \ 502 block[0] = rol (block[0], 13); \ 503 block[2] = rol (block[2], 3); \ 504 block[1] = block[1] ^ block[0] ^ block[2]; \ 505 block[3] = block[3] ^ block[2] ^ (block[0] << 3); \ 506 block[1] = rol (block[1], 1); \ 507 block[3] = rol (block[3], 7); \ 508 block[0] = block[0] ^ block[1] ^ block[3]; \ 509 block[2] = block[2] ^ block[3] ^ (block[1] << 7); \ 510 block[0] = rol (block[0], 5); \ 511 block[2] = rol (block[2], 22); \ 512 } 513 514/* Apply the inverse linear transformation to BLOCK. */ 515#define LINEAR_TRANSFORMATION_INVERSE(block) \ 516 { \ 517 block[2] = ror (block[2], 22); \ 518 block[0] = ror (block[0] , 5); \ 519 block[2] = block[2] ^ block[3] ^ (block[1] << 7); \ 520 block[0] = block[0] ^ block[1] ^ block[3]; \ 521 block[3] = ror (block[3], 7); \ 522 block[1] = ror (block[1], 1); \ 523 block[3] = block[3] ^ block[2] ^ (block[0] << 3); \ 524 block[1] = block[1] ^ block[0] ^ block[2]; \ 525 block[2] = ror (block[2], 3); \ 526 block[0] = ror (block[0], 13); \ 527 } 528 529/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the 530 subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. 531 This macro increments `round'. */ 532#define ROUND(which, subkeys, block, block_tmp) \ 533 { \ 534 BLOCK_XOR (block, subkeys[round]); \ 535 round++; \ 536 SBOX (which, block, block_tmp, 0); \ 537 LINEAR_TRANSFORMATION (block_tmp); \ 538 BLOCK_COPY (block, block_tmp); \ 539 } 540 541/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH 542 and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary 543 storage. The result will be stored in BLOCK_TMP. This macro 544 increments `round'. */ 545#define ROUND_LAST(which, subkeys, block, block_tmp) \ 546 { \ 547 BLOCK_XOR (block, subkeys[round]); \ 548 round++; \ 549 SBOX (which, block, block_tmp, 0); \ 550 BLOCK_XOR (block_tmp, subkeys[round]); \ 551 round++; \ 552 } 553 554/* Apply an inverse Serpent round to BLOCK, using the SBOX number 555 WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as 556 temporary storage. This macro increments `round'. */ 557#define ROUND_INVERSE(which, subkey, block, block_tmp) \ 558 { \ 559 LINEAR_TRANSFORMATION_INVERSE (block); \ 560 SBOX_INVERSE (which, block, block_tmp, 0); \ 561 BLOCK_XOR (block_tmp, subkey[round]); \ 562 round--; \ 563 BLOCK_COPY (block, block_tmp); \ 564 } 565 566/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH 567 and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary 568 storage. The result will be stored in BLOCK_TMP. This macro 569 increments `round'. */ 570#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \ 571 { \ 572 BLOCK_XOR (block, subkeys[round]); \ 573 round--; \ 574 SBOX_INVERSE (which, block, block_tmp, 0); \ 575 BLOCK_XOR (block_tmp, subkeys[round]); \ 576 round--; \ 577 } 578 579/* Convert the user provided key KEY of KEY_LENGTH bytes into the 580 internally used format. */ 581static void 582serpent_key_prepare (const byte *key, unsigned int key_length, 583 serpent_key_t key_prepared) 584{ 585 int i; 586 587 /* Copy key. */ 588 for (i = 0; i < key_length / 4; i++) 589 { 590#ifdef WORDS_BIGENDIAN 591 key_prepared[i] = byte_swap_32 (((u32 *) key)[i]); 592#else 593 key_prepared[i] = ((u32 *) key)[i]; 594#endif 595 } 596 597 if (i < 8) 598 { 599 /* Key must be padded according to the Serpent 600 specification. */ 601 key_prepared[i] = 0x00000001; 602 603 for (i++; i < 8; i++) 604 key_prepared[i] = 0; 605 } 606} 607 608/* Derive the 33 subkeys from KEY and store them in SUBKEYS. */ 609static void 610serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys) 611{ 612 u32 w_real[140]; /* The `prekey'. */ 613 u32 k[132]; 614 u32 *w = &w_real[8]; 615 int i, j; 616 617 /* Initialize with key values. */ 618 for (i = 0; i < 8; i++) 619 w[i - 8] = key[i]; 620 621 /* Expand to intermediate key using the affine recurrence. */ 622 for (i = 0; i < 132; i++) 623 w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11); 624 625 /* Calculate subkeys via S-Boxes, in bitslice mode. */ 626 SBOX (3, w, k, 0); 627 SBOX (2, w, k, 4); 628 SBOX (1, w, k, 8); 629 SBOX (0, w, k, 12); 630 SBOX (7, w, k, 16); 631 SBOX (6, w, k, 20); 632 SBOX (5, w, k, 24); 633 SBOX (4, w, k, 28); 634 SBOX (3, w, k, 32); 635 SBOX (2, w, k, 36); 636 SBOX (1, w, k, 40); 637 SBOX (0, w, k, 44); 638 SBOX (7, w, k, 48); 639 SBOX (6, w, k, 52); 640 SBOX (5, w, k, 56); 641 SBOX (4, w, k, 60); 642 SBOX (3, w, k, 64); 643 SBOX (2, w, k, 68); 644 SBOX (1, w, k, 72); 645 SBOX (0, w, k, 76); 646 SBOX (7, w, k, 80); 647 SBOX (6, w, k, 84); 648 SBOX (5, w, k, 88); 649 SBOX (4, w, k, 92); 650 SBOX (3, w, k, 96); 651 SBOX (2, w, k, 100); 652 SBOX (1, w, k, 104); 653 SBOX (0, w, k, 108); 654 SBOX (7, w, k, 112); 655 SBOX (6, w, k, 116); 656 SBOX (5, w, k, 120); 657 SBOX (4, w, k, 124); 658 SBOX (3, w, k, 128); 659 660 /* Renumber subkeys. */ 661 for (i = 0; i < ROUNDS + 1; i++) 662 for (j = 0; j < 4; j++) 663 subkeys[i][j] = k[4 * i + j]; 664} 665 666/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */ 667static void 668serpent_setkey_internal (serpent_context_t *context, 669 const byte *key, unsigned int key_length) 670{ 671 serpent_key_t key_prepared; 672 673 serpent_key_prepare (key, key_length, key_prepared); 674 serpent_subkeys_generate (key_prepared, context->keys); 675 _gcry_burn_stack (272 * sizeof (u32)); 676} 677 678/* Initialize CTX with the key KEY of KEY_LENGTH bytes. */ 679static gcry_err_code_t 680serpent_setkey (void *ctx, 681 const byte *key, unsigned int key_length) 682{ 683 serpent_context_t *context = ctx; 684 static const char *serpent_test_ret; 685 static int serpent_init_done; 686 gcry_err_code_t ret = GPG_ERR_NO_ERROR; 687 688 if (! serpent_init_done) 689 { 690 /* Execute a self-test the first time, Serpent is used. */ 691 serpent_test_ret = serpent_test (); 692 if (serpent_test_ret) 693 log_error ("Serpent test failure: %s\n", serpent_test_ret); 694 serpent_init_done = 1; 695 } 696 697 if (serpent_test_ret) 698 ret = GPG_ERR_SELFTEST_FAILED; 699 else 700 { 701 serpent_setkey_internal (context, key, key_length); 702 _gcry_burn_stack (sizeof (serpent_key_t)); 703 } 704 705 return ret; 706} 707 708static void 709serpent_encrypt_internal (serpent_context_t *context, 710 const serpent_block_t input, serpent_block_t output) 711{ 712 serpent_block_t b, b_next; 713 int round = 0; 714 715#ifdef WORDS_BIGENDIAN 716 b[0] = byte_swap_32 (input[0]); 717 b[1] = byte_swap_32 (input[1]); 718 b[2] = byte_swap_32 (input[2]); 719 b[3] = byte_swap_32 (input[3]); 720#else 721 b[0] = input[0]; 722 b[1] = input[1]; 723 b[2] = input[2]; 724 b[3] = input[3]; 725#endif 726 727 ROUND (0, context->keys, b, b_next); 728 ROUND (1, context->keys, b, b_next); 729 ROUND (2, context->keys, b, b_next); 730 ROUND (3, context->keys, b, b_next); 731 ROUND (4, context->keys, b, b_next); 732 ROUND (5, context->keys, b, b_next); 733 ROUND (6, context->keys, b, b_next); 734 ROUND (7, context->keys, b, b_next); 735 ROUND (0, context->keys, b, b_next); 736 ROUND (1, context->keys, b, b_next); 737 ROUND (2, context->keys, b, b_next); 738 ROUND (3, context->keys, b, b_next); 739 ROUND (4, context->keys, b, b_next); 740 ROUND (5, context->keys, b, b_next); 741 ROUND (6, context->keys, b, b_next); 742 ROUND (7, context->keys, b, b_next); 743 ROUND (0, context->keys, b, b_next); 744 ROUND (1, context->keys, b, b_next); 745 ROUND (2, context->keys, b, b_next); 746 ROUND (3, context->keys, b, b_next); 747 ROUND (4, context->keys, b, b_next); 748 ROUND (5, context->keys, b, b_next); 749 ROUND (6, context->keys, b, b_next); 750 ROUND (7, context->keys, b, b_next); 751 ROUND (0, context->keys, b, b_next); 752 ROUND (1, context->keys, b, b_next); 753 ROUND (2, context->keys, b, b_next); 754 ROUND (3, context->keys, b, b_next); 755 ROUND (4, context->keys, b, b_next); 756 ROUND (5, context->keys, b, b_next); 757 ROUND (6, context->keys, b, b_next); 758 759 ROUND_LAST (7, context->keys, b, b_next); 760 761#ifdef WORDS_BIGENDIAN 762 output[0] = byte_swap_32 (b_next[0]); 763 output[1] = byte_swap_32 (b_next[1]); 764 output[2] = byte_swap_32 (b_next[2]); 765 output[3] = byte_swap_32 (b_next[3]); 766#else 767 output[0] = b_next[0]; 768 output[1] = b_next[1]; 769 output[2] = b_next[2]; 770 output[3] = b_next[3]; 771#endif 772} 773 774static void 775serpent_decrypt_internal (serpent_context_t *context, 776 const serpent_block_t input, serpent_block_t output) 777{ 778 serpent_block_t b, b_next; 779 int round = ROUNDS; 780 781#ifdef WORDS_BIGENDIAN 782 b_next[0] = byte_swap_32 (input[0]); 783 b_next[1] = byte_swap_32 (input[1]); 784 b_next[2] = byte_swap_32 (input[2]); 785 b_next[3] = byte_swap_32 (input[3]); 786#else 787 b_next[0] = input[0]; 788 b_next[1] = input[1]; 789 b_next[2] = input[2]; 790 b_next[3] = input[3]; 791#endif 792 793 ROUND_FIRST_INVERSE (7, context->keys, b_next, b); 794 795 ROUND_INVERSE (6, context->keys, b, b_next); 796 ROUND_INVERSE (5, context->keys, b, b_next); 797 ROUND_INVERSE (4, context->keys, b, b_next); 798 ROUND_INVERSE (3, context->keys, b, b_next); 799 ROUND_INVERSE (2, context->keys, b, b_next); 800 ROUND_INVERSE (1, context->keys, b, b_next); 801 ROUND_INVERSE (0, context->keys, b, b_next); 802 ROUND_INVERSE (7, context->keys, b, b_next); 803 ROUND_INVERSE (6, context->keys, b, b_next); 804 ROUND_INVERSE (5, context->keys, b, b_next); 805 ROUND_INVERSE (4, context->keys, b, b_next); 806 ROUND_INVERSE (3, context->keys, b, b_next); 807 ROUND_INVERSE (2, context->keys, b, b_next); 808 ROUND_INVERSE (1, context->keys, b, b_next); 809 ROUND_INVERSE (0, context->keys, b, b_next); 810 ROUND_INVERSE (7, context->keys, b, b_next); 811 ROUND_INVERSE (6, context->keys, b, b_next); 812 ROUND_INVERSE (5, context->keys, b, b_next); 813 ROUND_INVERSE (4, context->keys, b, b_next); 814 ROUND_INVERSE (3, context->keys, b, b_next); 815 ROUND_INVERSE (2, context->keys, b, b_next); 816 ROUND_INVERSE (1, context->keys, b, b_next); 817 ROUND_INVERSE (0, context->keys, b, b_next); 818 ROUND_INVERSE (7, context->keys, b, b_next); 819 ROUND_INVERSE (6, context->keys, b, b_next); 820 ROUND_INVERSE (5, context->keys, b, b_next); 821 ROUND_INVERSE (4, context->keys, b, b_next); 822 ROUND_INVERSE (3, context->keys, b, b_next); 823 ROUND_INVERSE (2, context->keys, b, b_next); 824 ROUND_INVERSE (1, context->keys, b, b_next); 825 ROUND_INVERSE (0, context->keys, b, b_next); 826 827 828#ifdef WORDS_BIGENDIAN 829 output[0] = byte_swap_32 (b_next[0]); 830 output[1] = byte_swap_32 (b_next[1]); 831 output[2] = byte_swap_32 (b_next[2]); 832 output[3] = byte_swap_32 (b_next[3]); 833#else 834 output[0] = b_next[0]; 835 output[1] = b_next[1]; 836 output[2] = b_next[2]; 837 output[3] = b_next[3]; 838#endif 839} 840 841static void 842serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in) 843{ 844 serpent_context_t *context = ctx; 845 846 serpent_encrypt_internal (context, 847 (const u32 *) buffer_in, (u32 *) buffer_out); 848 _gcry_burn_stack (2 * sizeof (serpent_block_t)); 849} 850 851static void 852serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in) 853{ 854 serpent_context_t *context = ctx; 855 856 serpent_decrypt_internal (context, 857 (const u32 *) buffer_in, 858 (u32 *) buffer_out); 859 _gcry_burn_stack (2 * sizeof (serpent_block_t)); 860} 861 862 863 864/* Serpent test. */ 865 866static const char * 867serpent_test (void) 868{ 869 serpent_context_t context; 870 unsigned char scratch[16]; 871 unsigned int i; 872 873 static struct test 874 { 875 int key_length; 876 unsigned char key[32]; 877 unsigned char text_plain[16]; 878 unsigned char text_cipher[16]; 879 } test_data[] = 880 { 881 { 882 16, 883 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 884 "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E", 885 "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D" 886 }, 887 { 888 24, 889 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 890 "\x00\x00\x00\x00\x00\x00\x00\x00", 891 "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E", 892 "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9" 893 }, 894 { 895 32, 896 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 897 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 898 "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E", 899 "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B" 900 }, 901 { 902 32, 903 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 904 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 905 "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00", 906 "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C" 907 }, 908 { 909 0 910 }, 911 }; 912 913 for (i = 0; test_data[i].key_length; i++) 914 { 915 serpent_setkey_internal (&context, test_data[i].key, 916 test_data[i].key_length); 917 serpent_encrypt_internal (&context, 918 (const u32 *) test_data[i].text_plain, 919 (u32 *) scratch); 920 921 if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t))) 922 switch (test_data[i].key_length) 923 { 924 case 16: 925 return "Serpent-128 test encryption failed."; 926 case 24: 927 return "Serpent-192 test encryption failed."; 928 case 32: 929 return "Serpent-256 test encryption failed."; 930 } 931 932 serpent_decrypt_internal (&context, 933 (const u32 *) test_data[i].text_cipher, 934 (u32 *) scratch); 935 if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t))) 936 switch (test_data[i].key_length) 937 { 938 case 16: 939 return "Serpent-128 test decryption failed."; 940 case 24: 941 return "Serpent-192 test decryption failed."; 942 case 32: 943 return "Serpent-256 test decryption failed."; 944 } 945 } 946 947 return NULL; 948} 949 950 951 952/* "SERPENT" is an alias for "SERPENT128". */ 953static const char *cipher_spec_serpent128_aliases[] = 954 { 955 "SERPENT", 956 NULL 957 }; 958 959gcry_cipher_spec_t _gcry_cipher_spec_serpent128 = 960 { 961 "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128, 962 sizeof (serpent_context_t), 963 serpent_setkey, serpent_encrypt, serpent_decrypt 964 }; 965 966gcry_cipher_spec_t _gcry_cipher_spec_serpent192 = 967 { 968 "SERPENT192", NULL, NULL, 16, 192, 969 sizeof (serpent_context_t), 970 serpent_setkey, serpent_encrypt, serpent_decrypt 971 }; 972 973gcry_cipher_spec_t _gcry_cipher_spec_serpent256 = 974 { 975 "SERPENT256", NULL, NULL, 16, 256, 976 sizeof (serpent_context_t), 977 serpent_setkey, serpent_encrypt, serpent_decrypt 978 }; 979