home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / des2.zip / DES.C < prev    next >
Text File  |  1993-03-16  |  6KB  |  334 lines

  1. /* ---------------------- des.c --------------------------- */
  2. /* Functions and tables for DES encryption and decryption
  3.  */
  4.  
  5. #define INCL_BASE
  6. #include <os2.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "des.h"
  10.  
  11. /* -------- 48-bit key permutation ------- */
  12. struct ks
  13.    {
  14.    CHAR ki[6];
  15.    };
  16.  
  17. /* ------- two halves of a 64-bit data block ------- */
  18. struct LR
  19.    {
  20.    LONG L;
  21.    LONG R;
  22.    };
  23.  
  24. static struct ks keys[16];
  25.  
  26. VOID rotate(UCHAR *c, SHORT n);
  27. SHORT fourbits(struct ks, SHORT s);
  28. SHORT sixbits(struct ks, SHORT s);
  29. VOID inverse_permute(LONG *op,LONG *ip,LONG *tbl,SHORT n);
  30. VOID permute(LONG *op, LONG *ip, LONG *tbl, SHORT n);
  31. LONG f(LONG blk, struct ks ky);
  32. struct ks KS(SHORT n, CHAR *key);
  33. VOID swapbyte(LONG *l);
  34.  
  35.  
  36. SHORT EXPENTRY EncryptData(CHAR *key, CHAR *data, SHORT length)
  37. {
  38. UCHAR lkey[9], block[8], *ptr ;
  39. SHORT x ;
  40.  
  41. memset(lkey, 0, 9) ;
  42. strcpy(lkey, key) ;
  43. if(strlen(lkey) > 8)
  44.     lkey[8] = 0 ;
  45.  
  46. setparity(lkey);
  47. initkey(lkey);
  48. ptr = data ;
  49.    for(x = 0 ; x <= length/8 ; x++)
  50.       {
  51.       memcpy(block, ptr, 8) ;
  52.       encrypt(block);
  53.       memcpy(ptr, block, 8) ;
  54.       ptr+= 8 ;
  55.       }
  56. data[length] = 0 ;
  57. }
  58.  
  59.  
  60. SHORT EXPENTRY DecryptData(CHAR *key, CHAR *data, SHORT length)
  61. {
  62. UCHAR lkey[9], block[8], *ptr ;
  63. SHORT x ;
  64.  
  65. memset(lkey, 0, 9) ;
  66. strcpy(lkey, key) ;
  67. if(strlen(lkey) > 8)
  68.     lkey[8] = 0 ;
  69.  
  70. setparity(lkey);
  71. initkey(lkey);
  72. ptr = data ;
  73.    for(x = 0 ; x <= length/8 ; x++)
  74.       {
  75.       memcpy(block, ptr, 8) ;
  76.       decrypt(block);
  77.       memcpy(ptr, block, 8) ;
  78.       ptr+= 8 ;
  79.       }
  80. data[length] = 0 ;
  81. }
  82.  
  83.  
  84. /* ----------- initialize the key -------------- */
  85. VOID initkey(CHAR *key)
  86. {
  87. SHORT i;
  88. for (i = 0; i < 16; i++)
  89.    keys[i] = KS(i, key);
  90. }
  91.  
  92. /* ----------- encrypt an 8-byte block ------------ */
  93. VOID encrypt(CHAR *blk)
  94. {
  95. struct LR ip, op;
  96. LONG temp;
  97. SHORT n;
  98.  
  99. memcpy(&ip, blk, sizeof(struct LR));
  100. /* -------- initial permuation -------- */
  101. permute(&op.L, &ip.L, (LONG *)IPtbl, 64);
  102. swapbyte(&op.L);
  103. swapbyte(&op.R);
  104. /* ------ swap and key iterations ----- */
  105. for (n = 0; n < 16; n++)
  106.    {
  107.    temp = op.R;
  108.    op.R = op.L ^ f(op.R, keys[n]);
  109.    op.L = temp;
  110.    }
  111. ip.R = op.L;
  112. ip.L = op.R;
  113. swapbyte(&ip.L);
  114. swapbyte(&ip.R);
  115. /* ----- inverse initial permutation ---- */
  116. inverse_permute(&op.L, &ip.L,
  117.     (LONG *)IPtbl, 64);
  118. memcpy(blk, &op, sizeof(struct LR));
  119. }
  120.  
  121. /* ----------- decrypt an 8-byte block ------------ */
  122. VOID decrypt(CHAR *blk)
  123. {
  124. struct LR ip, op;
  125. LONG temp;
  126. SHORT n;
  127.  
  128. memcpy(&ip, blk, sizeof(struct LR));
  129. /* -------- initial permuation -------- */
  130. permute(&op.L, &ip.L, (LONG *)IPtbl, 64);
  131. swapbyte(&op.L);
  132. swapbyte(&op.R);
  133. ip.R = op.L;
  134. ip.L = op.R;
  135. /* ------ swap and key iterations ----- */
  136. for (n = 15; n >= 0; --n)
  137.    {
  138.    temp = ip.L;
  139.    ip.L = ip.R ^ f(ip.L, keys[n]);
  140.    ip.R = temp;
  141.    }
  142. swapbyte(&ip.L);
  143. swapbyte(&ip.R);
  144. /* ----- inverse initial permuation ---- */
  145. inverse_permute(&op.L, &ip.L,
  146.     (LONG *)IPtbl, 64);
  147. memcpy(blk, &op, sizeof(struct LR));
  148. }
  149.  
  150. /* ------- inverse permute a 64-bit string ------- */
  151. VOID inverse_permute(LONG *op,LONG *ip,LONG *tbl,SHORT n)
  152. {
  153. SHORT i;
  154. LONG *pt = (LONG *)Pmask;
  155.  
  156. *op = *(op+1) = 0;
  157. for (i = 0; i < n; i++)
  158.    {
  159.    if ((*ip & *pt) || (*(ip+1) & *(pt+1)))
  160.       {
  161.       *op |= *tbl;
  162.       *(op+1) |= *(tbl+1);
  163.       }
  164.    tbl += 2;
  165.    pt += 2;
  166.    }
  167. }
  168.  
  169. /* ------- permute a 64-bit string ------- */
  170. VOID permute(LONG *op, LONG *ip, LONG *tbl, SHORT n)
  171. {
  172. SHORT i;
  173. LONG *pt = (LONG *)Pmask;
  174.  
  175. *op = *(op+1) = 0;
  176. for (i = 0; i < n; i++)
  177.    {
  178.    if ((*ip & *tbl) || (*(ip+1) & *(tbl+1)))
  179.       {
  180.       *op |= *pt;
  181.       *(op+1) |= *(pt+1);
  182.       }
  183.    tbl += 2;
  184.    pt += 2;
  185.    }
  186. }
  187.  
  188. /* ----- Key dependent computation function f(R,K) ----- */
  189. LONG f(LONG blk, struct ks key)
  190. {
  191. struct LR ir;
  192. struct LR or;
  193. SHORT i;
  194.  
  195. union
  196.    {
  197.    struct LR f;
  198.    struct ks kn;
  199.    } tr = {0,0}, kr = {0,0};
  200.  
  201. ir.L = blk;
  202. ir.R = 0;
  203.  
  204. kr.kn = key;
  205.  
  206. swapbyte(&ir.L);
  207. swapbyte(&ir.R);
  208.  
  209. permute(&tr.f.L, &ir.L, (LONG *)Etbl, 48);
  210.  
  211. tr.f.L ^= kr.f.L;
  212. tr.f.R ^= kr.f.R;
  213.  
  214. /*   the DES S function: ir.L = S(tr.kn);  */
  215. ir.L = 0;
  216. for (i = 0; i < 8; i++)
  217.    {
  218.    LONG four = fourbits(tr.kn, i);
  219.    ir.L |= four << ((7-i) * 4);
  220.    }
  221. swapbyte(&ir.L);
  222.  
  223. ir.R = or.R = 0;
  224. permute(&or.L, &ir.L, (LONG *)Ptbl, 32);
  225.  
  226. swapbyte(&or.L);
  227. swapbyte(&or.R);
  228.  
  229. return or.L;
  230. }
  231.  
  232. /* ------- extract a 4-bit stream from the block/key ------- */
  233. SHORT fourbits(struct ks k, SHORT s)
  234. {
  235. SHORT i, row, col ;
  236.  
  237. i = sixbits(k, s);
  238. row = ((i >> 4) & 2) | (i & 1);
  239. col = (i >> 1) & 0xf;
  240. return stbl[s][row][col];
  241. }
  242.  
  243. /* ---- extract 6-bit stream fr pos s of the  block/key ---- */
  244. SHORT sixbits(struct ks k, SHORT s)
  245. {
  246. SHORT op = 0;
  247. SHORT n = (s);
  248. SHORT i;
  249. for (i = 0; i < 2; i++)
  250.    {
  251.    SHORT off = ex6[n][i][0];
  252.    UCHAR c = k.ki[off];
  253.    c >>= ex6[n][i][1];
  254.    c <<= ex6[n][i][2];
  255.    c &=  ex6[n][i][3];
  256.    op |= c;
  257.    }
  258. return op;
  259. }
  260.  
  261. /* ---------- DES Key Schedule (KS) function ----------- */
  262. struct ks KS(SHORT n, CHAR *key)
  263. {
  264.  UCHAR cd[8];
  265.  SHORT its[] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
  266. union
  267.    {
  268.    struct ks kn;
  269.    struct LR filler;
  270.    } result;
  271.  
  272. if (n == 0)
  273.     permute((LONG *)cd, (LONG *) key, (LONG *)PC1tbl, 64);
  274.  
  275. rotate(cd, its[n]);
  276. rotate(cd+4, its[n]);
  277.  
  278. permute(&result.filler.L, (LONG *)cd, (LONG *)PC2tbl, 48);
  279. return result.kn;
  280. }
  281.  
  282. /* rotate a 4-byte string n (1 or 2) positions to the left */
  283. VOID rotate(UCHAR *c, SHORT n)
  284. {
  285. SHORT i;
  286. USHORT j, k;
  287.  
  288. k = ((*c) & 255) >> (8 - n);
  289. for (i = 3; i >= 0; --i)
  290.    {
  291.    j = ((*(c+i) << n) + k);
  292.    k = (j >> 8) & 255;
  293.    *(c+i) = j & 255;
  294.    }
  295. if (n == 2)
  296.    *(c+3) = (*(c+3) & 0xc0) | ((*(c+3) << 4) & 0x30);
  297. else
  298.    *(c+3) = (*(c+3) & 0xe0) | ((*(c+3) << 4) & 0x10);
  299. }
  300.  
  301. /* -------- swap bytes in a LONG integer ---------- */
  302. VOID swapbyte(LONG *l)
  303. {
  304. CHAR *cp = (CHAR *) l;
  305. CHAR t = *(cp+3);
  306.  
  307. *(cp+3) = *cp;
  308. *cp = t;
  309. t = *(cp+2);
  310. *(cp+2) = *(cp+1);
  311. *(cp+1) = t;
  312. }
  313.  
  314. /* -------- make a CHARacter odd parity ---------- */
  315. UCHAR oddparity(UCHAR s)
  316. {
  317. UCHAR c = s | 0x80;
  318. while (s)
  319.    {
  320.    if (s & 1)
  321.       c ^= 0x80;
  322.    s = (s >> 1) & 0x7f;
  323.    }
  324. return c;
  325. }
  326.  
  327. /* ------ make a key odd parity ------- */
  328. VOID setparity(CHAR *key)
  329. {
  330. SHORT i;
  331. for (i = 0; i < 8; i++)
  332.    *(key+i) = oddparity(*(key+i));
  333. }
  334.