home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 125.img / PRO-C4.ZIP / BENCH1.ZIP / BENCH / DES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-28  |  9.5 KB  |  359 lines

  1. /* ---( bench/des.c )----------------------------- */
  2. /* Pro-C Copyright (c) 1988 - 1990 Vestronix Inc.  */
  3. /* Modification to this source is not supported    */
  4. /* by Vestronix Inc.                               */
  5. /*            All Rights Reserved                  */
  6. /* ----------------------------------------------- */
  7. /* Written   NVS    20-Jan-90                        */
  8. /* Modified  BRC     2-May-90                        */
  9. /* ----------------------------------------------- */
  10. /* %W%  (%H% %T%) */
  11.  
  12. /*
  13.  *    Modifications
  14.  *
  15.  * Nig 30-Jan-90  Ensure Password is padded to 8 chars with NULL's
  16.  * BRC  2-May-90  made passwords printable 11 character strings
  17. */
  18.  
  19. /*
  20.  * Password encryption and decryption routines
  21.  * using the Data Encryption Standard (DES)
  22.  * algorithm.  Accepts an eight char password and
  23.  * an eight char encryption key, and produces an
  24.  * eight char encrypted password.
  25. */
  26.  
  27. /*
  28.  * Acknowledgments : Brian Carson please expand
  29.  * 
  30.  * Also, I don't think we can put the copyright 
  31.  * message at the top ! - Nig
  32. */
  33.  
  34. #include <stdio.h>
  35. #include <bench.h>
  36. #include <passwd.h>
  37.  
  38. # ifdef ANSI
  39. static void copy(int [], int []);
  40. static void defunc( int, int [], int [], int [] );
  41. static void func( int, int [], int [], int [] );
  42. static void transpose( int [], int [], int );
  43. # else
  44. static void copy();
  45. static void defunc();
  46. static void func();
  47. static void transpose();
  48. # endif
  49.  
  50. /* static arrays used for encryption */
  51. static char mapper[65] =
  52. ".0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
  53.  
  54. static int 
  55.  
  56.     /* InitialTr - initial mapping of text */
  57.     InitialTr[64] =
  58.     {58,50,42,34,26,18,10,2 ,60,52,44,36,28,20,12,4 ,62,54,
  59.      46,38,30,22,14,6 ,64,56,48,40,32,24,16,8 ,57,49,41,33,
  60.      25,17,9 ,1 ,59,51,43,35,27,19,11,3 ,61,53,45,37,29,21,
  61.      13,5 ,63,55,47,39,31,23,15,7 },
  62.  
  63.     /* FinalTr - final mapping of encrypted text */
  64.     FinalTr[64] =
  65.     {40,8 ,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,38,6 ,
  66.      46,14,54,22,62,30,37,5 ,45,13,53,21,61,29,36,4 ,44,12,
  67.      52,20,60,28,35,3 ,43,11,51,19,59,27,34,2 ,42,10,50,18,
  68.      58,26,33,1 ,41,9 ,49,17,57,25},
  69.  
  70.     /* swap - transpose to swap halves */
  71.     swap[64] =
  72.     {33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,
  73.      51,52,53,54,55,56,57,58,59,60,61,62,63,64,1 ,2 ,3 ,4 ,
  74.      5 ,6 ,7 ,8 ,9 ,10,11,12,13,14,15,16,17,18,19,20,21,22,
  75.      23,24,25,26,27,28,29,30,31,32},
  76.  
  77.     /* lrotate - transpose to do two 28 bit left rotates on 56 bit string */
  78.     lrotate[56] =
  79.     { 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,
  80.      21,22,23,24,25,26,27,28, 1,30,31,32,33,34,35,36,37,38,39,
  81.      40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,29},
  82.  
  83.     /* rrotate - transpose for two 28 bit right rotates on 56 bit string */
  84.     rrotate[56] = 
  85.     {28, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,
  86.      19,20,21,22,23,24,25,26,27,56,29,30,31,32,33,34,35,36,37,
  87.      38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55},
  88.  
  89.     /* KeyTr1 - inital key transpose */
  90.     KeyTr1[56] =
  91.     {57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,10, 2,59,51,43,
  92.      35,27,19,11, 3,60,52,44,36,63,55,47,39,31,23,15, 7,62,54,
  93.      46,38,30,22,14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4},
  94.  
  95.     /* KeyTr2 - second key transpose */
  96.     KeyTr2[48] = 
  97.     {14,17,11,24,1 ,5 ,3 ,28,15,6 ,21,10,23,19,12,4 ,26,8 ,16,
  98.       7,27,20,13,2 ,41,52,31,37,47,55,30,40,51,45,33,48,44,49,
  99.      39,56,34,53,46,42,50,36,29,32},
  100.  
  101.     /* etr */
  102.     etr[48] =
  103.     {32,1, 2, 3, 4, 5, 4, 5, 6 ,7 ,8 ,9 ,8 ,9 ,10,11,12,13,12,
  104.     13,14,15,16,17,16,17,18,19,20,21,20,21,22,23,24,25,24,25,
  105.     26,27,28,29,28,29,30,31,32,1},
  106.  
  107.     /* ptr */
  108.     ptr[32] = 
  109.     { 16,7 ,20,21,29,12,28,17,1 ,15,23,26,5 ,18,31,10,2 ,8 ,24,
  110.     14,32,27, 3,9 ,19,13,30,6 ,22,11,4 ,25},
  111.  
  112.     /* s[][] - array of 8 64 bit transposes - known as S-boxes in 
  113.         des encryption algorithm */
  114.     s[8][64] = {
  115.     {14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,0,15,7,
  116.      4,14,2,13,1,10,6,12,11,9,5,3,8,4,1,14,8,13,6,
  117.     2,11,15,12,9,7,3,10,5,0,15,12,8,2,4,9,1,7,5,
  118.     11,3,14,10,0,6,13},
  119.  
  120.     {15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,3,13,4,7,15,2,8,14,
  121.      12,0,1,10,6,9,11,5,0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
  122.      13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9},
  123.  
  124.     {10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,13,7,0,9,3,4,6,10,2,
  125.       8,5,14,12,11,15,1,13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
  126.       1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12},
  127.  
  128.     {7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,13,8,11,5,6,15,0,3,
  129.      4,7,2,12,1,10,14,9,10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
  130.      3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14},
  131.  
  132.     {2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,14,11,2,12,4,7,13,
  133.      1,5,0,15,10,3,9,8,6,4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
  134.      11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3},
  135.  
  136.     {12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,10,15,4,2,7,12,9,5,
  137.       6,1,13,14,0,11,3,8,9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
  138.       4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13},
  139.  
  140.     {4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,13,0,11,7,4,9,1,10,
  141.      14,3,5,12,2,15,8,6,1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
  142.       6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12},
  143.  
  144.     {13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,1,15,13,8,10,3,7,4,
  145.      12,5,6,11,0,14,9,2,7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
  146.       2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}
  147.     },
  148.  
  149.     /* rots[] - rotates to be performed on key */
  150.     rots[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
  151.  
  152.  
  153.  
  154. /*
  155.  * TRANSPOSE - apply transpose mapping to data array
  156. */
  157. static void transpose( data, tranx, n )
  158. int data[], tranx[], n;
  159. {
  160.    int x[64];
  161.    register int i;
  162.  
  163.    copy( x, data );
  164.    for(i=0; i<n; i++ ) {
  165.       data[i] = x[tranx[i]-1];
  166.    }
  167. }
  168.  
  169. /*
  170.  * FUNC - function is called during each iteration within des encryption 
  171. */
  172. static void func( i, key, a, x )
  173. int i, key[], a[], x[]; 
  174. {
  175.    int e[64], y[64], ikey[64];
  176.     register int r, k, j;
  177.  
  178.     copy( e, a );
  179.    transpose( e, etr, 48 );
  180.    for(j=0; j<rots[i]; j++ ) transpose( key, lrotate, 56);
  181.     copy( ikey, key );
  182.    transpose( ikey, KeyTr2, 48 );
  183.    for( j=0; j<48; j++ ) y[j] = e[j]^ikey[j];
  184.    for( k=1; k<=8; k++ ) {
  185.       r = 32*y[6*k-6]+16*y[6*k-1]+8*y[6*k-5]+4*y[6*k-4]+2*y[6*k-3]+y[6*k-2];
  186.       x[4*k-4] = (s[k-1][r]/8)%2;
  187.       x[4*k-3] = (s[k-1][r]/4)%2;
  188.       x[4*k-2] = (s[k-1][r]/2)%2;
  189.       x[4*k-1] = s[k-1][r]%2;
  190.    }
  191.    transpose( x, ptr, 32 );
  192. }
  193.  
  194. /*
  195.  * ENCRYPT - encryption algorithm
  196. */
  197. void encrypt( text, key )
  198. char *text, *key;
  199. {
  200.    int i, btext[64], bkey[64], b[64], x[64];
  201.     register int j;
  202.  
  203.     /*
  204.      * First Pad the text with NULL's, up to 8 chars
  205.      * We are assuming that there is room !!!
  206.     */
  207.     for (i = strlen(text); i <= 8; i++)
  208.         text[i] = '\0';
  209.  
  210.    text_to_bin( text, btext );
  211.    text_to_bin( key, bkey );
  212.    transpose( btext, InitialTr, 64 );
  213.    transpose( bkey, KeyTr1, 56 );
  214.    for( i=0; i<16; i++ ) {
  215.         copy( b, btext );
  216.         for( j=0; j<32; j++ ) btext[j] = b[j+32];
  217.       func( i, bkey, btext, x );
  218.       for( j=0; j<32; j++ ) btext[j+32] = b[j]^x[j];
  219.    }
  220.    transpose( btext, swap, 64 );
  221.    transpose( btext, FinalTr, 64 );
  222.    bin_to_text_64( btext, text );
  223. }
  224.  
  225.  
  226. /*
  227.  * DEFUNC - function for decryption
  228. */
  229. static void defunc( i, key, a, x )
  230. int i, key[], a[], x[]; 
  231. {
  232.    int e[64], y[64], ikey[64];
  233.     register int r, k, j;
  234.  
  235.     copy( e, a );
  236.    transpose( e, etr, 48 );
  237.     copy( ikey, key );
  238.    transpose( ikey, KeyTr2, 48 );
  239.    for(j=0; j<rots[i]; j++ ) transpose( key, rrotate, 56);
  240.    for( j=0; j<48; j++ ) y[j] = e[j]^ikey[j];
  241.    for( k=1; k<=8; k++ ) 
  242.     {
  243.       r = 32*y[6*k-6]+16*y[6*k-1]+8*y[6*k-5]+4*y[6*k-4]+2*y[6*k-3]+y[6*k-2];
  244.       x[4*k-4] = (s[k-1][r]/8)%2;
  245.       x[4*k-3] = (s[k-1][r]/4)%2;
  246.       x[4*k-2] = (s[k-1][r]/2)%2;
  247.       x[4*k-1] = s[k-1][r]%2;
  248.    }
  249.    transpose( x, ptr, 32 );
  250. }
  251.  
  252.  
  253. /*
  254.  * DECRYPT - decryption algorithm
  255. */
  256. void decrypt( text, key )
  257. char *text, *key;
  258. {
  259.    int i, btext[64], bkey[64], b[64], x[64];
  260.     register int j;
  261.  
  262.    text_to_bin_64( text, btext );
  263.    text_to_bin( key, bkey );
  264.    transpose( btext, InitialTr, 64 );
  265.    transpose( btext, swap, 64 );
  266.    transpose( bkey, KeyTr1, 56 );
  267.    for( i=15; i>=0; i-- ) 
  268.     {
  269.         copy( b, btext );
  270.         for( j=0; j<32; j++ ) btext[j+32] = b[j];
  271.       defunc( i, bkey, btext, x );
  272.       for( j=0; j<32; j++ ) btext[j] = b[j+32]^x[j];
  273.    }
  274.    transpose( btext, FinalTr, 64 );
  275.    bin_to_text( btext, text );
  276. }
  277.  
  278.  
  279. /*
  280.  * COPY - copy second integer array into first
  281. */
  282. static void copy( x, y )   
  283. int x[],y[];
  284. {
  285.     register int i;   
  286.    for(i=0; i<64; i++) x[i] = y[i];
  287. }
  288.  
  289.  
  290. /*
  291.  * BIN_TO_TEXT_64 - convert a 64 bit binary array into
  292.  * an 11 byte, 64-bitcode text string
  293. */
  294. void bin_to_text_64(bin, text)
  295. int bin[];
  296. unsigned char *text;
  297. {
  298.    unsigned int i, j, x;
  299.  
  300.    for (i = 0; i < 11; text[i++] = mapper[x])
  301.       for (x = 0, j = 0; j < 6 && i * 6 + j < 64; j++)
  302.          if (bin[i * 6 + j])
  303.         x |= 1 << (5 - j);
  304. }
  305.  
  306.  
  307. /*
  308.  * TEXT_TO_BIN_64 - convert an 11 byte, 64-bitcode text string into an
  309.  * array of integers
  310. */
  311. void text_to_bin_64(text, bin)
  312. unsigned char *text;
  313. int bin[];
  314. {
  315.    int i, j, k, x;
  316.  
  317.    for (j = 0, i = 0; i < 11; i++)
  318.    {
  319.       for (x = 0; x < 64; x++)
  320.      if (mapper[x] == text[i])
  321.         break;
  322.  
  323.       for (k = 0; k < 6 && j < 64; k++, x <<= 1)
  324.      bin[j++] = (x & 0x20) ? 1 : 0;
  325.    }
  326. }
  327.  
  328.  
  329. /*
  330.  * BIN_TO_TEXT - convert a 64 bit binary array into
  331.  * an 8 bit text string
  332. */
  333. void bin_to_text(bin, text)
  334. int bin[];
  335. unsigned char *text;
  336. {
  337.    unsigned int i, j;
  338.  
  339.    for (i = 0; i < 8; i++)
  340.       for (text[i] = 0, j = 0; j < 8; j++)
  341.          if (bin[(i << 3) | j])
  342.         text[i] |= 1 << (7 - j);
  343. }
  344.  
  345.  
  346. /*
  347.  * TEXT_TO_BIN - convert an 8 byte text string into an
  348.  * array of integers
  349. */
  350. void text_to_bin(text, bin)
  351. unsigned char *text;
  352. int bin[];
  353. {
  354.    int i;
  355.  
  356.    for (i = 0; i < 64; i++)
  357.       bin[i] = (text[i / 8] >> (7 - i % 8)) & 1;
  358. }
  359.