NCBI C++ ToolKit
des.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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