Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:27

0001 /*
0002  * FreeSec: libcrypt for NetBSD
0003  *
0004  * Copyright (c) 1994 David Burren
0005  * All rights reserved.
0006  *
0007  * Ported to RTEMS and made reentrant by Till Straumann, 9/2003
0008  *
0009  * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
0010  *  this file should now *only* export crypt(), in order to make
0011  *  binaries of libcrypt exportable from the USA
0012  *
0013  * Adapted for FreeBSD-4.0 by Mark R V Murray
0014  *  this file should now *only* export crypt_des(), in order to make
0015  *  a module that can be optionally included in libcrypt.
0016  *
0017  * Redistribution and use in source and binary forms, with or without
0018  * modification, are permitted provided that the following conditions
0019  * are met:
0020  * 1. Redistributions of source code must retain the above copyright
0021  *    notice, this list of conditions and the following disclaimer.
0022  * 2. Redistributions in binary form must reproduce the above copyright
0023  *    notice, this list of conditions and the following disclaimer in the
0024  *    documentation and/or other materials provided with the distribution.
0025  * 3. Neither the name of the author nor the names of other contributors
0026  *    may be used to endorse or promote products derived from this software
0027  *    without specific prior written permission.
0028  *
0029  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0039  * SUCH DAMAGE.
0040  *
0041  * This is an original implementation of the DES and the crypt(3) interfaces
0042  * by David Burren <davidb@werj.com.au>.
0043  *
0044  * An excellent reference on the underlying algorithm (and related
0045  * algorithms) is:
0046  *
0047  *  B. Schneier, Applied Cryptography: protocols, algorithms,
0048  *  and source code in C, John Wiley & Sons, 1994.
0049  *
0050  * Note that in that book's description of DES the lookups for the initial,
0051  * pbox, and final permutations are inverted (this has been brought to the
0052  * attention of the author).  A list of errata for this book has been
0053  * posted to the sci.crypt newsgroup by the author and is available for FTP.
0054  *
0055  * ARCHITECTURE ASSUMPTIONS:
0056  *  It is assumed that the 8-byte arrays passed by reference can be
0057  *  addressed as arrays of u_int32_t's (ie. the CPU is not picky about
0058  *  alignment).
0059  */
0060 
0061 #ifdef HAVE_CONFIG_H
0062 #include "config.h"
0063 #endif
0064 
0065 #define __FORCE_GLIBC
0066 #include <sys/cdefs.h>
0067 #include <sys/types.h>
0068 #include <sys/param.h>
0069 #include <netinet/in.h>
0070 #ifndef __rtems__
0071 #include <pwd.h>
0072 #include <crypt.h>
0073 #endif
0074 #include <string.h>
0075 #include <stdlib.h>
0076 
0077 #include "des.h"
0078 
0079 #define REENTRANT
0080 /* Re-entrantify me -- all this junk needs to be in
0081  * struct crypt_data to make this really reentrant... */
0082 
0083 /* TS; not really - only the stuff in Des_Context */
0084 static struct fixed1 {
0085 u_char  inv_key_perm[64];
0086 u_char  inv_comp_perm[56];
0087 u_char  u_sbox[8][64];
0088 u_char  un_pbox[32];
0089 } des1_f;
0090 static struct fixed2 {
0091 u_int32_t ip_maskl[8][256], ip_maskr[8][256];
0092 } des2_f;
0093 static struct fixed3 {
0094 u_int32_t fp_maskl[8][256], fp_maskr[8][256];
0095 } des3_f;
0096 static struct fixed4 {
0097 u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
0098 u_int32_t comp_maskl[8][128], comp_maskr[8][128];
0099 } des4_f;
0100 
0101 #define inv_key_perm des1_f.inv_key_perm
0102 #define inv_comp_perm des1_f.inv_comp_perm
0103 #define u_sbox des1_f.u_sbox
0104 #define un_pbox des1_f.un_pbox
0105 #define ip_maskl des2_f.ip_maskl
0106 #define ip_maskr des2_f.ip_maskr
0107 #define fp_maskl des3_f.fp_maskl
0108 #define fp_maskr des3_f.fp_maskr
0109 #define key_perm_maskl des4_f.key_perm_maskl
0110 #define key_perm_maskr des4_f.key_perm_maskr
0111 #define comp_maskl des4_f.comp_maskl
0112 #define comp_maskr des4_f.comp_maskr
0113 
0114 /* These need to be maintained per-process */
0115 struct Des_Context {
0116 u_int32_t en_keysl[16], en_keysr[16];
0117 u_int32_t de_keysl[16], de_keysr[16];
0118 u_int32_t saltbits;
0119 u_int32_t old_salt;
0120 u_int32_t old_rawkey0, old_rawkey1;
0121 };
0122 
0123 #ifndef REENTRANT
0124 static struct Des_Context single;
0125 #endif
0126 
0127 #define en_keysl des_ctx->en_keysl
0128 #define en_keysr des_ctx->en_keysr
0129 #define de_keysl des_ctx->de_keysl
0130 #define de_keysr des_ctx->de_keysr
0131 #define saltbits des_ctx->saltbits
0132 #define old_salt des_ctx->old_salt
0133 #define old_rawkey0 des_ctx->old_rawkey0
0134 #define old_rawkey1 des_ctx->old_rawkey1
0135 
0136 /* Static stuff that stays resident and doesn't change after
0137  * being initialized, and therefore doesn't need to be made
0138  * reentrant. */
0139 static u_char   init_perm[64], final_perm[64];
0140 static u_char   m_sbox[4][4096];
0141 static u_int32_t psbox[4][256];
0142 
0143 
0144 
0145 
0146 /* A pile of data */
0147 static const u_char ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
0148 
0149 static const u_char IP[64] = {
0150   58, 50, 42, 34, 26, 18, 10,  2, 60, 52, 44, 36, 28, 20, 12,  4,
0151   62, 54, 46, 38, 30, 22, 14,  6, 64, 56, 48, 40, 32, 24, 16,  8,
0152   57, 49, 41, 33, 25, 17,  9,  1, 59, 51, 43, 35, 27, 19, 11,  3,
0153   61, 53, 45, 37, 29, 21, 13,  5, 63, 55, 47, 39, 31, 23, 15,  7
0154 };
0155 
0156 static const u_char key_perm[56] = {
0157   57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
0158   10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
0159   63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
0160   14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4
0161 };
0162 
0163 static const u_char key_shifts[16] = {
0164   1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
0165 };
0166 
0167 static const u_char comp_perm[48] = {
0168   14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
0169   23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
0170   41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
0171   44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
0172 };
0173 
0174 /*
0175  *  No E box is used, as it's replaced by some ANDs, shifts, and ORs.
0176  */
0177 
0178 static const u_char sbox[8][64] = {
0179   {
0180     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
0181      0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
0182      4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
0183     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13
0184   },
0185   {
0186     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
0187      3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
0188      0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
0189     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9
0190   },
0191   {
0192     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
0193     13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
0194     13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
0195      1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12
0196   },
0197   {
0198      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
0199     13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
0200     10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
0201      3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14
0202   },
0203   {
0204      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
0205     14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
0206      4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
0207     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3
0208   },
0209   {
0210     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
0211     10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
0212      9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
0213      4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13
0214   },
0215   {
0216      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
0217     13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
0218      1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
0219      6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12
0220   },
0221   {
0222     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
0223      1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
0224      7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
0225      2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
0226   }
0227 };
0228 
0229 static const u_char pbox[32] = {
0230   16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
0231    2,  8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25
0232 };
0233 
0234 static const u_int32_t bits32[32] =
0235 {
0236   0x80000000, 0x40000000, 0x20000000, 0x10000000,
0237   0x08000000, 0x04000000, 0x02000000, 0x01000000,
0238   0x00800000, 0x00400000, 0x00200000, 0x00100000,
0239   0x00080000, 0x00040000, 0x00020000, 0x00010000,
0240   0x00008000, 0x00004000, 0x00002000, 0x00001000,
0241   0x00000800, 0x00000400, 0x00000200, 0x00000100,
0242   0x00000080, 0x00000040, 0x00000020, 0x00000010,
0243   0x00000008, 0x00000004, 0x00000002, 0x00000001
0244 };
0245 
0246 static const u_char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
0247 static const u_int32_t *bits28, *bits24;
0248 
0249 
0250 static int
0251 ascii_to_bin(char ch)
0252 {
0253   if (ch > 'z')
0254     return(0);
0255   if (ch >= 'a')
0256     return(ch - 'a' + 38);
0257   if (ch > 'Z')
0258     return(0);
0259   if (ch >= 'A')
0260     return(ch - 'A' + 12);
0261   if (ch > '9')
0262     return(0);
0263   if (ch >= '.')
0264     return(ch - '.');
0265   return(0);
0266 }
0267 
0268 static struct Des_Context *
0269 des_ctx_init(void)
0270 {
0271 struct Des_Context *des_ctx;
0272 #ifdef REENTRANT
0273   des_ctx = malloc(sizeof(*des_ctx));
0274 #else
0275   des_ctx = &single;
0276 #endif
0277   old_rawkey0 = old_rawkey1 = 0L;
0278   saltbits = 0L;
0279   old_salt = 0L;
0280 
0281   return des_ctx;
0282 }
0283 
0284 static void
0285 des_init(void)
0286 {
0287   int   i, j, b, k, inbit, obit;
0288   u_int32_t *p, *il, *ir, *fl, *fr;
0289   static int des_initialised = 0;
0290 
0291   if (des_initialised==1)
0292       return;
0293 
0294 #ifndef REENTRANT
0295   des_ctx_init();
0296 #endif
0297 
0298   bits24 = (bits28 = bits32 + 4) + 4;
0299 
0300   /*
0301    * Invert the S-boxes, reordering the input bits.
0302    */
0303   for (i = 0; i < 8; i++)
0304     for (j = 0; j < 64; j++) {
0305       b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
0306       u_sbox[i][j] = sbox[i][b];
0307     }
0308 
0309   /*
0310    * Convert the inverted S-boxes into 4 arrays of 8 bits.
0311    * Each will handle 12 bits of the S-box input.
0312    */
0313   for (b = 0; b < 4; b++)
0314     for (i = 0; i < 64; i++)
0315       for (j = 0; j < 64; j++)
0316         m_sbox[b][(i << 6) | j] =
0317           (u_char)((u_sbox[(b << 1)][i] << 4) |
0318           u_sbox[(b << 1) + 1][j]);
0319 
0320   /*
0321    * Set up the initial & final permutations into a useful form, and
0322    * initialise the inverted key permutation.
0323    */
0324   for (i = 0; i < 64; i++) {
0325     init_perm[final_perm[i] = IP[i] - 1] = (u_char)i;
0326     inv_key_perm[i] = 255;
0327   }
0328 
0329   /*
0330    * Invert the key permutation and initialise the inverted key
0331    * compression permutation.
0332    */
0333   for (i = 0; i < 56; i++) {
0334     inv_key_perm[key_perm[i] - 1] = (u_char)i;
0335     inv_comp_perm[i] = 255;
0336   }
0337 
0338   /*
0339    * Invert the key compression permutation.
0340    */
0341   for (i = 0; i < 48; i++) {
0342     inv_comp_perm[comp_perm[i] - 1] = (u_char)i;
0343   }
0344 
0345   /*
0346    * Set up the OR-mask arrays for the initial and final permutations,
0347    * and for the key initial and compression permutations.
0348    */
0349   for (k = 0; k < 8; k++) {
0350     for (i = 0; i < 256; i++) {
0351       *(il = &ip_maskl[k][i]) = 0L;
0352       *(ir = &ip_maskr[k][i]) = 0L;
0353       *(fl = &fp_maskl[k][i]) = 0L;
0354       *(fr = &fp_maskr[k][i]) = 0L;
0355       for (j = 0; j < 8; j++) {
0356         inbit = 8 * k + j;
0357         if (i & bits8[j]) {
0358           if ((obit = init_perm[inbit]) < 32)
0359             *il |= bits32[obit];
0360           else
0361             *ir |= bits32[obit-32];
0362           if ((obit = final_perm[inbit]) < 32)
0363             *fl |= bits32[obit];
0364           else
0365             *fr |= bits32[obit - 32];
0366         }
0367       }
0368     }
0369     for (i = 0; i < 128; i++) {
0370       *(il = &key_perm_maskl[k][i]) = 0L;
0371       *(ir = &key_perm_maskr[k][i]) = 0L;
0372       for (j = 0; j < 7; j++) {
0373         inbit = 8 * k + j;
0374         if (i & bits8[j + 1]) {
0375           if ((obit = inv_key_perm[inbit]) == 255)
0376             continue;
0377           if (obit < 28)
0378             *il |= bits28[obit];
0379           else
0380             *ir |= bits28[obit - 28];
0381         }
0382       }
0383       *(il = &comp_maskl[k][i]) = 0L;
0384       *(ir = &comp_maskr[k][i]) = 0L;
0385       for (j = 0; j < 7; j++) {
0386         inbit = 7 * k + j;
0387         if (i & bits8[j + 1]) {
0388           if ((obit=inv_comp_perm[inbit]) == 255)
0389             continue;
0390           if (obit < 24)
0391             *il |= bits24[obit];
0392           else
0393             *ir |= bits24[obit - 24];
0394         }
0395       }
0396     }
0397   }
0398 
0399   /*
0400    * Invert the P-box permutation, and convert into OR-masks for
0401    * handling the output of the S-box arrays setup above.
0402    */
0403   for (i = 0; i < 32; i++)
0404     un_pbox[pbox[i] - 1] = (u_char)i;
0405 
0406   for (b = 0; b < 4; b++)
0407     for (i = 0; i < 256; i++) {
0408       *(p = &psbox[b][i]) = 0L;
0409       for (j = 0; j < 8; j++) {
0410         if (i & bits8[j])
0411           *p |= bits32[un_pbox[8 * b + j]];
0412       }
0413     }
0414 
0415   des_initialised = 1;
0416 }
0417 
0418 
0419 static void
0420 setup_salt(long salt, struct Des_Context *des_ctx)
0421 {
0422   u_int32_t obit, saltbit;
0423   int   i;
0424 
0425   if (salt == old_salt)
0426     return;
0427   old_salt = salt;
0428 
0429   saltbits = 0L;
0430   saltbit = 1;
0431   obit = 0x800000;
0432   for (i = 0; i < 24; i++) {
0433     if (salt & saltbit)
0434       saltbits |= obit;
0435     saltbit <<= 1;
0436     obit >>= 1;
0437   }
0438 }
0439 
0440 
0441 static int
0442 des_setkey(const char *key, struct Des_Context *des_ctx)
0443 {
0444   u_int32_t k0, k1, rawkey0, rawkey1;
0445   int       shifts, round;
0446 
0447   des_init();
0448 
0449   rawkey0 = ntohl(*(const u_int32_t *) key);
0450   rawkey1 = ntohl(*(const u_int32_t *) (key + 4));
0451 
0452   if ((rawkey0 | rawkey1)
0453       && rawkey0 == old_rawkey0
0454       && rawkey1 == old_rawkey1) {
0455     /*
0456      * Already setup for this key.
0457      * This optimisation fails on a zero key (which is weak and
0458      * has bad parity anyway) in order to simplify the starting
0459      * conditions.
0460      */
0461     return(0);
0462   }
0463   old_rawkey0 = rawkey0;
0464   old_rawkey1 = rawkey1;
0465 
0466   /*
0467    *    Do key permutation and split into two 28-bit subkeys.
0468    */
0469   k0 = key_perm_maskl[0][rawkey0 >> 25]
0470      | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
0471      | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
0472      | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
0473      | key_perm_maskl[4][rawkey1 >> 25]
0474      | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
0475      | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
0476      | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
0477   k1 = key_perm_maskr[0][rawkey0 >> 25]
0478      | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
0479      | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
0480      | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
0481      | key_perm_maskr[4][rawkey1 >> 25]
0482      | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
0483      | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
0484      | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
0485   /*
0486    *    Rotate subkeys and do compression permutation.
0487    */
0488   shifts = 0;
0489   for (round = 0; round < 16; round++) {
0490     u_int32_t   t0, t1;
0491 
0492     shifts += key_shifts[round];
0493 
0494     t0 = (k0 << shifts) | (k0 >> (28 - shifts));
0495     t1 = (k1 << shifts) | (k1 >> (28 - shifts));
0496 
0497     de_keysl[15 - round] =
0498     en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
0499         | comp_maskl[1][(t0 >> 14) & 0x7f]
0500         | comp_maskl[2][(t0 >> 7) & 0x7f]
0501         | comp_maskl[3][t0 & 0x7f]
0502         | comp_maskl[4][(t1 >> 21) & 0x7f]
0503         | comp_maskl[5][(t1 >> 14) & 0x7f]
0504         | comp_maskl[6][(t1 >> 7) & 0x7f]
0505         | comp_maskl[7][t1 & 0x7f];
0506 
0507     de_keysr[15 - round] =
0508     en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
0509         | comp_maskr[1][(t0 >> 14) & 0x7f]
0510         | comp_maskr[2][(t0 >> 7) & 0x7f]
0511         | comp_maskr[3][t0 & 0x7f]
0512         | comp_maskr[4][(t1 >> 21) & 0x7f]
0513         | comp_maskr[5][(t1 >> 14) & 0x7f]
0514         | comp_maskr[6][(t1 >> 7) & 0x7f]
0515         | comp_maskr[7][t1 & 0x7f];
0516   }
0517   return(0);
0518 }
0519 
0520 
0521 static int
0522 do_des( u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, int count, struct Des_Context *des_ctx)
0523 {
0524   /*
0525    *    l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
0526    */
0527   u_int32_t l, r, *kl, *kr, *kl1, *kr1;
0528   u_int32_t f, r48l, r48r;
0529   int       round;
0530 
0531   if (count == 0) {
0532     return(1);
0533   } else if (count > 0) {
0534     /*
0535      * Encrypting
0536      */
0537     kl1 = en_keysl;
0538     kr1 = en_keysr;
0539   } else {
0540     /*
0541      * Decrypting
0542      */
0543     count = -count;
0544     kl1 = de_keysl;
0545     kr1 = de_keysr;
0546   }
0547 
0548   /*
0549    *    Do initial permutation (IP).
0550    */
0551   l = ip_maskl[0][l_in >> 24]
0552     | ip_maskl[1][(l_in >> 16) & 0xff]
0553     | ip_maskl[2][(l_in >> 8) & 0xff]
0554     | ip_maskl[3][l_in & 0xff]
0555     | ip_maskl[4][r_in >> 24]
0556     | ip_maskl[5][(r_in >> 16) & 0xff]
0557     | ip_maskl[6][(r_in >> 8) & 0xff]
0558     | ip_maskl[7][r_in & 0xff];
0559   r = ip_maskr[0][l_in >> 24]
0560     | ip_maskr[1][(l_in >> 16) & 0xff]
0561     | ip_maskr[2][(l_in >> 8) & 0xff]
0562     | ip_maskr[3][l_in & 0xff]
0563     | ip_maskr[4][r_in >> 24]
0564     | ip_maskr[5][(r_in >> 16) & 0xff]
0565     | ip_maskr[6][(r_in >> 8) & 0xff]
0566     | ip_maskr[7][r_in & 0xff];
0567 
0568   while (count--) {
0569     /*
0570      * Do each round.
0571      */
0572     kl = kl1;
0573     kr = kr1;
0574     round = 16;
0575     while (round--) {
0576       /*
0577        * Expand R to 48 bits (simulate the E-box).
0578        */
0579       r48l  = ((r & 0x00000001) << 23)
0580         | ((r & 0xf8000000) >> 9)
0581         | ((r & 0x1f800000) >> 11)
0582         | ((r & 0x01f80000) >> 13)
0583         | ((r & 0x001f8000) >> 15);
0584 
0585       r48r  = ((r & 0x0001f800) << 7)
0586         | ((r & 0x00001f80) << 5)
0587         | ((r & 0x000001f8) << 3)
0588         | ((r & 0x0000001f) << 1)
0589         | ((r & 0x80000000) >> 31);
0590       /*
0591        * Do salting for crypt() and friends, and
0592        * XOR with the permuted key.
0593        */
0594       f = (r48l ^ r48r) & saltbits;
0595       r48l ^= f ^ *kl++;
0596       r48r ^= f ^ *kr++;
0597       /*
0598        * Do sbox lookups (which shrink it back to 32 bits)
0599        * and do the pbox permutation at the same time.
0600        */
0601       f = psbox[0][m_sbox[0][r48l >> 12]]
0602         | psbox[1][m_sbox[1][r48l & 0xfff]]
0603         | psbox[2][m_sbox[2][r48r >> 12]]
0604         | psbox[3][m_sbox[3][r48r & 0xfff]];
0605       /*
0606        * Now that we've permuted things, complete f().
0607        */
0608       f ^= l;
0609       l = r;
0610       r = f;
0611     }
0612     r = l;
0613     l = f;
0614   }
0615   /*
0616    * Do final permutation (inverse of IP).
0617    */
0618   *l_out    = fp_maskl[0][l >> 24]
0619     | fp_maskl[1][(l >> 16) & 0xff]
0620     | fp_maskl[2][(l >> 8) & 0xff]
0621     | fp_maskl[3][l & 0xff]
0622     | fp_maskl[4][r >> 24]
0623     | fp_maskl[5][(r >> 16) & 0xff]
0624     | fp_maskl[6][(r >> 8) & 0xff]
0625     | fp_maskl[7][r & 0xff];
0626   *r_out    = fp_maskr[0][l >> 24]
0627     | fp_maskr[1][(l >> 16) & 0xff]
0628     | fp_maskr[2][(l >> 8) & 0xff]
0629     | fp_maskr[3][l & 0xff]
0630     | fp_maskr[4][r >> 24]
0631     | fp_maskr[5][(r >> 16) & 0xff]
0632     | fp_maskr[6][(r >> 8) & 0xff]
0633     | fp_maskr[7][r & 0xff];
0634   return(0);
0635 }
0636 
0637 
0638 #if 0
0639 static int
0640 des_cipher(const char *in, char *out, u_int32_t salt, int count)
0641 {
0642   u_int32_t l_out, r_out, rawl, rawr;
0643   int       retval;
0644   union {
0645     u_int32_t   *ui32;
0646     const char  *c;
0647   } trans;
0648 
0649   des_init();
0650 
0651   setup_salt(salt);
0652 
0653   trans.c = in;
0654   rawl = ntohl(*trans.ui32++);
0655   rawr = ntohl(*trans.ui32);
0656 
0657   retval = do_des(rawl, rawr, &l_out, &r_out, count);
0658 
0659   trans.c = out;
0660   *trans.ui32++ = htonl(l_out);
0661   *trans.ui32 = htonl(r_out);
0662   return(retval);
0663 }
0664 #endif
0665 
0666 
0667 #ifndef REENTRANT
0668 void
0669 setkey(const char *key)
0670 {
0671   int   i, j;
0672   u_int32_t packed_keys[2];
0673   u_char    *p;
0674 
0675   p = (u_char *) packed_keys;
0676 
0677   for (i = 0; i < 8; i++) {
0678     p[i] = 0;
0679     for (j = 0; j < 8; j++)
0680       if (*key++ & 1)
0681         p[i] |= bits8[j];
0682   }
0683   des_setkey(p, &single);
0684 }
0685 #endif
0686 
0687 
0688 #ifndef REENTRANT
0689 void
0690 encrypt(char *block, int flag)
0691 {
0692   u_int32_t io[2];
0693   u_char    *p;
0694   int   i, j;
0695 
0696   des_init();
0697 
0698   setup_salt(0L, &single);
0699   p = block;
0700   for (i = 0; i < 2; i++) {
0701     io[i] = 0L;
0702     for (j = 0; j < 32; j++)
0703       if (*p++ & 1)
0704         io[i] |= bits32[j];
0705   }
0706   do_des(io[0], io[1], io, io + 1, flag ? -1 : 1, &single);
0707   for (i = 0; i < 2; i++)
0708     for (j = 0; j < 32; j++)
0709       block[(i << 5) | j] = (io[i] & bits32[j]) ? 1 : 0;
0710 }
0711 
0712 #endif
0713 
0714 char *
0715 __des_crypt_r(const char *key, const char *setting, char *output, int sz)
0716 {
0717   char *rval = 0;
0718   struct Des_Context *des_ctx;
0719   u_int32_t count, salt, l, r0, r1, keybuf[2];
0720   u_char        *p, *q;
0721 
0722   if (sz < 21)
0723     return NULL;
0724 
0725   des_init();
0726   des_ctx = des_ctx_init();
0727 
0728   /*
0729    * Copy the key, shifting each character up by one bit
0730    * and padding with zeros.
0731    */
0732   q = (u_char *)keybuf;
0733   while (q - (u_char *)keybuf - 8) {
0734     *q++ = *key << 1;
0735     if (*(q - 1))
0736       key++;
0737   }
0738   if (des_setkey((char *)keybuf, des_ctx))
0739     goto bailout;
0740 
0741 #if 0
0742   if (*setting == _PASSWORD_EFMT1) {
0743     int     i;
0744     /*
0745      * "new"-style:
0746      *  setting - underscore, 4 bytes of count, 4 bytes of salt
0747      *  key - unlimited characters
0748      */
0749     for (i = 1, count = 0L; i < 5; i++)
0750       count |= ascii_to_bin(setting[i]) << ((i - 1) * 6);
0751 
0752     for (i = 5, salt = 0L; i < 9; i++)
0753       salt |= ascii_to_bin(setting[i]) << ((i - 5) * 6);
0754 
0755     while (*key) {
0756       /*
0757        * Encrypt the key with itself.
0758        */
0759       if (des_cipher((char *)keybuf, (char *)keybuf, 0L, 1))
0760         goto bailout;
0761       /*
0762        * And XOR with the next 8 characters of the key.
0763        */
0764       q = (u_char *)keybuf;
0765       while (q - (u_char *)keybuf - 8 && *key)
0766         *q++ ^= *key++ << 1;
0767 
0768       if (des_setkey((char *)keybuf))
0769         goto bailout;
0770     }
0771     strncpy(output, setting, 9);
0772 
0773     /*
0774      * Double check that we weren't given a short setting.
0775      * If we were, the above code will probably have created
0776      * wierd values for count and salt, but we don't really care.
0777      * Just make sure the output string doesn't have an extra
0778      * NUL in it.
0779      */
0780     output[9] = '\0';
0781     p = (u_char *)output + strlen(output);
0782   } else
0783 #endif
0784   {
0785     /*
0786      * "old"-style:
0787      *  setting - 2 bytes of salt
0788      *  key - up to 8 characters
0789      */
0790     count = 25;
0791 
0792     salt = (ascii_to_bin(setting[1]) << 6)
0793          |  ascii_to_bin(setting[0]);
0794 
0795     output[0] = setting[0];
0796     /*
0797      * If the encrypted password that the salt was extracted from
0798      * is only 1 character long, the salt will be corrupted.  We
0799      * need to ensure that the output string doesn't have an extra
0800      * NUL in it!
0801      */
0802     output[1] = setting[1] ? setting[1] : output[0];
0803 
0804     p = (u_char *)output + 2;
0805   }
0806   setup_salt(salt, des_ctx);
0807   /*
0808    * Do it.
0809    */
0810   if (do_des(0L, 0L, &r0, &r1, (int)count, des_ctx))
0811     goto bailout;
0812   /*
0813    * Now encode the result...
0814    */
0815   l = (r0 >> 8);
0816   *p++ = ascii64[(l >> 18) & 0x3f];
0817   *p++ = ascii64[(l >> 12) & 0x3f];
0818   *p++ = ascii64[(l >> 6) & 0x3f];
0819   *p++ = ascii64[l & 0x3f];
0820 
0821   l = (r0 << 16) | ((r1 >> 16) & 0xffff);
0822   *p++ = ascii64[(l >> 18) & 0x3f];
0823   *p++ = ascii64[(l >> 12) & 0x3f];
0824   *p++ = ascii64[(l >> 6) & 0x3f];
0825   *p++ = ascii64[l & 0x3f];
0826 
0827   l = r1 << 2;
0828   *p++ = ascii64[(l >> 12) & 0x3f];
0829   *p++ = ascii64[(l >> 6) & 0x3f];
0830   *p++ = ascii64[l & 0x3f];
0831   *p = 0;
0832 
0833   rval = output;
0834 bailout:
0835   free(des_ctx);
0836   return rval;
0837 }
0838 
0839 #ifdef DEBUG
0840 
0841 void
0842 des_snap(void **pf, void **pd)
0843 {
0844   uint8* pfc;
0845   *pf = malloc(sizeof(struct fixed1) + sizeof(struct fixed2) + sizeof(struct fixed3) + sizeof(struct fixed4));
0846   pfc = *pf;
0847   memcpy(pfc, &des1_f, sizeof(des1_f));
0848   pfc += sizeof(des1_f);
0849   memcpy(pfc, &des2_f, sizeof(des2_f));
0850   pfc += sizeof(des2_f);
0851   memcpy(pfc, &des3_f, sizeof(des3_f));
0852   pfc += sizeof(des3_f);
0853   memcpy(pfc, &des4_f, sizeof(des4_f));
0854 //  *pd = malloc(sizeof(struct Des_Context));
0855 //  memcpy(*pd, &des_ctx, sizeof(des_ctx));
0856 }
0857 
0858 void
0859 des_check(void *pf, void *pd)
0860 {
0861   uint8* pfc1, pfc2, pfc3, pfc4;
0862   pfc1 = pf;
0863   pfc2 = pfc1 + sizeof(des1_f);
0864   pfc3 = pfc2 + sizeof(des2_f);
0865   pfc4 = pfc3 + sizeof(des3_f);
0866   printf("Fixed: do%s differ"/*", Context: do%s differ"*/"\n",
0867          (memcmp(pfc1, &des1_f, sizeof(des1_f)) ||
0868           memcmp(pfc2, &des2_f, sizeof(des2_f)) ||
0869           memcmp(pfc3, &des4_f, sizeof(des3_f)) ||
0870           memcmp(pfc4, &des4_f, sizeof(des4_f))) ? "" : "nt");
0871 }
0872 
0873 #endif