des_crypt.c revision 1219:f89f56c2d9ac
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 */
59static 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 */
73static 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 */
90static 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
97static 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 */
107static 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 */
113static 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
120static 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
131static char C[28];
132static char D[28];
133/*
134 * The key schedule.
135 * Generated from the key.
136 */
137static char KS[16][48];
138
139/*
140 * The E bit-selection table.
141 */
142static char E[48];
143static 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
158static mutex_t lock = DEFAULTMUTEX;
159
160/* EXPORT DELETE END */
161
162
163static void
164des_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
213void
214des_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 */
229static 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 */
275static 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 */
289static char L[64];
290static char tempL[32];
291static char f[32];
292
293/*
294 * The combination of the key and the input, before selection.
295 */
296static char preS[48];
297
298/*
299 * The payoff: encrypt a block.
300 */
301/* EXPORT DELETE END */
302
303static void
304des_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
318void
319des_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
332static 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
354char *
355des_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