xref: /csrg-svn/lib/libc/gen/crypt.c (revision 46597)
126545Sdonn #if defined(LIBC_SCCS) && !defined(lint)
2*46597Sdonn static char sccsid[] = "@(#)crypt.c	5.4 (Berkeley) 02/23/91";
326545Sdonn #endif LIBC_SCCS and not lint
422083Smckusick 
5*46597Sdonn #include <unistd.h>
6*46597Sdonn 
71958Swnj /*
81958Swnj  * This program implements the
91958Swnj  * Proposed Federal Information Processing
101958Swnj  *  Data Encryption Standard.
111958Swnj  * See Federal Register, March 17, 1975 (40FR12134)
121958Swnj  */
131958Swnj 
141958Swnj /*
151958Swnj  * Initial permutation,
161958Swnj  */
171958Swnj static	char	IP[] = {
181958Swnj 	58,50,42,34,26,18,10, 2,
191958Swnj 	60,52,44,36,28,20,12, 4,
201958Swnj 	62,54,46,38,30,22,14, 6,
211958Swnj 	64,56,48,40,32,24,16, 8,
221958Swnj 	57,49,41,33,25,17, 9, 1,
231958Swnj 	59,51,43,35,27,19,11, 3,
241958Swnj 	61,53,45,37,29,21,13, 5,
251958Swnj 	63,55,47,39,31,23,15, 7,
261958Swnj };
271958Swnj 
281958Swnj /*
291958Swnj  * Final permutation, FP = IP^(-1)
301958Swnj  */
311958Swnj static	char	FP[] = {
321958Swnj 	40, 8,48,16,56,24,64,32,
331958Swnj 	39, 7,47,15,55,23,63,31,
341958Swnj 	38, 6,46,14,54,22,62,30,
351958Swnj 	37, 5,45,13,53,21,61,29,
361958Swnj 	36, 4,44,12,52,20,60,28,
371958Swnj 	35, 3,43,11,51,19,59,27,
381958Swnj 	34, 2,42,10,50,18,58,26,
391958Swnj 	33, 1,41, 9,49,17,57,25,
401958Swnj };
411958Swnj 
421958Swnj /*
431958Swnj  * Permuted-choice 1 from the key bits
441958Swnj  * to yield C and D.
451958Swnj  * Note that bits 8,16... are left out:
461958Swnj  * They are intended for a parity check.
471958Swnj  */
481958Swnj static	char	PC1_C[] = {
491958Swnj 	57,49,41,33,25,17, 9,
501958Swnj 	 1,58,50,42,34,26,18,
511958Swnj 	10, 2,59,51,43,35,27,
521958Swnj 	19,11, 3,60,52,44,36,
531958Swnj };
541958Swnj 
551958Swnj static	char	PC1_D[] = {
561958Swnj 	63,55,47,39,31,23,15,
571958Swnj 	 7,62,54,46,38,30,22,
581958Swnj 	14, 6,61,53,45,37,29,
591958Swnj 	21,13, 5,28,20,12, 4,
601958Swnj };
611958Swnj 
621958Swnj /*
631958Swnj  * Sequence of shifts used for the key schedule.
641958Swnj */
651958Swnj static	char	shifts[] = {
661958Swnj 	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
671958Swnj };
681958Swnj 
691958Swnj /*
701958Swnj  * Permuted-choice 2, to pick out the bits from
711958Swnj  * the CD array that generate the key schedule.
721958Swnj  */
731958Swnj static	char	PC2_C[] = {
741958Swnj 	14,17,11,24, 1, 5,
751958Swnj 	 3,28,15, 6,21,10,
761958Swnj 	23,19,12, 4,26, 8,
771958Swnj 	16, 7,27,20,13, 2,
781958Swnj };
791958Swnj 
801958Swnj static	char	PC2_D[] = {
811958Swnj 	41,52,31,37,47,55,
821958Swnj 	30,40,51,45,33,48,
831958Swnj 	44,49,39,56,34,53,
841958Swnj 	46,42,50,36,29,32,
851958Swnj };
861958Swnj 
871958Swnj /*
881958Swnj  * The C and D arrays used to calculate the key schedule.
891958Swnj  */
901958Swnj 
911958Swnj static	char	C[28];
921958Swnj static	char	D[28];
931958Swnj /*
941958Swnj  * The key schedule.
951958Swnj  * Generated from the key.
961958Swnj  */
971958Swnj static	char	KS[16][48];
981958Swnj 
991958Swnj /*
10017337Sralph  * The E bit-selection table.
10117337Sralph  */
10217337Sralph static	char	E[48];
10317337Sralph static	char	e[] = {
10417337Sralph 	32, 1, 2, 3, 4, 5,
10517337Sralph 	 4, 5, 6, 7, 8, 9,
10617337Sralph 	 8, 9,10,11,12,13,
10717337Sralph 	12,13,14,15,16,17,
10817337Sralph 	16,17,18,19,20,21,
10917337Sralph 	20,21,22,23,24,25,
11017337Sralph 	24,25,26,27,28,29,
11117337Sralph 	28,29,30,31,32, 1,
11217337Sralph };
11317337Sralph 
11417337Sralph /*
1151958Swnj  * Set up the key schedule from the key.
1161958Swnj  */
1171958Swnj 
118*46597Sdonn void
1191958Swnj setkey(key)
120*46597Sdonn const char *key;
1211958Swnj {
1221958Swnj 	register i, j, k;
1231958Swnj 	int t;
1241958Swnj 
1251958Swnj 	/*
1261958Swnj 	 * First, generate C and D by permuting
1271958Swnj 	 * the key.  The low order bit of each
1281958Swnj 	 * 8-bit char is not used, so C and D are only 28
1291958Swnj 	 * bits apiece.
1301958Swnj 	 */
1311958Swnj 	for (i=0; i<28; i++) {
1321958Swnj 		C[i] = key[PC1_C[i]-1];
1331958Swnj 		D[i] = key[PC1_D[i]-1];
1341958Swnj 	}
1351958Swnj 	/*
1361958Swnj 	 * To generate Ki, rotate C and D according
1371958Swnj 	 * to schedule and pick up a permutation
1381958Swnj 	 * using PC2.
1391958Swnj 	 */
1401958Swnj 	for (i=0; i<16; i++) {
1411958Swnj 		/*
1421958Swnj 		 * rotate.
1431958Swnj 		 */
1441958Swnj 		for (k=0; k<shifts[i]; k++) {
1451958Swnj 			t = C[0];
1461958Swnj 			for (j=0; j<28-1; j++)
1471958Swnj 				C[j] = C[j+1];
1481958Swnj 			C[27] = t;
1491958Swnj 			t = D[0];
1501958Swnj 			for (j=0; j<28-1; j++)
1511958Swnj 				D[j] = D[j+1];
1521958Swnj 			D[27] = t;
1531958Swnj 		}
1541958Swnj 		/*
1551958Swnj 		 * get Ki. Note C and D are concatenated.
1561958Swnj 		 */
1571958Swnj 		for (j=0; j<24; j++) {
1581958Swnj 			KS[i][j] = C[PC2_C[j]-1];
1591958Swnj 			KS[i][j+24] = D[PC2_D[j]-28-1];
1601958Swnj 		}
1611958Swnj 	}
16217337Sralph 
16317337Sralph 	for(i=0;i<48;i++)
16417337Sralph 		E[i] = e[i];
1651958Swnj }
1661958Swnj 
1671958Swnj /*
1681958Swnj  * The 8 selection functions.
1691958Swnj  * For some reason, they give a 0-origin
1701958Swnj  * index, unlike everything else.
1711958Swnj  */
1721958Swnj static	char	S[8][64] = {
1731958Swnj 	14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
1741958Swnj 	 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
1751958Swnj 	 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
1761958Swnj 	15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
1771958Swnj 
1781958Swnj 	15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
1791958Swnj 	 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
1801958Swnj 	 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
1811958Swnj 	13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
1821958Swnj 
1831958Swnj 	10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
1841958Swnj 	13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
1851958Swnj 	13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
1861958Swnj 	 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
1871958Swnj 
1881958Swnj 	 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
1891958Swnj 	13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
1901958Swnj 	10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
1911958Swnj 	 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
1921958Swnj 
1931958Swnj 	 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
1941958Swnj 	14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
1951958Swnj 	 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
1961958Swnj 	11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
1971958Swnj 
1981958Swnj 	12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
1991958Swnj 	10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
2001958Swnj 	 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
2011958Swnj 	 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
2021958Swnj 
2031958Swnj 	 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
2041958Swnj 	13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
2051958Swnj 	 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
2061958Swnj 	 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
2071958Swnj 
2081958Swnj 	13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
2091958Swnj 	 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
2101958Swnj 	 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
2111958Swnj 	 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
2121958Swnj };
2131958Swnj 
2141958Swnj /*
2151958Swnj  * P is a permutation on the selected combination
2161958Swnj  * of the current L and key.
2171958Swnj  */
2181958Swnj static	char	P[] = {
2191958Swnj 	16, 7,20,21,
2201958Swnj 	29,12,28,17,
2211958Swnj 	 1,15,23,26,
2221958Swnj 	 5,18,31,10,
2231958Swnj 	 2, 8,24,14,
2241958Swnj 	32,27, 3, 9,
2251958Swnj 	19,13,30, 6,
2261958Swnj 	22,11, 4,25,
2271958Swnj };
2281958Swnj 
2291958Swnj /*
2301958Swnj  * The current block, divided into 2 halves.
2311958Swnj  */
23241752Sbostic static	char	L[64], *R = L+32;
2331958Swnj static	char	tempL[32];
2341958Swnj static	char	f[32];
2351958Swnj 
2361958Swnj /*
2371958Swnj  * The combination of the key and the input, before selection.
2381958Swnj  */
2391958Swnj static	char	preS[48];
2401958Swnj 
2411958Swnj /*
2421958Swnj  * The payoff: encrypt a block.
2431958Swnj  */
2441958Swnj 
245*46597Sdonn void
2461958Swnj encrypt(block, edflag)
2471958Swnj char *block;
248*46597Sdonn int edflag;
2491958Swnj {
2501958Swnj 	int i, ii;
2511958Swnj 	register t, j, k;
2521958Swnj 
2531958Swnj 	/*
2541958Swnj 	 * First, permute the bits in the input
2551958Swnj 	 */
2561958Swnj 	for (j=0; j<64; j++)
2571958Swnj 		L[j] = block[IP[j]-1];
2581958Swnj 	/*
2591958Swnj 	 * Perform an encryption operation 16 times.
2601958Swnj 	 */
2611958Swnj 	for (ii=0; ii<16; ii++) {
2621958Swnj 		/*
263*46597Sdonn 		 * Set direction
2641958Swnj 		 */
265*46597Sdonn 		if (edflag)
266*46597Sdonn 			i = 15-ii;
267*46597Sdonn 		else
268*46597Sdonn 			i = ii;
2691958Swnj 		/*
2701958Swnj 		 * Save the R array,
2711958Swnj 		 * which will be the new L.
2721958Swnj 		 */
2731958Swnj 		for (j=0; j<32; j++)
2741958Swnj 			tempL[j] = R[j];
2751958Swnj 		/*
2761958Swnj 		 * Expand R to 48 bits using the E selector;
2771958Swnj 		 * exclusive-or with the current key bits.
2781958Swnj 		 */
2791958Swnj 		for (j=0; j<48; j++)
2801958Swnj 			preS[j] = R[E[j]-1] ^ KS[i][j];
2811958Swnj 		/*
2821958Swnj 		 * The pre-select bits are now considered
2831958Swnj 		 * in 8 groups of 6 bits each.
2841958Swnj 		 * The 8 selection functions map these
2851958Swnj 		 * 6-bit quantities into 4-bit quantities
2861958Swnj 		 * and the results permuted
2871958Swnj 		 * to make an f(R, K).
2881958Swnj 		 * The indexing into the selection functions
2891958Swnj 		 * is peculiar; it could be simplified by
2901958Swnj 		 * rewriting the tables.
2911958Swnj 		 */
2921958Swnj 		for (j=0; j<8; j++) {
2931958Swnj 			t = 6*j;
2941958Swnj 			k = S[j][(preS[t+0]<<5)+
2951958Swnj 				(preS[t+1]<<3)+
2961958Swnj 				(preS[t+2]<<2)+
2971958Swnj 				(preS[t+3]<<1)+
2981958Swnj 				(preS[t+4]<<0)+
2991958Swnj 				(preS[t+5]<<4)];
3001958Swnj 			t = 4*j;
3011958Swnj 			f[t+0] = (k>>3)&01;
3021958Swnj 			f[t+1] = (k>>2)&01;
3031958Swnj 			f[t+2] = (k>>1)&01;
3041958Swnj 			f[t+3] = (k>>0)&01;
3051958Swnj 		}
3061958Swnj 		/*
3071958Swnj 		 * The new R is L ^ f(R, K).
3081958Swnj 		 * The f here has to be permuted first, though.
3091958Swnj 		 */
3101958Swnj 		for (j=0; j<32; j++)
3111958Swnj 			R[j] = L[j] ^ f[P[j]-1];
3121958Swnj 		/*
3131958Swnj 		 * Finally, the new L (the original R)
3141958Swnj 		 * is copied back.
3151958Swnj 		 */
3161958Swnj 		for (j=0; j<32; j++)
3171958Swnj 			L[j] = tempL[j];
3181958Swnj 	}
3191958Swnj 	/*
3201958Swnj 	 * The output L and R are reversed.
3211958Swnj 	 */
3221958Swnj 	for (j=0; j<32; j++) {
3231958Swnj 		t = L[j];
3241958Swnj 		L[j] = R[j];
3251958Swnj 		R[j] = t;
3261958Swnj 	}
3271958Swnj 	/*
3281958Swnj 	 * The final output
3291958Swnj 	 * gets the inverse permutation of the very original.
3301958Swnj 	 */
3311958Swnj 	for (j=0; j<64; j++)
3321958Swnj 		block[j] = L[FP[j]-1];
3331958Swnj }
3341958Swnj 
3351958Swnj char *
3361958Swnj crypt(pw,salt)
337*46597Sdonn const char *pw;
338*46597Sdonn const char *salt;
3391958Swnj {
3401958Swnj 	register i, j, c;
3411958Swnj 	int temp;
3421958Swnj 	static char block[66], iobuf[16];
34317337Sralph 
3441958Swnj 	for(i=0; i<66; i++)
3451958Swnj 		block[i] = 0;
3461958Swnj 	for(i=0; (c= *pw) && i<64; pw++){
3471958Swnj 		for(j=0; j<7; j++, i++)
3481958Swnj 			block[i] = (c>>(6-j)) & 01;
3491958Swnj 		i++;
3501958Swnj 	}
3511958Swnj 
3521958Swnj 	setkey(block);
3531958Swnj 
3541958Swnj 	for(i=0; i<66; i++)
3551958Swnj 		block[i] = 0;
3561958Swnj 
3571958Swnj 	for(i=0;i<2;i++){
3581958Swnj 		c = *salt++;
3591958Swnj 		iobuf[i] = c;
3601958Swnj 		if(c>'Z') c -= 6;
3611958Swnj 		if(c>'9') c -= 7;
3621958Swnj 		c -= '.';
3631958Swnj 		for(j=0;j<6;j++){
3641958Swnj 			if((c>>j) & 01){
3651958Swnj 				temp = E[6*i+j];
3661958Swnj 				E[6*i+j] = E[6*i+j+24];
3671958Swnj 				E[6*i+j+24] = temp;
3681958Swnj 				}
3691958Swnj 			}
3701958Swnj 		}
3711958Swnj 
3721958Swnj 	for(i=0; i<25; i++)
3731958Swnj 		encrypt(block,0);
3741958Swnj 
3751958Swnj 	for(i=0; i<11; i++){
3761958Swnj 		c = 0;
3771958Swnj 		for(j=0; j<6; j++){
3781958Swnj 			c <<= 1;
3791958Swnj 			c |= block[6*i+j];
3801958Swnj 			}
3811958Swnj 		c += '.';
3821958Swnj 		if(c>'9') c += 7;
3831958Swnj 		if(c>'Z') c += 6;
3841958Swnj 		iobuf[i+2] = c;
3851958Swnj 	}
3861958Swnj 	iobuf[i+2] = 0;
3871958Swnj 	if(iobuf[1]==0)
3881958Swnj 		iobuf[1] = iobuf[0];
3891958Swnj 	return(iobuf);
3901958Swnj }
391