• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KIO

des.cpp

Go to the documentation of this file.
00001 /*
00002  * Sofware DES functions
00003  *
00004  * Copyright 1988-1991 Phil Karn <karn@ka9q.net>
00005  * Copyright 2003      Nikos Mavroyanopoulos <nmav@hellug.gr>
00006  *
00007  * Taken from libmcrypt (http://mcrypt.hellug.gr/lib/index.html).
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00021  * MA  02110-1301  USA
00022  */
00023 
00024 /* Sofware DES functions
00025  * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
00026  * the 1977 public-domain program by Jim Gillogly
00027  * Modified for additional speed - 6 December 1988 Phil Karn
00028  * Modified for parameterized key schedules - Jan 1991 Phil Karn
00029  * Callers now allocate a key schedule as follows:
00030  *  kn = (char (*)[8])malloc(sizeof(char) * 8 * 16);
00031  *  or
00032  *  char kn[16][8];
00033  */
00034 
00035 /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos 
00036  * All modifications are placed under the license of libmcrypt.
00037  */
00038 
00039 
00040 #include "des.h"
00041 
00042 #include <string.h>
00043 #include <QtCore/qendian.h>
00044 
00045 static void permute_ip (unsigned char *inblock, DES_KEY * key, unsigned char *outblock);
00046 static void permute_fp (unsigned char *inblock, DES_KEY * key, unsigned char *outblock);
00047 static void perminit_ip (DES_KEY * key);
00048 static void spinit (DES_KEY * key);
00049 static void perminit_fp (DES_KEY * key);
00050 static quint32 f (DES_KEY * key,  quint32 r,  char *subkey);
00051 
00052 
00053 /* Tables defined in the Data Encryption Standard documents */
00054 
00055 /* initial permutation IP */
00056 static const char ip[] = {
00057   58, 50, 42, 34, 26, 18, 10, 2,
00058   60, 52, 44, 36, 28, 20, 12, 4,
00059   62, 54, 46, 38, 30, 22, 14, 6,
00060   64, 56, 48, 40, 32, 24, 16, 8,
00061   57, 49, 41, 33, 25, 17, 9, 1,
00062   59, 51, 43, 35, 27, 19, 11, 3,
00063   61, 53, 45, 37, 29, 21, 13, 5,
00064   63, 55, 47, 39, 31, 23, 15, 7
00065 };
00066 
00067 /* final permutation IP^-1 */
00068 static const char fp[] = {
00069   40, 8, 48, 16, 56, 24, 64, 32,
00070   39, 7, 47, 15, 55, 23, 63, 31,
00071   38, 6, 46, 14, 54, 22, 62, 30,
00072   37, 5, 45, 13, 53, 21, 61, 29,
00073   36, 4, 44, 12, 52, 20, 60, 28,
00074   35, 3, 43, 11, 51, 19, 59, 27,
00075   34, 2, 42, 10, 50, 18, 58, 26,
00076   33, 1, 41, 9, 49, 17, 57, 25
00077 };
00078 
00079 /* expansion operation matrix
00080  * This is for reference only; it is unused in the code
00081  * as the f() function performs it implicitly for speed
00082  */
00083 #ifdef notdef
00084 static const char ei[] = {
00085   32, 1, 2, 3, 4, 5,
00086   4, 5, 6, 7, 8, 9,
00087   8, 9, 10, 11, 12, 13,
00088   12, 13, 14, 15, 16, 17,
00089   16, 17, 18, 19, 20, 21,
00090   20, 21, 22, 23, 24, 25,
00091   24, 25, 26, 27, 28, 29,
00092   28, 29, 30, 31, 32, 1
00093 };
00094 #endif
00095 
00096 /* permuted choice table (key) */
00097 static const char pc1[] = {
00098   57, 49, 41, 33, 25, 17, 9,
00099   1, 58, 50, 42, 34, 26, 18,
00100   10, 2, 59, 51, 43, 35, 27,
00101   19, 11, 3, 60, 52, 44, 36,
00102 
00103   63, 55, 47, 39, 31, 23, 15,
00104   7, 62, 54, 46, 38, 30, 22,
00105   14, 6, 61, 53, 45, 37, 29,
00106   21, 13, 5, 28, 20, 12, 4
00107 };
00108 
00109 /* number left rotations of pc1 */
00110 static const char totrot[] = {
00111   1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
00112 };
00113 
00114 /* permuted choice key (table) */
00115 static const char pc2[] = {
00116   14, 17, 11, 24, 1, 5,
00117   3, 28, 15, 6, 21, 10,
00118   23, 19, 12, 4, 26, 8,
00119   16, 7, 27, 20, 13, 2,
00120   41, 52, 31, 37, 47, 55,
00121   30, 40, 51, 45, 33, 48,
00122   44, 49, 39, 56, 34, 53,
00123   46, 42, 50, 36, 29, 32
00124 };
00125 
00126 /* The (in)famous S-boxes */
00127 static const char si[8][64] = {
00128   /* S1 */
00129   {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
00130    0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
00131    4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
00132    15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
00133 
00134   /* S2 */
00135   {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
00136    3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
00137    0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
00138    13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
00139 
00140   /* S3 */
00141   {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
00142    13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
00143    13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
00144    1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
00145 
00146   /* S4 */
00147   {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
00148    13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
00149    10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
00150    3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
00151 
00152   /* S5 */
00153   {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
00154    14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
00155    4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
00156    11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
00157 
00158   /* S6 */
00159   {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
00160    10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
00161    9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
00162    4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
00163 
00164   /* S7 */
00165   {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
00166    13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
00167    1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
00168    6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
00169 
00170   /* S8 */
00171   {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
00172    1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
00173    7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
00174    2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
00175 
00176 };
00177 
00178 /* 32-bit permutation function P used on the output of the S-boxes */
00179 static const char p32i[] = {
00180   16, 7, 20, 21,
00181   29, 12, 28, 17,
00182   1, 15, 23, 26,
00183   5, 18, 31, 10,
00184   2, 8, 24, 14,
00185   32, 27, 3, 9,
00186   19, 13, 30, 6,
00187   22, 11, 4, 25
00188 };
00189 
00190 /* End of DES-defined tables */
00191 
00192 /* Lookup tables initialized once only at startup by desinit() */
00193 
00194 /* bit 0 is left-most in byte */
00195 static const int bytebit[] = {
00196   0200, 0100, 040, 020, 010, 04, 02, 01
00197 };
00198 
00199 static const int nibblebit[] = {
00200   010, 04, 02, 01
00201 };
00202 
00203 /* Allocate space and initialize DES lookup arrays
00204  * mode == 0: standard Data Encryption Algorithm
00205  */
00206 static int
00207 desinit (DES_KEY * key)
00208 {
00209 
00210   spinit (key);
00211   perminit_ip (key);
00212   perminit_fp (key);
00213 
00214   return 0;
00215 }
00216 
00217 
00218 /* Set key (initialize key schedule array) */
00219 int
00220 ntlm_des_set_key (DES_KEY * dkey, char *user_key, int /*len*/)
00221 {
00222   char pc1m[56];        /* place to modify pc1 into */
00223   char pcr[56];         /* place to rotate pc1 into */
00224    int i, j, l;
00225   int m;
00226 
00227   memset(dkey, 0, sizeof (DES_KEY));
00228   desinit (dkey);
00229 
00230   /* Clear key schedule */
00231 
00232 
00233   for (j = 0; j < 56; ++j)
00234     {               /* convert pc1 to bits of key */
00235       l = pc1[j] - 1;       /* integer bit location  */
00236       m = l & 07;       /* find bit              */
00237       pc1m[j] = (user_key[l >> 3] & /* find which key byte l is in */
00238          bytebit[m])    /* and which bit of that byte */
00239     ? 1 : 0;        /* and store 1-bit result */
00240 
00241     }
00242   for (i = 0; i < 16; ++i)
00243     {               /* key chunk for each iteration */
00244       for (j = 0; j < 56; ++j)  /* rotate pc1 the right amount */
00245     pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l - 28];
00246       /* rotate left and right halves independently */
00247       for (j = 0; j < 48; ++j)
00248     {           /* select bits individually */
00249       /* check bit that goes to kn[j] */
00250       if (pcr[pc2[j] - 1])
00251         {
00252           /* mask it in if it's there */
00253           l = j % 6;
00254           dkey->kn[i][j / 6] |= bytebit[l] >> 2;
00255         }
00256     }
00257     }
00258   return 0;
00259 }
00260 
00261 /* In-place encryption of 64-bit block */
00262 static void
00263 ntlm_des_encrypt (DES_KEY * key, unsigned char *block)
00264 {
00265   quint32 left, right;
00266   char *knp;
00267   quint32 work[2];      /* Working data storage */
00268 
00269   permute_ip (block, key, (unsigned char *) work);  /* Initial Permutation */
00270   left = qFromBigEndian(work[0]);
00271   right = qFromBigEndian(work[1]);
00272   
00273   /* Do the 16 rounds.
00274    * The rounds are numbered from 0 to 15. On even rounds
00275    * the right half is fed to f() and the result exclusive-ORs
00276    * the left half; on odd rounds the reverse is done.
00277    */
00278   knp = &key->kn[0][0];
00279   left ^= f (key, right, knp);
00280   knp += 8;
00281   right ^= f (key, left, knp);
00282   knp += 8;
00283   left ^= f (key, right, knp);
00284   knp += 8;
00285   right ^= f (key, left, knp);
00286   knp += 8;
00287   left ^= f (key, right, knp);
00288   knp += 8;
00289   right ^= f (key, left, knp);
00290   knp += 8;
00291   left ^= f (key, right, knp);
00292   knp += 8;
00293   right ^= f (key, left, knp);
00294   knp += 8;
00295   left ^= f (key, right, knp);
00296   knp += 8;
00297   right ^= f (key, left, knp);
00298   knp += 8;
00299   left ^= f (key, right, knp);
00300   knp += 8;
00301   right ^= f (key, left, knp);
00302   knp += 8;
00303   left ^= f (key, right, knp);
00304   knp += 8;
00305   right ^= f (key, left, knp);
00306   knp += 8;
00307   left ^= f (key, right, knp);
00308   knp += 8;
00309   right ^= f (key, left, knp);
00310 
00311   /* Left/right half swap, plus byte swap if little-endian */
00312   work[1] = qToBigEndian( left );
00313   work[0] = qToBigEndian( right );
00314 
00315   permute_fp ((unsigned char *) work, key, block);  /* Inverse initial permutation */
00316 }
00317 
00318 /* Permute inblock with perm */
00319 static void
00320 permute_ip (unsigned char *inblock, DES_KEY * key, unsigned char *outblock)
00321 {
00322    unsigned char *ib, *ob;  /* ptr to input or output block */
00323    char *p, *q;
00324    int j;
00325 
00326   /* Clear output block */
00327   memset(outblock, 0, 8);
00328 
00329   ib = inblock;
00330   for (j = 0; j < 16; j += 2, ++ib)
00331     {               /* for each input nibble */
00332       ob = outblock;
00333       p = key->iperm[j][(*ib >> 4) & 0xf];
00334       q = key->iperm[j + 1][*ib & 0xf];
00335       /* and each output byte, OR the masks together */
00336       *ob++ |= *p++ | *q++;
00337       *ob++ |= *p++ | *q++;
00338       *ob++ |= *p++ | *q++;
00339       *ob++ |= *p++ | *q++;
00340       *ob++ |= *p++ | *q++;
00341       *ob++ |= *p++ | *q++;
00342       *ob++ |= *p++ | *q++;
00343       *ob++ |= *p++ | *q++;
00344     }
00345 }
00346 
00347 /* Permute inblock with perm */
00348 static void
00349 permute_fp (unsigned char *inblock, DES_KEY * key, unsigned char *outblock)
00350 {
00351    unsigned char *ib, *ob;  /* ptr to input or output block */
00352    char *p, *q;
00353    int j;
00354 
00355   /* Clear output block */
00356   memset(outblock, 0, 8);
00357 
00358   ib = inblock;
00359   for (j = 0; j < 16; j += 2, ++ib)
00360     {               /* for each input nibble */
00361       ob = outblock;
00362       p = key->fperm[j][(*ib >> 4) & 0xf];
00363       q = key->fperm[j + 1][*ib & 0xf];
00364       /* and each output byte, OR the masks together */
00365       *ob++ |= *p++ | *q++;
00366       *ob++ |= *p++ | *q++;
00367       *ob++ |= *p++ | *q++;
00368       *ob++ |= *p++ | *q++;
00369       *ob++ |= *p++ | *q++;
00370       *ob++ |= *p++ | *q++;
00371       *ob++ |= *p++ | *q++;
00372       *ob++ |= *p++ | *q++;
00373     }
00374 }
00375 
00376 /* The nonlinear function f(r,k), the heart of DES */
00377 static quint32
00378 f (DES_KEY * key,  quint32 r,  char *subkey)
00379 {
00380    quint32 *spp;
00381    quint32 rval, rt;
00382    int er;
00383 
00384 #ifdef  TRACE
00385   printf ("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
00386       r,
00387       subkey[0], subkey[1], subkey[2],
00388       subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]);
00389 #endif
00390   /* Run E(R) ^ K through the combined S & P boxes.
00391    * This code takes advantage of a convenient regularity in
00392    * E, namely that each group of 6 bits in E(R) feeding
00393    * a single S-box is a contiguous segment of R.
00394    */
00395   subkey += 7;
00396 
00397   /* Compute E(R) for each block of 6 bits, and run thru boxes */
00398   er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0);
00399   spp = &key->sp[7][0];
00400   rval = spp[(er ^ *subkey--) & 0x3f];
00401   spp -= 64;
00402   rt = (quint32) r >> 3;
00403   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00404   spp -= 64;
00405   rt >>= 4;
00406   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00407   spp -= 64;
00408   rt >>= 4;
00409   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00410   spp -= 64;
00411   rt >>= 4;
00412   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00413   spp -= 64;
00414   rt >>= 4;
00415   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00416   spp -= 64;
00417   rt >>= 4;
00418   rval |= spp[((int) rt ^ *subkey--) & 0x3f];
00419   spp -= 64;
00420   rt >>= 4;
00421   rt |= (r & 1) << 5;
00422   rval |= spp[((int) rt ^ *subkey) & 0x3f];
00423 #ifdef  TRACE
00424   printf (" %08lx\n", rval);
00425 #endif
00426   return rval;
00427 }
00428 
00429 /* initialize a perm array */
00430 static void
00431 perminit_ip (DES_KEY * key)
00432 {
00433    int l, j, k;
00434   int i, m;
00435 
00436   /* Clear the permutation array */
00437   memset(key->iperm, 0, 16 * 16 * 8);
00438 
00439   for (i = 0; i < 16; ++i)  /* each input nibble position */
00440     for (j = 0; j < 16; ++j)    /* each possible input nibble */
00441       for (k = 0; k < 64; ++k)
00442     {           /* each output bit position */
00443       l = ip[k] - 1;    /* where does this bit come from */
00444       if ((l >> 2) != i)    /* does it come from input posn? */
00445         continue;       /* if not, bit k is 0    */
00446       if (!(j & nibblebit[l & 3]))
00447         continue;       /* any such bit in input? */
00448       m = k & 07;       /* which bit is this in the byte */
00449       key->iperm[i][j][k >> 3] |= bytebit[m];
00450     }
00451 }
00452 
00453 static void
00454 perminit_fp (DES_KEY * key)
00455 {
00456   int l, j, k;
00457   int i, m;
00458 
00459   /* Clear the permutation array */
00460   memset(key->fperm, 0, 16 * 16 * 8);
00461 
00462   for (i = 0; i < 16; ++i)  /* each input nibble position */
00463     for (j = 0; j < 16; ++j)    /* each possible input nibble */
00464       for (k = 0; k < 64; ++k)
00465     {           /* each output bit position */
00466       l = fp[k] - 1;    /* where does this bit come from */
00467       if ((l >> 2) != i)    /* does it come from input posn? */
00468         continue;       /* if not, bit k is 0    */
00469       if (!(j & nibblebit[l & 3]))
00470         continue;       /* any such bit in input? */
00471       m = k & 07;       /* which bit is this in the byte */
00472       key->fperm[i][j][k >> 3] |= bytebit[m];
00473     }
00474 }
00475 
00476 /* Initialize the lookup table for the combined S and P boxes */
00477 static void
00478 spinit (DES_KEY * key)
00479 {
00480   char pbox[32];
00481   int p, i, s, j, rowcol;
00482   quint32 val;
00483 
00484   /* Compute pbox, the inverse of p32i.
00485    * This is easier to work with
00486    */
00487   for (p = 0; p < 32; ++p)
00488     {
00489       for (i = 0; i < 32; ++i)
00490     {
00491       if (p32i[i] - 1 == p)
00492         {
00493           pbox[p] = i;
00494           break;
00495         }
00496     }
00497     }
00498   for (s = 0; s < 8; ++s)
00499     {               /* For each S-box */
00500       for (i = 0; i < 64; ++i)
00501     {           /* For each possible input */
00502       val = 0;
00503       /* The row number is formed from the first and last
00504        * bits; the column number is from the middle 4
00505        */
00506       rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
00507       for (j = 0; j < 4; j++)
00508         {           /* For each output bit */
00509           if (si[s][rowcol] & (8 >> j))
00510         {
00511           val |= 1L << (31 - pbox[4 * s + j]);
00512         }
00513         }
00514       key->sp[s][i] = val;
00515     }
00516     }
00517 }
00518 
00519 int
00520 ntlm_des_ecb_encrypt (const void *plaintext, int len, DES_KEY * akey,
00521               unsigned char output[8])
00522 {
00523   int j;
00524   const unsigned char *plain = (const unsigned char *) plaintext;
00525 
00526   for (j = 0; j < len / 8; ++j)
00527     {
00528       memcpy (&output[j * 8], &plain[j * 8], 8);
00529       ntlm_des_encrypt (akey, &output[j * 8]);
00530     }
00531 
00532   if (j == 0 && len != 0)
00533     return -1;          /* no blocks were encrypted */
00534   return 0;
00535 }

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal