xref: /plan9/sys/src/cmd/unix/drawterm/libsec/des.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include "os.h"
2*8ccd4a63SDavid du Colombier #include <libsec.h>
39b943567SDavid du Colombier 
49b943567SDavid du Colombier /*
59b943567SDavid du Colombier  * integrated sbox & p perm
69b943567SDavid du Colombier  */
79b943567SDavid du Colombier static u32int spbox[] = {
89b943567SDavid du Colombier 
99b943567SDavid du Colombier 0x00808200,0x00000000,0x00008000,0x00808202,0x00808002,0x00008202,0x00000002,0x00008000,
109b943567SDavid du Colombier 0x00000200,0x00808200,0x00808202,0x00000200,0x00800202,0x00808002,0x00800000,0x00000002,
119b943567SDavid du Colombier 0x00000202,0x00800200,0x00800200,0x00008200,0x00008200,0x00808000,0x00808000,0x00800202,
129b943567SDavid du Colombier 0x00008002,0x00800002,0x00800002,0x00008002,0x00000000,0x00000202,0x00008202,0x00800000,
139b943567SDavid du Colombier 0x00008000,0x00808202,0x00000002,0x00808000,0x00808200,0x00800000,0x00800000,0x00000200,
149b943567SDavid du Colombier 0x00808002,0x00008000,0x00008200,0x00800002,0x00000200,0x00000002,0x00800202,0x00008202,
159b943567SDavid du Colombier 0x00808202,0x00008002,0x00808000,0x00800202,0x00800002,0x00000202,0x00008202,0x00808200,
169b943567SDavid du Colombier 0x00000202,0x00800200,0x00800200,0x00000000,0x00008002,0x00008200,0x00000000,0x00808002,
179b943567SDavid du Colombier 
189b943567SDavid du Colombier 0x40084010,0x40004000,0x00004000,0x00084010,0x00080000,0x00000010,0x40080010,0x40004010,
199b943567SDavid du Colombier 0x40000010,0x40084010,0x40084000,0x40000000,0x40004000,0x00080000,0x00000010,0x40080010,
209b943567SDavid du Colombier 0x00084000,0x00080010,0x40004010,0x00000000,0x40000000,0x00004000,0x00084010,0x40080000,
219b943567SDavid du Colombier 0x00080010,0x40000010,0x00000000,0x00084000,0x00004010,0x40084000,0x40080000,0x00004010,
229b943567SDavid du Colombier 0x00000000,0x00084010,0x40080010,0x00080000,0x40004010,0x40080000,0x40084000,0x00004000,
239b943567SDavid du Colombier 0x40080000,0x40004000,0x00000010,0x40084010,0x00084010,0x00000010,0x00004000,0x40000000,
249b943567SDavid du Colombier 0x00004010,0x40084000,0x00080000,0x40000010,0x00080010,0x40004010,0x40000010,0x00080010,
259b943567SDavid du Colombier 0x00084000,0x00000000,0x40004000,0x00004010,0x40000000,0x40080010,0x40084010,0x00084000,
269b943567SDavid du Colombier 
279b943567SDavid du Colombier 0x00000104,0x04010100,0x00000000,0x04010004,0x04000100,0x00000000,0x00010104,0x04000100,
289b943567SDavid du Colombier 0x00010004,0x04000004,0x04000004,0x00010000,0x04010104,0x00010004,0x04010000,0x00000104,
299b943567SDavid du Colombier 0x04000000,0x00000004,0x04010100,0x00000100,0x00010100,0x04010000,0x04010004,0x00010104,
309b943567SDavid du Colombier 0x04000104,0x00010100,0x00010000,0x04000104,0x00000004,0x04010104,0x00000100,0x04000000,
319b943567SDavid du Colombier 0x04010100,0x04000000,0x00010004,0x00000104,0x00010000,0x04010100,0x04000100,0x00000000,
329b943567SDavid du Colombier 0x00000100,0x00010004,0x04010104,0x04000100,0x04000004,0x00000100,0x00000000,0x04010004,
339b943567SDavid du Colombier 0x04000104,0x00010000,0x04000000,0x04010104,0x00000004,0x00010104,0x00010100,0x04000004,
349b943567SDavid du Colombier 0x04010000,0x04000104,0x00000104,0x04010000,0x00010104,0x00000004,0x04010004,0x00010100,
359b943567SDavid du Colombier 
369b943567SDavid du Colombier 0x80401000,0x80001040,0x80001040,0x00000040,0x00401040,0x80400040,0x80400000,0x80001000,
379b943567SDavid du Colombier 0x00000000,0x00401000,0x00401000,0x80401040,0x80000040,0x00000000,0x00400040,0x80400000,
389b943567SDavid du Colombier 0x80000000,0x00001000,0x00400000,0x80401000,0x00000040,0x00400000,0x80001000,0x00001040,
399b943567SDavid du Colombier 0x80400040,0x80000000,0x00001040,0x00400040,0x00001000,0x00401040,0x80401040,0x80000040,
409b943567SDavid du Colombier 0x00400040,0x80400000,0x00401000,0x80401040,0x80000040,0x00000000,0x00000000,0x00401000,
419b943567SDavid du Colombier 0x00001040,0x00400040,0x80400040,0x80000000,0x80401000,0x80001040,0x80001040,0x00000040,
429b943567SDavid du Colombier 0x80401040,0x80000040,0x80000000,0x00001000,0x80400000,0x80001000,0x00401040,0x80400040,
439b943567SDavid du Colombier 0x80001000,0x00001040,0x00400000,0x80401000,0x00000040,0x00400000,0x00001000,0x00401040,
449b943567SDavid du Colombier 
459b943567SDavid du Colombier 0x00000080,0x01040080,0x01040000,0x21000080,0x00040000,0x00000080,0x20000000,0x01040000,
469b943567SDavid du Colombier 0x20040080,0x00040000,0x01000080,0x20040080,0x21000080,0x21040000,0x00040080,0x20000000,
479b943567SDavid du Colombier 0x01000000,0x20040000,0x20040000,0x00000000,0x20000080,0x21040080,0x21040080,0x01000080,
489b943567SDavid du Colombier 0x21040000,0x20000080,0x00000000,0x21000000,0x01040080,0x01000000,0x21000000,0x00040080,
499b943567SDavid du Colombier 0x00040000,0x21000080,0x00000080,0x01000000,0x20000000,0x01040000,0x21000080,0x20040080,
509b943567SDavid du Colombier 0x01000080,0x20000000,0x21040000,0x01040080,0x20040080,0x00000080,0x01000000,0x21040000,
519b943567SDavid du Colombier 0x21040080,0x00040080,0x21000000,0x21040080,0x01040000,0x00000000,0x20040000,0x21000000,
529b943567SDavid du Colombier 0x00040080,0x01000080,0x20000080,0x00040000,0x00000000,0x20040000,0x01040080,0x20000080,
539b943567SDavid du Colombier 
549b943567SDavid du Colombier 0x10000008,0x10200000,0x00002000,0x10202008,0x10200000,0x00000008,0x10202008,0x00200000,
559b943567SDavid du Colombier 0x10002000,0x00202008,0x00200000,0x10000008,0x00200008,0x10002000,0x10000000,0x00002008,
569b943567SDavid du Colombier 0x00000000,0x00200008,0x10002008,0x00002000,0x00202000,0x10002008,0x00000008,0x10200008,
579b943567SDavid du Colombier 0x10200008,0x00000000,0x00202008,0x10202000,0x00002008,0x00202000,0x10202000,0x10000000,
589b943567SDavid du Colombier 0x10002000,0x00000008,0x10200008,0x00202000,0x10202008,0x00200000,0x00002008,0x10000008,
599b943567SDavid du Colombier 0x00200000,0x10002000,0x10000000,0x00002008,0x10000008,0x10202008,0x00202000,0x10200000,
609b943567SDavid du Colombier 0x00202008,0x10202000,0x00000000,0x10200008,0x00000008,0x00002000,0x10200000,0x00202008,
619b943567SDavid du Colombier 0x00002000,0x00200008,0x10002008,0x00000000,0x10202000,0x10000000,0x00200008,0x10002008,
629b943567SDavid du Colombier 
639b943567SDavid du Colombier 0x00100000,0x02100001,0x02000401,0x00000000,0x00000400,0x02000401,0x00100401,0x02100400,
649b943567SDavid du Colombier 0x02100401,0x00100000,0x00000000,0x02000001,0x00000001,0x02000000,0x02100001,0x00000401,
659b943567SDavid du Colombier 0x02000400,0x00100401,0x00100001,0x02000400,0x02000001,0x02100000,0x02100400,0x00100001,
669b943567SDavid du Colombier 0x02100000,0x00000400,0x00000401,0x02100401,0x00100400,0x00000001,0x02000000,0x00100400,
679b943567SDavid du Colombier 0x02000000,0x00100400,0x00100000,0x02000401,0x02000401,0x02100001,0x02100001,0x00000001,
689b943567SDavid du Colombier 0x00100001,0x02000000,0x02000400,0x00100000,0x02100400,0x00000401,0x00100401,0x02100400,
699b943567SDavid du Colombier 0x00000401,0x02000001,0x02100401,0x02100000,0x00100400,0x00000000,0x00000001,0x02100401,
709b943567SDavid du Colombier 0x00000000,0x00100401,0x02100000,0x00000400,0x02000001,0x02000400,0x00000400,0x00100001,
719b943567SDavid du Colombier 
729b943567SDavid du Colombier 0x08000820,0x00000800,0x00020000,0x08020820,0x08000000,0x08000820,0x00000020,0x08000000,
739b943567SDavid du Colombier 0x00020020,0x08020000,0x08020820,0x00020800,0x08020800,0x00020820,0x00000800,0x00000020,
749b943567SDavid du Colombier 0x08020000,0x08000020,0x08000800,0x00000820,0x00020800,0x00020020,0x08020020,0x08020800,
759b943567SDavid du Colombier 0x00000820,0x00000000,0x00000000,0x08020020,0x08000020,0x08000800,0x00020820,0x00020000,
769b943567SDavid du Colombier 0x00020820,0x00020000,0x08020800,0x00000800,0x00000020,0x08020020,0x00000800,0x00020820,
779b943567SDavid du Colombier 0x08000800,0x00000020,0x08000020,0x08020000,0x08020020,0x08000000,0x00020000,0x08000820,
789b943567SDavid du Colombier 0x00000000,0x08020820,0x00020020,0x08000020,0x08020000,0x08000800,0x08000820,0x00000000,
799b943567SDavid du Colombier 0x08020820,0x00020800,0x00020800,0x00000820,0x00000820,0x00020020,0x08000000,0x08020800,
809b943567SDavid du Colombier };
819b943567SDavid du Colombier 
829b943567SDavid du Colombier /*
839b943567SDavid du Colombier  * for manual index calculation
849b943567SDavid du Colombier  * #define fetch(box, i, sh) (*((u32int*)((uchar*)spbox + (box << 8) + ((i >> (sh)) & 0xfc))))
859b943567SDavid du Colombier  */
869b943567SDavid du Colombier #define fetch(box, i, sh) ((spbox+(box << 6))[((i >> (sh + 2)) & 0x3f)])
879b943567SDavid du Colombier 
889b943567SDavid du Colombier /*
899b943567SDavid du Colombier  * DES electronic codebook encryption of one block
909b943567SDavid du Colombier  */
919b943567SDavid du Colombier void
block_cipher(ulong key[32],uchar text[8],int decrypting)929b943567SDavid du Colombier block_cipher(ulong key[32], uchar text[8], int decrypting)
939b943567SDavid du Colombier {
949b943567SDavid du Colombier 	u32int right, left, v0, v1;
959b943567SDavid du Colombier 	int i, keystep;
969b943567SDavid du Colombier 
979b943567SDavid du Colombier 	/*
989b943567SDavid du Colombier 	 * initial permutation
999b943567SDavid du Colombier 	 */
1009b943567SDavid du Colombier 	v0 = text[0] | ((u32int)text[2]<<8) | ((u32int)text[4]<<16) | ((u32int)text[6]<<24);
1019b943567SDavid du Colombier 	left = text[1] | ((u32int)text[3]<<8) | ((u32int)text[5]<<16) | ((u32int)text[7]<<24);
1029b943567SDavid du Colombier 	right = (left & 0xaaaaaaaa) | ((v0 >> 1) & 0x55555555);
1039b943567SDavid du Colombier 	left = ((left << 1) & 0xaaaaaaaa) | (v0 & 0x55555555);
1049b943567SDavid du Colombier 	left = ((left << 6) & 0x33003300)
1059b943567SDavid du Colombier 		| (left & 0xcc33cc33)
1069b943567SDavid du Colombier 		| ((left >> 6) & 0x00cc00cc);
1079b943567SDavid du Colombier 	left = ((left << 12) & 0x0f0f0000)
1089b943567SDavid du Colombier 		| (left & 0xf0f00f0f)
1099b943567SDavid du Colombier 		| ((left >> 12) & 0x0000f0f0);
1109b943567SDavid du Colombier 	right = ((right << 6) & 0x33003300)
1119b943567SDavid du Colombier 		| (right & 0xcc33cc33)
1129b943567SDavid du Colombier 		| ((right >> 6) & 0x00cc00cc);
1139b943567SDavid du Colombier 	right = ((right << 12) & 0x0f0f0000)
1149b943567SDavid du Colombier 		| (right & 0xf0f00f0f)
1159b943567SDavid du Colombier 		| ((right >> 12) & 0x0000f0f0);
1169b943567SDavid du Colombier 
1179b943567SDavid du Colombier 	if (decrypting) {
1189b943567SDavid du Colombier 		keystep = -2;
1199b943567SDavid du Colombier 		key = key + 32 - 2;
1209b943567SDavid du Colombier 	} else
1219b943567SDavid du Colombier 		keystep = 2;
1229b943567SDavid du Colombier 	for (i = 0; i < 8; i++) {
1239b943567SDavid du Colombier 		v0 = key[0];
1249b943567SDavid du Colombier 		v0 ^= (right >> 1) | (right << 31);
1259b943567SDavid du Colombier 		left ^= fetch(0, v0, 24)
1269b943567SDavid du Colombier 			^ fetch(2, v0, 16)
1279b943567SDavid du Colombier 			^ fetch(4, v0, 8)
1289b943567SDavid du Colombier 			^ fetch(6, v0, 0);
1299b943567SDavid du Colombier 		v1 = key[1];
1309b943567SDavid du Colombier 		v1 ^= (right << 3) | (right >> 29);
1319b943567SDavid du Colombier 		left ^= fetch(1, v1, 24)
1329b943567SDavid du Colombier 			^ fetch(3, v1, 16)
1339b943567SDavid du Colombier 			^ fetch(5, v1, 8)
1349b943567SDavid du Colombier 			^ fetch(7, v1, 0);
1359b943567SDavid du Colombier 		key += keystep;
1369b943567SDavid du Colombier 
1379b943567SDavid du Colombier 		v0 = key[0];
1389b943567SDavid du Colombier 		v0 ^= (left >> 1) | (left << 31);
1399b943567SDavid du Colombier 		right ^= fetch(0, v0, 24)
1409b943567SDavid du Colombier 			^ fetch(2, v0, 16)
1419b943567SDavid du Colombier 			^ fetch(4, v0, 8)
1429b943567SDavid du Colombier 			^ fetch(6, v0, 0);
1439b943567SDavid du Colombier 		v1 = key[1];
1449b943567SDavid du Colombier 		v1 ^= (left << 3) | (left >> 29);
1459b943567SDavid du Colombier 		right ^= fetch(1, v1, 24)
1469b943567SDavid du Colombier 			^ fetch(3, v1, 16)
1479b943567SDavid du Colombier 			^ fetch(5, v1, 8)
1489b943567SDavid du Colombier 			^ fetch(7, v1, 0);
1499b943567SDavid du Colombier 		key += keystep;
1509b943567SDavid du Colombier 	}
1519b943567SDavid du Colombier 
1529b943567SDavid du Colombier 	/*
1539b943567SDavid du Colombier 	 * final permutation, inverse initial permutation
1549b943567SDavid du Colombier 	 */
1559b943567SDavid du Colombier 	v0 = ((left << 1) & 0xaaaaaaaa) | (right & 0x55555555);
1569b943567SDavid du Colombier 	v1 = (left & 0xaaaaaaaa) | ((right >> 1) & 0x55555555);
1579b943567SDavid du Colombier 	v1 = ((v1 << 6) & 0x33003300)
1589b943567SDavid du Colombier 		| (v1 & 0xcc33cc33)
1599b943567SDavid du Colombier 		| ((v1 >> 6) & 0x00cc00cc);
1609b943567SDavid du Colombier 	v1 = ((v1 << 12) & 0x0f0f0000)
1619b943567SDavid du Colombier 		| (v1 & 0xf0f00f0f)
1629b943567SDavid du Colombier 		| ((v1 >> 12) & 0x0000f0f0);
1639b943567SDavid du Colombier 	v0 = ((v0 << 6) & 0x33003300)
1649b943567SDavid du Colombier 		| (v0 & 0xcc33cc33)
1659b943567SDavid du Colombier 		| ((v0 >> 6) & 0x00cc00cc);
1669b943567SDavid du Colombier 	v0 = ((v0 << 12) & 0x0f0f0000)
1679b943567SDavid du Colombier 		| (v0 & 0xf0f00f0f)
1689b943567SDavid du Colombier 		| ((v0 >> 12) & 0x0000f0f0);
1699b943567SDavid du Colombier 	text[0] = v0;
1709b943567SDavid du Colombier 	text[2] = v0 >> 8;
1719b943567SDavid du Colombier 	text[4] = v0 >> 16;
1729b943567SDavid du Colombier 	text[6] = v0 >> 24;
1739b943567SDavid du Colombier 	text[1] = v1;
1749b943567SDavid du Colombier 	text[3] = v1 >> 8;
1759b943567SDavid du Colombier 	text[5] = v1 >> 16;
1769b943567SDavid du Colombier 	text[7] = v1 >> 24;
1779b943567SDavid du Colombier }
1789b943567SDavid du Colombier 
1799b943567SDavid du Colombier /*
1809b943567SDavid du Colombier  * triple DES electronic codebook encryption of one block
1819b943567SDavid du Colombier  */
1829b943567SDavid du Colombier void
triple_block_cipher(ulong expanded_key[3][32],uchar text[8],int ende)1839b943567SDavid du Colombier triple_block_cipher(ulong expanded_key[3][32], uchar text[8], int ende)
1849b943567SDavid du Colombier {
1859b943567SDavid du Colombier 	ulong *key;
1869b943567SDavid du Colombier 	u32int right, left, v0, v1;
1879b943567SDavid du Colombier 	int i, j, keystep;
1889b943567SDavid du Colombier 
1899b943567SDavid du Colombier 	/*
1909b943567SDavid du Colombier 	 * initial permutation
1919b943567SDavid du Colombier 	 */
1929b943567SDavid du Colombier 	v0 = text[0] | ((u32int)text[2]<<8) | ((u32int)text[4]<<16) | ((u32int)text[6]<<24);
1939b943567SDavid du Colombier 	left = text[1] | ((u32int)text[3]<<8) | ((u32int)text[5]<<16) | ((u32int)text[7]<<24);
1949b943567SDavid du Colombier 	right = (left & 0xaaaaaaaa) | ((v0 >> 1) & 0x55555555);
1959b943567SDavid du Colombier 	left = ((left << 1) & 0xaaaaaaaa) | (v0 & 0x55555555);
1969b943567SDavid du Colombier 	left = ((left << 6) & 0x33003300)
1979b943567SDavid du Colombier 		| (left & 0xcc33cc33)
1989b943567SDavid du Colombier 		| ((left >> 6) & 0x00cc00cc);
1999b943567SDavid du Colombier 	left = ((left << 12) & 0x0f0f0000)
2009b943567SDavid du Colombier 		| (left & 0xf0f00f0f)
2019b943567SDavid du Colombier 		| ((left >> 12) & 0x0000f0f0);
2029b943567SDavid du Colombier 	right = ((right << 6) & 0x33003300)
2039b943567SDavid du Colombier 		| (right & 0xcc33cc33)
2049b943567SDavid du Colombier 		| ((right >> 6) & 0x00cc00cc);
2059b943567SDavid du Colombier 	right = ((right << 12) & 0x0f0f0000)
2069b943567SDavid du Colombier 		| (right & 0xf0f00f0f)
2079b943567SDavid du Colombier 		| ((right >> 12) & 0x0000f0f0);
2089b943567SDavid du Colombier 
2099b943567SDavid du Colombier 	for(j = 0; j < 3; j++){
2109b943567SDavid du Colombier 		if((ende & 1) == DES3D) {
2119b943567SDavid du Colombier 			key = &expanded_key[2-j][32-2];
2129b943567SDavid du Colombier 			keystep = -2;
2139b943567SDavid du Colombier 		} else {
2149b943567SDavid du Colombier 			key = &expanded_key[j][0];
2159b943567SDavid du Colombier 			keystep = 2;
2169b943567SDavid du Colombier 		}
2179b943567SDavid du Colombier 		ende >>= 1;
2189b943567SDavid du Colombier 		for (i = 0; i < 8; i++) {
2199b943567SDavid du Colombier 			v0 = key[0];
2209b943567SDavid du Colombier 			v0 ^= (right >> 1) | (right << 31);
2219b943567SDavid du Colombier 			left ^= fetch(0, v0, 24)
2229b943567SDavid du Colombier 				^ fetch(2, v0, 16)
2239b943567SDavid du Colombier 				^ fetch(4, v0, 8)
2249b943567SDavid du Colombier 				^ fetch(6, v0, 0);
2259b943567SDavid du Colombier 			v1 = key[1];
2269b943567SDavid du Colombier 			v1 ^= (right << 3) | (right >> 29);
2279b943567SDavid du Colombier 			left ^= fetch(1, v1, 24)
2289b943567SDavid du Colombier 				^ fetch(3, v1, 16)
2299b943567SDavid du Colombier 				^ fetch(5, v1, 8)
2309b943567SDavid du Colombier 				^ fetch(7, v1, 0);
2319b943567SDavid du Colombier 			key += keystep;
2329b943567SDavid du Colombier 
2339b943567SDavid du Colombier 			v0 = key[0];
2349b943567SDavid du Colombier 			v0 ^= (left >> 1) | (left << 31);
2359b943567SDavid du Colombier 			right ^= fetch(0, v0, 24)
2369b943567SDavid du Colombier 				^ fetch(2, v0, 16)
2379b943567SDavid du Colombier 				^ fetch(4, v0, 8)
2389b943567SDavid du Colombier 				^ fetch(6, v0, 0);
2399b943567SDavid du Colombier 			v1 = key[1];
2409b943567SDavid du Colombier 			v1 ^= (left << 3) | (left >> 29);
2419b943567SDavid du Colombier 			right ^= fetch(1, v1, 24)
2429b943567SDavid du Colombier 				^ fetch(3, v1, 16)
2439b943567SDavid du Colombier 				^ fetch(5, v1, 8)
2449b943567SDavid du Colombier 				^ fetch(7, v1, 0);
2459b943567SDavid du Colombier 			key += keystep;
2469b943567SDavid du Colombier 		}
2479b943567SDavid du Colombier 
2489b943567SDavid du Colombier 		v0 = left;
2499b943567SDavid du Colombier 		left = right;
2509b943567SDavid du Colombier 		right = v0;
2519b943567SDavid du Colombier 	}
2529b943567SDavid du Colombier 
2539b943567SDavid du Colombier 	/*
2549b943567SDavid du Colombier 	 * final permutation, inverse initial permutation
2559b943567SDavid du Colombier 	 * left and right are swapped here
2569b943567SDavid du Colombier 	 */
2579b943567SDavid du Colombier 	v0 = ((right << 1) & 0xaaaaaaaa) | (left & 0x55555555);
2589b943567SDavid du Colombier 	v1 = (right & 0xaaaaaaaa) | ((left >> 1) & 0x55555555);
2599b943567SDavid du Colombier 	v1 = ((v1 << 6) & 0x33003300)
2609b943567SDavid du Colombier 		| (v1 & 0xcc33cc33)
2619b943567SDavid du Colombier 		| ((v1 >> 6) & 0x00cc00cc);
2629b943567SDavid du Colombier 	v1 = ((v1 << 12) & 0x0f0f0000)
2639b943567SDavid du Colombier 		| (v1 & 0xf0f00f0f)
2649b943567SDavid du Colombier 		| ((v1 >> 12) & 0x0000f0f0);
2659b943567SDavid du Colombier 	v0 = ((v0 << 6) & 0x33003300)
2669b943567SDavid du Colombier 		| (v0 & 0xcc33cc33)
2679b943567SDavid du Colombier 		| ((v0 >> 6) & 0x00cc00cc);
2689b943567SDavid du Colombier 	v0 = ((v0 << 12) & 0x0f0f0000)
2699b943567SDavid du Colombier 		| (v0 & 0xf0f00f0f)
2709b943567SDavid du Colombier 		| ((v0 >> 12) & 0x0000f0f0);
2719b943567SDavid du Colombier 	text[0] = v0;
2729b943567SDavid du Colombier 	text[2] = v0 >> 8;
2739b943567SDavid du Colombier 	text[4] = v0 >> 16;
2749b943567SDavid du Colombier 	text[6] = v0 >> 24;
2759b943567SDavid du Colombier 	text[1] = v1;
2769b943567SDavid du Colombier 	text[3] = v1 >> 8;
2779b943567SDavid du Colombier 	text[5] = v1 >> 16;
2789b943567SDavid du Colombier 	text[7] = v1 >> 24;
2799b943567SDavid du Colombier }
2809b943567SDavid du Colombier 
2819b943567SDavid du Colombier /*
2829b943567SDavid du Colombier  * key compression permutation, 4 bits at a time
2839b943567SDavid du Colombier  */
2849b943567SDavid du Colombier static u32int comptab[] = {
2859b943567SDavid du Colombier 
2869b943567SDavid du Colombier 0x000000,0x010000,0x000008,0x010008,0x000080,0x010080,0x000088,0x010088,
2879b943567SDavid du Colombier 0x000000,0x010000,0x000008,0x010008,0x000080,0x010080,0x000088,0x010088,
2889b943567SDavid du Colombier 
2899b943567SDavid du Colombier 0x000000,0x100000,0x000800,0x100800,0x000000,0x100000,0x000800,0x100800,
2909b943567SDavid du Colombier 0x002000,0x102000,0x002800,0x102800,0x002000,0x102000,0x002800,0x102800,
2919b943567SDavid du Colombier 
2929b943567SDavid du Colombier 0x000000,0x000004,0x000400,0x000404,0x000000,0x000004,0x000400,0x000404,
2939b943567SDavid du Colombier 0x400000,0x400004,0x400400,0x400404,0x400000,0x400004,0x400400,0x400404,
2949b943567SDavid du Colombier 
2959b943567SDavid du Colombier 0x000000,0x000020,0x008000,0x008020,0x800000,0x800020,0x808000,0x808020,
2969b943567SDavid du Colombier 0x000002,0x000022,0x008002,0x008022,0x800002,0x800022,0x808002,0x808022,
2979b943567SDavid du Colombier 
2989b943567SDavid du Colombier 0x000000,0x000200,0x200000,0x200200,0x001000,0x001200,0x201000,0x201200,
2999b943567SDavid du Colombier 0x000000,0x000200,0x200000,0x200200,0x001000,0x001200,0x201000,0x201200,
3009b943567SDavid du Colombier 
3019b943567SDavid du Colombier 0x000000,0x000040,0x000010,0x000050,0x004000,0x004040,0x004010,0x004050,
3029b943567SDavid du Colombier 0x040000,0x040040,0x040010,0x040050,0x044000,0x044040,0x044010,0x044050,
3039b943567SDavid du Colombier 
3049b943567SDavid du Colombier 0x000000,0x000100,0x020000,0x020100,0x000001,0x000101,0x020001,0x020101,
3059b943567SDavid du Colombier 0x080000,0x080100,0x0a0000,0x0a0100,0x080001,0x080101,0x0a0001,0x0a0101,
3069b943567SDavid du Colombier 
3079b943567SDavid du Colombier 0x000000,0x000100,0x040000,0x040100,0x000000,0x000100,0x040000,0x040100,
3089b943567SDavid du Colombier 0x000040,0x000140,0x040040,0x040140,0x000040,0x000140,0x040040,0x040140,
3099b943567SDavid du Colombier 
3109b943567SDavid du Colombier 0x000000,0x400000,0x008000,0x408000,0x000008,0x400008,0x008008,0x408008,
3119b943567SDavid du Colombier 0x000400,0x400400,0x008400,0x408400,0x000408,0x400408,0x008408,0x408408,
3129b943567SDavid du Colombier 
3139b943567SDavid du Colombier 0x000000,0x001000,0x080000,0x081000,0x000020,0x001020,0x080020,0x081020,
3149b943567SDavid du Colombier 0x004000,0x005000,0x084000,0x085000,0x004020,0x005020,0x084020,0x085020,
3159b943567SDavid du Colombier 
3169b943567SDavid du Colombier 0x000000,0x000800,0x000000,0x000800,0x000010,0x000810,0x000010,0x000810,
3179b943567SDavid du Colombier 0x800000,0x800800,0x800000,0x800800,0x800010,0x800810,0x800010,0x800810,
3189b943567SDavid du Colombier 
3199b943567SDavid du Colombier 0x000000,0x010000,0x000200,0x010200,0x000000,0x010000,0x000200,0x010200,
3209b943567SDavid du Colombier 0x100000,0x110000,0x100200,0x110200,0x100000,0x110000,0x100200,0x110200,
3219b943567SDavid du Colombier 
3229b943567SDavid du Colombier 0x000000,0x000004,0x000000,0x000004,0x000080,0x000084,0x000080,0x000084,
3239b943567SDavid du Colombier 0x002000,0x002004,0x002000,0x002004,0x002080,0x002084,0x002080,0x002084,
3249b943567SDavid du Colombier 
3259b943567SDavid du Colombier 0x000000,0x000001,0x200000,0x200001,0x020000,0x020001,0x220000,0x220001,
3269b943567SDavid du Colombier 0x000002,0x000003,0x200002,0x200003,0x020002,0x020003,0x220002,0x220003,
3279b943567SDavid du Colombier };
3289b943567SDavid du Colombier 
3299b943567SDavid du Colombier static int keysh[] =
3309b943567SDavid du Colombier {
3319b943567SDavid du Colombier 	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
3329b943567SDavid du Colombier };
3339b943567SDavid du Colombier 
3349b943567SDavid du Colombier static void
keycompperm(u32int left,u32int right,ulong * ek)3359b943567SDavid du Colombier keycompperm(u32int left, u32int right, ulong *ek)
3369b943567SDavid du Colombier {
3379b943567SDavid du Colombier 	u32int v0, v1;
3389b943567SDavid du Colombier 	int i;
3399b943567SDavid du Colombier 
3409b943567SDavid du Colombier 	for(i = 0; i < 16; i++){
3419b943567SDavid du Colombier 		left = (left << keysh[i]) | (left >> (28 - keysh[i]));
3429b943567SDavid du Colombier 		left &= 0xfffffff0;
3439b943567SDavid du Colombier 		right = (right << keysh[i]) | (right >> (28 - keysh[i]));
3449b943567SDavid du Colombier 		right &= 0xfffffff0;
3459b943567SDavid du Colombier 		v0 = comptab[6 * (1 << 4) + ((left >> (32-4)) & 0xf)]
3469b943567SDavid du Colombier 			| comptab[5 * (1 << 4) + ((left >> (32-8)) & 0xf)]
3479b943567SDavid du Colombier 			| comptab[4 * (1 << 4) + ((left >> (32-12)) & 0xf)]
3489b943567SDavid du Colombier 			| comptab[3 * (1 << 4) + ((left >> (32-16)) & 0xf)]
3499b943567SDavid du Colombier 			| comptab[2 * (1 << 4) + ((left >> (32-20)) & 0xf)]
3509b943567SDavid du Colombier 			| comptab[1 * (1 << 4) + ((left >> (32-24)) & 0xf)]
3519b943567SDavid du Colombier 			| comptab[0 * (1 << 4) + ((left >> (32-28)) & 0xf)];
3529b943567SDavid du Colombier 		v1 = comptab[13 * (1 << 4) + ((right >> (32-4)) & 0xf)]
3539b943567SDavid du Colombier 			| comptab[12 * (1 << 4) + ((right >> (32-8)) & 0xf)]
3549b943567SDavid du Colombier 			| comptab[11 * (1 << 4) + ((right >> (32-12)) & 0xf)]
3559b943567SDavid du Colombier 			| comptab[10 * (1 << 4) + ((right >> (32-16)) & 0xf)]
3569b943567SDavid du Colombier 			| comptab[9 * (1 << 4) + ((right >> (32-20)) & 0xf)]
3579b943567SDavid du Colombier 			| comptab[8 * (1 << 4) + ((right >> (32-24)) & 0xf)]
3589b943567SDavid du Colombier 			| comptab[7 * (1 << 4) + ((right >> (32-28)) & 0xf)];
3599b943567SDavid du Colombier 		ek[0] = (((v0 >> (24-6)) & 0x3f) << 26)
3609b943567SDavid du Colombier 			| (((v0 >> (24-18)) & 0x3f) << 18)
3619b943567SDavid du Colombier 			| (((v1 >> (24-6)) & 0x3f) << 10)
3629b943567SDavid du Colombier 			| (((v1 >> (24-18)) & 0x3f) << 2);
3639b943567SDavid du Colombier 		ek[1] = (((v0 >> (24-12)) & 0x3f) << 26)
3649b943567SDavid du Colombier 			| (((v0 >> (24-24)) & 0x3f) << 18)
3659b943567SDavid du Colombier 			| (((v1 >> (24-12)) & 0x3f) << 10)
3669b943567SDavid du Colombier 			| (((v1 >> (24-24)) & 0x3f) << 2);
3679b943567SDavid du Colombier 		ek += 2;
3689b943567SDavid du Colombier 	}
3699b943567SDavid du Colombier }
3709b943567SDavid du Colombier 
3719b943567SDavid du Colombier void
des_key_setup(uchar key[8],ulong * ek)3729b943567SDavid du Colombier des_key_setup(uchar key[8], ulong *ek)
3739b943567SDavid du Colombier {
3749b943567SDavid du Colombier 	u32int left, right, v0, v1;
3759b943567SDavid du Colombier 
3769b943567SDavid du Colombier 	v0 = key[0] | ((u32int)key[2] << 8) | ((u32int)key[4] << 16) | ((u32int)key[6] << 24);
3779b943567SDavid du Colombier 	v1 = key[1] | ((u32int)key[3] << 8) | ((u32int)key[5] << 16) | ((u32int)key[7] << 24);
3789b943567SDavid du Colombier 	left = ((v0 >> 1) & 0x40404040)
3799b943567SDavid du Colombier 		| ((v0 >> 2) & 0x10101010)
3809b943567SDavid du Colombier 		| ((v0 >> 3) & 0x04040404)
3819b943567SDavid du Colombier 		| ((v0 >> 4) & 0x01010101)
3829b943567SDavid du Colombier 		| ((v1 >> 0) & 0x80808080)
3839b943567SDavid du Colombier 		| ((v1 >> 1) & 0x20202020)
3849b943567SDavid du Colombier 		| ((v1 >> 2) & 0x08080808)
3859b943567SDavid du Colombier 		| ((v1 >> 3) & 0x02020202);
3869b943567SDavid du Colombier 	right = ((v0 >> 1) & 0x04040404)
3879b943567SDavid du Colombier 		| ((v0 << 2) & 0x10101010)
3889b943567SDavid du Colombier 		| ((v0 << 5) & 0x40404040)
3899b943567SDavid du Colombier 		| ((v1 << 0) & 0x08080808)
3909b943567SDavid du Colombier 		| ((v1 << 3) & 0x20202020)
3919b943567SDavid du Colombier 		| ((v1 << 6) & 0x80808080);
3929b943567SDavid du Colombier 	left = ((left << 6) & 0x33003300)
3939b943567SDavid du Colombier 		| (left & 0xcc33cc33)
3949b943567SDavid du Colombier 		| ((left >> 6) & 0x00cc00cc);
3959b943567SDavid du Colombier 	v0 = ((left << 12) & 0x0f0f0000)
3969b943567SDavid du Colombier 		| (left & 0xf0f00f0f)
3979b943567SDavid du Colombier 		| ((left >> 12) & 0x0000f0f0);
3989b943567SDavid du Colombier 	right = ((right << 6) & 0x33003300)
3999b943567SDavid du Colombier 		| (right & 0xcc33cc33)
4009b943567SDavid du Colombier 		| ((right >> 6) & 0x00cc00cc);
4019b943567SDavid du Colombier 	v1 = ((right << 12) & 0x0f0f0000)
4029b943567SDavid du Colombier 		| (right & 0xf0f00f0f)
4039b943567SDavid du Colombier 		| ((right >> 12) & 0x0000f0f0);
4049b943567SDavid du Colombier 	left = v0 & 0xfffffff0;
4059b943567SDavid du Colombier 	right = (v1 & 0xffffff00) | ((v0 << 4) & 0xf0);
4069b943567SDavid du Colombier 
4079b943567SDavid du Colombier 	keycompperm(left, right, ek);
4089b943567SDavid du Colombier }
4099b943567SDavid du Colombier 
4109b943567SDavid du Colombier static uchar parity[128] =
4119b943567SDavid du Colombier {
4129b943567SDavid du Colombier 	0x01, 0x02, 0x04, 0x07, 0x08, 0x0b, 0x0d, 0x0e,
4139b943567SDavid du Colombier 	0x10, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x1f,
4149b943567SDavid du Colombier 	0x20, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x2f,
4159b943567SDavid du Colombier 	0x31, 0x32, 0x34, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
4169b943567SDavid du Colombier 	0x40, 0x43, 0x45, 0x46, 0x49, 0x4a, 0x4c, 0x4f,
4179b943567SDavid du Colombier 	0x51, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, 0x5e,
4189b943567SDavid du Colombier 	0x61, 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x6e,
4199b943567SDavid du Colombier 	0x70, 0x73, 0x75, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
4209b943567SDavid du Colombier 	0x80, 0x83, 0x85, 0x86, 0x89, 0x8a, 0x8c, 0x8f,
4219b943567SDavid du Colombier 	0x91, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d, 0x9e,
4229b943567SDavid du Colombier 	0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xae,
4239b943567SDavid du Colombier 	0xb0, 0xb3, 0xb5, 0xb6, 0xb9, 0xba, 0xbc, 0xbf,
4249b943567SDavid du Colombier 	0xc1, 0xc2, 0xc4, 0xc7, 0xc8, 0xcb, 0xcd, 0xce,
4259b943567SDavid du Colombier 	0xd0, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc, 0xdf,
4269b943567SDavid du Colombier 	0xe0, 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xef,
4279b943567SDavid du Colombier 	0xf1, 0xf2, 0xf4, 0xf7, 0xf8, 0xfb, 0xfd, 0xfe,
4289b943567SDavid du Colombier };
4299b943567SDavid du Colombier 
4309b943567SDavid du Colombier /*
4319b943567SDavid du Colombier  *  convert a 7 byte key to an 8 byte one
4329b943567SDavid du Colombier  */
4339b943567SDavid du Colombier void
des56to64(uchar * k56,uchar * k64)4349b943567SDavid du Colombier des56to64(uchar *k56, uchar *k64)
4359b943567SDavid du Colombier {
4369b943567SDavid du Colombier 	u32int hi, lo;
4379b943567SDavid du Colombier 
4389b943567SDavid du Colombier 	hi = ((u32int)k56[0]<<24)|((u32int)k56[1]<<16)|((u32int)k56[2]<<8)|k56[3];
4399b943567SDavid du Colombier 	lo = ((u32int)k56[4]<<24)|((u32int)k56[5]<<16)|((u32int)k56[6]<<8);
4409b943567SDavid du Colombier 
4419b943567SDavid du Colombier 	k64[0] = parity[(hi>>25)&0x7f];
4429b943567SDavid du Colombier 	k64[1] = parity[(hi>>18)&0x7f];
4439b943567SDavid du Colombier 	k64[2] = parity[(hi>>11)&0x7f];
4449b943567SDavid du Colombier 	k64[3] = parity[(hi>>4)&0x7f];
4459b943567SDavid du Colombier 	k64[4] = parity[((hi<<3)|(lo>>29))&0x7f];
4469b943567SDavid du Colombier 	k64[5] = parity[(lo>>22)&0x7f];
4479b943567SDavid du Colombier 	k64[6] = parity[(lo>>15)&0x7f];
4489b943567SDavid du Colombier 	k64[7] = parity[(lo>>8)&0x7f];
4499b943567SDavid du Colombier }
4509b943567SDavid du Colombier 
4519b943567SDavid du Colombier /*
4529b943567SDavid du Colombier  *  convert an 8 byte key to a 7 byte one
4539b943567SDavid du Colombier  */
4549b943567SDavid du Colombier void
des64to56(uchar * k64,uchar * k56)4559b943567SDavid du Colombier des64to56(uchar *k64, uchar *k56)
4569b943567SDavid du Colombier {
4579b943567SDavid du Colombier 	u32int hi, lo;
4589b943567SDavid du Colombier 
4599b943567SDavid du Colombier 	hi = (((u32int)k64[0]&0xfe)<<24)|(((u32int)k64[1]&0xfe)<<17)|(((u32int)k64[2]&0xfe)<<10)
4609b943567SDavid du Colombier 		|((k64[3]&0xfe)<<3)|(k64[4]>>4);
4619b943567SDavid du Colombier 	lo = (((u32int)k64[4]&0xfe)<<28)|(((u32int)k64[5]&0xfe)<<21)|(((u32int)k64[6]&0xfe)<<14)
4629b943567SDavid du Colombier 		|(((u32int)k64[7]&0xfe)<<7);
4639b943567SDavid du Colombier 
4649b943567SDavid du Colombier 	k56[0] = hi>>24;
4659b943567SDavid du Colombier 	k56[1] = hi>>16;
4669b943567SDavid du Colombier 	k56[2] = hi>>8;
4679b943567SDavid du Colombier 	k56[3] = hi>>0;
4689b943567SDavid du Colombier 	k56[4] = lo>>24;
4699b943567SDavid du Colombier 	k56[5] = lo>>16;
4709b943567SDavid du Colombier 	k56[6] = lo>>8;
4719b943567SDavid du Colombier }
4729b943567SDavid du Colombier 
4739b943567SDavid du Colombier void
key_setup(uchar key[7],ulong * ek)4749b943567SDavid du Colombier key_setup(uchar key[7], ulong *ek)
4759b943567SDavid du Colombier {
4769b943567SDavid du Colombier 	uchar k64[8];
4779b943567SDavid du Colombier 
4789b943567SDavid du Colombier 	des56to64(key, k64);
4799b943567SDavid du Colombier 	des_key_setup(k64, ek);
4809b943567SDavid du Colombier }
481