1/* $NetBSD: des.c,v 1.3 2023/06/19 21:41:43 christos Exp $ */ 2 3/* 4 * Copyright (c) 2005 Kungliga Tekniska H��gskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36/** 37 * @page page_des DES - Data Encryption Standard crypto interface 38 * 39 * See the library functions here: @ref hcrypto_des 40 * 41 * DES was created by IBM, modififed by NSA and then adopted by NBS 42 * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1). 43 * 44 * Since the 19th May 2005 DES was withdrawn by NIST and should no 45 * longer be used. See @ref page_evp for replacement encryption 46 * algorithms and interfaces. 47 * 48 * Read more the iteresting history of DES on Wikipedia 49 * http://www.wikipedia.org/wiki/Data_Encryption_Standard . 50 * 51 * @section des_keygen DES key generation 52 * 53 * To generate a DES key safely you have to use the code-snippet 54 * below. This is because the DES_random_key() can fail with an 55 * abort() in case of and failure to start the random generator. 56 * 57 * There is a replacement function DES_new_random_key(), however that 58 * function does not exists in OpenSSL. 59 * 60 * @code 61 * DES_cblock key; 62 * do { 63 * if (RAND_rand(&key, sizeof(key)) != 1) 64 * goto failure; 65 * DES_set_odd_parity(key); 66 * } while (DES_is_weak_key(&key)); 67 * @endcode 68 * 69 * @section des_impl DES implementation history 70 * 71 * There was no complete BSD licensed, fast, GPL compatible 72 * implementation of DES, so Love wrote the part that was missing, 73 * fast key schedule setup and adapted the interface to the orignal 74 * libdes. 75 * 76 * The document that got me started for real was "Efficient 77 * Implementation of the Data Encryption Standard" by Dag Arne Osvik. 78 * I never got to the PC1 transformation was working, instead I used 79 * table-lookup was used for all key schedule setup. The document was 80 * very useful since it de-mystified other implementations for me. 81 * 82 * The core DES function (SBOX + P transformation) is from Richard 83 * Outerbridge public domain DES implementation. My sanity is saved 84 * thanks to his work. Thank you Richard. 85 */ 86 87#include <config.h> 88#include <krb5/roken.h> 89 90#define HC_DEPRECATED 91#include <krb5/krb5-types.h> 92#include <assert.h> 93 94#include "des.h" 95#include "ui.h" 96 97static void desx(uint32_t [2], DES_key_schedule *, int); 98static void IP(uint32_t [2]); 99static void FP(uint32_t [2]); 100 101#include "des-tables.h" 102 103#define ROTATE_LEFT28(x,one) \ 104 if (one) { \ 105 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \ 106 } else { \ 107 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \ 108 } 109 110/** 111 * Set the parity of the key block, used to generate a des key from a 112 * random key. See @ref des_keygen. 113 * 114 * @param key key to fixup the parity for. 115 * @ingroup hcrypto_des 116 */ 117 118void 119DES_set_odd_parity(DES_cblock *key) 120{ 121 unsigned int i; 122 for (i = 0; i < DES_CBLOCK_LEN; i++) 123 (*key)[i] = odd_parity[(*key)[i]]; 124} 125 126/** 127 * Check if the key have correct parity. 128 * 129 * @param key key to check the parity. 130 * @return 1 on success, 0 on failure. 131 * @ingroup hcrypto_des 132 */ 133 134int HC_DEPRECATED 135DES_check_key_parity(DES_cblock *key) 136{ 137 unsigned int i; 138 139 for (i = 0; i < DES_CBLOCK_LEN; i++) 140 if ((*key)[i] != odd_parity[(*key)[i]]) 141 return 0; 142 return 1; 143} 144 145/* 146 * 147 */ 148 149/* FIPS 74 */ 150static DES_cblock weak_keys[] = { 151 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */ 152 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE}, 153 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, 154 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1}, 155 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */ 156 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01}, 157 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1}, 158 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E}, 159 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1}, 160 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01}, 161 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE}, 162 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E}, 163 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E}, 164 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01}, 165 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, 166 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1} 167}; 168 169/** 170 * Checks if the key is any of the weaks keys that makes DES attacks 171 * trival. 172 * 173 * @param key key to check. 174 * 175 * @return 1 if the key is weak, 0 otherwise. 176 * @ingroup hcrypto_des 177 */ 178 179int 180DES_is_weak_key(DES_cblock *key) 181{ 182 int weak = 0; 183 int i; 184 185 for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) 186 weak ^= (ct_memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0); 187 188 return !!weak; 189} 190 191/** 192 * Setup a des key schedule from a key. Deprecated function, use 193 * DES_set_key_unchecked() or DES_set_key_checked() instead. 194 * 195 * @param key a key to initialize the key schedule with. 196 * @param ks a key schedule to initialize. 197 * 198 * @return 0 on success 199 * @ingroup hcrypto_des 200 */ 201 202int HC_DEPRECATED 203DES_set_key(DES_cblock *key, DES_key_schedule *ks) 204{ 205 return DES_set_key_checked(key, ks); 206} 207 208/** 209 * Setup a des key schedule from a key. The key is no longer needed 210 * after this transaction and can cleared. 211 * 212 * Does NOT check that the key is weak for or have wrong parity. 213 * 214 * @param key a key to initialize the key schedule with. 215 * @param ks a key schedule to initialize. 216 * 217 * @return 0 on success 218 * @ingroup hcrypto_des 219 */ 220 221int 222DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks) 223{ 224 uint32_t t1, t2; 225 uint32_t c, d; 226 int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 }; 227 uint32_t *k = &ks->ks[0]; 228 int i; 229 230 t1 = (uint32_t)(*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3]; 231 t2 = (uint32_t)(*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7]; 232 233 c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3) 234 | (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2) 235 | (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1) 236 | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0) 237 | (pc1_c_4[(t2 >> (4 )) & 0xf] << 3) 238 | (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2) 239 | (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1) 240 | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0); 241 242 243 d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3) 244 | (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2) 245 | (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1) 246 | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0) 247 | (pc1_d_4[(t1 >> (1 )) & 0xf] << 3) 248 | (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2) 249 | (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1) 250 | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0); 251 252 for (i = 0; i < 16; i++) { 253 uint32_t kc, kd; 254 255 ROTATE_LEFT28(c, shifts[i]); 256 ROTATE_LEFT28(d, shifts[i]); 257 258 kc = pc2_c_1[(c >> 22) & 0x3f] | 259 pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] | 260 pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] | 261 pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)]; 262 kd = pc2_d_1[(d >> 22) & 0x3f] | 263 pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] | 264 pc2_d_3[ (d >> 7 ) & 0x3f] | 265 pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)]; 266 267 /* Change to byte order used by the S boxes */ 268 *k = (kc & 0x00fc0000L) << 6; 269 *k |= (kc & 0x00000fc0L) << 10; 270 *k |= (kd & 0x00fc0000L) >> 10; 271 *k++ |= (kd & 0x00000fc0L) >> 6; 272 *k = (kc & 0x0003f000L) << 12; 273 *k |= (kc & 0x0000003fL) << 16; 274 *k |= (kd & 0x0003f000L) >> 4; 275 *k++ |= (kd & 0x0000003fL); 276 } 277 278 return 0; 279} 280 281/** 282 * Just like DES_set_key_unchecked() except checking that the key is 283 * not weak for or have correct parity. 284 * 285 * @param key a key to initialize the key schedule with. 286 * @param ks a key schedule to initialize. 287 * 288 * @return 0 on success, -1 on invalid parity, -2 on weak key. 289 * @ingroup hcrypto_des 290 */ 291 292int 293DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks) 294{ 295 if (!DES_check_key_parity(key)) { 296 memset(ks, 0, sizeof(*ks)); 297 return -1; 298 } 299 if (DES_is_weak_key(key)) { 300 memset(ks, 0, sizeof(*ks)); 301 return -2; 302 } 303 return DES_set_key_unchecked(key, ks); 304} 305 306/** 307 * Compatibility function for eay libdes, works just like 308 * DES_set_key_checked(). 309 * 310 * @param key a key to initialize the key schedule with. 311 * @param ks a key schedule to initialize. 312 * 313 * @return 0 on success, -1 on invalid parity, -2 on weak key. 314 * @ingroup hcrypto_des 315 */ 316 317int 318DES_key_sched(DES_cblock *key, DES_key_schedule *ks) 319{ 320 return DES_set_key_checked(key, ks); 321} 322 323/* 324 * 325 */ 326 327static void 328load(const unsigned char *b, uint32_t v[2]) 329{ 330 v[0] = (uint32_t)b[0] << 24U; 331 v[0] |= b[1] << 16U; 332 v[0] |= b[2] << 8U; 333 v[0] |= b[3] << 0U; 334 v[1] = (uint32_t)b[4] << 24U; 335 v[1] |= b[5] << 16U; 336 v[1] |= b[6] << 8U; 337 v[1] |= b[7] << 0U; 338} 339 340static void 341store(const uint32_t v[2], unsigned char *b) 342{ 343 b[0] = (v[0] >> 24) & 0xffU; 344 b[1] = (v[0] >> 16) & 0xffU; 345 b[2] = (v[0] >> 8) & 0xffU; 346 b[3] = (v[0] >> 0) & 0xffU; 347 b[4] = (v[1] >> 24) & 0xffU; 348 b[5] = (v[1] >> 16) & 0xffU; 349 b[6] = (v[1] >> 8) & 0xffU; 350 b[7] = (v[1] >> 0) & 0xffU; 351} 352 353/** 354 * Encrypt/decrypt a block using DES. Also called ECB mode 355 * 356 * @param u data to encrypt 357 * @param ks key schedule to use 358 * @param encp if non zero, encrypt. if zero, decrypt. 359 * 360 * @ingroup hcrypto_des 361 */ 362 363void 364DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp) 365{ 366 IP(u); 367 desx(u, ks, encp); 368 FP(u); 369} 370 371/** 372 * Encrypt/decrypt a block using DES. 373 * 374 * @param input data to encrypt 375 * @param output data to encrypt 376 * @param ks key schedule to use 377 * @param encp if non zero, encrypt. if zero, decrypt. 378 * 379 * @ingroup hcrypto_des 380 */ 381 382void 383DES_ecb_encrypt(DES_cblock *input, DES_cblock *output, 384 DES_key_schedule *ks, int encp) 385{ 386 uint32_t u[2]; 387 load(*input, u); 388 DES_encrypt(u, ks, encp); 389 store(u, *output); 390} 391 392/** 393 * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc). 394 * 395 * The IV must always be diffrent for diffrent input data blocks. 396 * 397 * @param in data to encrypt 398 * @param out data to encrypt 399 * @param length length of data 400 * @param ks key schedule to use 401 * @param iv initial vector to use 402 * @param encp if non zero, encrypt. if zero, decrypt. 403 * 404 * @ingroup hcrypto_des 405 */ 406 407void 408DES_cbc_encrypt(const void *in, void *out, long length, 409 DES_key_schedule *ks, DES_cblock *iv, int encp) 410{ 411 const unsigned char *input = in; 412 unsigned char *output = out; 413 uint32_t u[2]; 414 uint32_t uiv[2]; 415 416 load(*iv, uiv); 417 418 if (encp) { 419 while (length >= DES_CBLOCK_LEN) { 420 load(input, u); 421 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 422 DES_encrypt(u, ks, 1); 423 uiv[0] = u[0]; uiv[1] = u[1]; 424 store(u, output); 425 426 length -= DES_CBLOCK_LEN; 427 input += DES_CBLOCK_LEN; 428 output += DES_CBLOCK_LEN; 429 } 430 if (length) { 431 unsigned char tmp[DES_CBLOCK_LEN]; 432 memcpy(tmp, input, length); 433 memset(tmp + length, 0, DES_CBLOCK_LEN - length); 434 load(tmp, u); 435 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 436 DES_encrypt(u, ks, 1); 437 store(u, output); 438 } 439 } else { 440 uint32_t t[2]; 441 while (length >= DES_CBLOCK_LEN) { 442 load(input, u); 443 t[0] = u[0]; t[1] = u[1]; 444 DES_encrypt(u, ks, 0); 445 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 446 store(u, output); 447 uiv[0] = t[0]; uiv[1] = t[1]; 448 449 length -= DES_CBLOCK_LEN; 450 input += DES_CBLOCK_LEN; 451 output += DES_CBLOCK_LEN; 452 } 453 if (length) { 454 unsigned char tmp[DES_CBLOCK_LEN]; 455 memcpy(tmp, input, length); 456 memset(tmp + length, 0, DES_CBLOCK_LEN - length); 457 load(tmp, u); 458 DES_encrypt(u, ks, 0); 459 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 460 store(u, output); 461 } 462 } 463 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; 464} 465 466/** 467 * Encrypt/decrypt a block using DES in Propagating Cipher Block 468 * Chaining mode. This mode is only used for Kerberos 4, and it should 469 * stay that way. 470 * 471 * The IV must always be diffrent for diffrent input data blocks. 472 * 473 * @param in data to encrypt 474 * @param out data to encrypt 475 * @param length length of data 476 * @param ks key schedule to use 477 * @param iv initial vector to use 478 * @param encp if non zero, encrypt. if zero, decrypt. 479 * 480 * @ingroup hcrypto_des 481 */ 482 483void 484DES_pcbc_encrypt(const void *in, void *out, long length, 485 DES_key_schedule *ks, DES_cblock *iv, int encp) 486{ 487 const unsigned char *input = in; 488 unsigned char *output = out; 489 uint32_t u[2]; 490 uint32_t uiv[2]; 491 492 load(*iv, uiv); 493 494 if (encp) { 495 uint32_t t[2]; 496 while (length >= DES_CBLOCK_LEN) { 497 load(input, u); 498 t[0] = u[0]; t[1] = u[1]; 499 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 500 DES_encrypt(u, ks, 1); 501 uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1]; 502 store(u, output); 503 504 length -= DES_CBLOCK_LEN; 505 input += DES_CBLOCK_LEN; 506 output += DES_CBLOCK_LEN; 507 } 508 if (length) { 509 unsigned char tmp[DES_CBLOCK_LEN]; 510 memcpy(tmp, input, length); 511 memset(tmp + length, 0, DES_CBLOCK_LEN - length); 512 load(tmp, u); 513 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 514 DES_encrypt(u, ks, 1); 515 store(u, output); 516 } 517 } else { 518 uint32_t t[2]; 519 while (length >= DES_CBLOCK_LEN) { 520 load(input, u); 521 t[0] = u[0]; t[1] = u[1]; 522 DES_encrypt(u, ks, 0); 523 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 524 store(u, output); 525 uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1]; 526 527 length -= DES_CBLOCK_LEN; 528 input += DES_CBLOCK_LEN; 529 output += DES_CBLOCK_LEN; 530 } 531 if (length) { 532 unsigned char tmp[DES_CBLOCK_LEN]; 533 memcpy(tmp, input, length); 534 memset(tmp + length, 0, DES_CBLOCK_LEN - length); 535 load(tmp, u); 536 DES_encrypt(u, ks, 0); 537 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 538 } 539 } 540 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; 541} 542 543/* 544 * 545 */ 546 547static void 548_des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, 549 DES_key_schedule *ks3, int encp) 550{ 551 IP(u); 552 if (encp) { 553 desx(u, ks1, 1); /* IP + FP cancel out each other */ 554 desx(u, ks2, 0); 555 desx(u, ks3, 1); 556 } else { 557 desx(u, ks3, 0); 558 desx(u, ks2, 1); 559 desx(u, ks1, 0); 560 } 561 FP(u); 562} 563 564/** 565 * Encrypt/decrypt a block using triple DES using EDE mode, 566 * encrypt/decrypt/encrypt. 567 * 568 * @param input data to encrypt 569 * @param output data to encrypt 570 * @param ks1 key schedule to use 571 * @param ks2 key schedule to use 572 * @param ks3 key schedule to use 573 * @param encp if non zero, encrypt. if zero, decrypt. 574 * 575 * @ingroup hcrypto_des 576 */ 577 578void 579DES_ecb3_encrypt(DES_cblock *input, 580 DES_cblock *output, 581 DES_key_schedule *ks1, 582 DES_key_schedule *ks2, 583 DES_key_schedule *ks3, 584 int encp) 585{ 586 uint32_t u[2]; 587 load(*input, u); 588 _des3_encrypt(u, ks1, ks2, ks3, encp); 589 store(u, *output); 590 return; 591} 592 593/** 594 * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc). 595 * 596 * The IV must always be diffrent for diffrent input data blocks. 597 * 598 * @param in data to encrypt 599 * @param out data to encrypt 600 * @param length length of data 601 * @param ks1 key schedule to use 602 * @param ks2 key schedule to use 603 * @param ks3 key schedule to use 604 * @param iv initial vector to use 605 * @param encp if non zero, encrypt. if zero, decrypt. 606 * 607 * @ingroup hcrypto_des 608 */ 609 610void 611DES_ede3_cbc_encrypt(const void *in, void *out, 612 long length, DES_key_schedule *ks1, 613 DES_key_schedule *ks2, DES_key_schedule *ks3, 614 DES_cblock *iv, int encp) 615{ 616 const unsigned char *input = in; 617 unsigned char *output = out; 618 uint32_t u[2]; 619 uint32_t uiv[2]; 620 621 load(*iv, uiv); 622 623 if (encp) { 624 while (length >= DES_CBLOCK_LEN) { 625 load(input, u); 626 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 627 _des3_encrypt(u, ks1, ks2, ks3, 1); 628 uiv[0] = u[0]; uiv[1] = u[1]; 629 store(u, output); 630 631 length -= DES_CBLOCK_LEN; 632 input += DES_CBLOCK_LEN; 633 output += DES_CBLOCK_LEN; 634 } 635 if (length) { 636 unsigned char tmp[DES_CBLOCK_LEN]; 637 memcpy(tmp, input, length); 638 memset(tmp + length, 0, DES_CBLOCK_LEN - length); 639 load(tmp, u); 640 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 641 _des3_encrypt(u, ks1, ks2, ks3, 1); 642 store(u, output); 643 } 644 } else { 645 uint32_t t[2]; 646 while (length >= DES_CBLOCK_LEN) { 647 load(input, u); 648 t[0] = u[0]; t[1] = u[1]; 649 _des3_encrypt(u, ks1, ks2, ks3, 0); 650 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 651 store(u, output); 652 uiv[0] = t[0]; uiv[1] = t[1]; 653 654 length -= DES_CBLOCK_LEN; 655 input += DES_CBLOCK_LEN; 656 output += DES_CBLOCK_LEN; 657 } 658 if (length) { 659 unsigned char tmp[DES_CBLOCK_LEN]; 660 memcpy(tmp, input, length); 661 memset(tmp + length, 0, DES_CBLOCK_LEN - length); 662 load(tmp, u); 663 _des3_encrypt(u, ks1, ks2, ks3, 0); 664 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 665 store(u, output); 666 } 667 } 668 store(uiv, *iv); 669 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; 670} 671 672/** 673 * Encrypt/decrypt using DES in cipher feedback mode with 64 bit 674 * feedback. 675 * 676 * The IV must always be diffrent for diffrent input data blocks. 677 * 678 * @param in data to encrypt 679 * @param out data to encrypt 680 * @param length length of data 681 * @param ks key schedule to use 682 * @param iv initial vector to use 683 * @param num offset into in cipher block encryption/decryption stop last time. 684 * @param encp if non zero, encrypt. if zero, decrypt. 685 * 686 * @ingroup hcrypto_des 687 */ 688 689void 690DES_cfb64_encrypt(const void *in, void *out, 691 long length, DES_key_schedule *ks, DES_cblock *iv, 692 int *num, int encp) 693{ 694 const unsigned char *input = in; 695 unsigned char *output = out; 696 unsigned char tmp[DES_CBLOCK_LEN]; 697 uint32_t uiv[2]; 698 699 load(*iv, uiv); 700 701 assert(*num >= 0 && *num < DES_CBLOCK_LEN); 702 703 if (encp) { 704 int i = *num; 705 706 while (length > 0) { 707 if (i == 0) 708 DES_encrypt(uiv, ks, 1); 709 store(uiv, tmp); 710 for (; i < DES_CBLOCK_LEN && i < length; i++) { 711 output[i] = tmp[i] ^ input[i]; 712 } 713 if (i == DES_CBLOCK_LEN) 714 load(output, uiv); 715 output += i; 716 input += i; 717 length -= i; 718 if (i == DES_CBLOCK_LEN) 719 i = 0; 720 } 721 store(uiv, *iv); 722 *num = i; 723 } else { 724 int i = *num; 725 unsigned char c; 726 727 while (length > 0) { 728 if (i == 0) { 729 DES_encrypt(uiv, ks, 1); 730 store(uiv, tmp); 731 } 732 for (; i < DES_CBLOCK_LEN && i < length; i++) { 733 c = input[i]; 734 output[i] = tmp[i] ^ input[i]; 735 (*iv)[i] = c; 736 } 737 output += i; 738 input += i; 739 length -= i; 740 if (i == DES_CBLOCK_LEN) { 741 i = 0; 742 load(*iv, uiv); 743 } 744 } 745 store(uiv, *iv); 746 *num = i; 747 } 748} 749 750/** 751 * Crete a checksum using DES in CBC encryption mode. This mode is 752 * only used for Kerberos 4, and it should stay that way. 753 * 754 * The IV must always be diffrent for diffrent input data blocks. 755 * 756 * @param in data to checksum 757 * @param output the checksum 758 * @param length length of data 759 * @param ks key schedule to use 760 * @param iv initial vector to use 761 * 762 * @ingroup hcrypto_des 763 */ 764 765uint32_t 766DES_cbc_cksum(const void *in, DES_cblock *output, 767 long length, DES_key_schedule *ks, DES_cblock *iv) 768{ 769 const unsigned char *input = in; 770 uint32_t uiv[2]; 771 uint32_t u[2] = { 0, 0 }; 772 773 load(*iv, uiv); 774 775 while (length >= DES_CBLOCK_LEN) { 776 load(input, u); 777 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 778 DES_encrypt(u, ks, 1); 779 uiv[0] = u[0]; uiv[1] = u[1]; 780 781 length -= DES_CBLOCK_LEN; 782 input += DES_CBLOCK_LEN; 783 } 784 if (length) { 785 unsigned char tmp[DES_CBLOCK_LEN]; 786 memcpy(tmp, input, length); 787 memset(tmp + length, 0, DES_CBLOCK_LEN - length); 788 load(tmp, u); 789 u[0] ^= uiv[0]; u[1] ^= uiv[1]; 790 DES_encrypt(u, ks, 1); 791 } 792 if (output) 793 store(u, *output); 794 795 uiv[0] = 0; u[0] = 0; uiv[1] = 0; 796 return u[1]; 797} 798 799/* 800 * 801 */ 802 803static unsigned char 804bitswap8(unsigned char b) 805{ 806 unsigned char r = 0; 807 int i; 808 for (i = 0; i < 8; i++) { 809 r = r << 1 | (b & 1); 810 b = b >> 1; 811 } 812 return r; 813} 814 815/** 816 * Convert a string to a DES key. Use something like 817 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords. 818 * 819 * @param str The string to convert to a key 820 * @param key the resulting key 821 * 822 * @ingroup hcrypto_des 823 */ 824 825void 826DES_string_to_key(const char *str, DES_cblock *key) 827{ 828 const unsigned char *s; 829 unsigned char *k; 830 DES_key_schedule ks; 831 size_t i, len; 832 833 memset(key, 0, sizeof(*key)); 834 k = *key; 835 s = (const unsigned char *)str; 836 837 len = strlen(str); 838 for (i = 0; i < len; i++) { 839 if ((i % 16) < 8) 840 k[i % 8] ^= s[i] << 1; 841 else 842 k[7 - (i % 8)] ^= bitswap8(s[i]); 843 } 844 DES_set_odd_parity(key); 845 if (DES_is_weak_key(key)) 846 k[7] ^= 0xF0; 847 DES_set_key(key, &ks); 848 DES_cbc_cksum(s, key, len, &ks, key); 849 memset(&ks, 0, sizeof(ks)); 850 DES_set_odd_parity(key); 851 if (DES_is_weak_key(key)) 852 k[7] ^= 0xF0; 853} 854 855/** 856 * Read password from prompt and create a DES key. Internal uses 857 * DES_string_to_key(). Really, go use a really string2key function 858 * like PKCS5_PBKDF2_HMAC_SHA1(). 859 * 860 * @param key key to convert to 861 * @param prompt prompt to display user 862 * @param verify prompt twice. 863 * 864 * @return 1 on success, non 1 on failure. 865 */ 866 867int 868DES_read_password(DES_cblock *key, char *prompt, int verify) 869{ 870 char buf[512]; 871 int ret; 872 873 ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify); 874 if (ret == 1) 875 DES_string_to_key(buf, key); 876 return ret; 877} 878 879/* 880 * 881 */ 882 883 884void 885_DES_ipfp_test(void) 886{ 887 DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2; 888 uint32_t u[2] = { 1, 0 }; 889 IP(u); 890 FP(u); 891 IP(u); 892 FP(u); 893 if (u[0] != 1 || u[1] != 0) 894 abort(); 895 896 load(k, u); 897 store(u, k2); 898 if (memcmp(k, k2, 8) != 0) 899 abort(); 900} 901 902/* D3DES (V5.09) - 903 * 904 * A portable, public domain, version of the Data Encryption Standard. 905 * 906 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. 907 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation 908 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis 909 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, 910 * for humouring me on. 911 * 912 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. 913 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. 914 */ 915 916static uint32_t SP1[64] = { 917 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, 918 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, 919 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, 920 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, 921 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, 922 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, 923 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, 924 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, 925 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, 926 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, 927 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, 928 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, 929 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, 930 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, 931 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, 932 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; 933 934static uint32_t SP2[64] = { 935 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, 936 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, 937 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, 938 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, 939 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, 940 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, 941 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, 942 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, 943 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, 944 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, 945 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, 946 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, 947 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, 948 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, 949 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, 950 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; 951 952static uint32_t SP3[64] = { 953 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, 954 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, 955 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, 956 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, 957 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, 958 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, 959 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, 960 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, 961 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, 962 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, 963 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, 964 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, 965 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, 966 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, 967 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, 968 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; 969 970static uint32_t SP4[64] = { 971 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, 972 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, 973 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, 974 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, 975 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, 976 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, 977 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, 978 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, 979 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, 980 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, 981 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, 982 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, 983 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, 984 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, 985 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, 986 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; 987 988static uint32_t SP5[64] = { 989 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, 990 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, 991 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, 992 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, 993 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, 994 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, 995 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, 996 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, 997 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, 998 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, 999 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, 1000 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, 1001 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, 1002 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, 1003 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, 1004 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; 1005 1006static uint32_t SP6[64] = { 1007 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, 1008 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, 1009 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, 1010 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, 1011 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, 1012 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, 1013 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, 1014 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, 1015 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, 1016 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, 1017 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, 1018 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, 1019 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, 1020 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, 1021 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, 1022 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; 1023 1024static uint32_t SP7[64] = { 1025 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, 1026 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, 1027 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, 1028 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, 1029 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, 1030 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, 1031 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, 1032 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, 1033 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, 1034 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, 1035 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, 1036 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, 1037 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, 1038 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, 1039 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, 1040 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; 1041 1042static uint32_t SP8[64] = { 1043 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, 1044 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, 1045 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, 1046 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, 1047 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, 1048 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, 1049 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, 1050 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, 1051 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, 1052 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, 1053 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, 1054 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, 1055 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, 1056 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, 1057 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, 1058 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; 1059 1060static void 1061IP(uint32_t v[2]) 1062{ 1063 uint32_t work; 1064 1065 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL; 1066 v[1] ^= work; 1067 v[0] ^= (work << 4); 1068 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL; 1069 v[1] ^= work; 1070 v[0] ^= (work << 16); 1071 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L; 1072 v[0] ^= work; 1073 v[1] ^= (work << 2); 1074 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL; 1075 v[0] ^= work; 1076 v[1] ^= (work << 8); 1077 v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL; 1078 work = (v[0] ^ v[1]) & 0xaaaaaaaaL; 1079 v[0] ^= work; 1080 v[1] ^= work; 1081 v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL; 1082} 1083 1084static void 1085FP(uint32_t v[2]) 1086{ 1087 uint32_t work; 1088 1089 v[0] = (v[0] << 31) | (v[0] >> 1); 1090 work = (v[1] ^ v[0]) & 0xaaaaaaaaL; 1091 v[1] ^= work; 1092 v[0] ^= work; 1093 v[1] = (v[1] << 31) | (v[1] >> 1); 1094 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL; 1095 v[0] ^= work; 1096 v[1] ^= (work << 8); 1097 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L; 1098 v[0] ^= work; 1099 v[1] ^= (work << 2); 1100 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL; 1101 v[1] ^= work; 1102 v[0] ^= (work << 16); 1103 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL; 1104 v[1] ^= work; 1105 v[0] ^= (work << 4); 1106} 1107 1108static void 1109desx(uint32_t block[2], DES_key_schedule *ks, int encp) 1110{ 1111 uint32_t *keys; 1112 uint32_t fval, work, right, left; 1113 int round; 1114 1115 left = block[0]; 1116 right = block[1]; 1117 1118 if (encp) { 1119 keys = &ks->ks[0]; 1120 1121 for( round = 0; round < 8; round++ ) { 1122 work = (right << 28) | (right >> 4); 1123 work ^= *keys++; 1124 fval = SP7[ work & 0x3fL]; 1125 fval |= SP5[(work >> 8) & 0x3fL]; 1126 fval |= SP3[(work >> 16) & 0x3fL]; 1127 fval |= SP1[(work >> 24) & 0x3fL]; 1128 work = right ^ *keys++; 1129 fval |= SP8[ work & 0x3fL]; 1130 fval |= SP6[(work >> 8) & 0x3fL]; 1131 fval |= SP4[(work >> 16) & 0x3fL]; 1132 fval |= SP2[(work >> 24) & 0x3fL]; 1133 left ^= fval; 1134 work = (left << 28) | (left >> 4); 1135 work ^= *keys++; 1136 fval = SP7[ work & 0x3fL]; 1137 fval |= SP5[(work >> 8) & 0x3fL]; 1138 fval |= SP3[(work >> 16) & 0x3fL]; 1139 fval |= SP1[(work >> 24) & 0x3fL]; 1140 work = left ^ *keys++; 1141 fval |= SP8[ work & 0x3fL]; 1142 fval |= SP6[(work >> 8) & 0x3fL]; 1143 fval |= SP4[(work >> 16) & 0x3fL]; 1144 fval |= SP2[(work >> 24) & 0x3fL]; 1145 right ^= fval; 1146 } 1147 } else { 1148 keys = &ks->ks[30]; 1149 1150 for( round = 0; round < 8; round++ ) { 1151 work = (right << 28) | (right >> 4); 1152 work ^= *keys++; 1153 fval = SP7[ work & 0x3fL]; 1154 fval |= SP5[(work >> 8) & 0x3fL]; 1155 fval |= SP3[(work >> 16) & 0x3fL]; 1156 fval |= SP1[(work >> 24) & 0x3fL]; 1157 work = right ^ *keys++; 1158 fval |= SP8[ work & 0x3fL]; 1159 fval |= SP6[(work >> 8) & 0x3fL]; 1160 fval |= SP4[(work >> 16) & 0x3fL]; 1161 fval |= SP2[(work >> 24) & 0x3fL]; 1162 left ^= fval; 1163 work = (left << 28) | (left >> 4); 1164 keys -= 4; 1165 work ^= *keys++; 1166 fval = SP7[ work & 0x3fL]; 1167 fval |= SP5[(work >> 8) & 0x3fL]; 1168 fval |= SP3[(work >> 16) & 0x3fL]; 1169 fval |= SP1[(work >> 24) & 0x3fL]; 1170 work = left ^ *keys++; 1171 fval |= SP8[ work & 0x3fL]; 1172 fval |= SP6[(work >> 8) & 0x3fL]; 1173 fval |= SP4[(work >> 16) & 0x3fL]; 1174 fval |= SP2[(work >> 24) & 0x3fL]; 1175 right ^= fval; 1176 keys -= 4; 1177 } 1178 } 1179 block[0] = right; 1180 block[1] = left; 1181} 1182