LCOV - code coverage report
Current view: top level - contrib/pgcrypto - crypt-des.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 95.4 % 285 272
Test Date: 2026-03-04 08:14:57 Functions: 100.0 % 7 7
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           72 : ascii_to_bin(char ch)
     204              : {
     205           72 :     if (ch > 'z')
     206            0 :         return 0;
     207           72 :     if (ch >= 'a')
     208           15 :         return (ch - 'a' + 38);
     209           57 :     if (ch > 'Z')
     210            0 :         return 0;
     211           57 :     if (ch >= 'A')
     212           11 :         return (ch - 'A' + 12);
     213           46 :     if (ch > '9')
     214            0 :         return 0;
     215           46 :     if (ch >= '.')
     216           33 :         return (ch - '.');
     217           13 :     return 0;
     218              : }
     219              : 
     220              : static void
     221            2 : des_init(void)
     222              : {
     223              :     int         i,
     224              :                 j,
     225              :                 b,
     226              :                 k,
     227              :                 inbit,
     228              :                 obit;
     229              :     uint32     *p,
     230              :                *il,
     231              :                *ir,
     232              :                *fl,
     233              :                *fr;
     234              : 
     235            2 :     old_rawkey0 = old_rawkey1 = 0L;
     236            2 :     saltbits = 0L;
     237            2 :     old_salt = 0L;
     238            2 :     bits24 = (bits28 = _crypt_bits32 + 4) + 4;
     239              : 
     240              :     /*
     241              :      * Invert the S-boxes, reordering the input bits.
     242              :      */
     243           18 :     for (i = 0; i < 8; i++)
     244         1040 :         for (j = 0; j < 64; j++)
     245              :         {
     246         1024 :             b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
     247         1024 :             u_sbox[i][j] = sbox[i][b];
     248              :         }
     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           10 :     for (b = 0; b < 4; b++)
     255          520 :         for (i = 0; i < 64; i++)
     256        33280 :             for (j = 0; j < 64; j++)
     257        32768 :                 m_sbox[b][(i << 6) | j] =
     258        32768 :                     (u_sbox[(b << 1)][i] << 4) |
     259        32768 :                     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          130 :     for (i = 0; i < 64; i++)
     266              :     {
     267          128 :         init_perm[final_perm[i] = IP[i] - 1] = i;
     268          128 :         inv_key_perm[i] = 255;
     269              :     }
     270              : 
     271              :     /*
     272              :      * Invert the key permutation and initialise the inverted key compression
     273              :      * permutation.
     274              :      */
     275          114 :     for (i = 0; i < 56; i++)
     276              :     {
     277          112 :         u_key_perm[i] = key_perm[i] - 1;
     278          112 :         inv_key_perm[key_perm[i] - 1] = i;
     279          112 :         inv_comp_perm[i] = 255;
     280              :     }
     281              : 
     282              :     /*
     283              :      * Invert the key compression permutation.
     284              :      */
     285           98 :     for (i = 0; i < 48; i++)
     286           96 :         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           18 :     for (k = 0; k < 8; k++)
     293              :     {
     294         4112 :         for (i = 0; i < 256; i++)
     295              :         {
     296         4096 :             *(il = &ip_maskl[k][i]) = 0L;
     297         4096 :             *(ir = &ip_maskr[k][i]) = 0L;
     298         4096 :             *(fl = &fp_maskl[k][i]) = 0L;
     299         4096 :             *(fr = &fp_maskr[k][i]) = 0L;
     300        36864 :             for (j = 0; j < 8; j++)
     301              :             {
     302        32768 :                 inbit = 8 * k + j;
     303        32768 :                 if (i & _crypt_bits8[j])
     304              :                 {
     305        16384 :                     if ((obit = init_perm[inbit]) < 32)
     306         8192 :                         *il |= _crypt_bits32[obit];
     307              :                     else
     308         8192 :                         *ir |= _crypt_bits32[obit - 32];
     309        16384 :                     if ((obit = final_perm[inbit]) < 32)
     310         8192 :                         *fl |= _crypt_bits32[obit];
     311              :                     else
     312         8192 :                         *fr |= _crypt_bits32[obit - 32];
     313              :                 }
     314              :             }
     315              :         }
     316         2064 :         for (i = 0; i < 128; i++)
     317              :         {
     318         2048 :             *(il = &key_perm_maskl[k][i]) = 0L;
     319         2048 :             *(ir = &key_perm_maskr[k][i]) = 0L;
     320        16384 :             for (j = 0; j < 7; j++)
     321              :             {
     322        14336 :                 inbit = 8 * k + j;
     323        14336 :                 if (i & _crypt_bits8[j + 1])
     324              :                 {
     325         7168 :                     if ((obit = inv_key_perm[inbit]) == 255)
     326            0 :                         continue;
     327         7168 :                     if (obit < 28)
     328         3584 :                         *il |= bits28[obit];
     329              :                     else
     330         3584 :                         *ir |= bits28[obit - 28];
     331              :                 }
     332              :             }
     333         2048 :             *(il = &comp_maskl[k][i]) = 0L;
     334         2048 :             *(ir = &comp_maskr[k][i]) = 0L;
     335        16384 :             for (j = 0; j < 7; j++)
     336              :             {
     337        14336 :                 inbit = 7 * k + j;
     338        14336 :                 if (i & _crypt_bits8[j + 1])
     339              :                 {
     340         7168 :                     if ((obit = inv_comp_perm[inbit]) == 255)
     341         1024 :                         continue;
     342         6144 :                     if (obit < 24)
     343         3072 :                         *il |= bits24[obit];
     344              :                     else
     345         3072 :                         *ir |= bits24[obit - 24];
     346              :                 }
     347              :             }
     348              :         }
     349              :     }
     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           66 :     for (i = 0; i < 32; i++)
     356           64 :         un_pbox[pbox[i] - 1] = i;
     357              : 
     358           10 :     for (b = 0; b < 4; b++)
     359         2056 :         for (i = 0; i < 256; i++)
     360              :         {
     361         2048 :             *(p = &psbox[b][i]) = 0L;
     362        18432 :             for (j = 0; j < 8; j++)
     363              :             {
     364        16384 :                 if (i & _crypt_bits8[j])
     365         8192 :                     *p |= _crypt_bits32[un_pbox[8 * b + j]];
     366              :             }
     367              :         }
     368              : 
     369            2 :     des_initialised = 1;
     370            2 : }
     371              : 
     372              : static void
     373           13 : setup_salt(long salt)
     374              : {
     375              :     uint32      obit,
     376              :                 saltbit;
     377              :     int         i;
     378              : 
     379           13 :     if (salt == old_salt)
     380            6 :         return;
     381            7 :     old_salt = salt;
     382              : 
     383            7 :     saltbits = 0L;
     384            7 :     saltbit = 1;
     385            7 :     obit = 0x800000;
     386          175 :     for (i = 0; i < 24; i++)
     387              :     {
     388          168 :         if (salt & saltbit)
     389           52 :             saltbits |= obit;
     390          168 :         saltbit <<= 1;
     391          168 :         obit >>= 1;
     392              :     }
     393              : }
     394              : 
     395              : static int
     396           15 : des_setkey(const char *key)
     397              : {
     398              :     uint32      k0,
     399              :                 k1,
     400              :                 rawkey0,
     401              :                 rawkey1;
     402              :     int         shifts,
     403              :                 round;
     404              : 
     405           15 :     if (!des_initialised)
     406            0 :         des_init();
     407              : 
     408           15 :     rawkey0 = pg_ntoh32(*(const uint32 *) key);
     409           15 :     rawkey1 = pg_ntoh32(*(const uint32 *) (key + 4));
     410              : 
     411           15 :     if ((rawkey0 | rawkey1)
     412           13 :         && rawkey0 == old_rawkey0
     413            6 :         && 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            6 :         return 0;
     421              :     }
     422            9 :     old_rawkey0 = rawkey0;
     423            9 :     old_rawkey1 = rawkey1;
     424              : 
     425              :     /*
     426              :      * Do key permutation and split into two 28-bit subkeys.
     427              :      */
     428            9 :     k0 = key_perm_maskl[0][rawkey0 >> 25]
     429            9 :         | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
     430            9 :         | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
     431            9 :         | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
     432            9 :         | key_perm_maskl[4][rawkey1 >> 25]
     433            9 :         | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
     434            9 :         | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
     435            9 :         | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
     436            9 :     k1 = key_perm_maskr[0][rawkey0 >> 25]
     437            9 :         | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
     438            9 :         | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
     439            9 :         | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
     440            9 :         | key_perm_maskr[4][rawkey1 >> 25]
     441            9 :         | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
     442            9 :         | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
     443            9 :         | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
     444              : 
     445              :     /*
     446              :      * Rotate subkeys and do compression permutation.
     447              :      */
     448            9 :     shifts = 0;
     449          153 :     for (round = 0; round < 16; round++)
     450              :     {
     451              :         uint32      t0,
     452              :                     t1;
     453              : 
     454          144 :         shifts += key_shifts[round];
     455              : 
     456          144 :         t0 = (k0 << shifts) | (k0 >> (28 - shifts));
     457          144 :         t1 = (k1 << shifts) | (k1 >> (28 - shifts));
     458              : 
     459          144 :         de_keysl[15 - round] =
     460          144 :             en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
     461          144 :             | comp_maskl[1][(t0 >> 14) & 0x7f]
     462          144 :             | comp_maskl[2][(t0 >> 7) & 0x7f]
     463          144 :             | comp_maskl[3][t0 & 0x7f]
     464          144 :             | comp_maskl[4][(t1 >> 21) & 0x7f]
     465          144 :             | comp_maskl[5][(t1 >> 14) & 0x7f]
     466          144 :             | comp_maskl[6][(t1 >> 7) & 0x7f]
     467          144 :             | comp_maskl[7][t1 & 0x7f];
     468              : 
     469          144 :         de_keysr[15 - round] =
     470          144 :             en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
     471          144 :             | comp_maskr[1][(t0 >> 14) & 0x7f]
     472          144 :             | comp_maskr[2][(t0 >> 7) & 0x7f]
     473          144 :             | comp_maskr[3][t0 & 0x7f]
     474          144 :             | comp_maskr[4][(t1 >> 21) & 0x7f]
     475          144 :             | comp_maskr[5][(t1 >> 14) & 0x7f]
     476          144 :             | comp_maskr[6][(t1 >> 7) & 0x7f]
     477          144 :             | comp_maskr[7][t1 & 0x7f];
     478              :     }
     479            9 :     return 0;
     480              : }
     481              : 
     482              : static int
     483           13 : 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              :     uint32      l,
     489              :                 r,
     490              :                *kl,
     491              :                *kr,
     492              :                *kl1,
     493              :                *kr1;
     494              :     uint32      f,
     495              :                 r48l,
     496              :                 r48r;
     497              :     int         round;
     498              : 
     499           13 :     if (count == 0)
     500            2 :         return 1;
     501           11 :     else if (count > 0)
     502              :     {
     503              :         /*
     504              :          * Encrypting
     505              :          */
     506           11 :         kl1 = en_keysl;
     507           11 :         kr1 = en_keysr;
     508              :     }
     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           11 :     l = ip_maskl[0][l_in >> 24]
     523           11 :         | ip_maskl[1][(l_in >> 16) & 0xff]
     524           11 :         | ip_maskl[2][(l_in >> 8) & 0xff]
     525           11 :         | ip_maskl[3][l_in & 0xff]
     526           11 :         | ip_maskl[4][r_in >> 24]
     527           11 :         | ip_maskl[5][(r_in >> 16) & 0xff]
     528           11 :         | ip_maskl[6][(r_in >> 8) & 0xff]
     529           11 :         | ip_maskl[7][r_in & 0xff];
     530           11 :     r = ip_maskr[0][l_in >> 24]
     531           11 :         | ip_maskr[1][(l_in >> 16) & 0xff]
     532           11 :         | ip_maskr[2][(l_in >> 8) & 0xff]
     533           11 :         | ip_maskr[3][l_in & 0xff]
     534           11 :         | ip_maskr[4][r_in >> 24]
     535           11 :         | ip_maskr[5][(r_in >> 16) & 0xff]
     536           11 :         | ip_maskr[6][(r_in >> 8) & 0xff]
     537           11 :         | ip_maskr[7][r_in & 0xff];
     538              : 
     539         4290 :     while (count--)
     540              :     {
     541         4279 :         CHECK_FOR_INTERRUPTS();
     542              : 
     543              :         /*
     544              :          * Do each round.
     545              :          */
     546         4279 :         kl = kl1;
     547         4279 :         kr = kr1;
     548         4279 :         round = 16;
     549        72743 :         while (round--)
     550              :         {
     551              :             /*
     552              :              * Expand R to 48 bits (simulate the E-box).
     553              :              */
     554        68464 :             r48l = ((r & 0x00000001) << 23)
     555        68464 :                 | ((r & 0xf8000000) >> 9)
     556        68464 :                 | ((r & 0x1f800000) >> 11)
     557        68464 :                 | ((r & 0x01f80000) >> 13)
     558        68464 :                 | ((r & 0x001f8000) >> 15);
     559              : 
     560        68464 :             r48r = ((r & 0x0001f800) << 7)
     561        68464 :                 | ((r & 0x00001f80) << 5)
     562        68464 :                 | ((r & 0x000001f8) << 3)
     563        68464 :                 | ((r & 0x0000001f) << 1)
     564        68464 :                 | ((r & 0x80000000) >> 31);
     565              : 
     566              :             /*
     567              :              * Do salting for crypt() and friends, and XOR with the permuted
     568              :              * key.
     569              :              */
     570        68464 :             f = (r48l ^ r48r) & saltbits;
     571        68464 :             r48l ^= f ^ *kl++;
     572        68464 :             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        68464 :             f = psbox[0][m_sbox[0][r48l >> 12]]
     579        68464 :                 | psbox[1][m_sbox[1][r48l & 0xfff]]
     580        68464 :                 | psbox[2][m_sbox[2][r48r >> 12]]
     581        68464 :                 | psbox[3][m_sbox[3][r48r & 0xfff]];
     582              : 
     583              :             /*
     584              :              * Now that we've permuted things, complete f().
     585              :              */
     586        68464 :             f ^= l;
     587        68464 :             l = r;
     588        68464 :             r = f;
     589              :         }
     590         4279 :         r = l;
     591         4279 :         l = f;
     592              :     }
     593              : 
     594              :     /*
     595              :      * Do final permutation (inverse of IP).
     596              :      */
     597           11 :     *l_out = fp_maskl[0][l >> 24]
     598           11 :         | fp_maskl[1][(l >> 16) & 0xff]
     599           11 :         | fp_maskl[2][(l >> 8) & 0xff]
     600           11 :         | fp_maskl[3][l & 0xff]
     601           11 :         | fp_maskl[4][r >> 24]
     602           11 :         | fp_maskl[5][(r >> 16) & 0xff]
     603           11 :         | fp_maskl[6][(r >> 8) & 0xff]
     604           11 :         | fp_maskl[7][r & 0xff];
     605           11 :     *r_out = fp_maskr[0][l >> 24]
     606           11 :         | fp_maskr[1][(l >> 16) & 0xff]
     607           11 :         | fp_maskr[2][(l >> 8) & 0xff]
     608           11 :         | fp_maskr[3][l & 0xff]
     609           11 :         | fp_maskr[4][r >> 24]
     610           11 :         | fp_maskr[5][(r >> 16) & 0xff]
     611           11 :         | fp_maskr[6][(r >> 8) & 0xff]
     612           11 :         | fp_maskr[7][r & 0xff];
     613           11 :     return 0;
     614              : }
     615              : 
     616              : static int
     617            1 : des_cipher(const char *in, char *out, long salt, int count)
     618              : {
     619              :     uint32      buffer[2];
     620              :     uint32      l_out,
     621              :                 r_out,
     622              :                 rawl,
     623              :                 rawr;
     624              :     int         retval;
     625              : 
     626            1 :     if (!des_initialised)
     627            0 :         des_init();
     628              : 
     629            1 :     setup_salt(salt);
     630              : 
     631              :     /* copy data to avoid assuming input is word-aligned */
     632            1 :     memcpy(buffer, in, sizeof(buffer));
     633              : 
     634            1 :     rawl = pg_ntoh32(buffer[0]);
     635            1 :     rawr = pg_ntoh32(buffer[1]);
     636              : 
     637            1 :     retval = do_des(rawl, rawr, &l_out, &r_out, count);
     638            1 :     if (retval)
     639            0 :         return retval;
     640              : 
     641            1 :     buffer[0] = pg_hton32(l_out);
     642            1 :     buffer[1] = pg_hton32(r_out);
     643              : 
     644              :     /* copy data to avoid assuming output is word-aligned */
     645            1 :     memcpy(out, buffer, sizeof(buffer));
     646              : 
     647            1 :     return retval;
     648              : }
     649              : 
     650              : char *
     651           14 : px_crypt_des(const char *key, const char *setting)
     652              : {
     653              :     int         i;
     654              :     uint32      count,
     655              :                 salt,
     656              :                 l,
     657              :                 r0,
     658              :                 r1,
     659              :                 keybuf[2];
     660              :     char       *p;
     661              :     uint8      *q;
     662              :     static char output[21];
     663              : 
     664           14 :     if (!des_initialised)
     665            2 :         des_init();
     666              : 
     667              : 
     668              :     /*
     669              :      * Copy the key, shifting each character up by one bit and padding with
     670              :      * zeros.
     671              :      */
     672           14 :     q = (uint8 *) keybuf;
     673          126 :     while (q - (uint8 *) keybuf - 8)
     674              :     {
     675          112 :         *q++ = *key << 1;
     676          112 :         if (*key != '\0')
     677           84 :             key++;
     678              :     }
     679           14 :     if (des_setkey((char *) keybuf))
     680            0 :         return NULL;
     681              : 
     682              : #ifndef DISABLE_XDES
     683           14 :     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            9 :         if (strlen(setting) < 9)
     695            1 :             ereport(ERROR,
     696              :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     697              :                      errmsg("invalid salt")));
     698              : 
     699           40 :         for (i = 1, count = 0L; i < 5; i++)
     700           32 :             count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
     701              : 
     702           40 :         for (i = 5, salt = 0L; i < 9; i++)
     703           32 :             salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
     704              : 
     705            9 :         while (*key)
     706              :         {
     707              :             /*
     708              :              * Encrypt the key with itself.
     709              :              */
     710            1 :             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            1 :             q = (uint8 *) keybuf;
     717            9 :             while (q - (uint8 *) keybuf - 8 && *key)
     718            8 :                 *q++ ^= *key++ << 1;
     719              : 
     720            1 :             if (des_setkey((char *) keybuf))
     721            0 :                 return NULL;
     722              :         }
     723            8 :         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            8 :         p = output + strlen(output);
     732              :     }
     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            5 :         count = 25;
     741              : 
     742            5 :         if (strlen(setting) < 2)
     743            1 :             ereport(ERROR,
     744              :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     745              :                      errmsg("invalid salt")));
     746              : 
     747            4 :         salt = (ascii_to_bin(setting[1]) << 6)
     748            4 :             | ascii_to_bin(setting[0]);
     749              : 
     750            4 :         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            4 :         output[1] = setting[1] ? setting[1] : output[0];
     758              : 
     759            4 :         p = output + 2;
     760              :     }
     761           12 :     setup_salt(salt);
     762              : 
     763              :     /*
     764              :      * Do it.
     765              :      */
     766           12 :     if (do_des(0L, 0L, &r0, &r1, count))
     767            2 :         return NULL;
     768              : 
     769              :     /*
     770              :      * Now encode the result...
     771              :      */
     772           10 :     l = (r0 >> 8);
     773           10 :     *p++ = _crypt_a64[(l >> 18) & 0x3f];
     774           10 :     *p++ = _crypt_a64[(l >> 12) & 0x3f];
     775           10 :     *p++ = _crypt_a64[(l >> 6) & 0x3f];
     776           10 :     *p++ = _crypt_a64[l & 0x3f];
     777              : 
     778           10 :     l = (r0 << 16) | ((r1 >> 16) & 0xffff);
     779           10 :     *p++ = _crypt_a64[(l >> 18) & 0x3f];
     780           10 :     *p++ = _crypt_a64[(l >> 12) & 0x3f];
     781           10 :     *p++ = _crypt_a64[(l >> 6) & 0x3f];
     782           10 :     *p++ = _crypt_a64[l & 0x3f];
     783              : 
     784           10 :     l = r1 << 2;
     785           10 :     *p++ = _crypt_a64[(l >> 12) & 0x3f];
     786           10 :     *p++ = _crypt_a64[(l >> 6) & 0x3f];
     787           10 :     *p++ = _crypt_a64[l & 0x3f];
     788           10 :     *p = 0;
     789              : 
     790           10 :     return output;
     791              : }
        

Generated by: LCOV version 2.0-1