xref: /illumos-gate/usr/src/lib/gss_mechs/mech_krb5/crypto/des/afsstring2key.c (revision cc6c5292fa8a241fe50604cf6a918edfbf7cd7d2)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*
9  * lib/crypto/des/string2key.c
10  *
11  * based on lib/crypto/des/string2key.c from MIT V5
12  * and on lib/des/afs_string_to_key.c from UMD.
13  * constructed by Mark Eichin, Cygnus Support, 1995.
14  */
15 
16 #include <k5-int.h>
17 #include <des_int.h>
18 #include <ctype.h>
19 
20 static char *afs_crypt PROTOTYPE((char*,char*));
21 
22 /*ARGSUSED*/
23 krb5_error_code
24 mit_afs_string_to_key (context, keyblock, data, salt)
25      krb5_context context;
26      krb5_keyblock FAR * keyblock;
27      const krb5_data FAR * data;
28      const krb5_data FAR * salt;
29 {
30     krb5_error_code retval = KRB5_PROG_ETYPE_NOSUPP;
31 /* EXPORT DELETE START */
32   /* totally different approach from MIT string2key. */
33   /* much of the work has already been done by the only caller
34      which is mit_des_string_to_key; in particular, *keyblock is already
35      set up. */
36     char *realm = salt->data;
37     int i;
38     krb5_octet *key = keyblock->contents;
39     krb5_keyblock usekey;
40 
41     if (data->length <= 8) {
42       char password[9];		/* trailing null for crypt() */
43       strncpy(password, realm, 8);
44       for (i=0; i<8; i++)
45 	if (isupper(password[i]))
46 	  password[i] = tolower(password[i]);
47       for (i=0; i<data->length; i++)
48 	password[i] ^= data->data[i];
49       for (i=0; i<8; i++)
50 	if (password[i] == '\0')
51 	  password[i] = 'X';
52       password[8] = '\0';
53       strncpy((char *)key, (char *) afs_crypt(password, "#~") + 2, 8);
54       for (i=0; i<8; i++)
55 	key[i] <<= 1;
56 
57       /* now fix up key parity again */
58       mit_des_fixup_key_parity(key);
59       /* clean & free the input string */
60       memset(password, 0, (size_t) sizeof(password));
61     } else {
62       mit_des_cblock ikey, tkey;
63 
64       int pw_len = strlen(realm)+data->length;
65       char *password = malloc(pw_len+1);
66       if (!password) return ENOMEM;
67 
68       /* some bound checks from the original code are elided here as
69 	 the malloc above makes sure we have enough storage. */
70       strcpy (password, data->data);
71       for (i=data->length; *realm; i++) {
72 	password[i] = *realm++;
73 	if (isupper(password[i]))
74 	  password[i] = tolower(password[i]);
75       }
76 
77       memcpy (ikey, "kerberos", sizeof(ikey));
78       memcpy (tkey, ikey, sizeof(tkey));
79       mit_des_fixup_key_parity (tkey);
80 
81       usekey.enctype = ENCTYPE_DES_CBC_CRC;
82       usekey.contents = tkey;
83       usekey.length = 8;
84 
85       retval = mit_des_cbc_cksum (context, (unsigned char *)password,
86 		tkey, i, &usekey, ikey);
87 
88       memcpy (ikey, tkey, sizeof(ikey));
89       mit_des_fixup_key_parity (tkey);
90 
91       if (usekey.hKey != CK_INVALID_HANDLE) {
92          (void) C_DestroyObject(krb_ctx_hSession(context), usekey.hKey);
93          usekey.hKey = CK_INVALID_HANDLE;
94       }
95       usekey.contents = tkey;
96       usekey.length = 8;
97 
98       retval = mit_des_cbc_cksum (context, (unsigned char *) password,
99 		key, i, &usekey, ikey);
100 
101       /* now fix up key parity again */
102       mit_des_fixup_key_parity(key);
103 
104       if (usekey.hKey != CK_INVALID_HANDLE) {
105          (void) C_DestroyObject(krb_ctx_hSession(context), usekey.hKey);
106          usekey.hKey = CK_INVALID_HANDLE;
107       }
108       /* clean & free the input string */
109       memset(password, 0, (size_t) pw_len);
110       krb5_xfree(password);
111     }
112 #if 0
113     /* must free here because it was copied for this special case */
114     krb5_xfree(salt->data);
115 #endif
116 
117     retval = 0;
118 /* EXPORT DELETE END */
119     return retval;
120 }
121 
122 
123 /* Portions of this code:
124    Copyright 1989 by the Massachusetts Institute of Technology
125    */
126 
127 /*
128  * Copyright (c) 1990 Regents of The University of Michigan.
129  * All Rights Reserved.
130  *
131  * Permission to use, copy, modify, and distribute this software
132  * and its documentation for any purpose and without fee is hereby
133  * granted, provided that the above copyright notice appears in all
134  * copies and that both that copyright notice and this permission
135  * notice appear in supporting documentation, and that the name of
136  * The University of Michigan not be used in advertising or
137  * publicity pertaining to distribution of the software without
138  * specific, written prior permission. This software is supplied as
139  * is without expressed or implied warranties of any kind.
140  *
141  *	ITD Research Systems
142  *	University of Michigan
143  *	535 W. William Street
144  *	Ann Arbor, Michigan
145  *	+1-313-936-2652
146  *	netatalk@terminator.cc.umich.edu
147  */
148 
149 /* EXPORT DELETE START */
150 static void krb5_afs_crypt_setkey PROTOTYPE((char*));
151 static void krb5_afs_encrypt PROTOTYPE((char*,long));
152 
153 /*
154  * Initial permutation,
155  */
156 static char	IP[] = {
157 	58,50,42,34,26,18,10, 2,
158 	60,52,44,36,28,20,12, 4,
159 	62,54,46,38,30,22,14, 6,
160 	64,56,48,40,32,24,16, 8,
161 	57,49,41,33,25,17, 9, 1,
162 	59,51,43,35,27,19,11, 3,
163 	61,53,45,37,29,21,13, 5,
164 	63,55,47,39,31,23,15, 7,
165 };
166 
167 /*
168  * Final permutation, FP = IP^(-1)
169  */
170 static char	FP[] = {
171 	40, 8,48,16,56,24,64,32,
172 	39, 7,47,15,55,23,63,31,
173 	38, 6,46,14,54,22,62,30,
174 	37, 5,45,13,53,21,61,29,
175 	36, 4,44,12,52,20,60,28,
176 	35, 3,43,11,51,19,59,27,
177 	34, 2,42,10,50,18,58,26,
178 	33, 1,41, 9,49,17,57,25,
179 };
180 
181 /*
182  * Permuted-choice 1 from the key bits to yield C and D.
183  * Note that bits 8,16... are left out: They are intended for a parity check.
184  */
185 static char	PC1_C[] = {
186 	57,49,41,33,25,17, 9,
187 	 1,58,50,42,34,26,18,
188 	10, 2,59,51,43,35,27,
189 	19,11, 3,60,52,44,36,
190 };
191 
192 static char	PC1_D[] = {
193 	63,55,47,39,31,23,15,
194 	 7,62,54,46,38,30,22,
195 	14, 6,61,53,45,37,29,
196 	21,13, 5,28,20,12, 4,
197 };
198 
199 /*
200  * Sequence of shifts used for the key schedule.
201  */
202 static char	shifts[] = {
203 	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
204 };
205 
206 /*
207  * Permuted-choice 2, to pick out the bits from
208  * the CD array that generate the key schedule.
209  */
210 static char	PC2_C[] = {
211 	14,17,11,24, 1, 5,
212 	 3,28,15, 6,21,10,
213 	23,19,12, 4,26, 8,
214 	16, 7,27,20,13, 2,
215 };
216 
217 static char	PC2_D[] = {
218 	41,52,31,37,47,55,
219 	30,40,51,45,33,48,
220 	44,49,39,56,34,53,
221 	46,42,50,36,29,32,
222 };
223 
224 /*
225  * The E bit-selection table.
226  */
227 static char	E[48];
228 static char	e[] = {
229 	32, 1, 2, 3, 4, 5,
230 	 4, 5, 6, 7, 8, 9,
231 	 8, 9,10,11,12,13,
232 	12,13,14,15,16,17,
233 	16,17,18,19,20,21,
234 	20,21,22,23,24,25,
235 	24,25,26,27,28,29,
236 	28,29,30,31,32, 1,
237 };
238 
239 /*
240  * P is a permutation on the selected combination
241  * of the current L and key.
242  */
243 static char	P[] = {
244 	16, 7,20,21,
245 	29,12,28,17,
246 	 1,15,23,26,
247 	 5,18,31,10,
248 	 2, 8,24,14,
249 	32,27, 3, 9,
250 	19,13,30, 6,
251 	22,11, 4,25,
252 };
253 
254 /*
255  * The 8 selection functions.
256  * For some reason, they give a 0-origin
257  * index, unlike everything else.
258  */
259 static char	S[8][64] = {
260 	14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
261 	 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
262 	 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
263 	15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
264 
265 	15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
266 	 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
267 	 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
268 	13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
269 
270 	10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
271 	13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
272 	13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
273 	 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
274 
275 	 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
276 	13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
277 	10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
278 	 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
279 
280 	 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
281 	14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
282 	 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
283 	11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
284 
285 	12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
286 	10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
287 	 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
288 	 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
289 
290 	 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
291 	13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
292 	 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
293 	 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
294 
295 	13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
296 	 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
297 	 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
298 	 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
299 };
300 
301 /*
302  * The C and D arrays used to calculate the key schedule.
303  */
304 
305 static char	C[28];
306 static char	D[28];
307 /*
308  * The key schedule.
309  * Generated from the key.
310  */
311 static char	KS[16][48];
312 
313 /*
314  * The current block, divided into 2 halves.
315  */
316 static char	L[64];
317 static char	*R=&L[32];
318 
319 static char	tempL[32];
320 static char	f[32];
321 
322 /*
323  * The combination of the key and the input, before selection.
324  */
325 static char	preS[48];
326 
327 static char *afs_crypt(pw, salt)
328      char *pw;
329      char *salt;
330 {
331 	int i, j, c;
332 	int temp;
333 	static char block[66], iobuf[16];
334 
335 	for(i=0; i<66; i++)
336 		block[i] = 0;
337 	for(i=0; ((c= *pw) != NULL) && i<64; pw++){
338 		for(j=0; j<7; j++, i++)
339 			block[i] = (c>>(6-j)) & 01;
340 		i++;
341 	}
342 
343 	krb5_afs_crypt_setkey(block);
344 
345 	for(i=0; i<66; i++)
346 		block[i] = 0;
347 
348 	for(i=0;i<2;i++){
349 		c = *salt++;
350 		iobuf[i] = c;
351 		if(c>'Z') c -= 6;
352 		if(c>'9') c -= 7;
353 		c -= '.';
354 		for(j=0;j<6;j++){
355 			if((c>>j) & 01){
356 				temp = E[6*i+j];
357 				E[6*i+j] = E[6*i+j+24];
358 				E[6*i+j+24] = temp;
359 				}
360 			}
361 		}
362 
363 	for(i=0; i<25; i++)
364 		krb5_afs_encrypt(block,0);
365 
366 	for(i=0; i<11; i++){
367 		c = 0;
368 		for(j=0; j<6; j++){
369 			c <<= 1;
370 			c |= block[6*i+j];
371 			}
372 		c += '.';
373 		if(c>'9') c += 7;
374 		if(c>'Z') c += 6;
375 		iobuf[i+2] = c;
376 	}
377 	iobuf[i+2] = 0;
378 	if(iobuf[1]==0)
379 		iobuf[1] = iobuf[0];
380 	return(iobuf);
381 }
382 
383 
384 /*
385  * Set up the key schedule from the key.
386  */
387 
388 static void krb5_afs_crypt_setkey(key)
389      char *key;
390 {
391 	int i, j, k;
392 	int t;
393 
394 	/*
395 	 * First, generate C and D by permuting
396 	 * the key.  The low order bit of each
397 	 * 8-bit char is not used, so C and D are only 28
398 	 * bits apiece.
399 	 */
400 	for (i=0; i<28; i++) {
401 		C[i] = key[PC1_C[i]-1];
402 		D[i] = key[PC1_D[i]-1];
403 	}
404 	/*
405 	 * To generate Ki, rotate C and D according
406 	 * to schedule and pick up a permutation
407 	 * using PC2.
408 	 */
409 	for (i=0; i<16; i++) {
410 		/*
411 		 * rotate.
412 		 */
413 		for (k=0; k<shifts[i]; k++) {
414 			t = C[0];
415 			for (j=0; j<28-1; j++)
416 				C[j] = C[j+1];
417 			C[27] = t;
418 			t = D[0];
419 			for (j=0; j<28-1; j++)
420 				D[j] = D[j+1];
421 			D[27] = t;
422 		}
423 		/*
424 		 * get Ki. Note C and D are concatenated.
425 		 */
426 		for (j=0; j<24; j++) {
427 			KS[i][j] = C[PC2_C[j]-1];
428 			KS[i][j+24] = D[PC2_D[j]-28-1];
429 		}
430 	}
431 
432 	for(i=0;i<48;i++) {
433 		E[i] = e[i];
434 	}
435 }
436 
437 /*
438  * The payoff: encrypt a block.
439  */
440 
441 static void krb5_afs_encrypt(block, edflag)
442      char *block;
443      long edflag;
444 {
445 	int i, ii;
446 	int t, j, k;
447 
448 	/*
449 	 * First, permute the bits in the input
450 	 */
451 	for (j=0; j<64; j++)
452 		L[j] = block[IP[j]-1];
453 	/*
454 	 * Perform an encryption operation 16 times.
455 	 */
456 	for (ii=0; ii<16; ii++) {
457 		/*
458 		 * Set direction
459 		 */
460 		if (edflag)
461 			i = 15-ii;
462 		else
463 			i = ii;
464 		/*
465 		 * Save the R array,
466 		 * which will be the new L.
467 		 */
468 		for (j=0; j<32; j++)
469 			tempL[j] = R[j];
470 		/*
471 		 * Expand R to 48 bits using the E selector;
472 		 * exclusive-or with the current key bits.
473 		 */
474 		for (j=0; j<48; j++)
475 			preS[j] = R[E[j]-1] ^ KS[i][j];
476 		/*
477 		 * The pre-select bits are now considered
478 		 * in 8 groups of 6 bits each.
479 		 * The 8 selection functions map these
480 		 * 6-bit quantities into 4-bit quantities
481 		 * and the results permuted
482 		 * to make an f(R, K).
483 		 * The indexing into the selection functions
484 		 * is peculiar; it could be simplified by
485 		 * rewriting the tables.
486 		 */
487 		for (j=0; j<8; j++) {
488 			t = 6*j;
489 			k = S[j][(preS[t+0]<<5)+
490 				(preS[t+1]<<3)+
491 				(preS[t+2]<<2)+
492 				(preS[t+3]<<1)+
493 				(preS[t+4]<<0)+
494 				(preS[t+5]<<4)];
495 			t = 4*j;
496 				f[t+0] = (k>>3)&01;
497 				f[t+1] = (k>>2)&01;
498 				f[t+2] = (k>>1)&01;
499 				f[t+3] = (k>>0)&01;
500 		}
501 		/*
502 		 * The new R is L ^ f(R, K).
503 		 * The f here has to be permuted first, though.
504 		 */
505 		for (j=0; j<32; j++)
506 			R[j] = L[j] ^ f[P[j]-1];
507 		/*
508 		 * Finally, the new L (the original R)
509 		 * is copied back.
510 		 */
511 		for (j=0; j<32; j++)
512 			L[j] = tempL[j];
513 	}
514 	/*
515 	 * The output L and R are reversed.
516 	 */
517 	for (j=0; j<32; j++) {
518 		t = L[j];
519 		L[j] = R[j];
520 		R[j] = t;
521 	}
522 	/*
523 	 * The final output
524 	 * gets the inverse permutation of the very original.
525 	 */
526 	for (j=0; j<64; j++)
527 		block[j] = L[FP[j]-1];
528 }
529 
530 /* EXPORT DELETE END */
531