LCOV - code coverage report
Current view: top level - src/utils - des.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 165 173 95.4 %
Date: 2025-01-18 12:13:41 Functions: 10 11 90.9 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 1998,1999,2000,2001 Nikos Mavroyanopoulos
       3             :  * 
       4             :  * This library is free software; you can redistribute it and/or modify it 
       5             :  * under the terms of the GNU Library General Public License as published 
       6             :  * by the Free Software Foundation; either version 2 of the License, or 
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Library General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Library General Public
      15             :  * License along with this library; if not, write to the
      16             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      17             :  * Boston, MA 02111-1307, USA.
      18             :  */
      19             : 
      20             : /* Sofware DES functions
      21             :  * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
      22             :  * the 1977 public-domain program by Jim Gillogly
      23             :  * Modified for additional speed - 6 December 1988 Phil Karn
      24             :  * Modified for parameterized key schedules - Jan 1991 Phil Karn
      25             :  * Callers now allocate a key schedule as follows:
      26             :  *      kn = (char (*)[8])malloc(sizeof(char) * 8 * 16);
      27             :  *      or
      28             :  *      char kn[16][8];
      29             :  */
      30             : 
      31             : /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos 
      32             :  * All modifications are placed under the license of libmcrypt.
      33             :  */
      34             : 
      35             : #include <config.h>
      36             : 
      37             : #if HAVE_STRING_H
      38             : #include <string.h>
      39             : #endif /* HAVE_STRING_H */
      40             : 
      41             : #include <tds_sysdep_public.h>
      42             : #include <freetds/bytes.h>
      43             : #include <freetds/utils/des.h>
      44             : 
      45             : void
      46           0 : tds_des_set_odd_parity(des_cblock key)
      47             : {
      48             : 
      49             :         int i;
      50             :         unsigned char parity;
      51             : 
      52           0 :         for (i = 0; i < 8; i++) {
      53           0 :                 parity = key[i];
      54             : 
      55           0 :                 parity ^= parity >> 4;
      56           0 :                 parity ^= parity >> 2;
      57           0 :                 parity ^= parity >> 1;
      58             : 
      59           0 :                 key[i] = (key[i] & 0xfe) | (parity & 1);
      60             :         }
      61           0 : }
      62             : 
      63             : #ifndef HAVE_NETTLE
      64             : 
      65             : static void permute_ip(const des_cblock inblock, const DES_KEY * key, des_cblock outblock);
      66             : static void permute_fp(const des_cblock inblock, const DES_KEY * key, des_cblock outblock);
      67             : static void perminit_ip(DES_KEY * key);
      68             : static void spinit(DES_KEY * key);
      69             : static void perminit_fp(DES_KEY * key);
      70             : static uint32_t f(const DES_KEY * key, register uint32_t r, register const unsigned char *subkey);
      71             : 
      72             : /* Tables defined in the Data Encryption Standard documents */
      73             : 
      74             : /* initial permutation IP */
      75             : static const char ip[] = {
      76             :         58, 50, 42, 34, 26, 18, 10, 2,
      77             :         60, 52, 44, 36, 28, 20, 12, 4,
      78             :         62, 54, 46, 38, 30, 22, 14, 6,
      79             :         64, 56, 48, 40, 32, 24, 16, 8,
      80             :         57, 49, 41, 33, 25, 17, 9, 1,
      81             :         59, 51, 43, 35, 27, 19, 11, 3,
      82             :         61, 53, 45, 37, 29, 21, 13, 5,
      83             :         63, 55, 47, 39, 31, 23, 15, 7
      84             : };
      85             : 
      86             : /* final permutation IP^-1 */
      87             : static const char fp[] = {
      88             :         40, 8, 48, 16, 56, 24, 64, 32,
      89             :         39, 7, 47, 15, 55, 23, 63, 31,
      90             :         38, 6, 46, 14, 54, 22, 62, 30,
      91             :         37, 5, 45, 13, 53, 21, 61, 29,
      92             :         36, 4, 44, 12, 52, 20, 60, 28,
      93             :         35, 3, 43, 11, 51, 19, 59, 27,
      94             :         34, 2, 42, 10, 50, 18, 58, 26,
      95             :         33, 1, 41, 9, 49, 17, 57, 25
      96             : };
      97             : 
      98             : /* expansion operation matrix
      99             :  * This is for reference only; it is unused in the code
     100             :  * as the f() function performs it implicitly for speed
     101             :  */
     102             : #ifdef notdef
     103             : static char ei[] = {
     104             :         32, 1, 2, 3, 4, 5,
     105             :         4, 5, 6, 7, 8, 9,
     106             :         8, 9, 10, 11, 12, 13,
     107             :         12, 13, 14, 15, 16, 17,
     108             :         16, 17, 18, 19, 20, 21,
     109             :         20, 21, 22, 23, 24, 25,
     110             :         24, 25, 26, 27, 28, 29,
     111             :         28, 29, 30, 31, 32, 1
     112             : };
     113             : #endif
     114             : 
     115             : /* permuted choice table (key) */
     116             : static const char pc1[] = {
     117             :         57, 49, 41, 33, 25, 17, 9,
     118             :         1, 58, 50, 42, 34, 26, 18,
     119             :         10, 2, 59, 51, 43, 35, 27,
     120             :         19, 11, 3, 60, 52, 44, 36,
     121             : 
     122             :         63, 55, 47, 39, 31, 23, 15,
     123             :         7, 62, 54, 46, 38, 30, 22,
     124             :         14, 6, 61, 53, 45, 37, 29,
     125             :         21, 13, 5, 28, 20, 12, 4
     126             : };
     127             : 
     128             : /* number left rotations of pc1 */
     129             : static const char totrot[] = {
     130             :         1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
     131             : };
     132             : 
     133             : /* permuted choice key (table) */
     134             : static const char pc2[] = {
     135             :         14, 17, 11, 24, 1, 5,
     136             :         3, 28, 15, 6, 21, 10,
     137             :         23, 19, 12, 4, 26, 8,
     138             :         16, 7, 27, 20, 13, 2,
     139             :         41, 52, 31, 37, 47, 55,
     140             :         30, 40, 51, 45, 33, 48,
     141             :         44, 49, 39, 56, 34, 53,
     142             :         46, 42, 50, 36, 29, 32
     143             : };
     144             : 
     145             : /* The (in)famous S-boxes */
     146             : static const char si[8][64] = {
     147             :         /* S1 */
     148             :         {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
     149             :          0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
     150             :          4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
     151             :          15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
     152             : 
     153             :         /* S2 */
     154             :         {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
     155             :          3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
     156             :          0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
     157             :          13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
     158             : 
     159             :         /* S3 */
     160             :         {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
     161             :          13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
     162             :          13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
     163             :          1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
     164             : 
     165             :         /* S4 */
     166             :         {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
     167             :          13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
     168             :          10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
     169             :          3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
     170             : 
     171             :         /* S5 */
     172             :         {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
     173             :          14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
     174             :          4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
     175             :          11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
     176             : 
     177             :         /* S6 */
     178             :         {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
     179             :          10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
     180             :          9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
     181             :          4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
     182             : 
     183             :         /* S7 */
     184             :         {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
     185             :          13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
     186             :          1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
     187             :          6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
     188             : 
     189             :         /* S8 */
     190             :         {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
     191             :          1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
     192             :          7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
     193             :          2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
     194             : 
     195             : };
     196             : 
     197             : #ifdef notdef
     198             : /* 32-bit permutation function P used on the output of the S-boxes */
     199             : static const char p32i[] = {
     200             :         16, 7, 20, 21,
     201             :         29, 12, 28, 17,
     202             :         1, 15, 23, 26,
     203             :         5, 18, 31, 10,
     204             :         2, 8, 24, 14,
     205             :         32, 27, 3, 9,
     206             :         19, 13, 30, 6,
     207             :         22, 11, 4, 25
     208             : };
     209             : #endif
     210             : 
     211             : #define P32I_INDEX_ROW(n,i,a,b,c,d) \
     212             :         n==a ? 0+i : n==b ? 1+i : n==c ? 2+i : n==d ? 3+i
     213             : #define P32I_INDEX(n) \
     214             :         (P32I_INDEX_ROW(n, 0, 16, 7, 20, 21) :\
     215             :          P32I_INDEX_ROW(n, 4, 29, 12, 28, 17) :\
     216             :          P32I_INDEX_ROW(n, 8, 1, 15, 23, 26) :\
     217             :          P32I_INDEX_ROW(n,12, 5, 18, 31, 10) :\
     218             :          P32I_INDEX_ROW(n,16, 2, 8, 24, 14) :\
     219             :          P32I_INDEX_ROW(n,20, 32, 27, 3, 9) :\
     220             :          P32I_INDEX_ROW(n,24, 19, 13, 30, 6) :\
     221             :          P32I_INDEX_ROW(n,28, 22, 11, 4, 25) : 0x7f)
     222             : 
     223             : static const char pbox[32] = {
     224             :         P32I_INDEX( 1),
     225             :         P32I_INDEX( 2),
     226             :         P32I_INDEX( 3),
     227             :         P32I_INDEX( 4),
     228             :         P32I_INDEX( 5),
     229             :         P32I_INDEX( 6),
     230             :         P32I_INDEX( 7),
     231             :         P32I_INDEX( 8),
     232             :         P32I_INDEX( 9),
     233             :         P32I_INDEX(10),
     234             :         P32I_INDEX(11),
     235             :         P32I_INDEX(12),
     236             :         P32I_INDEX(13),
     237             :         P32I_INDEX(14),
     238             :         P32I_INDEX(15),
     239             :         P32I_INDEX(16),
     240             :         P32I_INDEX(17),
     241             :         P32I_INDEX(18),
     242             :         P32I_INDEX(19),
     243             :         P32I_INDEX(20),
     244             :         P32I_INDEX(21),
     245             :         P32I_INDEX(22),
     246             :         P32I_INDEX(23),
     247             :         P32I_INDEX(24),
     248             :         P32I_INDEX(25),
     249             :         P32I_INDEX(26),
     250             :         P32I_INDEX(27),
     251             :         P32I_INDEX(28),
     252             :         P32I_INDEX(29),
     253             :         P32I_INDEX(30),
     254             :         P32I_INDEX(31),
     255             :         P32I_INDEX(32),
     256             : };
     257             : 
     258             : /* End of DES-defined tables */
     259             : 
     260             : /* Lookup tables initialized once only at startup by des_init() */
     261             : 
     262             : /* bit 0 is left-most in byte */
     263             : static const int bytebit[] = {
     264             :         0200, 0100, 040, 020, 010, 04, 02, 01
     265             : };
     266             : 
     267             : static const int nibblebit[] = {
     268             :         010, 04, 02, 01
     269             : };
     270             : 
     271             : /* Allocate space and initialize DES lookup arrays
     272             :  * mode == 0: standard Data Encryption Algorithm
     273             :  */
     274             : static int
     275          12 : des_init(DES_KEY * key)
     276             : {
     277             : 
     278          12 :         spinit(key);
     279          12 :         perminit_ip(key);
     280          12 :         perminit_fp(key);
     281             : 
     282          12 :         return 0;
     283             : }
     284             : 
     285             : 
     286             : /* Set key (initialize key schedule array) */
     287             : int
     288          12 : tds_des_set_key(DES_KEY * dkey, const des_cblock user_key, int len)
     289             : {
     290             :         char pc1m[56];          /* place to modify pc1 into */
     291             :         char pcr[56];           /* place to rotate pc1 into */
     292             :         register int i, j, l;
     293             :         int m;
     294             : 
     295          12 :         memset(dkey, '\0', sizeof(DES_KEY));
     296          12 :         des_init(dkey);
     297             : 
     298             :         /* Clear key schedule */
     299             : 
     300             : 
     301         684 :         for (j = 0; j < 56; j++) {   /* convert pc1 to bits of key */
     302         672 :                 l = pc1[j] - 1; /* integer bit location  */
     303         672 :                 m = l & 07; /* find bit              */
     304        2016 :                 pc1m[j] = (user_key[l >> 3] & /* find which key byte l is in */
     305         672 :                            bytebit[m])  /* and which bit of that byte */
     306         672 :                         ? 1 : 0;        /* and store 1-bit result */
     307             : 
     308             :         }
     309         192 :         for (i = 0; i < 16; i++) {   /* key chunk for each iteration */
     310       10752 :                 for (j = 0; j < 56; j++)     /* rotate pc1 the right amount */
     311       10752 :                         pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l - 28];
     312             :                 /* rotate left and right halves independently */
     313        9216 :                 for (j = 0; j < 48; j++) {   /* select bits individually */
     314             :                         /* check bit that goes to kn[j] */
     315        9216 :                         if (pcr[pc2[j] - 1]) {
     316             :                                 /* mask it in if it's there */
     317        2820 :                                 l = j % 6;
     318        2820 :                                 dkey->kn[i][j / 6] |= bytebit[l] >> 2;
     319             :                         }
     320             :                 }
     321             :         }
     322          12 :         return 0;
     323             : }
     324             : 
     325             : /* In-place encryption of 64-bit block */
     326             : void
     327          28 : tds_des_encrypt(const DES_KEY * key, des_cblock block)
     328             : {
     329             :         register uint32_t left, right;
     330             :         register const unsigned char *knp;
     331             :         uint32_t work[2];       /* Working data storage */
     332             : 
     333          28 :         permute_ip(block, key, (unsigned char *) work); /* Initial Permutation */
     334          28 :         left = TDS_GET_A4BE(&work[0]);
     335          28 :         right = TDS_GET_A4BE(&work[1]);
     336             : 
     337             :         /* Do the 16 rounds.
     338             :          * The rounds are numbered from 0 to 15. On even rounds
     339             :          * the right half is fed to f() and the result exclusive-ORs
     340             :          * the left half; on odd rounds the reverse is done.
     341             :          */
     342          28 :         knp = &key->kn[0][0];
     343          28 :         left ^= f(key, right, knp);
     344          28 :         knp += 8;
     345          28 :         right ^= f(key, left, knp);
     346          28 :         knp += 8;
     347          28 :         left ^= f(key, right, knp);
     348          28 :         knp += 8;
     349          28 :         right ^= f(key, left, knp);
     350          28 :         knp += 8;
     351          28 :         left ^= f(key, right, knp);
     352          28 :         knp += 8;
     353          28 :         right ^= f(key, left, knp);
     354          28 :         knp += 8;
     355          28 :         left ^= f(key, right, knp);
     356          28 :         knp += 8;
     357          28 :         right ^= f(key, left, knp);
     358          28 :         knp += 8;
     359          28 :         left ^= f(key, right, knp);
     360          28 :         knp += 8;
     361          28 :         right ^= f(key, left, knp);
     362          28 :         knp += 8;
     363          28 :         left ^= f(key, right, knp);
     364          28 :         knp += 8;
     365          28 :         right ^= f(key, left, knp);
     366          28 :         knp += 8;
     367          28 :         left ^= f(key, right, knp);
     368          28 :         knp += 8;
     369          28 :         right ^= f(key, left, knp);
     370          28 :         knp += 8;
     371          28 :         left ^= f(key, right, knp);
     372          28 :         knp += 8;
     373          28 :         right ^= f(key, left, knp);
     374             : 
     375             :         /* Left/right half swap, plus byte swap if little-endian */
     376          28 :         TDS_PUT_A4BE(&work[0], right);
     377          28 :         TDS_PUT_A4BE(&work[1], left);
     378          28 :         permute_fp((unsigned char *) work, key, block); /* Inverse initial permutation */
     379          28 : }
     380             : 
     381             : /* In-place decryption of 64-bit block. This function is the mirror
     382             :  * image of encryption; exactly the same steps are taken, but in
     383             :  * reverse order
     384             :  */
     385             : #if 0
     386             : void
     387             : _mcrypt_decrypt(DES_KEY * key, unsigned char *block)
     388             : {
     389             :         register uint32_t left, right;
     390             :         register unsigned char *knp;
     391             :         uint32_t work[2];       /* Working data storage */
     392             : 
     393             :         permute_ip(block, key, (unsigned char *) work); /* Initial permutation */
     394             : 
     395             :         /* Left/right half swap, plus byte swap if little-endian */
     396             :         right = TDS_GET_A4BE(&work[0]);
     397             :         left  = TDS_GET_A4BE(&work[1]);
     398             :         /* Do the 16 rounds in reverse order.
     399             :          * The rounds are numbered from 15 to 0. On even rounds
     400             :          * the right half is fed to f() and the result exclusive-ORs
     401             :          * the left half; on odd rounds the reverse is done.
     402             :          */
     403             :         knp = &key->kn[15][0];
     404             :         right ^= f(key, left, knp);
     405             :         knp -= 8;
     406             :         left ^= f(key, right, knp);
     407             :         knp -= 8;
     408             :         right ^= f(key, left, knp);
     409             :         knp -= 8;
     410             :         left ^= f(key, right, knp);
     411             :         knp -= 8;
     412             :         right ^= f(key, left, knp);
     413             :         knp -= 8;
     414             :         left ^= f(key, right, knp);
     415             :         knp -= 8;
     416             :         right ^= f(key, left, knp);
     417             :         knp -= 8;
     418             :         left ^= f(key, right, knp);
     419             :         knp -= 8;
     420             :         right ^= f(key, left, knp);
     421             :         knp -= 8;
     422             :         left ^= f(key, right, knp);
     423             :         knp -= 8;
     424             :         right ^= f(key, left, knp);
     425             :         knp -= 8;
     426             :         left ^= f(key, right, knp);
     427             :         knp -= 8;
     428             :         right ^= f(key, left, knp);
     429             :         knp -= 8;
     430             :         left ^= f(key, right, knp);
     431             :         knp -= 8;
     432             :         right ^= f(key, left, knp);
     433             :         knp -= 8;
     434             :         left ^= f(key, right, knp);
     435             : 
     436             :         TDS_PUT_A4BE(&work[0], left);
     437             :         TDS_PUT_A4BE(&work[1], right);
     438             :         permute_fp((unsigned char *) work, key, block); /* Inverse initial permutation */
     439             : }
     440             : #endif
     441             : 
     442             : /* Permute inblock with perm */
     443             : static void
     444          28 : permute_ip(const des_cblock inblock, const DES_KEY * key, des_cblock outblock)
     445             : {
     446             :         register const unsigned char *ib;       /* ptr to input block */
     447             :         register unsigned char *ob;     /* ptr to output block */
     448             :         register const unsigned char *p, *q;
     449             :         register int j;
     450             : 
     451             :         /* Clear output block */
     452          28 :         memset(outblock, '\0', 8);
     453             : 
     454          28 :         ib = inblock;
     455         252 :         for (j = 0; j < 16; j += 2, ib++) {  /* for each input nibble */
     456         224 :                 ob = outblock;
     457         224 :                 p = key->iperm[j][(*ib >> 4) & 0xf];
     458         224 :                 q = key->iperm[j + 1][*ib & 0xf];
     459             :                 /* and each output byte, OR the masks together */
     460         224 :                 *ob++ |= *p++ | *q++;
     461         224 :                 *ob++ |= *p++ | *q++;
     462         224 :                 *ob++ |= *p++ | *q++;
     463         224 :                 *ob++ |= *p++ | *q++;
     464         224 :                 *ob++ |= *p++ | *q++;
     465         224 :                 *ob++ |= *p++ | *q++;
     466         224 :                 *ob++ |= *p++ | *q++;
     467         224 :                 *ob++ |= *p++ | *q++;
     468             :         }
     469          28 : }
     470             : 
     471             : /* Permute inblock with perm */
     472             : static void
     473          28 : permute_fp(const des_cblock inblock, const DES_KEY * key, des_cblock outblock)
     474             : {
     475             :         register const unsigned char *ib;       /* ptr to input block */
     476             :         register unsigned char *ob;     /* ptr to output block */
     477             :         register const unsigned char *p, *q;
     478             :         register int j;
     479             : 
     480             :         /* Clear output block */
     481          28 :         memset(outblock, '\0', 8);
     482             : 
     483          28 :         ib = inblock;
     484         252 :         for (j = 0; j < 16; j += 2, ib++) {  /* for each input nibble */
     485         224 :                 ob = outblock;
     486         224 :                 p = key->fperm[j][(*ib >> 4) & 0xf];
     487         224 :                 q = key->fperm[j + 1][*ib & 0xf];
     488             :                 /* and each output byte, OR the masks together */
     489         224 :                 *ob++ |= *p++ | *q++;
     490         224 :                 *ob++ |= *p++ | *q++;
     491         224 :                 *ob++ |= *p++ | *q++;
     492         224 :                 *ob++ |= *p++ | *q++;
     493         224 :                 *ob++ |= *p++ | *q++;
     494         224 :                 *ob++ |= *p++ | *q++;
     495         224 :                 *ob++ |= *p++ | *q++;
     496         224 :                 *ob++ |= *p++ | *q++;
     497             :         }
     498          28 : }
     499             : 
     500             : /* The nonlinear function f(r,k), the heart of DES */
     501             : static uint32_t
     502         448 : f(const DES_KEY * key, register uint32_t r, register const unsigned char *subkey)
     503             : {
     504             :         register const uint32_t *spp;
     505             :         register uint32_t rval, rt;
     506             :         register int er;
     507             : 
     508             : #ifdef  TRACE
     509             :         printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
     510             :                r, subkey[0], subkey[1], subkey[2], subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]);
     511             : #endif
     512             :         /* Run E(R) ^ K through the combined S & P boxes.
     513             :          * This code takes advantage of a convenient regularity in
     514             :          * E, namely that each group of 6 bits in E(R) feeding
     515             :          * a single S-box is a contiguous segment of R.
     516             :          */
     517         448 :         subkey += 7;
     518             : 
     519             :         /* Compute E(R) for each block of 6 bits, and run thru boxes */
     520         448 :         er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0);
     521         448 :         spp = &key->sp[7][0];
     522         448 :         rval = spp[(er ^ *subkey--) & 0x3f];
     523         448 :         spp -= 64;
     524         448 :         rt = (uint32_t) r >> 3;
     525         448 :         rval |= spp[((int) rt ^ *subkey--) & 0x3f];
     526         448 :         spp -= 64;
     527         448 :         rt >>= 4;
     528         448 :         rval |= spp[((int) rt ^ *subkey--) & 0x3f];
     529         448 :         spp -= 64;
     530         448 :         rt >>= 4;
     531         448 :         rval |= spp[((int) rt ^ *subkey--) & 0x3f];
     532         448 :         spp -= 64;
     533         448 :         rt >>= 4;
     534         448 :         rval |= spp[((int) rt ^ *subkey--) & 0x3f];
     535         448 :         spp -= 64;
     536         448 :         rt >>= 4;
     537         448 :         rval |= spp[((int) rt ^ *subkey--) & 0x3f];
     538         448 :         spp -= 64;
     539         448 :         rt >>= 4;
     540         448 :         rval |= spp[((int) rt ^ *subkey--) & 0x3f];
     541         448 :         spp -= 64;
     542         448 :         rt >>= 4;
     543         448 :         rt |= (r & 1) << 5;
     544         448 :         rval |= spp[((int) rt ^ *subkey) & 0x3f];
     545             : #ifdef  TRACE
     546             :         printf(" %08lx\n", rval);
     547             : #endif
     548         448 :         return rval;
     549             : }
     550             : 
     551             : /* initialize a perm array */
     552             : static void
     553          12 : perminit_ip(DES_KEY * key)
     554             : {
     555             :         register int l, j, k;
     556             :         int i, m;
     557             : 
     558             :         /* Clear the permutation array */
     559          12 :         memset(key->iperm, '\0', 16 * 16 * 8);
     560             : 
     561         204 :         for (i = 0; i < 16; i++)     /* each input nibble position */
     562        3072 :                 for (j = 0; j < 16; j++)     /* each possible input nibble */
     563      196608 :                         for (k = 0; k < 64; k++) {   /* each output bit position */
     564      196608 :                                 l = ip[k] - 1;  /* where does this bit come from */
     565      196608 :                                 if ((l >> 2) != i)        /* does it come from input posn? */
     566      184320 :                                         continue;       /* if not, bit k is 0    */
     567       12288 :                                 if (!(j & nibblebit[l & 3]))
     568        6144 :                                         continue;       /* any such bit in input? */
     569        6144 :                                 m = k & 07; /* which bit is this in the byte */
     570        6144 :                                 key->iperm[i][j][k >> 3] |= bytebit[m];
     571             :                         }
     572          12 : }
     573             : 
     574             : static void
     575          12 : perminit_fp(DES_KEY * key)
     576             : {
     577             :         register int l, j, k;
     578             :         int i, m;
     579             : 
     580             :         /* Clear the permutation array */
     581          12 :         memset(key->fperm, '\0', 16 * 16 * 8);
     582             : 
     583         204 :         for (i = 0; i < 16; i++)     /* each input nibble position */
     584        3072 :                 for (j = 0; j < 16; j++)     /* each possible input nibble */
     585      196608 :                         for (k = 0; k < 64; k++) {   /* each output bit position */
     586      196608 :                                 l = fp[k] - 1;  /* where does this bit come from */
     587      196608 :                                 if ((l >> 2) != i)        /* does it come from input posn? */
     588      184320 :                                         continue;       /* if not, bit k is 0    */
     589       12288 :                                 if (!(j & nibblebit[l & 3]))
     590        6144 :                                         continue;       /* any such bit in input? */
     591        6144 :                                 m = k & 07; /* which bit is this in the byte */
     592        6144 :                                 key->fperm[i][j][k >> 3] |= bytebit[m];
     593             :                         }
     594          12 : }
     595             : 
     596             : /* Initialize the lookup table for the combined S and P boxes */
     597             : static void
     598          12 : spinit(DES_KEY * key)
     599             : {
     600             :         int i, s, j, rowcol;
     601             :         uint32_t val;
     602             : 
     603         108 :         for (s = 0; s < 8; s++) {    /* For each S-box */
     604        6144 :                 for (i = 0; i < 64; i++) {   /* For each possible input */
     605        6144 :                         val = 0;
     606             :                         /* The row number is formed from the first and last
     607             :                          * bits; the column number is from the middle 4
     608             :                          */
     609        6144 :                         rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
     610       30720 :                         for (j = 0; j < 4; j++) {    /* For each output bit */
     611       24576 :                                 if (si[s][rowcol] & (8 >> j)) {
     612       12288 :                                         val |= 1L << (31 - pbox[4 * s + j]);
     613             :                                 }
     614             :                         }
     615        6144 :                         key->sp[s][i] = val;
     616             :                 }
     617             :         }
     618          12 : }
     619             : 
     620             : #endif
     621             : 
     622             : /* ECB MODE */
     623             : 
     624             : int
     625          24 : tds_des_ecb_encrypt(const void *plaintext, int len, DES_KEY * akey, unsigned char *output)
     626             : {
     627             :         int j;
     628          24 :         const unsigned char *plain = (const unsigned char *) plaintext;
     629             : 
     630          80 :         for (j = 0; j < len / 8; j++) {
     631          56 :                 memcpy(&output[j * 8], &plain[j * 8], 8);
     632          84 :                 tds_des_encrypt(akey, &output[j * 8]);
     633             :         }
     634          24 :         if (j == 0 && len != 0)
     635             :                 return -1;      /* no blocks were encrypted */
     636          24 :         return 0;
     637             : }

Generated by: LCOV version 1.13