xref: /csrg-svn/lib/libc/gen/crypt.c (revision 1958)
1*1958Swnj /* @(#)crypt.c	4.1 (Berkeley) 12/21/80 */
2*1958Swnj /*
3*1958Swnj  * This program implements the
4*1958Swnj  * Proposed Federal Information Processing
5*1958Swnj  *  Data Encryption Standard.
6*1958Swnj  * See Federal Register, March 17, 1975 (40FR12134)
7*1958Swnj  */
8*1958Swnj 
9*1958Swnj /*
10*1958Swnj  * Initial permutation,
11*1958Swnj  */
12*1958Swnj static	char	IP[] = {
13*1958Swnj 	58,50,42,34,26,18,10, 2,
14*1958Swnj 	60,52,44,36,28,20,12, 4,
15*1958Swnj 	62,54,46,38,30,22,14, 6,
16*1958Swnj 	64,56,48,40,32,24,16, 8,
17*1958Swnj 	57,49,41,33,25,17, 9, 1,
18*1958Swnj 	59,51,43,35,27,19,11, 3,
19*1958Swnj 	61,53,45,37,29,21,13, 5,
20*1958Swnj 	63,55,47,39,31,23,15, 7,
21*1958Swnj };
22*1958Swnj 
23*1958Swnj /*
24*1958Swnj  * Final permutation, FP = IP^(-1)
25*1958Swnj  */
26*1958Swnj static	char	FP[] = {
27*1958Swnj 	40, 8,48,16,56,24,64,32,
28*1958Swnj 	39, 7,47,15,55,23,63,31,
29*1958Swnj 	38, 6,46,14,54,22,62,30,
30*1958Swnj 	37, 5,45,13,53,21,61,29,
31*1958Swnj 	36, 4,44,12,52,20,60,28,
32*1958Swnj 	35, 3,43,11,51,19,59,27,
33*1958Swnj 	34, 2,42,10,50,18,58,26,
34*1958Swnj 	33, 1,41, 9,49,17,57,25,
35*1958Swnj };
36*1958Swnj 
37*1958Swnj /*
38*1958Swnj  * Permuted-choice 1 from the key bits
39*1958Swnj  * to yield C and D.
40*1958Swnj  * Note that bits 8,16... are left out:
41*1958Swnj  * They are intended for a parity check.
42*1958Swnj  */
43*1958Swnj static	char	PC1_C[] = {
44*1958Swnj 	57,49,41,33,25,17, 9,
45*1958Swnj 	 1,58,50,42,34,26,18,
46*1958Swnj 	10, 2,59,51,43,35,27,
47*1958Swnj 	19,11, 3,60,52,44,36,
48*1958Swnj };
49*1958Swnj 
50*1958Swnj static	char	PC1_D[] = {
51*1958Swnj 	63,55,47,39,31,23,15,
52*1958Swnj 	 7,62,54,46,38,30,22,
53*1958Swnj 	14, 6,61,53,45,37,29,
54*1958Swnj 	21,13, 5,28,20,12, 4,
55*1958Swnj };
56*1958Swnj 
57*1958Swnj /*
58*1958Swnj  * Sequence of shifts used for the key schedule.
59*1958Swnj */
60*1958Swnj static	char	shifts[] = {
61*1958Swnj 	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
62*1958Swnj };
63*1958Swnj 
64*1958Swnj /*
65*1958Swnj  * Permuted-choice 2, to pick out the bits from
66*1958Swnj  * the CD array that generate the key schedule.
67*1958Swnj  */
68*1958Swnj static	char	PC2_C[] = {
69*1958Swnj 	14,17,11,24, 1, 5,
70*1958Swnj 	 3,28,15, 6,21,10,
71*1958Swnj 	23,19,12, 4,26, 8,
72*1958Swnj 	16, 7,27,20,13, 2,
73*1958Swnj };
74*1958Swnj 
75*1958Swnj static	char	PC2_D[] = {
76*1958Swnj 	41,52,31,37,47,55,
77*1958Swnj 	30,40,51,45,33,48,
78*1958Swnj 	44,49,39,56,34,53,
79*1958Swnj 	46,42,50,36,29,32,
80*1958Swnj };
81*1958Swnj 
82*1958Swnj /*
83*1958Swnj  * The C and D arrays used to calculate the key schedule.
84*1958Swnj  */
85*1958Swnj 
86*1958Swnj static	char	C[28];
87*1958Swnj static	char	D[28];
88*1958Swnj /*
89*1958Swnj  * The key schedule.
90*1958Swnj  * Generated from the key.
91*1958Swnj  */
92*1958Swnj static	char	KS[16][48];
93*1958Swnj 
94*1958Swnj /*
95*1958Swnj  * Set up the key schedule from the key.
96*1958Swnj  */
97*1958Swnj 
98*1958Swnj setkey(key)
99*1958Swnj char *key;
100*1958Swnj {
101*1958Swnj 	register i, j, k;
102*1958Swnj 	int t;
103*1958Swnj 
104*1958Swnj 	/*
105*1958Swnj 	 * First, generate C and D by permuting
106*1958Swnj 	 * the key.  The low order bit of each
107*1958Swnj 	 * 8-bit char is not used, so C and D are only 28
108*1958Swnj 	 * bits apiece.
109*1958Swnj 	 */
110*1958Swnj 	for (i=0; i<28; i++) {
111*1958Swnj 		C[i] = key[PC1_C[i]-1];
112*1958Swnj 		D[i] = key[PC1_D[i]-1];
113*1958Swnj 	}
114*1958Swnj 	/*
115*1958Swnj 	 * To generate Ki, rotate C and D according
116*1958Swnj 	 * to schedule and pick up a permutation
117*1958Swnj 	 * using PC2.
118*1958Swnj 	 */
119*1958Swnj 	for (i=0; i<16; i++) {
120*1958Swnj 		/*
121*1958Swnj 		 * rotate.
122*1958Swnj 		 */
123*1958Swnj 		for (k=0; k<shifts[i]; k++) {
124*1958Swnj 			t = C[0];
125*1958Swnj 			for (j=0; j<28-1; j++)
126*1958Swnj 				C[j] = C[j+1];
127*1958Swnj 			C[27] = t;
128*1958Swnj 			t = D[0];
129*1958Swnj 			for (j=0; j<28-1; j++)
130*1958Swnj 				D[j] = D[j+1];
131*1958Swnj 			D[27] = t;
132*1958Swnj 		}
133*1958Swnj 		/*
134*1958Swnj 		 * get Ki. Note C and D are concatenated.
135*1958Swnj 		 */
136*1958Swnj 		for (j=0; j<24; j++) {
137*1958Swnj 			KS[i][j] = C[PC2_C[j]-1];
138*1958Swnj 			KS[i][j+24] = D[PC2_D[j]-28-1];
139*1958Swnj 		}
140*1958Swnj 	}
141*1958Swnj }
142*1958Swnj 
143*1958Swnj /*
144*1958Swnj  * The E bit-selection table.
145*1958Swnj  */
146*1958Swnj static	char	E[48];
147*1958Swnj static	char	e[] = {
148*1958Swnj 	32, 1, 2, 3, 4, 5,
149*1958Swnj 	 4, 5, 6, 7, 8, 9,
150*1958Swnj 	 8, 9,10,11,12,13,
151*1958Swnj 	12,13,14,15,16,17,
152*1958Swnj 	16,17,18,19,20,21,
153*1958Swnj 	20,21,22,23,24,25,
154*1958Swnj 	24,25,26,27,28,29,
155*1958Swnj 	28,29,30,31,32, 1,
156*1958Swnj };
157*1958Swnj 
158*1958Swnj /*
159*1958Swnj  * The 8 selection functions.
160*1958Swnj  * For some reason, they give a 0-origin
161*1958Swnj  * index, unlike everything else.
162*1958Swnj  */
163*1958Swnj static	char	S[8][64] = {
164*1958Swnj 	14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
165*1958Swnj 	 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
166*1958Swnj 	 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
167*1958Swnj 	15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
168*1958Swnj 
169*1958Swnj 	15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
170*1958Swnj 	 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
171*1958Swnj 	 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
172*1958Swnj 	13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
173*1958Swnj 
174*1958Swnj 	10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
175*1958Swnj 	13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
176*1958Swnj 	13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
177*1958Swnj 	 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
178*1958Swnj 
179*1958Swnj 	 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
180*1958Swnj 	13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
181*1958Swnj 	10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
182*1958Swnj 	 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
183*1958Swnj 
184*1958Swnj 	 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
185*1958Swnj 	14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
186*1958Swnj 	 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
187*1958Swnj 	11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
188*1958Swnj 
189*1958Swnj 	12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
190*1958Swnj 	10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
191*1958Swnj 	 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
192*1958Swnj 	 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
193*1958Swnj 
194*1958Swnj 	 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
195*1958Swnj 	13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
196*1958Swnj 	 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
197*1958Swnj 	 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
198*1958Swnj 
199*1958Swnj 	13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
200*1958Swnj 	 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
201*1958Swnj 	 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
202*1958Swnj 	 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
203*1958Swnj };
204*1958Swnj 
205*1958Swnj /*
206*1958Swnj  * P is a permutation on the selected combination
207*1958Swnj  * of the current L and key.
208*1958Swnj  */
209*1958Swnj static	char	P[] = {
210*1958Swnj 	16, 7,20,21,
211*1958Swnj 	29,12,28,17,
212*1958Swnj 	 1,15,23,26,
213*1958Swnj 	 5,18,31,10,
214*1958Swnj 	 2, 8,24,14,
215*1958Swnj 	32,27, 3, 9,
216*1958Swnj 	19,13,30, 6,
217*1958Swnj 	22,11, 4,25,
218*1958Swnj };
219*1958Swnj 
220*1958Swnj /*
221*1958Swnj  * The current block, divided into 2 halves.
222*1958Swnj  */
223*1958Swnj static	char	L[32], R[32];
224*1958Swnj static	char	tempL[32];
225*1958Swnj static	char	f[32];
226*1958Swnj 
227*1958Swnj /*
228*1958Swnj  * The combination of the key and the input, before selection.
229*1958Swnj  */
230*1958Swnj static	char	preS[48];
231*1958Swnj 
232*1958Swnj /*
233*1958Swnj  * The payoff: encrypt a block.
234*1958Swnj  */
235*1958Swnj 
236*1958Swnj encrypt(block, edflag)
237*1958Swnj char *block;
238*1958Swnj {
239*1958Swnj 	int i, ii;
240*1958Swnj 	register t, j, k;
241*1958Swnj 
242*1958Swnj 	/*
243*1958Swnj 	 * First, permute the bits in the input
244*1958Swnj 	 */
245*1958Swnj 	for (j=0; j<64; j++)
246*1958Swnj 		L[j] = block[IP[j]-1];
247*1958Swnj 	/*
248*1958Swnj 	 * Perform an encryption operation 16 times.
249*1958Swnj 	 */
250*1958Swnj 	for (ii=0; ii<16; ii++) {
251*1958Swnj 		/*
252*1958Swnj 		 * Set direction
253*1958Swnj 		 */
254*1958Swnj 		if (edflag)
255*1958Swnj 			i = 15-ii;
256*1958Swnj 		else
257*1958Swnj 			i = ii;
258*1958Swnj 		/*
259*1958Swnj 		 * Save the R array,
260*1958Swnj 		 * which will be the new L.
261*1958Swnj 		 */
262*1958Swnj 		for (j=0; j<32; j++)
263*1958Swnj 			tempL[j] = R[j];
264*1958Swnj 		/*
265*1958Swnj 		 * Expand R to 48 bits using the E selector;
266*1958Swnj 		 * exclusive-or with the current key bits.
267*1958Swnj 		 */
268*1958Swnj 		for (j=0; j<48; j++)
269*1958Swnj 			preS[j] = R[E[j]-1] ^ KS[i][j];
270*1958Swnj 		/*
271*1958Swnj 		 * The pre-select bits are now considered
272*1958Swnj 		 * in 8 groups of 6 bits each.
273*1958Swnj 		 * The 8 selection functions map these
274*1958Swnj 		 * 6-bit quantities into 4-bit quantities
275*1958Swnj 		 * and the results permuted
276*1958Swnj 		 * to make an f(R, K).
277*1958Swnj 		 * The indexing into the selection functions
278*1958Swnj 		 * is peculiar; it could be simplified by
279*1958Swnj 		 * rewriting the tables.
280*1958Swnj 		 */
281*1958Swnj 		for (j=0; j<8; j++) {
282*1958Swnj 			t = 6*j;
283*1958Swnj 			k = S[j][(preS[t+0]<<5)+
284*1958Swnj 				(preS[t+1]<<3)+
285*1958Swnj 				(preS[t+2]<<2)+
286*1958Swnj 				(preS[t+3]<<1)+
287*1958Swnj 				(preS[t+4]<<0)+
288*1958Swnj 				(preS[t+5]<<4)];
289*1958Swnj 			t = 4*j;
290*1958Swnj 			f[t+0] = (k>>3)&01;
291*1958Swnj 			f[t+1] = (k>>2)&01;
292*1958Swnj 			f[t+2] = (k>>1)&01;
293*1958Swnj 			f[t+3] = (k>>0)&01;
294*1958Swnj 		}
295*1958Swnj 		/*
296*1958Swnj 		 * The new R is L ^ f(R, K).
297*1958Swnj 		 * The f here has to be permuted first, though.
298*1958Swnj 		 */
299*1958Swnj 		for (j=0; j<32; j++)
300*1958Swnj 			R[j] = L[j] ^ f[P[j]-1];
301*1958Swnj 		/*
302*1958Swnj 		 * Finally, the new L (the original R)
303*1958Swnj 		 * is copied back.
304*1958Swnj 		 */
305*1958Swnj 		for (j=0; j<32; j++)
306*1958Swnj 			L[j] = tempL[j];
307*1958Swnj 	}
308*1958Swnj 	/*
309*1958Swnj 	 * The output L and R are reversed.
310*1958Swnj 	 */
311*1958Swnj 	for (j=0; j<32; j++) {
312*1958Swnj 		t = L[j];
313*1958Swnj 		L[j] = R[j];
314*1958Swnj 		R[j] = t;
315*1958Swnj 	}
316*1958Swnj 	/*
317*1958Swnj 	 * The final output
318*1958Swnj 	 * gets the inverse permutation of the very original.
319*1958Swnj 	 */
320*1958Swnj 	for (j=0; j<64; j++)
321*1958Swnj 		block[j] = L[FP[j]-1];
322*1958Swnj }
323*1958Swnj 
324*1958Swnj char *
325*1958Swnj crypt(pw,salt)
326*1958Swnj char *pw;
327*1958Swnj char *salt;
328*1958Swnj {
329*1958Swnj 	register i, j, c;
330*1958Swnj 	int temp;
331*1958Swnj 	static char block[66], iobuf[16];
332*1958Swnj 	for(i=0; i<66; i++)
333*1958Swnj 		block[i] = 0;
334*1958Swnj 	for(i=0; (c= *pw) && i<64; pw++){
335*1958Swnj 		for(j=0; j<7; j++, i++)
336*1958Swnj 			block[i] = (c>>(6-j)) & 01;
337*1958Swnj 		i++;
338*1958Swnj 	}
339*1958Swnj 
340*1958Swnj 	setkey(block);
341*1958Swnj 
342*1958Swnj 	for(i=0; i<66; i++)
343*1958Swnj 		block[i] = 0;
344*1958Swnj 
345*1958Swnj 	for(i=0;i<48;i++)
346*1958Swnj 		E[i] = e[i];
347*1958Swnj 
348*1958Swnj 	for(i=0;i<2;i++){
349*1958Swnj 		c = *salt++;
350*1958Swnj 		iobuf[i] = c;
351*1958Swnj 		if(c>'Z') c -= 6;
352*1958Swnj 		if(c>'9') c -= 7;
353*1958Swnj 		c -= '.';
354*1958Swnj 		for(j=0;j<6;j++){
355*1958Swnj 			if((c>>j) & 01){
356*1958Swnj 				temp = E[6*i+j];
357*1958Swnj 				E[6*i+j] = E[6*i+j+24];
358*1958Swnj 				E[6*i+j+24] = temp;
359*1958Swnj 				}
360*1958Swnj 			}
361*1958Swnj 		}
362*1958Swnj 
363*1958Swnj 	for(i=0; i<25; i++)
364*1958Swnj 		encrypt(block,0);
365*1958Swnj 
366*1958Swnj 	for(i=0; i<11; i++){
367*1958Swnj 		c = 0;
368*1958Swnj 		for(j=0; j<6; j++){
369*1958Swnj 			c <<= 1;
370*1958Swnj 			c |= block[6*i+j];
371*1958Swnj 			}
372*1958Swnj 		c += '.';
373*1958Swnj 		if(c>'9') c += 7;
374*1958Swnj 		if(c>'Z') c += 6;
375*1958Swnj 		iobuf[i+2] = c;
376*1958Swnj 	}
377*1958Swnj 	iobuf[i+2] = 0;
378*1958Swnj 	if(iobuf[1]==0)
379*1958Swnj 		iobuf[1] = iobuf[0];
380*1958Swnj 	return(iobuf);
381*1958Swnj }
382