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