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