home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------- des.c --------------------------- */
-
- /*
- * Functions and tables for DES encryption and decryption
- */
-
- /* ----- inline swapbyte function -------- */
-
- #define swapbyte(c) { \
- register int swt; \
- swt = *((char *)&c+3); \
- *((char *)&c+3) = *(char *)&c; \
- *(char *)&c = swt; \
- swt = *((char *)&c+2); \
- *((char *)&c+2) = *((char *)&c+1); \
- *((char *)&c+1) = swt; \
- }
-
- #include <stdio.h>
- #include <string.h>
- #include "des.h"
-
- /* -------- 48-bit key permutation ------- */
- struct ks {
- char ki[6];
- };
-
- /* ------- two halves of a 64-bit data block ------- */
- struct LR {
- long L;
- long R;
- };
-
- static struct ks keys[16];
-
- static void rotate(unsigned char *c, int n);
- static void inverse_permute(long *op,long *ip,long *tbl,int n);
- static void permute(long *op, long *ip, long *tbl, int n);
- static long f(long blk, struct LR *ky);
- static struct ks KS(int n, char *key);
-
- /* ----------- initialize the key -------------- */
- void initkey(char *key)
- {
- int i;
- for (i = 0; i < 16; i++)
- keys[i] = KS(i, key);
- }
-
- /* ----------- encrypt an 8-byte block ------------ */
- void encrypt(char *blk)
- {
- struct LR ip, op;
- long temp;
- int n;
-
- memcpy(&ip, blk, sizeof(struct LR));
- /* -------- initial permuation -------- */
- permute(&op.L, &ip.L, (long *)IPtbl, 64);
- swapbyte(op.L);
- swapbyte(op.R);
- /* ------ swap and key iterations ----- */
- for (n = 0; n < 16; n++) {
- temp = op.R;
- op.R = op.L ^ f(op.R, (struct LR *) &keys[n]);
- op.L = temp;
- }
- ip.R = op.L;
- ip.L = op.R;
- swapbyte(ip.L);
- swapbyte(ip.R);
- /* ----- inverse initial permutation ---- */
- inverse_permute(&op.L, &ip.L,
- (long *)IPtbl, 64);
- memcpy(blk, &op, sizeof(struct LR));
- }
-
- /* ----------- decrypt an 8-byte block ------------ */
- void decrypt(char *blk)
- {
- struct LR ip, op;
- long temp;
- int n;
-
- memcpy(&ip, blk, sizeof(struct LR));
- /* -------- initial permuation -------- */
- permute(&op.L, &ip.L, (long *)IPtbl, 64);
- swapbyte(op.L);
- swapbyte(op.R);
- ip.R = op.L;
- ip.L = op.R;
- /* ------ swap and key iterations ----- */
- for (n = 15; n >= 0; --n) {
- temp = ip.L;
- ip.L = ip.R ^ f(ip.L, (struct LR *) &keys[n]);
- ip.R = temp;
- }
- swapbyte(ip.L);
- swapbyte(ip.R);
- /* ----- inverse initial permuation ---- */
- inverse_permute(&op.L, &ip.L,
- (long *)IPtbl, 64);
- memcpy(blk, &op, sizeof(struct LR));
- }
-
- /* ------- inverse permute a 64-bit string ------- */
- static void inverse_permute(long *op,long *ip,long *tbl,int n)
- {
- int i;
- long *pt = (long *)Pmask;
-
- *op = *(op+1) = 0;
- for (i = 0; i < n; i++) {
- if ((*ip & *pt) || (*(ip+1) & *(pt+1))) {
- *op |= *tbl;
- *(op+1) |= *(tbl+1);
- }
- tbl += 2;
- pt += 2;
- }
- }
-
- /* ------- permute a 64-bit string ------- */
- static void permute(long *op, long *ip, long *tbl, int n)
- {
- int i;
- long *pt = (long *)Pmask;
-
- *op = *(op+1) = 0;
- for (i = 0; i < n; i++) {
- if ((*ip & *tbl) || (*(ip+1) & *(tbl+1))) {
- *op |= *pt;
- *(op+1) |= *(pt+1);
- }
- tbl += 2;
- pt += 2;
- }
- }
-
- /* ----- Key dependent computation function f(R,K) ----- */
- static long f(long blk, struct LR *key)
- {
- static long or;
- static int op;
- static unsigned j, k;
-
- static union {
- struct LR f;
- struct ks kn;
- } tr;
-
- static union {
- long lg;
- unsigned char ch[4];
- } ir;
-
- tr.f.L = tr.f.R = 0;
- ir.lg = blk;
-
- swapbyte(ir.lg);
-
- /* ----- permute function E ----------- */
- /* rotate the 4-byte string 1 position to the right */
- k = ir.ch[3] << 7;
- j = (ir.ch[0] >> 1) + k;
- k = ir.ch[0] << 7;
- ir.ch[0] = j & 255;
-
- j = (ir.ch[1] >> 1) + k;
- k = ir.ch[1] << 7;
- ir.ch[1] = j & 255;
-
- j = (ir.ch[2] >> 1) + k;
- k = ir.ch[2] << 7;
- ir.ch[2] = j & 255;
-
- j = (ir.ch[3] >> 1) + k;
- k = ir.ch[3] << 7;
- ir.ch[3] = j & 255;
-
- /* ------------- DES E function -------------- */
- tr.kn.ki[0] =
- (ir.ch[0] & 0xfc) | ((ir.ch[0] >> 2) & 3);
- tr.kn.ki[1] =
- ((ir.ch[0] << 6) & 0xc0) | (((ir.ch[1] >> 2) & 0x30) |
- ((ir.ch[1] >> 4) & 0x0f));
- tr.kn.ki[2] =
- ((ir.ch[1] << 4) & 0xc0) | ((ir.ch[1] << 2) & 0x3c) |
- ((ir.ch[2] >> 6) & 3);
- tr.kn.ki[3] =
- (ir.ch[2] & 0xfc) | ((ir.ch[2] >> 2) & 3);
- tr.kn.ki[4] =
- ((ir.ch[2] << 6) & 0xc0) | (((ir.ch[3] >> 2) & 0x30) |
- ((ir.ch[3] >> 4) & 0x0f));
- tr.kn.ki[5] =
- ((ir.ch[3] << 4) & 0xc0) | ((ir.ch[3] << 2) & 0x3c) |
- ((ir.ch[0] >> 6) & 3);
-
- tr.f.L ^= key->L;
- tr.f.R ^= key->R;
-
- /* ------ the DES S function: ir = S(tr.kn); ------ */
-
- #define S(n,op) (long)(stbl[n] \
- [((op >> 4) & 2) | (op & 1)] \
- [(op >> 1) & 0xf]) << (7-n)*4;
- ir.lg = 0;
- op = (tr.kn.ki[0] >> 2) & 0x3f;
- ir.lg |= S(0,op);
-
- op = ((tr.kn.ki[0] << 4) & 0x30) | ((tr.kn.ki[1] >> 4) & 0xf);
- ir.lg |= S(1,op);
-
- op = ((tr.kn.ki[1] << 2) & 0x3c) | ((tr.kn.ki[2] >> 6) & 0x3);
- ir.lg |= S(2,op);
-
- op = tr.kn.ki[2] & 0x3f;
- ir.lg |= S(3,op);
-
- op = (tr.kn.ki[3] >> 2) & 0x3f;
- ir.lg |= S(4,op);
-
- op = ((tr.kn.ki[3] << 4) & 0x30) | ((tr.kn.ki[4] >> 4) & 0xf);
- ir.lg |= S(5,op);
-
- op = ((tr.kn.ki[4] << 2) & 0x3c) | ((tr.kn.ki[5] >> 6) & 0x3);
- ir.lg |= S(6,op);
-
- op = tr.kn.ki[5] & 0x3f;
- ir.lg |= S(7,op);
-
- /* ------------------------------ */
- swapbyte(ir.lg);
-
- /* ---------- 32 bit P permutation --------- */
- {
- register long *pt, *pm;
- or = 0;
- pt = (long *) Ptbl;
- pm = (long *) P3mask;
- while (pt < ((long *)Ptbl)+32) {
- if (ir.lg & *pt)
- or |= *pm;
- pt++;
- pm++;
- }
- }
-
- swapbyte(or);
-
- return or;
- }
-
- /* ---------- DES Key Schedule (KS) function ----------- */
- static struct ks KS(int n, char *key)
- {
- static unsigned char cd[8];
- static int its[] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
- union {
- struct ks kn;
- struct LR filler;
- } result;
-
- if (n == 0)
- permute((long *)cd, (long *) key, (long *)PC1tbl, 64);
-
- rotate(cd, its[n]);
- rotate(cd+4, its[n]);
-
- permute(&result.filler.L, (long *)cd, (long *)PC2tbl, 48);
- return result.kn;
- }
-
- /* rotate a 4-byte string n (1 or 2) positions to the left */
- static void rotate(unsigned char *c, int n)
- {
- int i;
- unsigned j, k;
- k = ((*c) & 255) >> (8 - n);
- for (i = 3; i >= 0; --i) {
- j = ((*(c+i) << n) + k);
- k = (j >> 8) & 255;
- *(c+i) = j & 255;
- }
- if (n == 2)
- *(c+3) = (*(c+3) & 0xc0) | ((*(c+3) << 4) & 0x30);
- else
- *(c+3) = (*(c+3) & 0xe0) | ((*(c+3) << 4) & 0x10);
- }
-