Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using DES to encrypt data

Status
Not open for further replies.

psubs

Programmer
Jun 23, 2003
1
US
Has anyone used a DES package or written code to use the des utility to encrypt and decrypt data? I am looking for some leads in this regard. I am writing the code in C++ on Solaris 8 platform.

Any help is appreciated! Thanks.
 
Hope this helps......


/* -------------- des.h ---------------- */
/* Header file for Data Encryption Standard algorithms */

/* -------------- prototypes ------------------- */
void initkey(char *key);
void encrypt(char *blk);
void decrypt(char *blk);

/* ----------- tables ------------ */
extern unsigned char Pmask[];
extern unsigned char IPtbl[];
extern unsigned char Etbl[];
extern unsigned char Ptbl[];
extern unsigned char stbl[8][4][16];
extern unsigned char PC1tbl[];
extern unsigned char PC2tbl[];
extern unsigned char ex6[8][2][4];



/* Data Encryption Standard front end
* Usage: des [-e -d] keyvalue infile outfile
*/

#include <stdio.h>
#include <string.h>

static void setparity(char *key);

void des(char * mode, char * keyval, char * infile, char * outfile)
{
FILE *fi, *fo;
char key[9];
char blk[8];

strncpy(key, keyval, 8);
key[8] = '\0';
setparity(key);

initkey(key);
if ((fi = fopen(infile, &quot;rb&quot;)) != NULL) {
if ((fo = fopen(outfile, &quot;wb&quot;)) != NULL) {
while (!feof(fi)) {
memset(blk, 0, 8);
if (fread(blk, 1, 8, fi) != 0) {
if (mode[0]=='e')
encrypt(blk);
else
decrypt(blk);
fwrite(blk, 1, 8, fo);
}
}
fclose(fo);
}
fclose(fi);
}
}

/* -------- make a character odd parity ---------- */
static unsigned char oddparity(unsigned char s)
{
unsigned char c = s | 0x80;
while (s) {
if (s & 1)
c ^= 0x80;
s = (s >> 1) & 0x7f;
}
return c;
}

/* ------ make a key odd parity ------- */
void setparity(char *key)
{
int i;
for (i = 0; i < 8; i++)
*(key+i) = oddparity(*(key+i));
}



/* -------- 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 int fourbits(struct ks, int s);
static int sixbits(struct ks, int s);
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 ks ky);
static struct ks KS(int n, char *key);
static void swapbyte(long *l);

/* ----------- initialize the key -------------- */
void initkey(char *key)
{
int i;
for (i = 0; i < 16; i++)
keys = 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, 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, 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 ks key)
{
struct LR ir;
struct LR or;
int i;

union {
struct LR f;
struct ks kn;
} tr = {0,0}, kr = {0,0};

ir.L = blk;
ir.R = 0;

kr.kn = key;

swapbyte(&ir.L);
swapbyte(&ir.R);

permute(&tr.f.L, &ir.L, (long *)Etbl, 48);

tr.f.L ^= kr.f.L;
tr.f.R ^= kr.f.R;

/* the DES S function: ir.L = S(tr.kn); */
ir.L = 0;
for (i = 0; i < 8; i++) {
long four = fourbits(tr.kn, i);
ir.L |= four << ((7-i) * 4);
}
swapbyte(&ir.L);

ir.R = or.R = 0;
permute(&or.L, &ir.L, (long *)Ptbl, 32);

swapbyte(&or.L);
swapbyte(&or.R);

return or.L;
}

/* ------- extract a 4-bit stream from the block/key ------- */
static int fourbits(struct ks k, int s)
{
int i = sixbits(k, s);
int row, col;
row = ((i >> 4) & 2) | (i & 1);
col = (i >> 1) & 0xf;
return stbl[row][col];
}

/* ---- extract 6-bit stream fr pos s of the block/key ---- */
static int sixbits(struct ks k, int s)
{
int op = 0;
int n = (s);
int i;
for (i = 0; i < 2; i++) {
int off = ex6[n][0];
unsigned char c = k.ki[off];
c >>= ex6[n][1];
c <<= ex6[n][2];
c &= ex6[n][3];
op |= c;
}
return op;
}

/* ---------- 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);
}

/* -------- swap bytes in a long integer ---------- */
static void swapbyte(long *l)
{
char *cp = (char *) l;
char t = *(cp+3);

*(cp+3) = *cp;
*cp = t;
t = *(cp+2);
*(cp+2) = *(cp+1);
*(cp+1) = t;
}


/* --------------- tables.c --------------- */
/* tables for the DES algorithm
*/

/* --------- macros to define a permutation table ---------- */
#define ps(n) ((unsigned char)(0x80 >> (n-1)))
#define b(n,r) ((n>r||n<r-7)?0:ps(n-(r-8)))
#define p(n) b(n, 8),b(n,16),b(n,24),b(n,32), b(n,40),b(n,48),b(n,56),b(n,64)
#define q(n) p((n)+4)

/* --------- permutation masks ----------- */
unsigned char Pmask[] = {
p( 1),p( 2),p( 3),p( 4),p( 5),p( 6),p( 7),p( 8),
p( 9),p(10),p(11),p(12),p(13),p(14),p(15),p(16),
p(17),p(18),p(19),p(20),p(21),p(22),p(23),p(24),
p(25),p(26),p(27),p(28),p(29),p(30),p(31),p(32),
p(33),p(34),p(35),p(36),p(37),p(38),p(39),p(40),
p(41),p(42),p(43),p(44),p(45),p(46),p(47),p(48),
p(49),p(50),p(51),p(52),p(53),p(54),p(55),p(56),
p(57),p(58),p(59),p(60),p(61),p(62),p(63),p(64)
};

/* ----- initial and inverse-initial permutation table ----- */
unsigned char IPtbl[] = {
p(58),p(50),p(42),p(34),p(26),p(18),p(10),p( 2),
p(60),p(52),p(44),p(36),p(28),p(20),p(12),p( 4),
p(62),p(54),p(46),p(38),p(30),p(22),p(14),p( 6),
p(64),p(56),p(48),p(40),p(32),p(24),p(16),p( 8),
p(57),p(49),p(41),p(33),p(25),p(17),p( 9),p( 1),
p(59),p(51),p(43),p(35),p(27),p(19),p(11),p( 3),
p(61),p(53),p(45),p(37),p(29),p(21),p(13),p( 5),
p(63),p(55),p(47),p(39),p(31),p(23),p(15),p( 7)
};

/* ---------- permutation table E for f function --------- */
unsigned char Etbl[] = {
p(32),p( 1),p( 2),p( 3),p( 4),p( 5),
p( 4),p( 5),p( 6),p( 7),p( 8),p( 9),
p( 8),p( 9),p(10),p(11),p(12),p(13),
p(12),p(13),p(14),p(15),p(16),p(17),
p(16),p(17),p(18),p(19),p(20),p(21),
p(20),p(21),p(22),p(23),p(24),p(25),
p(24),p(25),p(26),p(27),p(28),p(29),
p(28),p(29),p(30),p(31),p(32),p( 1)
};

/* ---------- permutation table P for f function --------- */
unsigned char Ptbl[] = {
p(16),p( 7),p(20),p(21),p(29),p(12),p(28),p(17),
p( 1),p(15),p(23),p(26),p( 5),p(18),p(31),p(10),
p( 2),p( 8),p(24),p(14),p(32),p(27),p( 3),p( 9),
p(19),p(13),p(30),p( 6),p(22),p(11),p( 4),p(25)
};

/* --- table for converting six-bit to four-bit stream --- */
unsigned char stbl[8][4][16] = {
/* ------------- s1 --------------- */
14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,
/* ------------- s2 --------------- */
15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
/* ------------- s3 --------------- */
10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
/* ------------- s4 --------------- */
7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
/* ------------- s5 --------------- */
2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
/* ------------- s6 --------------- */
12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
/* ------------- s7 --------------- */
4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
/* ------------- s8 --------------- */
13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
};

/* ---- Permuted Choice 1 for Key Schedule calculation ---- */
unsigned char PC1tbl[] = {
p(57),p(49),p(41),p(33),p(25),p(17),p( 9),
p( 1),p(58),p(50),p(42),p(34),p(26),p(18),
p(10),p( 2),p(59),p(51),p(43),p(35),p(27),
p(19),p(11),p( 3),p(60),p(52),p(44),p(36),
p(0),p(0),p(0),p(0),

p(63),p(55),p(47),p(39),p(31),p(23),p(15),
p( 7),p(62),p(54),p(46),p(38),p(30),p(22),
p(14),p( 6),p(61),p(53),p(45),p(37),p(29),
p(21),p(13),p( 5),p(28),p(20),p(12),p( 4),
p(0),p(0),p(0),p(0)
};

/* ---- Permuted Choice 2 for Key Schedule calculation ---- */
unsigned char PC2tbl[] = {
p(14),p(17),p(11),p(24),p( 1),p( 5),p( 3),p(28),
p(15),p( 6),p(21),p(10),p(23),p(19),p(12),p( 4),
p(26),p( 8),p(16),p( 7),p(27),p(20),p(13),p( 2),

q(41),q(52),q(31),q(37),q(47),q(55),q(30),q(40),
q(51),q(45),q(33),q(48),q(44),q(49),q(39),q(56),
q(34),q(53),q(46),q(42),q(50),q(36),q(29),q(32)
};

/* ---- For extracting 6-bit strings from 64-bit string ---- */
unsigned char ex6[8][2][4] = {
/* byte, >>, <<, & */
/* ---- s = 8 ---- */
0,2,0,0x3f,
0,2,0,0x3f,
/* ---- s = 7 ---- */
0,0,4,0x30,
1,4,0,0x0f,
/* ---- s = 6 ---- */
1,0,2,0x3c,
2,6,0,0x03,
/* ---- s = 5 ---- */
2,0,0,0x3f,
2,0,0,0x3f,
/* ---- s = 4 ---- */
3,2,0,0x3f,
3,2,0,0x3f,
/* ---- s = 3 ---- */
3,0,4,0x30,
4,4,0,0x0f,
/* ---- s = 2 ---- */
4,0,2,0x3c,
5,6,0,0x03,
/* ---- s = 1 ---- */
5,0,0,0x3f,
5,0,0,0x3f
};
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top