PackIt crypt.c

/*		Encryption/Decryption

	This module performs encryption/decryption.

	Initial coding 5/23/86 by Harry R. Chesley.

	© Copyright 1986 by Harry R. Chesley.
	All rights reserved.
*/

#include <types.h>
#include <quickdraw.h>
#include <event.h>
#include <toolutil.h>
#include <osutil.h>

#define NIL 0L

/*#define DEBUG*/

int cryptFile;		/* Type of encryption. */

#define NOCRYPT 0
#define SIMPCRYPT 1
#define DESCRYPT 2

char password[9];	/* Password (Pascal string format). */

char key[64];		/* Mixed up password. */
char packedKey[8];
char *xorPtr;
int xorCnt;

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

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

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

int keyTr1[56] = {
  57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,10, 2,59,51,43,35,27,19,11,03,60,52,44,36,
  63,55,47,39,31,23,15, 7,62,54,46,38,30,22,14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4
};

int keyTr2[48] = {
	14,17,11,24, 1, 5, 3,28,15, 6,21,10,23,19,12, 4,26, 8,16, 7,27,20,13, 2,
	41,52,31,37,47,55,30,40,51,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32
};

int etr[48] = {
	32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9,10,11,12,13,12,13,14,15,16,17,
	16,17,18,19,20,21,20,21,22,23,24,25,24,25,26,27,28,29,28,29,30,31,32, 1
};

int ptr[32] = {
	16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
	 2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25
};

int s[8][64] = {
	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,

	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,

	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,

	 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,

	 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,

	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,

	 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,

	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
};

int rots[16] = {
	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};

/*ÇstartCrypt()È	startCrypt()

	Function: Start encryption/decryption.

	Algorithm: Synch the start of the encoded or decoded data.

	Comments: None.
*/

startCrypt()

{
	byToBi(password+1,key);
	transpose(key,keyTr1,56);
	biToBy(key,packedKey);
	xorPtr = packedKey; xorCnt = 7;
}

/*Çencrypt(buf,sz)È	encrypt(buf,sz)

	Function: Encrypt the contents of buffer buf, of size sz.

	Algorithm: Either exclusive or or DES.

	Comments: None.
*/

encrypt(buf,sz)

char *buf;
long sz;

{
	register char *ptr;
	register long cnt;

	ptr = buf; cnt = sz;

	switch (cryptFile) {
		case SIMPCRYPT:
			while (cnt--) {
				*ptr++ ^= *xorPtr++;
				if ((--xorCnt) == 0) {
					xorPtr = packedKey; xorCnt = 7;
				};
			};
			break;

		case DESCRYPT:
			while (cnt) {
				enc8(ptr);
				ptr += 8; cnt -= 8;
			};
			break;
	};
}

enc8(ptr)

char ptr[8];

{
	char a[64], b[64], x[64];
	register int i;
	register char *cptr, *cptr2;
	char *cptr3;

	byToBi(ptr,a);
	transpose(a,initialTr,64);
	byToBi(password+1,key);
	transpose(key,keyTr1,56);
	for (i = 0; i < 16; i++) {
		BlockMove(a,b,64L);
		for (cptr = a, cptr2 = &b[32]; cptr < &a[32]; *cptr++ = *cptr2++);
		f(i,key,a,x);
		for (cptr = b, cptr2 = x, cptr3 = &a[32]; cptr < &b[32];
			*cptr3++ = *cptr++ ^ *cptr2++);
	};
	transpose(a,swap,64);
	transpose(a,finalTr,64);
	biToBy(a,ptr);
}

/*Çdecrypt(buf,sz)È	decrypt(buf,sz)

	Function: Decrypt the contents of buffer buf, of size sz.

	Algorithm: Either exclusive or or DES.

	Comments: None.
*/

decrypt(buf,sz)

char *buf;
long sz;

{
	register char *ptr;
	register long cnt;

	ptr = buf; cnt = sz;

	switch (cryptFile) {
		case SIMPCRYPT:
			while (cnt--) {
				*ptr++ ^= *xorPtr++;
				if ((--xorCnt) == 0) {
					xorPtr = packedKey; xorCnt = 7;
				};
			};
			break;

		case DESCRYPT:
			while (cnt) {
				dec8(ptr);
				ptr += 8; cnt -= 8;
			};
			break;
	};
}

dec8(ptr)

char ptr[8];

{
	char a[64], b[64], x[64];
	register int i;
	register char *cptr, *cptr2;
	char *cptr3;

	byToBi(ptr,a);
	dtranspose(a,finalTr,64);
	dtranspose(a,swap,64);
	byToBi(password+1,key);
	transpose(key,keyTr1,56);
	for (i = 15; i >= 0; i--) {
		BlockMove(a,b,64L);
		df(i,key,a,x);
		for (cptr = a, cptr2 = &b[32], cptr3 = x; cptr < &a[32];
			*cptr++ = *cptr2++ ^ *cptr3++);
		for (cptr = b, cptr2 = &a[32]; cptr < &b[32]; *cptr2++ = *cptr++);
	};
	dtranspose(a,initialTr,64);
	biToBy(a,ptr);
}

/*ÇbyToBi(byteIn,bitOut), biToBy(bitIn,byteOut)È	byToBi(byteIn,bitOut), biToBy(bitIn,byteOut)

	Function: Convert between byte format and bit blocks (one bit per byte).

	Algorithm: Just cycle thru copying bits.

	Comments: None.
*/

byToBi(byteIn,bitOut)

char byteIn[8];
char bitOut[64];

{
	register char *bytePtr;
	register char *bitPtr;
	register int i;

	for (bytePtr = byteIn, bitPtr = bitOut; bytePtr < &byteIn[8]; bytePtr++)
		for (i = 7; i >= 0; i--) *bitPtr++ = (*bytePtr >> i) & 1;
}

biToBy(bitIn,byteOut)

char bitIn[64];
char byteOut[8];

{
	register char *bitPtr;
	register char *bytePtr;
	register int i;

	for (bitPtr = bitIn, bytePtr = byteOut; bytePtr < &byteOut[8]; bytePtr++) {
		*bytePtr = 0;
		for (i = 0; i < 8; i++) *bytePtr = (*bytePtr << 1) | (*bitPtr++ & 1);
	};
}

/*Çtranspose(data,t,n), dtranspose(data,t,n)È	transpose(data,t,n), dtranspose(data,t,n)

	Function: Transpose the data in data, of size n, according to transposition t. And it's inverse.

	Algorithm: Cycle thru all the bits and transpose each one.

	Comments: None.
*/

transpose(data,t,n)

char data[64];
int t[64];
int n;

{
	char x[64];
	register char *dptr;
	register int *tptr;
	char *endptr;

	BlockMove(data,x,64L);
	for (dptr = data, tptr = t, endptr = &data[n]; dptr < endptr; *dptr++ = x[*tptr++ - 1]);
}

dtranspose(data,t,n)

char data[64];
int t[64];
int n;

{
	char x[64];
	register char *dptr;
	register int *tptr;
	char *endptr;

	BlockMove(data,x,64L);
	for (dptr = x, tptr = t, endptr = &x[n]; dptr < endptr; data[*tptr++ - 1] = *dptr++);
}

/*Çrotate(k), drotate(k)È	rotate(k), drotate(k)

	Function: Rotate the block one bit. And it's inverse.

	Algorithm: Just cycle thru and move 'em over one.

	Comments: None.
*/

rotate(k)

char k[64];

{
	register char *cptr, *cptr2;
	char x[64];

	for (cptr = x, cptr2 = &k[1]; cptr < &x[55]; *cptr++ = *cptr2++);
	x[27] = k[0]; x[55] = k[28];
	BlockMove(x,k,64L);
}

drotate(k)

char k[64];

{
	register char *cptr, *cptr2;
	char x[64];

	for (cptr = &k[54], cptr2 = &x[55]; cptr >= k; *cptr2-- = *cptr--);
	x[0] = k[27]; x[28] = k[55];
	BlockMove(x,k,64L);
}

/*Çf(i,key,a,x)È	f(i,key,a,x)

	Function: Perform an interim DES encryption function.

	Algorithm: Yes, quite a lot.

	Comments: None.
*/

f(i,key,a,x)

int i;
char key[64];
char a[64];
char x[64];

{
	char e[64], y[64], ikey[64];
	register int r, k, j;
	register char *cptr, *cptr2;
	char *cptr3;

	BlockMove(a,e,64L);
	transpose(e,etr,48);
	rotate(key);
	if (rots[i] > 1) rotate(key);
	BlockMove(key,ikey,64L); transpose(ikey,keyTr2,48);
	for (cptr = y, cptr2 = e, cptr3 = ikey; cptr < &y[48]; *cptr++ = *cptr2++ ^ *cptr3++);
	for (k = 0; k < 8; k++) {
		j = 6*k;
		r = (y[j]<<5) + (y[j+5]<<4) + (y[j+1]<<3);
		r += (y[j+2]<<2) + (y[j+3]<<1) + y[j+4];
		j = 4*k;
		x[j] = (s[k][r]>>3) & 1;
		x[j+1] = (s[k][r]>>2) & 1;
		x[j+2] = (s[k][r]>>1) & 1;
		x[j+3] = s[k][r] & 1;
	};
	transpose(x,ptr,32);
}

df(i,key,a,x)

int i;
char key[64];
char a[64];
char x[64];

{
	char e[64], y[64], ikey[64];
	register int r, k, j;
	register char *cptr, *cptr2;
	char *cptr3;

	BlockMove(a,e,64L);
	transpose(e,etr,48);
	BlockMove(key,ikey,64L); transpose(ikey,keyTr2,48);
	for (cptr = y, cptr2 = e, cptr3 = ikey; cptr < &y[48]; *cptr++ = *cptr2++ ^ *cptr3++);
	for (k = 0; k < 8; k++) {
		j = 6*k;
		r = (y[j]<<5) + (y[j+5]<<4) + (y[j+1]<<3);
		r += (y[j+2]<<2) + (y[j+3]<<1) + y[j+4];
		j = 4*k;
		x[j] = (s[k][r]>>3) & 1;
		x[j+1] = (s[k][r]>>2) & 1;
		x[j+2] = (s[k][r]>>1) & 1;
		x[j+3] = s[k][r] & 1;
	};
	transpose(x,ptr,32);
	drotate(key);
	if (rots[i] > 1) drotate(key);
}

/*ÇDebugging RoutinesÈ	Debugging Routines
*/

#ifdef DEBUG

main()

{
	register int i, d;
	char inBlk[8], outBlk[8];

	cryptFile = DESCRYPT;
/*****
	for (i = 0; i < 8; i++) {
		printf("blk[%d]? ",i);
		scanf("%x",&d);
		inBlk[i] = d;
	};
	for (i = 0; i < 8; i++) {
		printf("pass[%d]? ",i);
		scanf("%x",&d);
		password[i+1] = d;
	};
*****/
	d = 1;
	while (1) {
		if (Button()) exit();
		printf("%d. ",d++);
		for (i = 0; i < 8; i++) {
			inBlk[i] = Random();
			password[i+1] = Random();
		};
		BlockMove(inBlk,outBlk,8L);
		/*printBytes(inBlk);*/
		startCrypt();
		encrypt(inBlk,8L);
		/*printf("; enc,"); printBytes(inBlk);*/
		decrypt(inBlk,8L);
		/*printf("; dec,"); printBytes(inBlk);
		printf("\n");*/
		for (i = 0; i < 8; i++)
			if (inBlk[i] != outBlk[i]) {
				printf("Fail!!!!!\n");
				exit();
			};
	};
}

printBytes(blk)

char blk[8];

{
	int i, d;

	for (i = 0; i < 8; i++) {
		d = blk[i] & 0xFF;
		if (d < 16) printf("0%x",d);
		else printf("%x",d);
	};
}

printBits(blk)

char blk[64];

{
	int i;

	for (i = 0; i < 64; i++) printf("%d",blk[i]);
}

#endif DEBUG