root/source4/heimdal/lib/hcrypto/des.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. DES_set_odd_parity
  2. DES_check_key_parity
  3. DES_is_weak_key
  4. DES_set_key
  5. DES_set_key_unchecked
  6. DES_set_key_checked
  7. DES_key_sched
  8. load
  9. store
  10. DES_encrypt
  11. DES_ecb_encrypt
  12. DES_cbc_encrypt
  13. DES_pcbc_encrypt
  14. _des3_encrypt
  15. DES_ecb3_encrypt
  16. DES_ede3_cbc_encrypt
  17. DES_cfb64_encrypt
  18. DES_cbc_cksum
  19. bitswap8
  20. DES_string_to_key
  21. DES_read_password
  22. _DES_ipfp_test
  23. IP
  24. FP
  25. desx

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

/* [<][>][^][v][top][bottom][index][help] */