"Fossies" - the Fresh Open Source Software Archive

Member "libmcrypt-2.5.8/modules/algorithms/des.c" (19 Jan 2003, 17077 Bytes) of package /linux/privat/old/libmcrypt-2.5.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "des.c" see the Fossies "Dox" file reference documentation.

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