Header And Logo

PostgreSQL
| The world's most advanced open source database.

crypt-des.c

Go to the documentation of this file.
00001 /*
00002  * FreeSec: libcrypt for NetBSD
00003  *
00004  * contrib/pgcrypto/crypt-des.c
00005  *
00006  * Copyright (c) 1994 David Burren
00007  * All rights reserved.
00008  *
00009  * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
00010  *  this file should now *only* export crypt(), in order to make
00011  *  binaries of libcrypt exportable from the USA
00012  *
00013  * Adapted for FreeBSD-4.0 by Mark R V Murray
00014  *  this file should now *only* export crypt_des(), in order to make
00015  *  a module that can be optionally included in libcrypt.
00016  *
00017  * Redistribution and use in source and binary forms, with or without
00018  * modification, are permitted provided that the following conditions
00019  * are met:
00020  * 1. Redistributions of source code must retain the above copyright
00021  *    notice, this list of conditions and the following disclaimer.
00022  * 2. Redistributions in binary form must reproduce the above copyright
00023  *    notice, this list of conditions and the following disclaimer in the
00024  *    documentation and/or other materials provided with the distribution.
00025  * 3. Neither the name of the author nor the names of other contributors
00026  *    may be used to endorse or promote products derived from this software
00027  *    without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
00030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00039  * SUCH DAMAGE.
00040  *
00041  * $FreeBSD: src/secure/lib/libcrypt/crypt-des.c,v 1.12 1999/09/20 12:39:20 markm Exp $
00042  *
00043  * This is an original implementation of the DES and the crypt(3) interfaces
00044  * by David Burren <[email protected]>.
00045  *
00046  * An excellent reference on the underlying algorithm (and related
00047  * algorithms) is:
00048  *
00049  *  B. Schneier, Applied Cryptography: protocols, algorithms,
00050  *  and source code in C, John Wiley & Sons, 1994.
00051  *
00052  * Note that in that book's description of DES the lookups for the initial,
00053  * pbox, and final permutations are inverted (this has been brought to the
00054  * attention of the author).  A list of errata for this book has been
00055  * posted to the sci.crypt newsgroup by the author and is available for FTP.
00056  *
00057  * ARCHITECTURE ASSUMPTIONS:
00058  *  It is assumed that the 8-byte arrays passed by reference can be
00059  *  addressed as arrays of uint32's (ie. the CPU is not picky about
00060  *  alignment).
00061  */
00062 
00063 #include "postgres.h"
00064 
00065 #include "px-crypt.h"
00066 
00067 /* for ntohl/htonl */
00068 #include <netinet/in.h>
00069 #include <arpa/inet.h>
00070 
00071 #define _PASSWORD_EFMT1 '_'
00072 
00073 static const char _crypt_a64[] =
00074 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00075 
00076 static uint8 IP[64] = {
00077     58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
00078     62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
00079     57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
00080     61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
00081 };
00082 
00083 static uint8 inv_key_perm[64];
00084 static uint8 u_key_perm[56];
00085 static uint8 key_perm[56] = {
00086     57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
00087     10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
00088     63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
00089     14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
00090 };
00091 
00092 static uint8 key_shifts[16] = {
00093     1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
00094 };
00095 
00096 static uint8 inv_comp_perm[56];
00097 static uint8 comp_perm[48] = {
00098     14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
00099     23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
00100     41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
00101     44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
00102 };
00103 
00104 /*
00105  *  No E box is used, as it's replaced by some ANDs, shifts, and ORs.
00106  */
00107 
00108 static uint8 u_sbox[8][64];
00109 static uint8 sbox[8][64] = {
00110     {
00111         14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
00112         0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
00113         4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
00114         15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
00115     },
00116     {
00117         15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
00118         3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
00119         0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
00120         13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
00121     },
00122     {
00123         10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
00124         13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
00125         13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
00126         1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
00127     },
00128     {
00129         7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
00130         13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
00131         10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
00132         3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
00133     },
00134     {
00135         2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
00136         14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
00137         4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
00138         11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
00139     },
00140     {
00141         12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
00142         10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
00143         9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
00144         4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
00145     },
00146     {
00147         4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
00148         13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
00149         1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
00150         6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
00151     },
00152     {
00153         13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
00154         1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
00155         7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
00156         2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
00157     }
00158 };
00159 
00160 static uint8 un_pbox[32];
00161 static uint8 pbox[32] = {
00162     16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
00163     2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
00164 };
00165 
00166 static uint32 _crypt_bits32[32] =
00167 {
00168     0x80000000, 0x40000000, 0x20000000, 0x10000000,
00169     0x08000000, 0x04000000, 0x02000000, 0x01000000,
00170     0x00800000, 0x00400000, 0x00200000, 0x00100000,
00171     0x00080000, 0x00040000, 0x00020000, 0x00010000,
00172     0x00008000, 0x00004000, 0x00002000, 0x00001000,
00173     0x00000800, 0x00000400, 0x00000200, 0x00000100,
00174     0x00000080, 0x00000040, 0x00000020, 0x00000010,
00175     0x00000008, 0x00000004, 0x00000002, 0x00000001
00176 };
00177 
00178 static uint8 _crypt_bits8[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
00179 
00180 static uint32 saltbits;
00181 static long old_salt;
00182 static uint32 *bits28,
00183            *bits24;
00184 static uint8 init_perm[64],
00185             final_perm[64];
00186 static uint32 en_keysl[16],
00187             en_keysr[16];
00188 static uint32 de_keysl[16],
00189             de_keysr[16];
00190 static int  des_initialised = 0;
00191 static uint8 m_sbox[4][4096];
00192 static uint32 psbox[4][256];
00193 static uint32 ip_maskl[8][256],
00194             ip_maskr[8][256];
00195 static uint32 fp_maskl[8][256],
00196             fp_maskr[8][256];
00197 static uint32 key_perm_maskl[8][128],
00198             key_perm_maskr[8][128];
00199 static uint32 comp_maskl[8][128],
00200             comp_maskr[8][128];
00201 static uint32 old_rawkey0,
00202             old_rawkey1;
00203 
00204 static inline int
00205 ascii_to_bin(char ch)
00206 {
00207     if (ch > 'z')
00208         return (0);
00209     if (ch >= 'a')
00210         return (ch - 'a' + 38);
00211     if (ch > 'Z')
00212         return (0);
00213     if (ch >= 'A')
00214         return (ch - 'A' + 12);
00215     if (ch > '9')
00216         return (0);
00217     if (ch >= '.')
00218         return (ch - '.');
00219     return (0);
00220 }
00221 
00222 static void
00223 des_init(void)
00224 {
00225     int         i,
00226                 j,
00227                 b,
00228                 k,
00229                 inbit,
00230                 obit;
00231     uint32     *p,
00232                *il,
00233                *ir,
00234                *fl,
00235                *fr;
00236 
00237     old_rawkey0 = old_rawkey1 = 0L;
00238     saltbits = 0L;
00239     old_salt = 0L;
00240     bits24 = (bits28 = _crypt_bits32 + 4) + 4;
00241 
00242     /*
00243      * Invert the S-boxes, reordering the input bits.
00244      */
00245     for (i = 0; i < 8; i++)
00246         for (j = 0; j < 64; j++)
00247         {
00248             b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
00249             u_sbox[i][j] = sbox[i][b];
00250         }
00251 
00252     /*
00253      * Convert the inverted S-boxes into 4 arrays of 8 bits. Each will handle
00254      * 12 bits of the S-box input.
00255      */
00256     for (b = 0; b < 4; b++)
00257         for (i = 0; i < 64; i++)
00258             for (j = 0; j < 64; j++)
00259                 m_sbox[b][(i << 6) | j] =
00260                     (u_sbox[(b << 1)][i] << 4) |
00261                     u_sbox[(b << 1) + 1][j];
00262 
00263     /*
00264      * Set up the initial & final permutations into a useful form, and
00265      * initialise the inverted key permutation.
00266      */
00267     for (i = 0; i < 64; i++)
00268     {
00269         init_perm[final_perm[i] = IP[i] - 1] = i;
00270         inv_key_perm[i] = 255;
00271     }
00272 
00273     /*
00274      * Invert the key permutation and initialise the inverted key compression
00275      * permutation.
00276      */
00277     for (i = 0; i < 56; i++)
00278     {
00279         u_key_perm[i] = key_perm[i] - 1;
00280         inv_key_perm[key_perm[i] - 1] = i;
00281         inv_comp_perm[i] = 255;
00282     }
00283 
00284     /*
00285      * Invert the key compression permutation.
00286      */
00287     for (i = 0; i < 48; i++)
00288         inv_comp_perm[comp_perm[i] - 1] = i;
00289 
00290     /*
00291      * Set up the OR-mask arrays for the initial and final permutations, and
00292      * for the key initial and compression permutations.
00293      */
00294     for (k = 0; k < 8; k++)
00295     {
00296         for (i = 0; i < 256; i++)
00297         {
00298             *(il = &ip_maskl[k][i]) = 0L;
00299             *(ir = &ip_maskr[k][i]) = 0L;
00300             *(fl = &fp_maskl[k][i]) = 0L;
00301             *(fr = &fp_maskr[k][i]) = 0L;
00302             for (j = 0; j < 8; j++)
00303             {
00304                 inbit = 8 * k + j;
00305                 if (i & _crypt_bits8[j])
00306                 {
00307                     if ((obit = init_perm[inbit]) < 32)
00308                         *il |= _crypt_bits32[obit];
00309                     else
00310                         *ir |= _crypt_bits32[obit - 32];
00311                     if ((obit = final_perm[inbit]) < 32)
00312                         *fl |= _crypt_bits32[obit];
00313                     else
00314                         *fr |= _crypt_bits32[obit - 32];
00315                 }
00316             }
00317         }
00318         for (i = 0; i < 128; i++)
00319         {
00320             *(il = &key_perm_maskl[k][i]) = 0L;
00321             *(ir = &key_perm_maskr[k][i]) = 0L;
00322             for (j = 0; j < 7; j++)
00323             {
00324                 inbit = 8 * k + j;
00325                 if (i & _crypt_bits8[j + 1])
00326                 {
00327                     if ((obit = inv_key_perm[inbit]) == 255)
00328                         continue;
00329                     if (obit < 28)
00330                         *il |= bits28[obit];
00331                     else
00332                         *ir |= bits28[obit - 28];
00333                 }
00334             }
00335             *(il = &comp_maskl[k][i]) = 0L;
00336             *(ir = &comp_maskr[k][i]) = 0L;
00337             for (j = 0; j < 7; j++)
00338             {
00339                 inbit = 7 * k + j;
00340                 if (i & _crypt_bits8[j + 1])
00341                 {
00342                     if ((obit = inv_comp_perm[inbit]) == 255)
00343                         continue;
00344                     if (obit < 24)
00345                         *il |= bits24[obit];
00346                     else
00347                         *ir |= bits24[obit - 24];
00348                 }
00349             }
00350         }
00351     }
00352 
00353     /*
00354      * Invert the P-box permutation, and convert into OR-masks for handling
00355      * the output of the S-box arrays setup above.
00356      */
00357     for (i = 0; i < 32; i++)
00358         un_pbox[pbox[i] - 1] = i;
00359 
00360     for (b = 0; b < 4; b++)
00361         for (i = 0; i < 256; i++)
00362         {
00363             *(p = &psbox[b][i]) = 0L;
00364             for (j = 0; j < 8; j++)
00365             {
00366                 if (i & _crypt_bits8[j])
00367                     *p |= _crypt_bits32[un_pbox[8 * b + j]];
00368             }
00369         }
00370 
00371     des_initialised = 1;
00372 }
00373 
00374 static void
00375 setup_salt(long salt)
00376 {
00377     uint32      obit,
00378                 saltbit;
00379     int         i;
00380 
00381     if (salt == old_salt)
00382         return;
00383     old_salt = salt;
00384 
00385     saltbits = 0L;
00386     saltbit = 1;
00387     obit = 0x800000;
00388     for (i = 0; i < 24; i++)
00389     {
00390         if (salt & saltbit)
00391             saltbits |= obit;
00392         saltbit <<= 1;
00393         obit >>= 1;
00394     }
00395 }
00396 
00397 static int
00398 des_setkey(const char *key)
00399 {
00400     uint32      k0,
00401                 k1,
00402                 rawkey0,
00403                 rawkey1;
00404     int         shifts,
00405                 round;
00406 
00407     if (!des_initialised)
00408         des_init();
00409 
00410     rawkey0 = ntohl(*(const uint32 *) key);
00411     rawkey1 = ntohl(*(const uint32 *) (key + 4));
00412 
00413     if ((rawkey0 | rawkey1)
00414         && rawkey0 == old_rawkey0
00415         && rawkey1 == old_rawkey1)
00416     {
00417         /*
00418          * Already setup for this key. This optimisation fails on a zero key
00419          * (which is weak and has bad parity anyway) in order to simplify the
00420          * starting conditions.
00421          */
00422         return (0);
00423     }
00424     old_rawkey0 = rawkey0;
00425     old_rawkey1 = rawkey1;
00426 
00427     /*
00428      * Do key permutation and split into two 28-bit subkeys.
00429      */
00430     k0 = key_perm_maskl[0][rawkey0 >> 25]
00431         | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
00432         | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
00433         | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
00434         | key_perm_maskl[4][rawkey1 >> 25]
00435         | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
00436         | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
00437         | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
00438     k1 = key_perm_maskr[0][rawkey0 >> 25]
00439         | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
00440         | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
00441         | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
00442         | key_perm_maskr[4][rawkey1 >> 25]
00443         | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
00444         | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
00445         | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
00446 
00447     /*
00448      * Rotate subkeys and do compression permutation.
00449      */
00450     shifts = 0;
00451     for (round = 0; round < 16; round++)
00452     {
00453         uint32      t0,
00454                     t1;
00455 
00456         shifts += key_shifts[round];
00457 
00458         t0 = (k0 << shifts) | (k0 >> (28 - shifts));
00459         t1 = (k1 << shifts) | (k1 >> (28 - shifts));
00460 
00461         de_keysl[15 - round] =
00462             en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
00463             | comp_maskl[1][(t0 >> 14) & 0x7f]
00464             | comp_maskl[2][(t0 >> 7) & 0x7f]
00465             | comp_maskl[3][t0 & 0x7f]
00466             | comp_maskl[4][(t1 >> 21) & 0x7f]
00467             | comp_maskl[5][(t1 >> 14) & 0x7f]
00468             | comp_maskl[6][(t1 >> 7) & 0x7f]
00469             | comp_maskl[7][t1 & 0x7f];
00470 
00471         de_keysr[15 - round] =
00472             en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
00473             | comp_maskr[1][(t0 >> 14) & 0x7f]
00474             | comp_maskr[2][(t0 >> 7) & 0x7f]
00475             | comp_maskr[3][t0 & 0x7f]
00476             | comp_maskr[4][(t1 >> 21) & 0x7f]
00477             | comp_maskr[5][(t1 >> 14) & 0x7f]
00478             | comp_maskr[6][(t1 >> 7) & 0x7f]
00479             | comp_maskr[7][t1 & 0x7f];
00480     }
00481     return (0);
00482 }
00483 
00484 static int
00485 do_des(uint32 l_in, uint32 r_in, uint32 *l_out, uint32 *r_out, int count)
00486 {
00487     /*
00488      * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
00489      */
00490     uint32      l,
00491                 r,
00492                *kl,
00493                *kr,
00494                *kl1,
00495                *kr1;
00496     uint32      f,
00497                 r48l,
00498                 r48r;
00499     int         round;
00500 
00501     if (count == 0)
00502         return (1);
00503     else if (count > 0)
00504     {
00505         /*
00506          * Encrypting
00507          */
00508         kl1 = en_keysl;
00509         kr1 = en_keysr;
00510     }
00511     else
00512     {
00513         /*
00514          * Decrypting
00515          */
00516         count = -count;
00517         kl1 = de_keysl;
00518         kr1 = de_keysr;
00519     }
00520 
00521     /*
00522      * Do initial permutation (IP).
00523      */
00524     l = ip_maskl[0][l_in >> 24]
00525         | ip_maskl[1][(l_in >> 16) & 0xff]
00526         | ip_maskl[2][(l_in >> 8) & 0xff]
00527         | ip_maskl[3][l_in & 0xff]
00528         | ip_maskl[4][r_in >> 24]
00529         | ip_maskl[5][(r_in >> 16) & 0xff]
00530         | ip_maskl[6][(r_in >> 8) & 0xff]
00531         | ip_maskl[7][r_in & 0xff];
00532     r = ip_maskr[0][l_in >> 24]
00533         | ip_maskr[1][(l_in >> 16) & 0xff]
00534         | ip_maskr[2][(l_in >> 8) & 0xff]
00535         | ip_maskr[3][l_in & 0xff]
00536         | ip_maskr[4][r_in >> 24]
00537         | ip_maskr[5][(r_in >> 16) & 0xff]
00538         | ip_maskr[6][(r_in >> 8) & 0xff]
00539         | ip_maskr[7][r_in & 0xff];
00540 
00541     while (count--)
00542     {
00543         /*
00544          * Do each round.
00545          */
00546         kl = kl1;
00547         kr = kr1;
00548         round = 16;
00549         while (round--)
00550         {
00551             /*
00552              * Expand R to 48 bits (simulate the E-box).
00553              */
00554             r48l = ((r & 0x00000001) << 23)
00555                 | ((r & 0xf8000000) >> 9)
00556                 | ((r & 0x1f800000) >> 11)
00557                 | ((r & 0x01f80000) >> 13)
00558                 | ((r & 0x001f8000) >> 15);
00559 
00560             r48r = ((r & 0x0001f800) << 7)
00561                 | ((r & 0x00001f80) << 5)
00562                 | ((r & 0x000001f8) << 3)
00563                 | ((r & 0x0000001f) << 1)
00564                 | ((r & 0x80000000) >> 31);
00565 
00566             /*
00567              * Do salting for crypt() and friends, and XOR with the permuted
00568              * key.
00569              */
00570             f = (r48l ^ r48r) & saltbits;
00571             r48l ^= f ^ *kl++;
00572             r48r ^= f ^ *kr++;
00573 
00574             /*
00575              * Do sbox lookups (which shrink it back to 32 bits) and do the
00576              * pbox permutation at the same time.
00577              */
00578             f = psbox[0][m_sbox[0][r48l >> 12]]
00579                 | psbox[1][m_sbox[1][r48l & 0xfff]]
00580                 | psbox[2][m_sbox[2][r48r >> 12]]
00581                 | psbox[3][m_sbox[3][r48r & 0xfff]];
00582 
00583             /*
00584              * Now that we've permuted things, complete f().
00585              */
00586             f ^= l;
00587             l = r;
00588             r = f;
00589         }
00590         r = l;
00591         l = f;
00592     }
00593 
00594     /*
00595      * Do final permutation (inverse of IP).
00596      */
00597     *l_out = fp_maskl[0][l >> 24]
00598         | fp_maskl[1][(l >> 16) & 0xff]
00599         | fp_maskl[2][(l >> 8) & 0xff]
00600         | fp_maskl[3][l & 0xff]
00601         | fp_maskl[4][r >> 24]
00602         | fp_maskl[5][(r >> 16) & 0xff]
00603         | fp_maskl[6][(r >> 8) & 0xff]
00604         | fp_maskl[7][r & 0xff];
00605     *r_out = fp_maskr[0][l >> 24]
00606         | fp_maskr[1][(l >> 16) & 0xff]
00607         | fp_maskr[2][(l >> 8) & 0xff]
00608         | fp_maskr[3][l & 0xff]
00609         | fp_maskr[4][r >> 24]
00610         | fp_maskr[5][(r >> 16) & 0xff]
00611         | fp_maskr[6][(r >> 8) & 0xff]
00612         | fp_maskr[7][r & 0xff];
00613     return (0);
00614 }
00615 
00616 static int
00617 des_cipher(const char *in, char *out, long salt, int count)
00618 {
00619     uint32      buffer[2];
00620     uint32      l_out,
00621                 r_out,
00622                 rawl,
00623                 rawr;
00624     int         retval;
00625 
00626     if (!des_initialised)
00627         des_init();
00628 
00629     setup_salt(salt);
00630 
00631     /* copy data to avoid assuming input is word-aligned */
00632     memcpy(buffer, in, sizeof(buffer));
00633 
00634     rawl = ntohl(buffer[0]);
00635     rawr = ntohl(buffer[1]);
00636 
00637     retval = do_des(rawl, rawr, &l_out, &r_out, count);
00638 
00639     buffer[0] = htonl(l_out);
00640     buffer[1] = htonl(r_out);
00641 
00642     /* copy data to avoid assuming output is word-aligned */
00643     memcpy(out, buffer, sizeof(buffer));
00644 
00645     return (retval);
00646 }
00647 
00648 char *
00649 px_crypt_des(const char *key, const char *setting)
00650 {
00651     int         i;
00652     uint32      count,
00653                 salt,
00654                 l,
00655                 r0,
00656                 r1,
00657                 keybuf[2];
00658     char       *p;
00659     uint8      *q;
00660     static char output[21];
00661 
00662     if (!des_initialised)
00663         des_init();
00664 
00665 
00666     /*
00667      * Copy the key, shifting each character up by one bit and padding with
00668      * zeros.
00669      */
00670     q = (uint8 *) keybuf;
00671     while (q - (uint8 *) keybuf - 8)
00672     {
00673         *q++ = *key << 1;
00674         if (*key != '\0')
00675             key++;
00676     }
00677     if (des_setkey((char *) keybuf))
00678         return (NULL);
00679 
00680 #ifndef DISABLE_XDES
00681     if (*setting == _PASSWORD_EFMT1)
00682     {
00683         /*
00684          * "new"-style: setting - underscore, 4 bytes of count, 4 bytes of
00685          * salt key - unlimited characters
00686          */
00687         for (i = 1, count = 0L; i < 5; i++)
00688             count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
00689 
00690         for (i = 5, salt = 0L; i < 9; i++)
00691             salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
00692 
00693         while (*key)
00694         {
00695             /*
00696              * Encrypt the key with itself.
00697              */
00698             if (des_cipher((char *) keybuf, (char *) keybuf, 0L, 1))
00699                 return (NULL);
00700 
00701             /*
00702              * And XOR with the next 8 characters of the key.
00703              */
00704             q = (uint8 *) keybuf;
00705             while (q - (uint8 *) keybuf - 8 && *key)
00706                 *q++ ^= *key++ << 1;
00707 
00708             if (des_setkey((char *) keybuf))
00709                 return (NULL);
00710         }
00711         strncpy(output, setting, 9);
00712 
00713         /*
00714          * Double check that we weren't given a short setting. If we were, the
00715          * above code will probably have created weird values for count and
00716          * salt, but we don't really care. Just make sure the output string
00717          * doesn't have an extra NUL in it.
00718          */
00719         output[9] = '\0';
00720         p = output + strlen(output);
00721     }
00722     else
00723 #endif   /* !DISABLE_XDES */
00724     {
00725         /*
00726          * "old"-style: setting - 2 bytes of salt key - up to 8 characters
00727          */
00728         count = 25;
00729 
00730         salt = (ascii_to_bin(setting[1]) << 6)
00731             | ascii_to_bin(setting[0]);
00732 
00733         output[0] = setting[0];
00734 
00735         /*
00736          * If the encrypted password that the salt was extracted from is only
00737          * 1 character long, the salt will be corrupted.  We need to ensure
00738          * that the output string doesn't have an extra NUL in it!
00739          */
00740         output[1] = setting[1] ? setting[1] : output[0];
00741 
00742         p = output + 2;
00743     }
00744     setup_salt(salt);
00745 
00746     /*
00747      * Do it.
00748      */
00749     if (do_des(0L, 0L, &r0, &r1, count))
00750         return (NULL);
00751 
00752     /*
00753      * Now encode the result...
00754      */
00755     l = (r0 >> 8);
00756     *p++ = _crypt_a64[(l >> 18) & 0x3f];
00757     *p++ = _crypt_a64[(l >> 12) & 0x3f];
00758     *p++ = _crypt_a64[(l >> 6) & 0x3f];
00759     *p++ = _crypt_a64[l & 0x3f];
00760 
00761     l = (r0 << 16) | ((r1 >> 16) & 0xffff);
00762     *p++ = _crypt_a64[(l >> 18) & 0x3f];
00763     *p++ = _crypt_a64[(l >> 12) & 0x3f];
00764     *p++ = _crypt_a64[(l >> 6) & 0x3f];
00765     *p++ = _crypt_a64[l & 0x3f];
00766 
00767     l = r1 << 2;
00768     *p++ = _crypt_a64[(l >> 12) & 0x3f];
00769     *p++ = _crypt_a64[(l >> 6) & 0x3f];
00770     *p++ = _crypt_a64[l & 0x3f];
00771     *p = 0;
00772 
00773     return (output);
00774 }