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