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