LCOV - code coverage report
Current view: top level - contrib/pgcrypto - crypt-des.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 326 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 7 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * FreeSec: libcrypt for NetBSD
       3              :  *
       4              :  * contrib/pgcrypto/crypt-des.c
       5              :  *
       6              :  * Copyright (c) 1994 David Burren
       7              :  * All rights reserved.
       8              :  *
       9              :  * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
      10              :  *      this file should now *only* export crypt(), in order to make
      11              :  *      binaries of libcrypt exportable from the USA
      12              :  *
      13              :  * Adapted for FreeBSD-4.0 by Mark R V Murray
      14              :  *      this file should now *only* export px_crypt_des(), in order to make
      15              :  *      a module that can be optionally included in libcrypt.
      16              :  *
      17              :  * Redistribution and use in source and binary forms, with or without
      18              :  * modification, are permitted provided that the following conditions
      19              :  * are met:
      20              :  * 1. Redistributions of source code must retain the above copyright
      21              :  *        notice, this list of conditions and the following disclaimer.
      22              :  * 2. Redistributions in binary form must reproduce the above copyright
      23              :  *        notice, this list of conditions and the following disclaimer in the
      24              :  *        documentation and/or other materials provided with the distribution.
      25              :  * 3. Neither the name of the author nor the names of other contributors
      26              :  *        may be used to endorse or promote products derived from this software
      27              :  *        without specific prior written permission.
      28              :  *
      29              :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      30              :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      31              :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      32              :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      33              :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      34              :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      35              :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      36              :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      37              :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      38              :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      39              :  * SUCH DAMAGE.
      40              :  *
      41              :  * $FreeBSD: src/secure/lib/libcrypt/crypt-des.c,v 1.12 1999/09/20 12:39:20 markm Exp $
      42              :  *
      43              :  * This is an original implementation of the DES and the crypt(3) interfaces
      44              :  * by David Burren <davidb@werj.com.au>.
      45              :  *
      46              :  * An excellent reference on the underlying algorithm (and related
      47              :  * algorithms) is:
      48              :  *
      49              :  *      B. Schneier, Applied Cryptography: protocols, algorithms,
      50              :  *      and source code in C, John Wiley & Sons, 1994.
      51              :  *
      52              :  * Note that in that book's description of DES the lookups for the initial,
      53              :  * pbox, and final permutations are inverted (this has been brought to the
      54              :  * attention of the author).  A list of errata for this book has been
      55              :  * posted to the sci.crypt newsgroup by the author and is available for FTP.
      56              :  *
      57              :  * ARCHITECTURE ASSUMPTIONS:
      58              :  *      It is assumed that the 8-byte arrays passed by reference can be
      59              :  *      addressed as arrays of uint32's (ie. the CPU is not picky about
      60              :  *      alignment).
      61              :  */
      62              : 
      63              : #include "postgres.h"
      64              : #include "miscadmin.h"
      65              : #include "port/pg_bswap.h"
      66              : 
      67              : #include "px-crypt.h"
      68              : 
      69              : #define _PASSWORD_EFMT1 '_'
      70              : 
      71              : static const char _crypt_a64[] =
      72              : "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
      73              : 
      74              : static uint8 IP[64] = {
      75              :         58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
      76              :         62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
      77              :         57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
      78              :         61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
      79              : };
      80              : 
      81              : static uint8 inv_key_perm[64];
      82              : static uint8 u_key_perm[56];
      83              : static uint8 key_perm[56] = {
      84              :         57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
      85              :         10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
      86              :         63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
      87              :         14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
      88              : };
      89              : 
      90              : static uint8 key_shifts[16] = {
      91              :         1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
      92              : };
      93              : 
      94              : static uint8 inv_comp_perm[56];
      95              : static uint8 comp_perm[48] = {
      96              :         14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
      97              :         23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
      98              :         41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
      99              :         44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
     100              : };
     101              : 
     102              : /*
     103              :  *      No E box is used, as it's replaced by some ANDs, shifts, and ORs.
     104              :  */
     105              : 
     106              : static uint8 u_sbox[8][64];
     107              : static uint8 sbox[8][64] = {
     108              :         {
     109              :                 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
     110              :                 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
     111              :                 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
     112              :                 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
     113              :         },
     114              :         {
     115              :                 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
     116              :                 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
     117              :                 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
     118              :                 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
     119              :         },
     120              :         {
     121              :                 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
     122              :                 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
     123              :                 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
     124              :                 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
     125              :         },
     126              :         {
     127              :                 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
     128              :                 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
     129              :                 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
     130              :                 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
     131              :         },
     132              :         {
     133              :                 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
     134              :                 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
     135              :                 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
     136              :                 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
     137              :         },
     138              :         {
     139              :                 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
     140              :                 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
     141              :                 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
     142              :                 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
     143              :         },
     144              :         {
     145              :                 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
     146              :                 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
     147              :                 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
     148              :                 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
     149              :         },
     150              :         {
     151              :                 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
     152              :                 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
     153              :                 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
     154              :                 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
     155              :         }
     156              : };
     157              : 
     158              : static uint8 un_pbox[32];
     159              : static uint8 pbox[32] = {
     160              :         16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
     161              :         2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
     162              : };
     163              : 
     164              : static uint32 _crypt_bits32[32] =
     165              : {
     166              :         0x80000000, 0x40000000, 0x20000000, 0x10000000,
     167              :         0x08000000, 0x04000000, 0x02000000, 0x01000000,
     168              :         0x00800000, 0x00400000, 0x00200000, 0x00100000,
     169              :         0x00080000, 0x00040000, 0x00020000, 0x00010000,
     170              :         0x00008000, 0x00004000, 0x00002000, 0x00001000,
     171              :         0x00000800, 0x00000400, 0x00000200, 0x00000100,
     172              :         0x00000080, 0x00000040, 0x00000020, 0x00000010,
     173              :         0x00000008, 0x00000004, 0x00000002, 0x00000001
     174              : };
     175              : 
     176              : static uint8 _crypt_bits8[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
     177              : 
     178              : static uint32 saltbits;
     179              : static long old_salt;
     180              : static uint32 *bits28,
     181              :                    *bits24;
     182              : static uint8 init_perm[64],
     183              :                         final_perm[64];
     184              : static uint32 en_keysl[16],
     185              :                         en_keysr[16];
     186              : static uint32 de_keysl[16],
     187              :                         de_keysr[16];
     188              : static int      des_initialised = 0;
     189              : static uint8 m_sbox[4][4096];
     190              : static uint32 psbox[4][256];
     191              : static uint32 ip_maskl[8][256],
     192              :                         ip_maskr[8][256];
     193              : static uint32 fp_maskl[8][256],
     194              :                         fp_maskr[8][256];
     195              : static uint32 key_perm_maskl[8][128],
     196              :                         key_perm_maskr[8][128];
     197              : static uint32 comp_maskl[8][128],
     198              :                         comp_maskr[8][128];
     199              : static uint32 old_rawkey0,
     200              :                         old_rawkey1;
     201              : 
     202              : static inline int
     203            0 : ascii_to_bin(char ch)
     204              : {
     205            0 :         if (ch > 'z')
     206            0 :                 return 0;
     207            0 :         if (ch >= 'a')
     208            0 :                 return (ch - 'a' + 38);
     209            0 :         if (ch > 'Z')
     210            0 :                 return 0;
     211            0 :         if (ch >= 'A')
     212            0 :                 return (ch - 'A' + 12);
     213            0 :         if (ch > '9')
     214            0 :                 return 0;
     215            0 :         if (ch >= '.')
     216            0 :                 return (ch - '.');
     217            0 :         return 0;
     218            0 : }
     219              : 
     220              : static void
     221            0 : des_init(void)
     222              : {
     223            0 :         int                     i,
     224              :                                 j,
     225              :                                 b,
     226              :                                 k,
     227              :                                 inbit,
     228              :                                 obit;
     229            0 :         uint32     *p,
     230              :                            *il,
     231              :                            *ir,
     232              :                            *fl,
     233              :                            *fr;
     234              : 
     235            0 :         old_rawkey0 = old_rawkey1 = 0L;
     236            0 :         saltbits = 0L;
     237            0 :         old_salt = 0L;
     238            0 :         bits24 = (bits28 = _crypt_bits32 + 4) + 4;
     239              : 
     240              :         /*
     241              :          * Invert the S-boxes, reordering the input bits.
     242              :          */
     243            0 :         for (i = 0; i < 8; i++)
     244            0 :                 for (j = 0; j < 64; j++)
     245              :                 {
     246            0 :                         b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
     247            0 :                         u_sbox[i][j] = sbox[i][b];
     248            0 :                 }
     249              : 
     250              :         /*
     251              :          * Convert the inverted S-boxes into 4 arrays of 8 bits. Each will handle
     252              :          * 12 bits of the S-box input.
     253              :          */
     254            0 :         for (b = 0; b < 4; b++)
     255            0 :                 for (i = 0; i < 64; i++)
     256            0 :                         for (j = 0; j < 64; j++)
     257            0 :                                 m_sbox[b][(i << 6) | j] =
     258            0 :                                         (u_sbox[(b << 1)][i] << 4) |
     259            0 :                                         u_sbox[(b << 1) + 1][j];
     260              : 
     261              :         /*
     262              :          * Set up the initial & final permutations into a useful form, and
     263              :          * initialise the inverted key permutation.
     264              :          */
     265            0 :         for (i = 0; i < 64; i++)
     266              :         {
     267            0 :                 init_perm[final_perm[i] = IP[i] - 1] = i;
     268            0 :                 inv_key_perm[i] = 255;
     269            0 :         }
     270              : 
     271              :         /*
     272              :          * Invert the key permutation and initialise the inverted key compression
     273              :          * permutation.
     274              :          */
     275            0 :         for (i = 0; i < 56; i++)
     276              :         {
     277            0 :                 u_key_perm[i] = key_perm[i] - 1;
     278            0 :                 inv_key_perm[key_perm[i] - 1] = i;
     279            0 :                 inv_comp_perm[i] = 255;
     280            0 :         }
     281              : 
     282              :         /*
     283              :          * Invert the key compression permutation.
     284              :          */
     285            0 :         for (i = 0; i < 48; i++)
     286            0 :                 inv_comp_perm[comp_perm[i] - 1] = i;
     287              : 
     288              :         /*
     289              :          * Set up the OR-mask arrays for the initial and final permutations, and
     290              :          * for the key initial and compression permutations.
     291              :          */
     292            0 :         for (k = 0; k < 8; k++)
     293              :         {
     294            0 :                 for (i = 0; i < 256; i++)
     295              :                 {
     296            0 :                         *(il = &ip_maskl[k][i]) = 0L;
     297            0 :                         *(ir = &ip_maskr[k][i]) = 0L;
     298            0 :                         *(fl = &fp_maskl[k][i]) = 0L;
     299            0 :                         *(fr = &fp_maskr[k][i]) = 0L;
     300            0 :                         for (j = 0; j < 8; j++)
     301              :                         {
     302            0 :                                 inbit = 8 * k + j;
     303            0 :                                 if (i & _crypt_bits8[j])
     304              :                                 {
     305            0 :                                         if ((obit = init_perm[inbit]) < 32)
     306            0 :                                                 *il |= _crypt_bits32[obit];
     307              :                                         else
     308            0 :                                                 *ir |= _crypt_bits32[obit - 32];
     309            0 :                                         if ((obit = final_perm[inbit]) < 32)
     310            0 :                                                 *fl |= _crypt_bits32[obit];
     311              :                                         else
     312            0 :                                                 *fr |= _crypt_bits32[obit - 32];
     313            0 :                                 }
     314            0 :                         }
     315            0 :                 }
     316            0 :                 for (i = 0; i < 128; i++)
     317              :                 {
     318            0 :                         *(il = &key_perm_maskl[k][i]) = 0L;
     319            0 :                         *(ir = &key_perm_maskr[k][i]) = 0L;
     320            0 :                         for (j = 0; j < 7; j++)
     321              :                         {
     322            0 :                                 inbit = 8 * k + j;
     323            0 :                                 if (i & _crypt_bits8[j + 1])
     324              :                                 {
     325            0 :                                         if ((obit = inv_key_perm[inbit]) == 255)
     326            0 :                                                 continue;
     327            0 :                                         if (obit < 28)
     328            0 :                                                 *il |= bits28[obit];
     329              :                                         else
     330            0 :                                                 *ir |= bits28[obit - 28];
     331            0 :                                 }
     332            0 :                         }
     333            0 :                         *(il = &comp_maskl[k][i]) = 0L;
     334            0 :                         *(ir = &comp_maskr[k][i]) = 0L;
     335            0 :                         for (j = 0; j < 7; j++)
     336              :                         {
     337            0 :                                 inbit = 7 * k + j;
     338            0 :                                 if (i & _crypt_bits8[j + 1])
     339              :                                 {
     340            0 :                                         if ((obit = inv_comp_perm[inbit]) == 255)
     341            0 :                                                 continue;
     342            0 :                                         if (obit < 24)
     343            0 :                                                 *il |= bits24[obit];
     344              :                                         else
     345            0 :                                                 *ir |= bits24[obit - 24];
     346            0 :                                 }
     347            0 :                         }
     348            0 :                 }
     349            0 :         }
     350              : 
     351              :         /*
     352              :          * Invert the P-box permutation, and convert into OR-masks for handling
     353              :          * the output of the S-box arrays setup above.
     354              :          */
     355            0 :         for (i = 0; i < 32; i++)
     356            0 :                 un_pbox[pbox[i] - 1] = i;
     357              : 
     358            0 :         for (b = 0; b < 4; b++)
     359            0 :                 for (i = 0; i < 256; i++)
     360              :                 {
     361            0 :                         *(p = &psbox[b][i]) = 0L;
     362            0 :                         for (j = 0; j < 8; j++)
     363              :                         {
     364            0 :                                 if (i & _crypt_bits8[j])
     365            0 :                                         *p |= _crypt_bits32[un_pbox[8 * b + j]];
     366            0 :                         }
     367            0 :                 }
     368              : 
     369            0 :         des_initialised = 1;
     370            0 : }
     371              : 
     372              : static void
     373            0 : setup_salt(long salt)
     374              : {
     375            0 :         uint32          obit,
     376              :                                 saltbit;
     377            0 :         int                     i;
     378              : 
     379            0 :         if (salt == old_salt)
     380            0 :                 return;
     381            0 :         old_salt = salt;
     382              : 
     383            0 :         saltbits = 0L;
     384            0 :         saltbit = 1;
     385            0 :         obit = 0x800000;
     386            0 :         for (i = 0; i < 24; i++)
     387              :         {
     388            0 :                 if (salt & saltbit)
     389            0 :                         saltbits |= obit;
     390            0 :                 saltbit <<= 1;
     391            0 :                 obit >>= 1;
     392            0 :         }
     393            0 : }
     394              : 
     395              : static int
     396            0 : des_setkey(const char *key)
     397              : {
     398            0 :         uint32          k0,
     399              :                                 k1,
     400              :                                 rawkey0,
     401              :                                 rawkey1;
     402            0 :         int                     shifts,
     403              :                                 round;
     404              : 
     405            0 :         if (!des_initialised)
     406            0 :                 des_init();
     407              : 
     408            0 :         rawkey0 = pg_ntoh32(*(const uint32 *) key);
     409            0 :         rawkey1 = pg_ntoh32(*(const uint32 *) (key + 4));
     410              : 
     411            0 :         if ((rawkey0 | rawkey1)
     412            0 :                 && rawkey0 == old_rawkey0
     413            0 :                 && rawkey1 == old_rawkey1)
     414              :         {
     415              :                 /*
     416              :                  * Already setup for this key. This optimization fails on a zero key
     417              :                  * (which is weak and has bad parity anyway) in order to simplify the
     418              :                  * starting conditions.
     419              :                  */
     420            0 :                 return 0;
     421              :         }
     422            0 :         old_rawkey0 = rawkey0;
     423            0 :         old_rawkey1 = rawkey1;
     424              : 
     425              :         /*
     426              :          * Do key permutation and split into two 28-bit subkeys.
     427              :          */
     428            0 :         k0 = key_perm_maskl[0][rawkey0 >> 25]
     429            0 :                 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
     430            0 :                 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
     431            0 :                 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
     432            0 :                 | key_perm_maskl[4][rawkey1 >> 25]
     433            0 :                 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
     434            0 :                 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
     435            0 :                 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
     436            0 :         k1 = key_perm_maskr[0][rawkey0 >> 25]
     437            0 :                 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
     438            0 :                 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
     439            0 :                 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
     440            0 :                 | key_perm_maskr[4][rawkey1 >> 25]
     441            0 :                 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
     442            0 :                 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
     443            0 :                 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
     444              : 
     445              :         /*
     446              :          * Rotate subkeys and do compression permutation.
     447              :          */
     448            0 :         shifts = 0;
     449            0 :         for (round = 0; round < 16; round++)
     450              :         {
     451            0 :                 uint32          t0,
     452              :                                         t1;
     453              : 
     454            0 :                 shifts += key_shifts[round];
     455              : 
     456            0 :                 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
     457            0 :                 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
     458              : 
     459            0 :                 de_keysl[15 - round] =
     460            0 :                         en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
     461            0 :                         | comp_maskl[1][(t0 >> 14) & 0x7f]
     462            0 :                         | comp_maskl[2][(t0 >> 7) & 0x7f]
     463            0 :                         | comp_maskl[3][t0 & 0x7f]
     464            0 :                         | comp_maskl[4][(t1 >> 21) & 0x7f]
     465            0 :                         | comp_maskl[5][(t1 >> 14) & 0x7f]
     466            0 :                         | comp_maskl[6][(t1 >> 7) & 0x7f]
     467            0 :                         | comp_maskl[7][t1 & 0x7f];
     468              : 
     469            0 :                 de_keysr[15 - round] =
     470            0 :                         en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
     471            0 :                         | comp_maskr[1][(t0 >> 14) & 0x7f]
     472            0 :                         | comp_maskr[2][(t0 >> 7) & 0x7f]
     473            0 :                         | comp_maskr[3][t0 & 0x7f]
     474            0 :                         | comp_maskr[4][(t1 >> 21) & 0x7f]
     475            0 :                         | comp_maskr[5][(t1 >> 14) & 0x7f]
     476            0 :                         | comp_maskr[6][(t1 >> 7) & 0x7f]
     477            0 :                         | comp_maskr[7][t1 & 0x7f];
     478            0 :         }
     479            0 :         return 0;
     480            0 : }
     481              : 
     482              : static int
     483            0 : do_des(uint32 l_in, uint32 r_in, uint32 *l_out, uint32 *r_out, int count)
     484              : {
     485              :         /*
     486              :          * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
     487              :          */
     488            0 :         uint32          l,
     489              :                                 r,
     490              :                            *kl,
     491              :                            *kr,
     492              :                            *kl1,
     493              :                            *kr1;
     494            0 :         uint32          f,
     495              :                                 r48l,
     496              :                                 r48r;
     497            0 :         int                     round;
     498              : 
     499            0 :         if (count == 0)
     500            0 :                 return 1;
     501            0 :         else if (count > 0)
     502              :         {
     503              :                 /*
     504              :                  * Encrypting
     505              :                  */
     506            0 :                 kl1 = en_keysl;
     507            0 :                 kr1 = en_keysr;
     508            0 :         }
     509              :         else
     510              :         {
     511              :                 /*
     512              :                  * Decrypting
     513              :                  */
     514            0 :                 count = -count;
     515            0 :                 kl1 = de_keysl;
     516            0 :                 kr1 = de_keysr;
     517              :         }
     518              : 
     519              :         /*
     520              :          * Do initial permutation (IP).
     521              :          */
     522            0 :         l = ip_maskl[0][l_in >> 24]
     523            0 :                 | ip_maskl[1][(l_in >> 16) & 0xff]
     524            0 :                 | ip_maskl[2][(l_in >> 8) & 0xff]
     525            0 :                 | ip_maskl[3][l_in & 0xff]
     526            0 :                 | ip_maskl[4][r_in >> 24]
     527            0 :                 | ip_maskl[5][(r_in >> 16) & 0xff]
     528            0 :                 | ip_maskl[6][(r_in >> 8) & 0xff]
     529            0 :                 | ip_maskl[7][r_in & 0xff];
     530            0 :         r = ip_maskr[0][l_in >> 24]
     531            0 :                 | ip_maskr[1][(l_in >> 16) & 0xff]
     532            0 :                 | ip_maskr[2][(l_in >> 8) & 0xff]
     533            0 :                 | ip_maskr[3][l_in & 0xff]
     534            0 :                 | ip_maskr[4][r_in >> 24]
     535            0 :                 | ip_maskr[5][(r_in >> 16) & 0xff]
     536            0 :                 | ip_maskr[6][(r_in >> 8) & 0xff]
     537            0 :                 | ip_maskr[7][r_in & 0xff];
     538              : 
     539            0 :         while (count--)
     540              :         {
     541            0 :                 CHECK_FOR_INTERRUPTS();
     542              : 
     543              :                 /*
     544              :                  * Do each round.
     545              :                  */
     546            0 :                 kl = kl1;
     547            0 :                 kr = kr1;
     548            0 :                 round = 16;
     549            0 :                 while (round--)
     550              :                 {
     551              :                         /*
     552              :                          * Expand R to 48 bits (simulate the E-box).
     553              :                          */
     554            0 :                         r48l = ((r & 0x00000001) << 23)
     555            0 :                                 | ((r & 0xf8000000) >> 9)
     556            0 :                                 | ((r & 0x1f800000) >> 11)
     557            0 :                                 | ((r & 0x01f80000) >> 13)
     558            0 :                                 | ((r & 0x001f8000) >> 15);
     559              : 
     560            0 :                         r48r = ((r & 0x0001f800) << 7)
     561            0 :                                 | ((r & 0x00001f80) << 5)
     562            0 :                                 | ((r & 0x000001f8) << 3)
     563            0 :                                 | ((r & 0x0000001f) << 1)
     564            0 :                                 | ((r & 0x80000000) >> 31);
     565              : 
     566              :                         /*
     567              :                          * Do salting for crypt() and friends, and XOR with the permuted
     568              :                          * key.
     569              :                          */
     570            0 :                         f = (r48l ^ r48r) & saltbits;
     571            0 :                         r48l ^= f ^ *kl++;
     572            0 :                         r48r ^= f ^ *kr++;
     573              : 
     574              :                         /*
     575              :                          * Do sbox lookups (which shrink it back to 32 bits) and do the
     576              :                          * pbox permutation at the same time.
     577              :                          */
     578            0 :                         f = psbox[0][m_sbox[0][r48l >> 12]]
     579            0 :                                 | psbox[1][m_sbox[1][r48l & 0xfff]]
     580            0 :                                 | psbox[2][m_sbox[2][r48r >> 12]]
     581            0 :                                 | psbox[3][m_sbox[3][r48r & 0xfff]];
     582              : 
     583              :                         /*
     584              :                          * Now that we've permuted things, complete f().
     585              :                          */
     586            0 :                         f ^= l;
     587            0 :                         l = r;
     588            0 :                         r = f;
     589              :                 }
     590            0 :                 r = l;
     591            0 :                 l = f;
     592              :         }
     593              : 
     594              :         /*
     595              :          * Do final permutation (inverse of IP).
     596              :          */
     597            0 :         *l_out = fp_maskl[0][l >> 24]
     598            0 :                 | fp_maskl[1][(l >> 16) & 0xff]
     599            0 :                 | fp_maskl[2][(l >> 8) & 0xff]
     600            0 :                 | fp_maskl[3][l & 0xff]
     601            0 :                 | fp_maskl[4][r >> 24]
     602            0 :                 | fp_maskl[5][(r >> 16) & 0xff]
     603            0 :                 | fp_maskl[6][(r >> 8) & 0xff]
     604            0 :                 | fp_maskl[7][r & 0xff];
     605            0 :         *r_out = fp_maskr[0][l >> 24]
     606            0 :                 | fp_maskr[1][(l >> 16) & 0xff]
     607            0 :                 | fp_maskr[2][(l >> 8) & 0xff]
     608            0 :                 | fp_maskr[3][l & 0xff]
     609            0 :                 | fp_maskr[4][r >> 24]
     610            0 :                 | fp_maskr[5][(r >> 16) & 0xff]
     611            0 :                 | fp_maskr[6][(r >> 8) & 0xff]
     612            0 :                 | fp_maskr[7][r & 0xff];
     613            0 :         return 0;
     614            0 : }
     615              : 
     616              : static int
     617            0 : des_cipher(const char *in, char *out, long salt, int count)
     618              : {
     619            0 :         uint32          buffer[2];
     620            0 :         uint32          l_out,
     621              :                                 r_out,
     622              :                                 rawl,
     623              :                                 rawr;
     624            0 :         int                     retval;
     625              : 
     626            0 :         if (!des_initialised)
     627            0 :                 des_init();
     628              : 
     629            0 :         setup_salt(salt);
     630              : 
     631              :         /* copy data to avoid assuming input is word-aligned */
     632            0 :         memcpy(buffer, in, sizeof(buffer));
     633              : 
     634            0 :         rawl = pg_ntoh32(buffer[0]);
     635            0 :         rawr = pg_ntoh32(buffer[1]);
     636              : 
     637            0 :         retval = do_des(rawl, rawr, &l_out, &r_out, count);
     638            0 :         if (retval)
     639            0 :                 return retval;
     640              : 
     641            0 :         buffer[0] = pg_hton32(l_out);
     642            0 :         buffer[1] = pg_hton32(r_out);
     643              : 
     644              :         /* copy data to avoid assuming output is word-aligned */
     645            0 :         memcpy(out, buffer, sizeof(buffer));
     646              : 
     647            0 :         return retval;
     648            0 : }
     649              : 
     650              : char *
     651            0 : px_crypt_des(const char *key, const char *setting)
     652              : {
     653            0 :         int                     i;
     654            0 :         uint32          count,
     655              :                                 salt,
     656              :                                 l,
     657              :                                 r0,
     658              :                                 r1,
     659              :                                 keybuf[2];
     660            0 :         char       *p;
     661            0 :         uint8      *q;
     662              :         static char output[21];
     663              : 
     664            0 :         if (!des_initialised)
     665            0 :                 des_init();
     666              : 
     667              : 
     668              :         /*
     669              :          * Copy the key, shifting each character up by one bit and padding with
     670              :          * zeros.
     671              :          */
     672            0 :         q = (uint8 *) keybuf;
     673            0 :         while (q - (uint8 *) keybuf - 8)
     674              :         {
     675            0 :                 *q++ = *key << 1;
     676            0 :                 if (*key != '\0')
     677            0 :                         key++;
     678              :         }
     679            0 :         if (des_setkey((char *) keybuf))
     680            0 :                 return NULL;
     681              : 
     682              : #ifndef DISABLE_XDES
     683            0 :         if (*setting == _PASSWORD_EFMT1)
     684              :         {
     685              :                 /*
     686              :                  * "new"-style: setting must be a 9-character (underscore, then 4
     687              :                  * bytes of count, then 4 bytes of salt) string. See CRYPT(3) under
     688              :                  * the "Extended crypt" heading for further details.
     689              :                  *
     690              :                  * Unlimited characters of the input key are used. This is known as
     691              :                  * the "Extended crypt" DES method.
     692              :                  *
     693              :                  */
     694            0 :                 if (strlen(setting) < 9)
     695            0 :                         ereport(ERROR,
     696              :                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     697              :                                          errmsg("invalid salt")));
     698              : 
     699            0 :                 for (i = 1, count = 0L; i < 5; i++)
     700            0 :                         count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
     701              : 
     702            0 :                 for (i = 5, salt = 0L; i < 9; i++)
     703            0 :                         salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
     704              : 
     705            0 :                 while (*key)
     706              :                 {
     707              :                         /*
     708              :                          * Encrypt the key with itself.
     709              :                          */
     710            0 :                         if (des_cipher((char *) keybuf, (char *) keybuf, 0L, 1))
     711            0 :                                 return NULL;
     712              : 
     713              :                         /*
     714              :                          * And XOR with the next 8 characters of the key.
     715              :                          */
     716            0 :                         q = (uint8 *) keybuf;
     717            0 :                         while (q - (uint8 *) keybuf - 8 && *key)
     718            0 :                                 *q++ ^= *key++ << 1;
     719              : 
     720            0 :                         if (des_setkey((char *) keybuf))
     721            0 :                                 return NULL;
     722              :                 }
     723            0 :                 strlcpy(output, setting, 10);
     724              : 
     725              :                 /*
     726              :                  * Double check that we weren't given a short setting. If we were, the
     727              :                  * above code will probably have created weird values for count and
     728              :                  * salt, but we don't really care. Just make sure the output string
     729              :                  * doesn't have an extra NUL in it.
     730              :                  */
     731            0 :                 p = output + strlen(output);
     732            0 :         }
     733              :         else
     734              : #endif                                                  /* !DISABLE_XDES */
     735              :         {
     736              :                 /*
     737              :                  * "old"-style: setting - 2 bytes of salt key - only up to the first 8
     738              :                  * characters of the input key are used.
     739              :                  */
     740            0 :                 count = 25;
     741              : 
     742            0 :                 if (strlen(setting) < 2)
     743            0 :                         ereport(ERROR,
     744              :                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     745              :                                          errmsg("invalid salt")));
     746              : 
     747            0 :                 salt = (ascii_to_bin(setting[1]) << 6)
     748            0 :                         | ascii_to_bin(setting[0]);
     749              : 
     750            0 :                 output[0] = setting[0];
     751              : 
     752              :                 /*
     753              :                  * If the encrypted password that the salt was extracted from is only
     754              :                  * 1 character long, the salt will be corrupted.  We need to ensure
     755              :                  * that the output string doesn't have an extra NUL in it!
     756              :                  */
     757            0 :                 output[1] = setting[1] ? setting[1] : output[0];
     758              : 
     759            0 :                 p = output + 2;
     760              :         }
     761            0 :         setup_salt(salt);
     762              : 
     763              :         /*
     764              :          * Do it.
     765              :          */
     766            0 :         if (do_des(0L, 0L, &r0, &r1, count))
     767            0 :                 return NULL;
     768              : 
     769              :         /*
     770              :          * Now encode the result...
     771              :          */
     772            0 :         l = (r0 >> 8);
     773            0 :         *p++ = _crypt_a64[(l >> 18) & 0x3f];
     774            0 :         *p++ = _crypt_a64[(l >> 12) & 0x3f];
     775            0 :         *p++ = _crypt_a64[(l >> 6) & 0x3f];
     776            0 :         *p++ = _crypt_a64[l & 0x3f];
     777              : 
     778            0 :         l = (r0 << 16) | ((r1 >> 16) & 0xffff);
     779            0 :         *p++ = _crypt_a64[(l >> 18) & 0x3f];
     780            0 :         *p++ = _crypt_a64[(l >> 12) & 0x3f];
     781            0 :         *p++ = _crypt_a64[(l >> 6) & 0x3f];
     782            0 :         *p++ = _crypt_a64[l & 0x3f];
     783              : 
     784            0 :         l = r1 << 2;
     785            0 :         *p++ = _crypt_a64[(l >> 12) & 0x3f];
     786            0 :         *p++ = _crypt_a64[(l >> 6) & 0x3f];
     787            0 :         *p++ = _crypt_a64[l & 0x3f];
     788            0 :         *p = 0;
     789              : 
     790            0 :         return output;
     791            0 : }
        

Generated by: LCOV version 2.3.2-1