xref: /illumos-gate/usr/src/lib/libcrypt/common/des_crypt.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1988 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #pragma weak _des_crypt = des_crypt
33 #pragma weak _des_encrypt = des_encrypt
34 #pragma weak _des_setkey = des_setkey
35 
36 #include <sys/types.h>
37 #include <crypt.h>
38 #include "des_soft.h"
39 
40 #include <stdlib.h>
41 #include <thread.h>
42 #include <pthread.h>
43 #include <sys/types.h>
44 
45 /* EXPORT DELETE START */
46 /*
47  * This program implements the
48  * Proposed Federal Information Processing
49  *  Data Encryption Standard.
50  * See Federal Register, March 17, 1975 (40FR12134)
51  */
52 
53 /*
54  * Initial permutation,
55  */
56 static char IP[] = {
57 	58, 50, 42, 34, 26, 18, 10, 2,
58 	60, 52, 44, 36, 28, 20, 12, 4,
59 	62, 54, 46, 38, 30, 22, 14, 6,
60 	64, 56, 48, 40, 32, 24, 16, 8,
61 	57, 49, 41, 33, 25, 17, 9, 1,
62 	59, 51, 43, 35, 27, 19, 11, 3,
63 	61, 53, 45, 37, 29, 21, 13, 5,
64 	63, 55, 47, 39, 31, 23, 15, 7,
65 };
66 
67 /*
68  * Final permutation, FP = IP^(-1)
69  */
70 static char FP[] = {
71 	40, 8, 48, 16, 56, 24, 64, 32,
72 	39, 7, 47, 15, 55, 23, 63, 31,
73 	38, 6, 46, 14, 54, 22, 62, 30,
74 	37, 5, 45, 13, 53, 21, 61, 29,
75 	36, 4, 44, 12, 52, 20, 60, 28,
76 	35, 3, 43, 11, 51, 19, 59, 27,
77 	34, 2, 42, 10, 50, 18, 58, 26,
78 	33, 1, 41, 9, 49, 17, 57, 25,
79 };
80 
81 /*
82  * Permuted-choice 1 from the key bits
83  * to yield C and D.
84  * Note that bits 8, 16... are left out:
85  * They are intended for a parity check.
86  */
87 static char PC1_C[] = {
88 	57, 49, 41, 33, 25, 17, 9,
89 	1, 58, 50, 42, 34, 26, 18,
90 	10, 2, 59, 51, 43, 35, 27,
91 	19, 11, 3, 60, 52, 44, 36,
92 };
93 
94 static char PC1_D[] = {
95 	63, 55, 47, 39, 31, 23, 15,
96 	7, 62, 54, 46, 38, 30, 22,
97 	14, 6, 61, 53, 45, 37, 29,
98 	21, 13, 5, 28, 20, 12, 4,
99 };
100 
101 /*
102  * Sequence of shifts used for the key schedule.
103  */
104 static char shifts[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, };
105 
106 /*
107  * Permuted-choice 2, to pick out the bits from
108  * the CD array that generate the key schedule.
109  */
110 static char PC2_C[] = {
111 	14, 17, 11, 24, 1, 5,
112 	3, 28, 15, 6, 21, 10,
113 	23, 19, 12, 4, 26, 8,
114 	16, 7, 27, 20, 13, 2,
115 };
116 
117 static char PC2_D[] = {
118 	41, 52, 31, 37, 47, 55,
119 	30, 40, 51, 45, 33, 48,
120 	44, 49, 39, 56, 34, 53,
121 	46, 42, 50, 36, 29, 32,
122 };
123 
124 /*
125  * The C and D arrays used to calculate the key schedule.
126  */
127 
128 static char C[28];
129 static char D[28];
130 /*
131  * The key schedule.
132  * Generated from the key.
133  */
134 static char KS[16][48];
135 
136 /*
137  * The E bit-selection table.
138  */
139 static char E[48];
140 static char e2[] = {
141 	32, 1, 2, 3, 4, 5,
142 	4, 5, 6, 7, 8, 9,
143 	8, 9, 10, 11, 12, 13,
144 	12, 13, 14, 15, 16, 17,
145 	16, 17, 18, 19, 20, 21,
146 	20, 21, 22, 23, 24, 25,
147 	24, 25, 26, 27, 28, 29,
148 	28, 29, 30, 31, 32, 1,
149 };
150 
151 /*
152  * Set up the key schedule from the key.
153  */
154 
155 static mutex_t lock = DEFAULTMUTEX;
156 
157 /* EXPORT DELETE END */
158 
159 
160 static void
161 des_setkey_nolock(const char *key)
162 {
163 /* EXPORT DELETE START */
164 	int i, j, k;
165 	char t;
166 
167 	/*
168 	 * First, generate C and D by permuting
169 	 * the key.  The low order bit of each
170 	 * 8-bit char is not used, so C and D are only 28
171 	 * bits apiece.
172 	 */
173 	for (i = 0; i < 28; i++) {
174 		C[i] = key[PC1_C[i]-1];
175 		D[i] = key[PC1_D[i]-1];
176 	}
177 	/*
178 	 * To generate Ki, rotate C and D according
179 	 * to schedule and pick up a permutation
180 	 * using PC2.
181 	 */
182 	for (i = 0; i < 16; i++) {
183 		/*
184 		 * rotate.
185 		 */
186 		for (k = 0; k < shifts[i]; k++) {
187 			t = C[0];
188 			for (j = 0; j < 28-1; j++)
189 				C[j] = C[j+1];
190 			C[27] = (char)t;
191 			t = D[0];
192 			for (j = 0; j < 28-1; j++)
193 				D[j] = D[j+1];
194 			D[27] = (char)t;
195 		}
196 		/*
197 		 * get Ki. Note C and D are concatenated.
198 		 */
199 		for (j = 0; j < 24; j++) {
200 			KS[i][j] = C[PC2_C[j]-1];
201 			KS[i][j+24] = D[PC2_D[j]-28-1];
202 		}
203 	}
204 
205 	for (i = 0; i < 48; i++)
206 		E[i] = e2[i];
207 /* EXPORT DELETE END */
208 }
209 
210 void
211 des_setkey(const char *key)
212 {
213 /* EXPORT DELETE START */
214 	(void) mutex_lock(&lock);
215 	des_setkey_nolock(key);
216 	(void) mutex_unlock(&lock);
217 /* EXPORT DELETE END */
218 }
219 
220 /* EXPORT DELETE START */
221 /*
222  * The 8 selection functions.
223  * For some reason, they give a 0-origin
224  * index, unlike everything else.
225  */
226 static char S[8][64] = {
227 	14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
228 	0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
229 	4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
230 	15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
231 
232 	15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
233 	3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
234 	0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
235 	13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
236 
237 	10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
238 	13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
239 	13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
240 	1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
241 
242 	7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
243 	13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
244 	10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
245 	3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
246 
247 	2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
248 	14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
249 	4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
250 	11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
251 
252 	12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
253 	10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
254 	9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
255 	4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
256 
257 	4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
258 	13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
259 	1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
260 	6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
261 
262 	13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
263 	1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
264 	7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
265 	2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
266 };
267 
268 /*
269  * P is a permutation on the selected combination
270  * of the current L and key.
271  */
272 static char P[] = {
273 	16, 7, 20, 21,
274 	29, 12, 28, 17,
275 	1, 15, 23, 26,
276 	5, 18, 31, 10,
277 	2, 8, 24, 14,
278 	32, 27, 3, 9,
279 	19, 13, 30, 6,
280 	22, 11, 4, 25,
281 };
282 
283 /*
284  * The current block, divided into 2 halves.
285  */
286 static char L[64];
287 static char tempL[32];
288 static char f[32];
289 
290 /*
291  * The combination of the key and the input, before selection.
292  */
293 static char preS[48];
294 
295 /*
296  * The payoff: encrypt a block.
297  */
298 /* EXPORT DELETE END */
299 
300 static void
301 des_encrypt_nolock(char *block, int edflag)
302 {
303 /* EXPORT DELETE START */
304 
305 	if (edflag)
306 		(void) _des_decrypt1(block, L, IP, &L[32],
307 		    preS, E, KS, S, f, tempL, P, FP);
308 	else
309 		(void) des_encrypt1(block, L, IP, &L[32],
310 		    preS, E, KS, S, f, tempL, P, FP);
311 
312 /* EXPORT DELETE END */
313 }
314 
315 void
316 des_encrypt(char *block, int edflag)
317 {
318 /* EXPORT DELETE START */
319 	(void) mutex_lock(&lock);
320 	des_encrypt_nolock(block, edflag);
321 	(void) mutex_unlock(&lock);
322 /* EXPORT DELETE END */
323 }
324 
325 
326 
327 #define	IOBUF_SIZE	16
328 
329 static char *
330 _get_iobuf(thread_key_t *keyp, unsigned size)
331 {
332 	char *iobuf;
333 
334 	if (thr_keycreate_once(keyp, free) != 0)
335 		return (NULL);
336 	iobuf = pthread_getspecific(*keyp);
337 	if (iobuf == NULL) {
338 		if (thr_setspecific(*keyp, (iobuf = malloc(size))) != 0) {
339 			if (iobuf)
340 				(void) free(iobuf);
341 			iobuf = NULL;
342 		}
343 	}
344 	return (iobuf);
345 }
346 
347 char *
348 des_crypt(const char *pw, const char *salt)
349 {
350 /* EXPORT DELETE START */
351 	int	i, j;
352 	char	c, temp;
353 	char block[66];
354 	static thread_key_t key = THR_ONCE_KEY;
355 	char *iobuf = _get_iobuf(&key, IOBUF_SIZE);
356 
357 	(void) mutex_lock(&lock);
358 	for (i = 0; i < 66; i++)
359 		block[i] = 0;
360 	for (i = 0; (c = *pw) && (i < 64); pw++) {
361 		for (j = 0; j < 7; j++, i++)
362 			block[i] = (c>>(6-j)) & 01;
363 		i++;
364 	}
365 
366 	des_setkey_nolock(block);
367 
368 	for (i = 0; i < 66; i++)
369 		block[i] = 0;
370 
371 	for (i = 0; i < 2; i++) {
372 		c = *salt++;
373 		iobuf[i] = (char)c;
374 		if (c > 'Z')
375 			c -= 6;
376 		if (c > '9')
377 			c -= 7;
378 		c -= '.';
379 		for (j = 0; j < 6; j++) {
380 			if ((c>>j) & 01) {
381 				temp = E[6*i+j];
382 				E[6*i+j] = E[6*i+j+24];
383 				E[6*i+j+24] = (char)temp;
384 			}
385 		}
386 	}
387 
388 	for (i = 0; i < 25; i++)
389 		(void) des_encrypt_nolock(block, 0);
390 
391 	for (i = 0; i < 11; i++) {
392 		c = 0;
393 		for (j = 0; j < 6; j++) {
394 			c <<= 1;
395 			c |= block[6*i+j];
396 		}
397 		c += '.';
398 		if (c > '9')
399 			c += 7;
400 		if (c > 'Z')
401 			c += 6;
402 		iobuf[i+2] = (char)c;
403 	}
404 	iobuf[i+2] = 0;
405 	if (iobuf[1] == 0)
406 		iobuf[1] = iobuf[0];
407 	(void) mutex_unlock(&lock);
408 	return (iobuf);
409 #if 0
410 /* EXPORT DELETE END */
411 	return (0);
412 /* EXPORT DELETE START */
413 #endif
414 /* EXPORT DELETE END */
415 }
416