home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / des / des.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-19  |  21.4 KB  |  717 lines

  1. /* des: duplicate the NBS Data Encryption Standard in software.
  2.  * usage: des <file>
  3.  * prompts for the password
  4.  * If the filename ends in ".n" it will be decrypted with the key;
  5.  * otherwise it will be encrypted.
  6.  *
  7.  * Permutation algorithm:
  8.  *    The permutation is defined by its effect on each of the 16 nibbles
  9.  *    of the 64-bit input.  For each nibble we give an 8-byte bit array
  10.  *    that has the bits in the input nibble distributed correctly.  The
  11.  *    complete permutation involves ORing the 16 sets of 8 bytes designated
  12.  *    by the 16 input nibbles.  Uses 16*16*8 = 2K bytes of storage for
  13.  *    each 64-bit permutation.  32-bit permutations (P) and expansion (E)
  14.  *    are done similarly, but using bytes instead of nibbles.
  15.  *    Should be able to use long ints, adding the masks, at a
  16.  *    later pass.  Tradeoff: can speed 64-bit perms up at cost of slowing 
  17.  *    down expansion or contraction operations by using 8K tables here and
  18.  *    decreasing the size of the other tables.
  19.  * The compressions are pre-computed in 12-bit chunks, combining 2 of the
  20.  *    6->4 bit compressions.
  21.  * The key schedule is also precomputed.
  22.  * Compile with VALIDATE defined to run the NBS validation suite.
  23.  *
  24.  * Jim Gillogly, May 1977
  25.  * Modified 8/84 by Jim Gillogly and Lauren Weinstein to compile with
  26.  *   post-1977 C compilers and systems
  27.  *
  28.  * This program is now officially in the public domain, and is available for
  29.  * any non-profit use as long as the authorship line is retained.
  30.  */
  31.  
  32. /*#define VALIDATE    */    /* define to check the NBS validation suite */
  33. /*#define DEBUG     */
  34. /*#define LATTICE    */    /* define for Lattice C on IBM PC */
  35.  
  36. #include <stdio.h>
  37.  
  38. #ifndef LATTICE
  39. #include <sgtty.h>
  40. #include <signal.h>
  41. #include <sys/types.h>  /* for local timer */
  42. #include <sys/timeb.h>  /* ditto */
  43.  
  44. struct sgttyb ttybuf;            /* for gtty/stty         */
  45. int bye();                /* for caught interrupts     */
  46.  
  47. #endif
  48.  
  49. char iperm[16][16][8],fperm[16][16][8]; /* inital and final permutations*/
  50. char s[4][4096];            /* S1 thru S8 precomputed    */
  51. char p32[4][256][4];            /* for permuting 32-bit f output*/
  52. char kn[16][6];                /* key selections        */
  53.  
  54. endes(inblock,outblock)            /* encrypt 64-bit inblock    */
  55. char *inblock, *outblock;
  56. {    char iters[17][8];        /* workspace for each iteration */
  57.     char swap[8];            /* place to interchange L and R */
  58.     register int i;
  59.     register char *s, *t;
  60.  
  61.     permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  62.     for (i=0; i<16; i++)        /* 16 churning operations    */
  63.         iter(i,iters[i],iters[i+1]);
  64.                     /* don't re-copy to save space  */
  65.     s = swap; t = &iters[16][4];    /* interchange left        */
  66.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  67.     t = &iters[16][0];        /* and right            */
  68.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  69.     permute(swap,fperm,outblock);   /* apply final permutation    */
  70. }
  71.  
  72. dedes(inblock,outblock)            /* decrypt 64-bit inblock    */
  73. char *inblock,*outblock;
  74. {    char iters[17][8];        /* workspace for each iteration */
  75.     char swap[8];            /* place to interchange L and R */
  76.     register int i;
  77.     register char *s, *t;
  78.  
  79.     permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  80.     for (i=0; i<16; i++)        /* 16 churning operations    */
  81.         iter(15-i,iters[i],iters[i+1]);
  82.                     /* reverse order from encrypting*/
  83.     s = swap; t = &iters[16][4];    /* interchange left        */
  84.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  85.     t = &iters[16][0];        /* and right            */
  86.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  87.     permute(swap,fperm,outblock);   /* apply final permutation    */
  88. }
  89.  
  90. permute(inblock,perm,outblock)        /* permute inblock with perm    */
  91. char *inblock, *outblock;        /* result into outblock,64 bits */
  92. char perm[16][16][8];            /* 2K bytes defining perm.    */
  93. {    register int i,j;
  94.     register char *ib, *ob;        /* ptr to input or output block */
  95.     register char *p, *q;
  96.  
  97.     for (i=0, ob = outblock; i<8; i++)
  98.         *ob++ = 0;        /* clear output block        */
  99.     ib = inblock;
  100.     for (j = 0; j < 16; j += 2, ib++) /* for each input nibble    */
  101.     {    ob = outblock;
  102.         p = perm[j][(*ib >> 4) & 017];
  103.         q = perm[j + 1][*ib & 017];
  104.         for (i = 0; i < 8; i++)   /* and each output byte    */
  105.             *ob++ |= *p++ | *q++;   /* OR the masks together*/
  106.     }
  107. }
  108.  
  109. char ip[]                /* initial permutation P    */
  110. = {    58, 50, 42, 34, 26, 18, 10,  2,
  111.     60, 52, 44, 36, 28, 20, 12,  4,
  112.     62, 54, 46, 38, 30, 22, 14,  6,
  113.     64, 56, 48, 40, 32, 24, 16,  8,
  114.     57, 49, 41, 33, 25, 17,  9,  1,
  115.     59, 51, 43, 35, 27, 19, 11,  3,
  116.     61, 53, 45, 37, 29, 21, 13,  5,
  117.     63, 55, 47, 39, 31, 23, 15,  7    };
  118.  
  119. char fp[]                /* final permutation F      */
  120. = {    40,  8, 48, 16, 56, 24, 64, 32,
  121.     39,  7, 47, 15, 55, 23, 63, 31,
  122.     38,  6, 46, 14, 54, 22, 62, 30,
  123.     37,  5, 45, 13, 53, 21, 61, 29,
  124.     36,  4, 44, 12, 52, 20, 60, 28,
  125.     35,  3, 43, 11, 51, 19, 59, 27,
  126.     34,  2, 42, 10, 50, 18, 58, 26,
  127.     33,  1, 41,  9, 49, 17, 57, 25    };
  128.  
  129. /* expansion operation matrix   */    /* rwo: unused    */
  130. /* char ei[] = {    32,  1,  2,  3,  4,  5,
  131.      4,  5,  6,  7,  8,  9,
  132.      8,  9, 10, 11, 12, 13,
  133.     12, 13, 14, 15, 16, 17,
  134.     16, 17, 18, 19, 20, 21,
  135.     20, 21, 22, 23, 24, 25,
  136.     24, 25, 26, 27, 28, 29,
  137.     28, 29, 30, 31, 32,  1  };    */
  138.  
  139. char pc1[]                /* permuted choice table (key)  */
  140. = {    57, 49, 41, 33, 25, 17,  9,
  141.      1, 58, 50, 42, 34, 26, 18,
  142.     10,  2, 59, 51, 43, 35, 27,
  143.     19, 11,  3, 60, 52, 44, 36,
  144.  
  145.     63, 55, 47, 39, 31, 23, 15,
  146.      7, 62, 54, 46, 38, 30, 22,
  147.     14,  6, 61, 53, 45, 37, 29,
  148.     21, 13,  5, 28, 20, 12,  4    };
  149.  
  150. char totrot[]               /* number left rotations of pc1 */
  151. = {    1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28    };
  152.  
  153. char pc1m[56];              /* place to modify pc1 into    */
  154. char pcr[56];               /* place to rotate pc1 into    */
  155.  
  156. char pc2[]                /* permuted choice key (table)  */
  157. = {    14, 17, 11, 24,  1,  5,
  158.      3, 28, 15,  6, 21, 10,
  159.     23, 19, 12,  4, 26,  8,
  160.     16,  7, 27, 20, 13,  2,
  161.     41, 52, 31, 37, 47, 55,
  162.     30, 40, 51, 45, 33, 48,
  163.     44, 49, 39, 56, 34, 53,
  164.     46, 42, 50, 36, 29, 32    };
  165.  
  166. char si[8][64]              /* 48->32 bit compression tables*/
  167. = {                    /* S[1]             */
  168.     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  169.      0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  170.      4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  171.     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  172.                     /* S[2]             */
  173.     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  174.      3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  175.      0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  176.     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
  177.                     /* S[3]             */
  178.     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  179.     13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  180.     13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  181.      1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  182.                     /* S[4]             */
  183.      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  184.     13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  185.     10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  186.      3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  187.                     /* S[5]             */
  188.      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  189.     14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  190.      4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  191.     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  192.                     /* S[6]             */
  193.     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  194.     10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  195.      9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  196.      4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  197.                     /* S[7]             */
  198.      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  199.     13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  200.      1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  201.      6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  202.                     /* S[8]             */
  203.     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  204.      1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  205.      7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  206.      2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11    };
  207.  
  208. char p32i[]                /* 32-bit permutation function  */
  209. = {    16,  7, 20, 21,
  210.     29, 12, 28, 17,
  211.      1, 15, 23, 26,
  212.      5, 18, 31, 10,
  213.      2,  8, 24, 14,
  214.     32, 27,  3,  9,
  215.     19, 13, 30,  6,
  216.     22, 11,  4, 25    };
  217.  
  218. desinit(key)                /* initialize all des arrays    */
  219. char *key;
  220. {
  221. #ifdef DEBUG
  222. /*deb*/ printf("Initial perm init.\n");
  223. #endif
  224.     perminit(iperm,ip);        /* initial permutation        */
  225. #ifdef DEBUG
  226. /*deb*/ printf("Final perm init.\n");
  227. #endif
  228.     perminit(fperm,fp);        /* final permutation        */
  229. #ifdef DEBUG
  230. /*deb*/ printf("Key sched init.\n");
  231. #endif
  232.     kinit(key);            /* key schedule            */
  233. #ifdef DEBUG
  234. /*deb*/ printf("Compression init.\n");
  235. #endif
  236.     sinit();            /* compression functions    */
  237.  
  238. #ifdef DEBUG
  239. /*deb*/ printf("32-bit perm init.\n");
  240. #endif
  241.     p32init();            /* 32-bit permutation in f    */
  242. #ifdef DEBUG
  243. /*deb*/ printf("End init.\n");
  244. #endif
  245. }
  246.  
  247. int bytebit[]               /* bit 0 is left-most in byte    */
  248.     = {    0200,0100,040,020,010,04,02,01 };
  249.  
  250. int nibblebit[] = { 010,04,02,01 };
  251.  
  252. sinit()                 /* initialize s1-s8 arrays        */
  253. {    register int i,j;
  254.  
  255.     for (i=0; i<4; i++)        /* each 12-bit position        */
  256.         for (j=0; j<4096; j++)  /* each possible 12-bit value   */
  257.             s[i][j]=(getcomp(i*2,j>>6)<<4) |
  258.                 (017&getcomp(i*2+1,j&077));
  259.                     /* store 2 compressions per char*/
  260. }
  261.  
  262. getcomp(k,v)                /* 1 compression value for sinit*/
  263. int k,v;
  264. {    register int i,j;        /* correspond to i and j in FIPS*/
  265.  
  266.     i=((v&040)>>4)|(v&1);        /* first and last bits make row */
  267.     j=(v&037)>>1;            /* middle 4 bits are column    */
  268.     return (int) si[k][(i<<4)+j];   /* result is ith row, jth col   */
  269. }
  270.  
  271. kinit(key)                /* initialize key schedule array*/
  272. char *key;                /* 64 bits (will use only 56)   */
  273. {    register int i,j,l;
  274.     int m;
  275.  
  276.     for (j=0; j<56; j++)        /* convert pc1 to bits of key   */
  277.     {    l=pc1[j]-1;        /* integer bit location        */
  278.         m = l & 07;        /* find bit            */
  279.         pc1m[j]=(key[l>>3] &    /* find which key byte l is in  */
  280.             bytebit[m])    /* and which bit of that byte   */
  281.             ? 1 : 0;    /* and store 1-bit result    */
  282.     }
  283.     for (i=0; i<16; i++)        /* for each key sched section   */
  284.         for (j=0; j<6; j++)    /* and each byte of the kn    */
  285.             kn[i][j]=0;    /* clear it for accumulation    */
  286.     for (i=0; i<16; i++)        /* key chunk for each iteration */
  287.     {    for (j=0; j<56; j++)    /* rotate pc1 the right amount  */
  288.         pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  289.             /* rotate left and right halves independently   */
  290.         for (j=0; j<48; j++)    /* select bits individually    */
  291.         if (pcr[pc2[j]-1])    /* check bit that goes to kn[j] */
  292.             {    l= j & 07;
  293.                 kn[i][j>>3] |= bytebit[l];
  294.             }        /* mask it in if it's there    */
  295.     }
  296. }
  297.  
  298. p32init()                /* initialize 32-bit permutation*/
  299. {    register int l, j, k;
  300.     int i,m;
  301.  
  302.     for (i=0; i<4; i++)        /* each input byte position    */
  303.         for (j=0; j<256; j++)    /* all possible input bytes    */
  304.         for (k=0; k<4; k++)    /* each byte of the mask    */
  305.             p32[i][j][k]=0;    /* clear permutation array    */
  306.     for (i=0; i<4; i++)        /* each input byte position    */
  307.         for (j=0; j<256; j++)    /* each possible input byte    */
  308.         for (k=0; k<32; k++)    /* each output bit position    */
  309.         {   l=p32i[k]-1;    /* invert this bit (0-31)    */
  310.             if ((l>>3)!=i)    /* does it come from input posn?*/
  311.             continue;    /* if not, bit k is 0        */
  312.             if (!(j&bytebit[l&07]))
  313.             continue;    /* any such bit in input?    */
  314.             m = k & 07;     /* which bit is it?        */
  315.             p32[i][j][k>>3] |= bytebit[m];
  316.         }
  317. }
  318.  
  319. perminit(perm,p)            /* initialize a perm array    */
  320. char perm[16][16][8];            /* 64-bit, either init or final */
  321. char p[64];
  322. {    register int l, j, k;
  323.     int i,m;
  324.  
  325.     for (i=0; i<16; i++)        /* each input nibble position   */
  326.         for (j=0; j<16; j++)    /* all possible input nibbles   */
  327.         for (k=0; k<8; k++)    /* each byte of the mask    */
  328.             perm[i][j][k]=0;/* clear permutation array    */
  329.     for (i=0; i<16; i++)        /* each input nibble position   */
  330.         for (j = 0; j < 16; j++)/* each possible input nibble   */
  331.         for (k = 0; k < 64; k++)/* each output bit position    */
  332.         {   l = p[k] - 1;    /* where does this bit come from*/
  333.             if ((l >> 2) != i)  /* does it come from input posn?*/
  334.             continue;    /* if not, bit k is 0        */
  335.             if (!(j & nibblebit[l & 3]))
  336.             continue;    /* any such bit in input?    */
  337.             m = k & 07;    /* which bit is this in the byte*/
  338.             perm[i][j][k>>3] |= bytebit[m];
  339.         }
  340. }
  341.  
  342. iter(num,inblock,outblock)        /* 1 churning operation        */
  343. int num;                /* i.e. the num-th one        */
  344. char *inblock, *outblock;        /* 64 bits each            */
  345. {    char fret[4];            /* return from f(R[i-1],key)    */
  346.     register char *ib, *ob, *fb;
  347. /*    register int i;    */    /* rwo: unused    */
  348.  
  349.     ob = outblock; ib = &inblock[4];
  350.     f(ib, num, fret);        /* the primary transformation   */
  351.     *ob++ = *ib++;            /* L[i] = R[i-1]        */
  352.     *ob++ = *ib++;
  353.     *ob++ = *ib++;
  354.     *ob++ = *ib++;
  355.     ib = inblock; fb = fret;    /* R[i]=L[i] XOR f(R[i-1],key)  */
  356.     *ob++ = *ib++ ^ *fb++;
  357.     *ob++ = *ib++ ^ *fb++;
  358.     *ob++ = *ib++ ^ *fb++;
  359.     *ob++ = *ib++ ^ *fb++;
  360. }
  361.  
  362. f(right,num,fret)            /* critical cryptographic trans */
  363. char *right, *fret;            /* 32 bits each            */
  364. int num;                /* index number of this iter    */
  365. {    register char *kb, *rb, *bb;    /* ptr to key selection &c    */
  366.     char bigright[6];        /* right expanded to 48 bits    */
  367.     char result[6];            /* expand(R) XOR keyselect[num] */
  368.     char preout[4];            /* result of 32-bit permutation */
  369.  
  370.     kb = kn[num];            /* fast version of iteration    */
  371.     bb = bigright;
  372.     rb = result;
  373.     expand(right,bb);        /* expand to 48 bits        */
  374.     *rb++ = *bb++ ^ *kb++;        /* expanded R XOR chunk of key  */
  375.     *rb++ = *bb++ ^ *kb++;
  376.     *rb++ = *bb++ ^ *kb++;
  377.     *rb++ = *bb++ ^ *kb++;
  378.     *rb++ = *bb++ ^ *kb++;
  379.     *rb++ = *bb++ ^ *kb++;
  380.     contract(result,preout);    /* use S fns to get 32 bits    */
  381.     perm32(preout,fret);        /* and do final 32-bit perm    */
  382. }
  383.  
  384. perm32(inblock,outblock)        /* 32-bit permutation at end    */
  385. char *inblock,*outblock;        /* of the f crypto function    */
  386. {    register int j;
  387. /*    register int i;    */    /* rwo: unused    */
  388.     register char *ib, *ob;
  389.     register char *q;
  390.  
  391.     ob = outblock;            /* clear output block        */
  392.     *ob++ = 0; *ob++ = 0; *ob++ = 0; *ob++ = 0;
  393.     ib=inblock;            /* ptr to 1st byte of input    */
  394.     for (j=0; j<4; j++, ib++)    /* for each input byte        */
  395.     {    q = p32[j][*ib & 0377];
  396.         ob = outblock;        /* and each output byte        */
  397.         *ob++ |= *q++;        /* OR the 16 masks together    */
  398.         *ob++ |= *q++;
  399.         *ob++ |= *q++;
  400.         *ob++ |= *q++;
  401.     }
  402. }
  403.  
  404. expand(right,bigright)            /* 32 to 48 bits with E oper    */
  405. char *right,*bigright;            /* right is 32, bigright 48    */
  406. {
  407.     register char *bb, *r, r0, r1, r2, r3;
  408.  
  409.     bb = bigright;
  410.     r = right; r0 = *r++; r1 = *r++; r2 = *r++; r3 = *r++;
  411.     *bb++ = ((r3 & 0001) << 7) |    /* 32                */
  412.         ((r0 & 0370) >> 1) |    /* 1 2 3 4 5            */
  413.         ((r0 & 0030) >> 3);    /* 4 5                */
  414.     *bb++ = ((r0 & 0007) << 5) |    /* 6 7 8            */
  415.         ((r1 & 0200) >> 3) |    /* 9                */
  416.         ((r0 & 0001) << 3) |    /* 8                */
  417.         ((r1 & 0340) >> 5);    /* 9 10 11            */
  418.     *bb++ = ((r1 & 0030) << 3) |    /* 12 13            */
  419.         ((r1 & 0037) << 1) |    /* 12 13 14 15 16        */
  420.         ((r2 & 0200) >> 7);    /* 17                */
  421.     *bb++ = ((r1 & 0001) << 7) |    /* 16                */
  422.         ((r2 & 0370) >> 1) |    /* 17 18 19 20 21        */
  423.         ((r2 & 0030) >> 3);    /* 20 21            */
  424.     *bb++ = ((r2 & 0007) << 5) |    /* 22 23 24            */
  425.         ((r3 & 0200) >> 3) |    /* 25                */
  426.         ((r2 & 0001) << 3) |    /* 24                */
  427.         ((r3 & 0340) >> 5);    /* 25 26 27            */
  428.     *bb++ = ((r3 & 0030) << 3) |    /* 28 29            */
  429.         ((r3 & 0037) << 1) |    /* 28 29 30 31 32        */
  430.         ((r0 & 0200) >> 7);    /* 1                */
  431. }
  432.  
  433. contract(in48,out32)            /* contract f from 48 to 32 bits*/
  434. char *in48,*out32;            /* using 12-bit pieces into bytes */
  435. {    register char *c;
  436.     register char *i;
  437.     register int i0, i1, i2, i3, i4, i5;
  438.  
  439.     i = in48;
  440.     i0 = *i++; i1 = *i++; i2 = *i++; i3 = *i++; i4 = *i++; i5 = *i++;
  441.     c = out32;            /* do output a byte at a time   */
  442.     *c++ = s[0][07777 & ((i0 << 4) | ((i1 >> 4) & 017  ))];
  443.     *c++ = s[1][07777 & ((i1 << 8) | ( i2    & 0377 ))];
  444.     *c++ = s[2][07777 & ((i3 << 4) | ((i4 >> 4) & 017  ))];
  445.     *c++ = s[3][07777 & ((i4 << 8) | ( i5    & 0377 ))];
  446. }
  447.  
  448. /* End of DES algorithm (except for calling desinit below)    */
  449.  
  450. #ifndef VALIDATE
  451. char *inname, *outname;
  452. FILE *infile, *outfile;
  453.  
  454. int encrypting;
  455. char buf[512];
  456. char keyx[9], keyy[9];
  457.  
  458. char *malloc(), *strcpy(), *strcat();
  459.  
  460. main(argc, argv)
  461. int argc; char *argv[];
  462. {    register char *u;
  463.     char *filename;
  464.  
  465.     if (argc < 2)            /* filenames given? */
  466.     {  fprintf(stderr, "Usage: des file ...\n");
  467.        exit(1);     
  468.     }
  469.  
  470.     for (++argv; --argc; ++argv)
  471.     {    inname = *argv;
  472.         outname = filename = malloc((unsigned) strlen(inname) + 3);
  473.         strcpy(filename, inname);
  474.         u = &filename[strlen(filename) - 2]; /* check last 2 chars */
  475.  
  476.         encrypting = (strcmp(".n", u) != 0);
  477.         if (!encrypting) *u = 0; /* strip .n from output filename */
  478.         else strcat(filename, ".n");  /* or add .n to output file */
  479.  
  480.         if ((infile = fopen(inname, "rb")) == NULL)
  481.         {    fprintf(stderr,"Can't read %s.\n", inname);
  482.             exit(1);
  483.         }
  484.         if ((outfile = fopen(outname, "rb")) != NULL)
  485.         {    fprintf(stderr, "%s would be overwritten.\n",outname);
  486.             exit(1);
  487.         }
  488.         if ((outfile = fopen(outname, "wb")) == NULL)
  489.         {    fprintf(stderr,"Can't write %s.\n", outname);
  490.             exit(1);
  491.         }
  492.  
  493.         key_get("Type password for ");
  494.         for (;;)
  495.         {    strcpy(keyx, keyy);
  496.             key_get("Verify password for ");
  497.             if (strcmp(keyx, keyy) == 0) break;
  498.         }
  499.         desinit(keyx);      /* set up tables for DES    */
  500.  
  501.         if (pfile() == 0) unlink(inname);
  502.         else    fprintf(stderr,
  503.                "%s: I/O Error -- File unchanged\n", inname);
  504.  
  505.         fclose(outfile);
  506.         fclose(infile);
  507.     }
  508.     exit(0);
  509. }
  510.  
  511. key_get(mes)            /* get file key */
  512. char *mes;
  513. {    register int i, j;
  514.     char linebuf[256];
  515.     int count;
  516.  
  517.     for (i=0; i<14; i++) keyy[i]=0;
  518.  
  519. #ifdef LATTICE
  520. #else
  521.     gtty(0, &ttybuf);
  522.     ttybuf.sg_flags &= ~ECHO;  /* turn off echoing */
  523.     signal(SIGINT, bye);    /* catch ints */
  524.     stty(0, &ttybuf);
  525. #endif
  526.  
  527.     printf("%s%s: ", mes, inname);
  528.     fflush(stdout);
  529.  
  530.     count = read(0, linebuf, 256);  /* read input line */
  531.     printf("\n");
  532.  
  533. #ifndef LATTICE
  534.     ttybuf.sg_flags |= ECHO;      /* restore echo */
  535.     stty(0, &ttybuf);
  536. #endif
  537.  
  538.     linebuf[count] = 0;  /* null terminate */
  539.     if (linebuf[count-1] == '\n')  /* ignore any terminating newline */
  540.     {  linebuf[count-1] = 0;
  541.        count--;     
  542.     }
  543.     if (count > 8) count = 8;    /* only use 8 chars */
  544.     for (i = j = 0; count--;)
  545.        keyy[i++] = linebuf[j++];
  546. }
  547.  
  548. pfile()                 /* process the file        */
  549. {    register int m, nsave;
  550.     register char *b;
  551.     int j;
  552.  
  553.     while (m = fread(buf, 1, 512, infile))
  554.     {
  555.         if ((nsave = m) < 0)    /* read error            */
  556.         return(-1);
  557.         for (b=buf; m>0;    /* encrypt/decrypt 1 buffer-full*/
  558.         m -= 8, b += 8)        /* 8-byte blocks        */
  559.         {   if (encrypting)
  560.         {   if (m<8)        /* don't have a full 64 bits    */
  561.             {   for (j=0; j<8-m; j++)
  562.                 b[m+j]=garbage(); /* fill block with trash  */
  563.             nsave += 8-m;   /* complete the block        */
  564.             }
  565.             else j=0;    /* number of nulls in last block*/
  566.             endes(b,b);    /* don't need diff input, output*/
  567.         }
  568.         else            /* decrypting            */
  569.         {   if (m < 8) deout(b, 1); /* last byte in file: count */
  570.             else
  571.             {   dedes(b, b); /* decrypt and output block    */
  572.             deout(b, 0);
  573.             }
  574.         }
  575.         }
  576.         if (encrypting) if (fwrite(buf, 1, nsave, outfile) != nsave)
  577.             return(-1);
  578.     }
  579.     /* have now encrypted/decrypted the whole file;
  580.      * need to append the byte count for the last block if encrypting.
  581.      */
  582.     if (encrypting) fputc(8 - j, outfile);  /* how many good bytes? */
  583.     return(0);
  584. }
  585.  
  586. int outcount = 0;            /* see when caught up with delay*/
  587.  
  588. deout(block,flag)            /* 1-block delay on output    */
  589. char *block,flag;            /* 64-bit block, last block flag*/
  590. {    static char last[8];        /* previous input block        */
  591.     register int i;
  592. /*    register char *c,*j;    */    /* rwo: unused    */
  593.  
  594.     if (flag)            /* output the last few bytes    */
  595.     {
  596.         fwrite(last, 1, block[0] & 0377, outfile);
  597.         return;
  598.     }
  599.     if (outcount++)            /* seen any blocks before?    */
  600.         fwrite(last, 1, 8, outfile);
  601.     for (i = 0; i < 8; i++) last[i] = block[i]; /* copy the block   */
  602. }
  603.  
  604. garbage()                /* generate garbage for filling */
  605. /* This garbage should be as random as possible.  We're using subsequent calls
  606.  * on the timer, but ideally each byte should be uncorrelated.  Preferable
  607.  * would be to call the timer once and use it to initialize a dumb random
  608.  * number generator.
  609.  */
  610. {
  611. #ifdef LATTICE
  612.     long timer(), ltime;
  613.  
  614.     ltime = timer();
  615.     return (int) ltime & 0377;
  616. #else
  617.     struct timeb tp;
  618.  
  619.     ftime(&tp);            /* get current time        */
  620.     return tp.millitm;        /* return time in milliseconds  */
  621. #endif
  622. }
  623.  
  624. #ifndef LATTICE
  625.  
  626. /* restore echo to tty and exit */
  627. bye()
  628. {
  629.     ttybuf.sg_flags |= ECHO;  /* restore echoing */
  630.     stty(0, &ttybuf);
  631.     exit(2);
  632. }
  633.  
  634. #endif
  635.  
  636. #else       /* validation */
  637.  
  638. #define VALFILE "valid.triples"
  639.  
  640. FILE *fd;
  641.  
  642. char key[8], plain[8], cipher[8], processed[8];
  643.  
  644. main()  /* read key/plain/cipher triples until exhausted */
  645. {    int count, i;
  646.  
  647.     if ((fd = fopen(VALFILE, "r")) == NULL)
  648.     {    fprintf(stderr, "Can't read %s.\n", VALFILE);
  649.         exit(1);
  650.     }
  651.     count = 0;
  652.     desinit(key);        /* initialize most of the arrays */
  653.     while (readvals())
  654.     {    kinit(key);    /* initialize key stuff        */
  655.         printf("Key: "); writehex(key);
  656.         printf("  Plain: "); writehex(plain);
  657.         printf("  Cipher: "); writehex(cipher);
  658.         printf("\n");
  659.         endes(plain, processed); /* encipher the plaintext */
  660.         printf("Encry:  "); writehex(processed);
  661.         printf("\n");
  662.         for (i = 0; i < 8; i++)
  663.             if (processed[i] != cipher[i])
  664.                 printf("Encryption failed.\n");
  665.         dedes(cipher, processed); /* decipher the ciphertext */
  666.         printf("Decry:  "); writehex(processed);
  667.         printf("\n");
  668.         for (i = 0; i < 8; i++)
  669.             if (processed[i] != plain[i])
  670.                 printf("Decryption failed.\n");
  671.         count++;
  672.     }
  673.     printf("Processed %d tests.\n", count);
  674. }
  675.  
  676. readvals()    /* get the next legit triple */
  677. {    int r;
  678.  
  679.     r = readhex(key);
  680.     readhex(plain);
  681.     readhex(cipher);
  682.     return r;
  683. }
  684.  
  685. writehex(str)   /* write the 64-bit hex string */
  686. char *str;
  687. {    int i;
  688.  
  689.     for (i = 0; i < 8; i++)
  690.         printf("%02x", str[i] & 0377);
  691. }
  692.  
  693. hex(n)  /* convert hex nibble into integer */
  694. int n;
  695. {
  696.     if (n >= 'A' && n <= 'F') return n - 'A' + 10;
  697.     return n - '0';
  698. }
  699.  
  700. readhex(str)    /* read 64 bits of hex code */
  701. char *str;
  702. {    int i, c;
  703.  
  704.     for (i = 0; i < 8; i++)
  705.     {    c = hex(getc(fd)) << 4;
  706.         str[i] = c | hex(getc(fd));
  707.     }
  708.     while ((c = getc(fd)) == ' ' || c == '\t' || c == '\n');
  709.     ungetc(c, fd);  /* skip to next field */
  710.     return c != EOF;
  711. }
  712.  
  713. #endif
  714.  
  715. /************ end scrydes ************/
  716.  
  717.