home *** CD-ROM | disk | FTP | other *** search
/ MPEG Toolkit / MPEG Toolkit.iso / dos / secmpeg3 / des.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-01  |  10.7 KB  |  548 lines

  1.  
  2. /* --- C ---
  3. ************************************************************************
  4. *
  5. *    Filename    : des.c
  6. *    Description : Crypting routines
  7. *    Part of     : SECMPEG
  8. *
  9. *    Version     : 1.0
  10. *    Language    : C
  11. *    For machine : SunOS 4.1.x, INTERACTIVE Unix 2.2.1, Linux, MS-DOS
  12. *    Compile as  : see Makefile
  13. *
  14. *    Authors     : Juergen Meyer, Frank Gadegast
  15. *    Contact     : jm@cs.tu-berlin.de, phade@cs.tu-berlin.de
  16. *
  17. ************************************************************************
  18. */
  19.  
  20. #include <stdio.h>
  21. #include <fcntl.h>
  22. #include <string.h>
  23. #include "defs.h"
  24. #include "des.h"
  25.  
  26. /* ------ DEFINES ------ */
  27.  
  28. /*
  29. #define LITTLE_ENDIAN
  30. */
  31. #ifdef DOS
  32.    #define bcopy(src,dest,size)  memcpy(dest,src,size)
  33.    #define bzero(dest,size)      memset(dest,0,size)
  34. #endif
  35.  
  36. /* ------ PUBLIC ------ */
  37.  
  38. int    desinit();
  39. void    desdone();
  40. int     Encrypt(char *,unsigned long);
  41. int     Decrypt(char *,unsigned long);
  42. char    *string_to_key(char *);
  43. void    setdeskey(char *);
  44.  
  45. /* ------ PRIVAT ------ */
  46.  
  47. static void permute(char *,char [16][16][8],char *);
  48. static void round(int,unsigned long *);
  49. static long f(unsigned long,unsigned char [8]);
  50. static void perminit(char [16][16][8],char [64]);
  51. static int  spinit();
  52. static void endes(char *);
  53. static void dedes(char *);
  54. static void endes_cbc(char *);
  55. static void endes_ecb(char *);
  56. static void dedes_cbc(char *);
  57. static void dedes_ecb(char *);
  58.  
  59. #ifdef    LITTLE_ENDIAN
  60. static unsigned long byteswap(unsigned long);
  61. #endif
  62.  
  63.  
  64.  
  65.  
  66. int    Encrypt(char *buffer,unsigned long len)
  67. {
  68.     unsigned long nblocks;
  69.     char          *block;
  70.  
  71.     block = buffer;
  72.  
  73.     nblocks = len / 8;
  74.  
  75.            while(nblocks--)
  76.     {
  77.         endes_ecb(block);
  78.         block += 8;
  79.     }
  80.     return(1);
  81. }
  82.  
  83. int    Decrypt(char *buffer,unsigned long len)
  84. {
  85.     unsigned long nblocks;
  86.     char          *block;
  87.  
  88.     block = buffer;
  89.  
  90.     nblocks = len / 8;
  91.     while(nblocks--)
  92.     {
  93.         dedes_ecb(block);
  94.         block += 8;
  95.     }
  96.     return(1);
  97. }
  98.  
  99.  
  100. char    *string_to_key(char *asckey)
  101. {
  102.     register char    *p;
  103.     register int    i;
  104.     char    k1[8], k2[8];
  105.     char    *key = NULL;
  106.  
  107.     if (!(key = (char *)malloc(8)))
  108.     {
  109.         fprintf(stderr,"key\n");
  110.         return(NULL);
  111.     }
  112.     if (DESINIT == FALSE) {
  113.         if (desinit(0) < 0)
  114.         {
  115.             fprintf(stderr,"desinit failed\n");
  116.             free(key);
  117.             return(NULL);
  118.         }
  119.  
  120.         DESINIT = TRUE;
  121.     }
  122.  
  123.  
  124.     for (i = 0; i < 8; i++)
  125.     {
  126.         k1[i] = k2[i] = 0;
  127.     }
  128.     for (i = 0, p = asckey; *p; p++, i++)
  129.     {
  130.         i %= 8;
  131.         k1[i] |= *p;
  132.         k2[i] |= *p;
  133.         setdeskey((char *)des_hash_key1);
  134.         endes(k1);
  135.         setdeskey((char *)des_hash_key2);
  136.         endes(k2);
  137.     }
  138.     for (i = 0; i < 8; i++)
  139.     {
  140.         key[i] = k1[i] ^ k2[i];
  141.     }
  142.     return(key);
  143. }
  144.  
  145.  
  146. int     desinit()
  147. {
  148. #ifdef DEBUG
  149.     fprintf(stderr," desinit \n");
  150. #endif
  151.     if(sp != NULL)
  152.     {
  153.         /* Already initialized */
  154.         return 0;
  155.     }
  156.  
  157.     if((sp = (long (*)[64])malloc(sizeof(long) * 8 * 64)) == NULL)
  158.     {
  159.         return -1;
  160.     }
  161.     spinit();
  162.     kn = (unsigned char (*)[8])malloc(sizeof(char) * 8 * 16);
  163.     if(kn == NULL){
  164.         free((char *)sp);
  165.         return -1;
  166.     }
  167.  
  168.     iperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
  169.     if(iperm == NULL){
  170.         free((char *)sp);
  171.         free((char *)kn);
  172.         return -1;
  173.     }
  174.     perminit(iperm,ip);
  175.  
  176.     fperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
  177.     if(fperm == NULL)
  178.     {
  179.         free((char *)sp);
  180.         free((char *)kn);
  181.         free((char *)iperm);
  182.         return -1;
  183.     }
  184.     perminit(fperm,fp);
  185.     DESINIT = TRUE;
  186.     return 0;
  187. }
  188.  
  189. /* Free up storage used by DES */
  190.  
  191. void     desdone()
  192. {
  193.     if(sp == NULL)
  194.         return;    /* Already done */
  195.  
  196.     free((char *)sp);
  197.     free((char *)kn);
  198.     if(iperm != NULL)
  199.         free((char *)iperm);
  200.     if(fperm != NULL)
  201.         free((char *)fperm);
  202.  
  203.     sp = NULL;
  204.     iperm = NULL;
  205.     fperm = NULL;
  206.     kn = NULL;
  207. }
  208.  
  209.  
  210.  
  211. void get8(char *cp)
  212. {
  213.     int i,t;
  214.  
  215.     for(i=0;i<8;i++){
  216.         scanf("%2x",&t);
  217.         if(feof(stdin))
  218.             exit(0);
  219.         *cp++ = t;
  220.     }
  221. }
  222. void put8(char *cp)
  223. {
  224.     int i;
  225.  
  226.     for(i=0;i<8;i++){
  227.         printf("%02x",*cp++ & 0xff);
  228.     }
  229. }
  230.  
  231.  
  232.  
  233. /* Set key (initialize key schedule array) */
  234.  
  235. void setdeskey(char *key)    /* 64 bits (will use only 56) */
  236. {
  237.     char pc1m[56];        /* place to modify pc1 into */
  238.     char pcr[56];        /* place to rotate pc1 into */
  239.     register int i,j,l;
  240.     int m;
  241.  
  242.     /* Clear key schedule */
  243.     for (i=0; i<16; i++)
  244.         for (j=0; j<8; j++)
  245.             kn[i][j]=0;
  246.  
  247.     for (j=0; j<56; j++) {        /* convert pc1 to bits of key */
  248.         l=pc1[j]-1;        /* integer bit location     */
  249.         m = l & 07;        /* find bit         */
  250.         pc1m[j]=(key[l>>3] &    /* find which key byte l is in */
  251.             bytebit[m])    /* and which bit of that byte */
  252.             ? 1 : 0;    /* and store 1-bit result */
  253.     }
  254.     for (i=0; i<16; i++) {        /* key chunk for each iteration */
  255.         for (j=0; j<56; j++)    /* rotate pc1 the right amount */
  256.             pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  257.             /* rotate left and right halves independently */
  258.         for (j=0; j<48; j++){    /* select bits individually */
  259.             /* check bit that goes to kn[j] */
  260.             if (pcr[pc2[j]-1]){
  261.                 /* mask it in if it's there */
  262.                 l= j % 6;
  263.                 kn[i][j/6] |= bytebit[l] >> 2;
  264.             }
  265.         }
  266.     }
  267. }
  268.  
  269. /* In-place encryption of 64-bit block */
  270. static void    endes(char *block)
  271. {
  272.     register int i;
  273.     unsigned long work[2];         /* Working data storage */
  274.     long tmp;
  275.  
  276.     permute(block,iperm,(char *)work);    /* Initial Permutation */
  277. #ifdef LITTLE_ENDIAN
  278.     work[0] = byteswap(work[0]);
  279.     work[1] = byteswap(work[1]);
  280. #endif
  281.  
  282.     /* Do the 16 rounds */
  283.     for (i=0; i<16; i++)
  284.         round(i,work);
  285.  
  286.     /* Left/right half swap */
  287.     tmp = work[0];
  288.     work[0] = work[1];    
  289.     work[1] = tmp;
  290.  
  291. #ifdef LITTLE_ENDIAN
  292.     work[0] = byteswap(work[0]);
  293.     work[1] = byteswap(work[1]);
  294. #endif
  295.     permute((char *)work,fperm,block);    /* Inverse initial permutation */
  296. }
  297.  
  298.  
  299. /* In-place decryption of 64-bit block */
  300. static void dedes(char *block)
  301. {
  302.     register int i;
  303.     unsigned long work[2];    /* Working data storage */
  304.     long tmp;
  305.  
  306.     permute(block,iperm,(char *)work);    /* Initial permutation */
  307.  
  308. #ifdef LITTLE_ENDIAN
  309.     work[0] = byteswap(work[0]);
  310.     work[1] = byteswap(work[1]);
  311. #endif
  312.  
  313.     /* Left/right half swap */
  314.     tmp = work[0];
  315.     work[0] = work[1];    
  316.     work[1] = tmp;
  317.  
  318.     /* Do the 16 rounds in reverse order */
  319.     for (i=15; i >= 0; i--)
  320.         round(i,work);
  321.  
  322. #ifdef LITTLE_ENDIAN
  323.     work[0] = byteswap(work[0]);
  324.     work[1] = byteswap(work[1]);
  325. #endif
  326.  
  327.     permute((char *)work,fperm,block);    /* Inverse initial permutation */
  328. }
  329.  
  330. /* Permute inblock with perm */
  331. static void permute(char *inblock,char perm[16][16][8],char *outblock)
  332. {
  333.     register int i,j;
  334.     register char *ib, *ob;        /* ptr to input or output block */
  335.     register char *p, *q;
  336.  
  337.     if(perm == NULL){
  338.         /* No permutation, just copy */
  339.         for(i=8; i!=0; i--)
  340.             *outblock++ = *inblock++;
  341.         return;
  342.     }
  343.     /* Clear output block     */
  344.     for (i=8, ob = outblock; i != 0; i--)
  345.         *ob++ = 0;
  346.  
  347.     ib = inblock;
  348.     for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
  349.         ob = outblock;
  350.         p = perm[j][(*ib >> 4) & 017];
  351.         q = perm[j + 1][*ib & 017];
  352.         for (i = 8; i != 0; i--){   /* and each output byte */
  353.             *ob++ |= *p++ | *q++;    /* OR the masks together*/
  354.         }
  355.     }
  356. }
  357.  
  358. /* Do one DES cipher round */
  359. static void round(int num,unsigned long *block)
  360. {
  361.     long f();
  362.  
  363.     /* The rounds are numbered from 0 to 15. On even rounds
  364.      * the right half is fed to f() and the result exclusive-ORs
  365.      * the left half; on odd rounds the reverse is done.
  366.      */
  367.     if(num & 1){
  368.         block[1] ^= f(block[0],kn[num]);
  369.     } else {
  370.         block[0] ^= f(block[1],kn[num]);
  371.     }
  372. }
  373. /* The nonlinear function f(r,k), the heart of DES */
  374. static long f(unsigned long r,unsigned char subkey[8])
  375. {
  376.     register unsigned long rval,rt;
  377. #ifdef    DES_DEBUG
  378.     unsigned char *cp;
  379.     int i;
  380.  
  381.     printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
  382.         r,
  383.         subkey[0], subkey[1], subkey[2],
  384.         subkey[3], subkey[4], subkey[5],
  385.         subkey[6], subkey[7]);
  386. #endif
  387.     /* Run E(R) ^ K through the combined S & P boxes
  388.      * This code takes advantage of a convenient regularity in
  389.      * E, namely that each group of 6 bits in E(R) feeding
  390.      * a single S-box is a contiguous segment of R.
  391.      */
  392.     rt = (r >> 1) | ((r & 1) ? 0x80000000 : 0);
  393.     rval = 0;
  394.     rval |= sp[0][((rt >> 26) ^ *subkey++) & 0x3f];
  395.     rval |= sp[1][((rt >> 22) ^ *subkey++) & 0x3f];
  396.     rval |= sp[2][((rt >> 18) ^ *subkey++) & 0x3f];
  397.     rval |= sp[3][((rt >> 14) ^ *subkey++) & 0x3f];
  398.     rval |= sp[4][((rt >> 10) ^ *subkey++) & 0x3f];
  399.     rval |= sp[5][((rt >> 6) ^ *subkey++) & 0x3f];
  400.     rval |= sp[6][((rt >> 2) ^ *subkey++) & 0x3f];
  401.     rt = (r << 1) | ((r & 0x80000000) ? 1 : 0);
  402.     rval |= sp[7][(rt ^ *subkey) & 0x3f];
  403. #ifdef    DES_DEBUG
  404.     fprintf(stderr," %08lx\n",rval);
  405. #endif
  406.     return rval;
  407. }
  408. /* initialize a perm array */
  409. static void perminit(char perm[16][16][8],char p[64])
  410. {
  411.     register int l, j, k;
  412.     int i,m;
  413.  
  414.     /* Clear the permutation array */
  415.     for (i=0; i<16; i++)
  416.         for (j=0; j<16; j++)
  417.             for (k=0; k<8; k++)
  418.                 perm[i][j][k]=0;
  419.  
  420.     for (i=0; i<16; i++)        /* each input nibble position */
  421.         for (j = 0; j < 16; j++)/* each possible input nibble */
  422.         for (k = 0; k < 64; k++)/* each output bit position */
  423.         {   l = p[k] - 1;    /* where does this bit come from*/
  424.             if ((l >> 2) != i)  /* does it come from input posn?*/
  425.             continue;    /* if not, bit k is 0     */
  426.             if (!(j & nibblebit[l & 3]))
  427.             continue;    /* any such bit in input? */
  428.             m = k & 07;    /* which bit is this in the byte*/
  429.             perm[i][j][k>>3] |= bytebit[m];
  430.         }
  431. }
  432.  
  433. /* Initialize the lookup table for the combined S and P boxes */
  434. static int spinit()
  435. {
  436.     char pbox[32];
  437.     int p,i,s,j,rowcol;
  438.     long val;
  439.  
  440.     /* Compute pbox, the inverse of p32i.
  441.      * This is easier to work with
  442.      */
  443.     for(p=0;p<32;p++){
  444.         for(i=0;i<32;i++){
  445.             if(p32i[i]-1 == p){
  446.                 pbox[p] = i;
  447.                 break;
  448.             }
  449.         }
  450.     }
  451.     for(s = 0; s < 8; s++){            /* For each S-box */
  452.         for(i=0; i<64; i++){        /* For each possible input */
  453.             val = 0;
  454.             /* The row number is formed from the first and last
  455.              * bits; the column number is from the middle 4
  456.              */
  457.             rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
  458.             for(j=0;j<4;j++){    /* For each output bit */
  459.                 if(si[s][rowcol] & (8 >> j)){
  460.                  val |= 1L << (31 - pbox[4*s + j]);
  461.                 }
  462.             }
  463.             sp[s][i] = val;
  464.  
  465. #ifdef    DES_DEBUG
  466.             fprintf(stderr,"sp[%d][%2d] = %08lx\n",s,i,sp[s][i]);
  467. #endif
  468.         }
  469.     }
  470.     return(0);
  471. }
  472.  
  473.  
  474. #ifdef    LITTLE_ENDIAN
  475. /* Byte swap a long */
  476. static unsigned long byteswap(unsigned long x)
  477. {
  478.     register char *cp,tmp;
  479.  
  480.     cp = (char *)&x;
  481.     tmp = cp[3];
  482.     cp[3] = cp[0];
  483.     cp[0] = tmp;
  484.  
  485.     tmp = cp[2];
  486.     cp[2] = cp[1];
  487.     cp[1] = tmp;
  488.  
  489.     return x;
  490. }
  491. #endif
  492.  
  493.  
  494.  
  495. static void endes_cbc(char *outblock)
  496. {
  497.     register char    *cp, *cp1;
  498.     register int    i;
  499.  
  500.     /* CBC mode; chain in last cipher word */
  501.  
  502.     cp = outblock;
  503.     cp1 = iv;
  504.     for (i = 8; i != 0; i--) *cp++ ^= *cp1++;
  505.  
  506.     endes_ecb(outblock);    /* in-block encryption */
  507.  
  508.     /* Save outblockgoing ciphertext for chain */
  509.  
  510.     bcopy(outblock, iv, 8);
  511. }
  512.  
  513. static void endes_ecb(char *outblock)
  514. {
  515.     endes(outblock);
  516.         return;
  517. }
  518.  
  519. static void dedes_cbc(char *outblock)
  520. {
  521.     char    ivtmp[8];
  522.     register char    *cp, *cp1;
  523.     register int    i;
  524.  
  525.  
  526.     /* Save incoming ciphertext for chain */
  527.  
  528.     bcopy(outblock, ivtmp, 8);
  529.  
  530.     dedes_ecb(outblock);   /* in-block decryption */
  531.  
  532.     /* Unchain block, save ciphertext for next */
  533.  
  534.     cp = outblock;
  535.     cp1 = iv;
  536.     for (i = 8; i != 0; i--)    
  537.         *cp++ ^= *cp1++;
  538.     bcopy(ivtmp, iv, 8);
  539. }
  540.  
  541. static void dedes_ecb(char *outblock)
  542. {
  543.     dedes(outblock);
  544.     return;
  545. }
  546.  
  547.  
  548.