dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / gss_mechs / mech_krb5 / crypto / des / afsstring2key.c
blob3df2453fff4af2a0fd67ea3fc533d5e1b59681d1
1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
7 /*
8 * lib/crypto/des/string2key.c
10 * based on lib/crypto/des/string2key.c from MIT V5
11 * and on lib/des/afs_string_to_key.c from UMD.
12 * constructed by Mark Eichin, Cygnus Support, 1995.
13 * made thread-safe by Ken Raeburn, MIT, 2001.
17 * Copyright 2001 by the Massachusetts Institute of Technology.
18 * All Rights Reserved.
20 * Export of this software from the United States of America may
21 * require a specific license from the United States Government.
22 * It is the responsibility of any person or organization contemplating
23 * export to obtain such a license before exporting.
25 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
26 * distribute this software and its documentation for any purpose and
27 * without fee is hereby granted, provided that the above copyright
28 * notice appear in all copies and that both that copyright notice and
29 * this permission notice appear in supporting documentation, and that
30 * the name of M.I.T. not be used in advertising or publicity pertaining
31 * to distribution of the software without specific, written prior
32 * permission. Furthermore if you modify this software you must label
33 * your software as modified software and not distribute it in such a
34 * fashion that it might be confused with the original M.I.T. software.
35 * M.I.T. makes no representations about the suitability of
36 * this software for any purpose. It is provided "as is" without express
37 * or implied warranty.
41 * Copyright (C) 1998 by the FundsXpress, INC.
43 * All rights reserved.
45 * Export of this software from the United States of America may require
46 * a specific license from the United States Government. It is the
47 * responsibility of any person or organization contemplating export to
48 * obtain such a license before exporting.
50 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
51 * distribute this software and its documentation for any purpose and
52 * without fee is hereby granted, provided that the above copyright
53 * notice appear in all copies and that both that copyright notice and
54 * this permission notice appear in supporting documentation, and that
55 * the name of FundsXpress. not be used in advertising or publicity pertaining
56 * to distribution of the software without specific, written prior
57 * permission. FundsXpress makes no representations about the suitability of
58 * this software for any purpose. It is provided "as is" without express
59 * or implied warranty.
61 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
62 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
63 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
66 #include "k5-int.h"
67 #include "des_int.h"
68 #include <ctype.h>
70 #define afs_crypt mit_afs_crypt
71 char *afs_crypt (const char *, const char *, char *);
73 #undef min
74 #define min(a,b) ((a)>(b)?(b):(a))
76 /*ARGSUSED*/
77 krb5_error_code
78 mit_afs_string_to_key (krb5_context context,
79 krb5_keyblock *keyblock, const krb5_data *data,
80 const krb5_data *salt)
82 /* Solaris Kerberos */
83 krb5_error_code retval = KRB5_PROG_ETYPE_NOSUPP;
84 /* totally different approach from MIT string2key. */
85 /* much of the work has already been done by the only caller
86 which is mit_des_string_to_key; in particular, *keyblock is already
87 set up. */
89 char *realm = salt->data;
90 unsigned int i, j;
91 krb5_octet *key = keyblock->contents;
92 /* Solaris Kerberos */
93 krb5_keyblock usekey;
95 if (data->length <= 8) {
96 /* One block only. Run afs_crypt and use the first eight
97 returned bytes after the copy of the (fixed) salt.
99 Since the returned bytes are alphanumeric, the output is
100 limited to 2**48 possibilities; for each byte, only 64
101 possible values can be used. */
102 unsigned char password[9]; /* trailing nul for crypt() */
103 char afs_crypt_buf[16];
105 memset (password, 0, sizeof (password));
106 memcpy (password, realm, min (salt->length, 8));
107 for (i=0; i<8; i++)
108 if (isupper(password[i]))
109 password[i] = tolower(password[i]);
110 for (i=0; i<data->length; i++)
111 password[i] ^= data->data[i];
112 for (i=0; i<8; i++)
113 if (password[i] == '\0')
114 password[i] = 'X';
115 password[8] = '\0';
116 /* Out-of-bounds salt characters are equivalent to a salt string
117 of "p1". */
118 strncpy((char *) key,
119 (char *) afs_crypt((char *) password, "#~", afs_crypt_buf) + 2,
121 for (i=0; i<8; i++)
122 key[i] <<= 1;
123 /* now fix up key parity again */
124 mit_des_fixup_key_parity(key);
125 /* clean & free the input string */
126 memset(password, 0, (size_t) sizeof(password));
128 /* Solaris Kerberos: Success */
129 retval = 0;
130 } else {
131 /* Multiple blocks. Do a CBC checksum, twice, and use the
132 result as the new key. */
133 mit_des_cblock ikey, tkey;
134 unsigned int pw_len = salt->length+data->length;
135 unsigned char *password = malloc(pw_len+1);
136 if (!password) return ENOMEM;
138 /* Some bound checks from the original code are elided here as
139 the malloc above makes sure we have enough storage. */
140 memcpy (password, data->data, data->length);
141 for (i=data->length, j = 0; j < salt->length; i++, j++) {
142 password[i] = realm[j];
143 if (isupper(password[i]))
144 password[i] = tolower(password[i]);
147 memcpy (ikey, "kerberos", sizeof(ikey));
148 memcpy (tkey, ikey, sizeof(tkey));
149 mit_des_fixup_key_parity (tkey);
151 /* Solaris Kerberos */
152 usekey.enctype = ENCTYPE_DES_CBC_CRC;
153 usekey.contents = tkey;
154 usekey.length = 8;
155 retval = mit_des_cbc_cksum (context, (unsigned char *)password,
156 tkey, i, &usekey, ikey);
158 memcpy (ikey, tkey, sizeof(ikey));
159 mit_des_fixup_key_parity (tkey);
160 /* Solaris Kerberos */
161 if (usekey.hKey != CK_INVALID_HANDLE) {
162 (void) C_DestroyObject(krb_ctx_hSession(context), usekey.hKey);
163 usekey.hKey = CK_INVALID_HANDLE;
165 usekey.contents = tkey;
166 usekey.length = 8;
167 retval = mit_des_cbc_cksum (context, (unsigned char *) password,
168 key, i, &usekey, ikey);
170 /* now fix up key parity again */
171 mit_des_fixup_key_parity(key);
173 /* Solaris Kerberos */
174 if (usekey.hKey != CK_INVALID_HANDLE) {
175 (void) C_DestroyObject(krb_ctx_hSession(context), usekey.hKey);
176 usekey.hKey = CK_INVALID_HANDLE;
178 /* clean & free the input string */
179 memset(password, 0, (size_t) pw_len);
180 krb5_xfree(password);
182 #if 0
183 /* must free here because it was copied for this special case */
184 krb5_xfree(salt->data);
185 #endif
187 return retval;
191 /* Portions of this code:
192 Copyright 1989 by the Massachusetts Institute of Technology
196 * Copyright (c) 1990 Regents of The University of Michigan.
197 * All Rights Reserved.
199 * Permission to use, copy, modify, and distribute this software
200 * and its documentation for any purpose and without fee is hereby
201 * granted, provided that the above copyright notice appears in all
202 * copies and that both that copyright notice and this permission
203 * notice appear in supporting documentation, and that the name of
204 * The University of Michigan not be used in advertising or
205 * publicity pertaining to distribution of the software without
206 * specific, written prior permission. This software is supplied as
207 * is without expressed or implied warranties of any kind.
209 * ITD Research Systems
210 * University of Michigan
211 * 535 W. William Street
212 * Ann Arbor, Michigan
213 * +1-313-936-2652
214 * netatalk@terminator.cc.umich.edu
217 static void krb5_afs_crypt_setkey (char*, char*, char(*)[48]);
218 static void krb5_afs_encrypt (char*,char*,char (*)[48]);
221 * Initial permutation,
223 static const char IP[] = {
224 58,50,42,34,26,18,10, 2,
225 60,52,44,36,28,20,12, 4,
226 62,54,46,38,30,22,14, 6,
227 64,56,48,40,32,24,16, 8,
228 57,49,41,33,25,17, 9, 1,
229 59,51,43,35,27,19,11, 3,
230 61,53,45,37,29,21,13, 5,
231 63,55,47,39,31,23,15, 7,
235 * Final permutation, FP = IP^(-1)
237 static const char FP[] = {
238 40, 8,48,16,56,24,64,32,
239 39, 7,47,15,55,23,63,31,
240 38, 6,46,14,54,22,62,30,
241 37, 5,45,13,53,21,61,29,
242 36, 4,44,12,52,20,60,28,
243 35, 3,43,11,51,19,59,27,
244 34, 2,42,10,50,18,58,26,
245 33, 1,41, 9,49,17,57,25,
249 * Permuted-choice 1 from the key bits to yield C and D.
250 * Note that bits 8,16... are left out: They are intended for a parity check.
252 static const char PC1_C[] = {
253 57,49,41,33,25,17, 9,
254 1,58,50,42,34,26,18,
255 10, 2,59,51,43,35,27,
256 19,11, 3,60,52,44,36,
259 static const char PC1_D[] = {
260 63,55,47,39,31,23,15,
261 7,62,54,46,38,30,22,
262 14, 6,61,53,45,37,29,
263 21,13, 5,28,20,12, 4,
267 * Sequence of shifts used for the key schedule.
269 static const char shifts[] = {
270 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
274 * Permuted-choice 2, to pick out the bits from
275 * the CD array that generate the key schedule.
277 static const char PC2_C[] = {
278 14,17,11,24, 1, 5,
279 3,28,15, 6,21,10,
280 23,19,12, 4,26, 8,
281 16, 7,27,20,13, 2,
284 static const char PC2_D[] = {
285 41,52,31,37,47,55,
286 30,40,51,45,33,48,
287 44,49,39,56,34,53,
288 46,42,50,36,29,32,
292 * The E bit-selection table.
294 static const char e[] = {
295 32, 1, 2, 3, 4, 5,
296 4, 5, 6, 7, 8, 9,
297 8, 9,10,11,12,13,
298 12,13,14,15,16,17,
299 16,17,18,19,20,21,
300 20,21,22,23,24,25,
301 24,25,26,27,28,29,
302 28,29,30,31,32, 1,
306 * P is a permutation on the selected combination
307 * of the current L and key.
309 static const char P[] = {
310 16, 7,20,21,
311 29,12,28,17,
312 1,15,23,26,
313 5,18,31,10,
314 2, 8,24,14,
315 32,27, 3, 9,
316 19,13,30, 6,
317 22,11, 4,25,
321 * The 8 selection functions.
322 * For some reason, they give a 0-origin
323 * index, unlike everything else.
325 static const char S[8][64] = {
326 {14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
327 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
328 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
329 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13},
331 {15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
332 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
333 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
334 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9},
336 {10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
337 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
338 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
339 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12},
341 { 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
342 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
343 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
344 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14},
346 { 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
347 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
348 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
349 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3},
351 {12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
352 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
353 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
354 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13},
356 { 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
357 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
358 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
359 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12},
361 {13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
362 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
363 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
364 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11},
368 char *afs_crypt(const char *pw, const char *salt,
369 /* must be at least 16 bytes */
370 char *iobuf)
372 int i, j, c;
373 int temp;
374 char block[66];
375 char E[48];
377 * The key schedule.
378 * Generated from the key.
380 char KS[16][48];
382 for(i=0; i<66; i++)
383 block[i] = 0;
384 /* Solaris Kerberos */
385 for(i=0; ((c= *pw) != '\0') && i<64; pw++){
386 for(j=0; j<7; j++, i++)
387 block[i] = (c>>(6-j)) & 01;
388 i++;
391 krb5_afs_crypt_setkey(block, E, KS);
393 for(i=0; i<66; i++)
394 block[i] = 0;
396 for(i=0;i<2;i++){
397 c = *salt++;
398 iobuf[i] = c;
399 if(c>'Z') c -= 6;
400 if(c>'9') c -= 7;
401 c -= '.';
402 for(j=0;j<6;j++){
403 if((c>>j) & 01){
404 temp = E[6*i+j];
405 E[6*i+j] = E[6*i+j+24];
406 E[6*i+j+24] = temp;
411 for(i=0; i<25; i++)
412 krb5_afs_encrypt(block,E,KS);
414 for(i=0; i<11; i++){
415 c = 0;
416 for(j=0; j<6; j++){
417 c <<= 1;
418 c |= block[6*i+j];
420 c += '.';
421 if(c>'9') c += 7;
422 if(c>'Z') c += 6;
423 iobuf[i+2] = c;
425 iobuf[i+2] = 0;
426 if(iobuf[1]==0)
427 iobuf[1] = iobuf[0];
428 return(iobuf);
432 * Set up the key schedule from the key.
435 static void krb5_afs_crypt_setkey(char *key, char *E, char (*KS)[48])
437 register int i, j, k;
438 int t;
440 * The C and D arrays used to calculate the key schedule.
442 char C[28], D[28];
445 * First, generate C and D by permuting
446 * the key. The low order bit of each
447 * 8-bit char is not used, so C and D are only 28
448 * bits apiece.
450 for (i=0; i<28; i++) {
451 C[i] = key[PC1_C[i]-1];
452 D[i] = key[PC1_D[i]-1];
455 * To generate Ki, rotate C and D according
456 * to schedule and pick up a permutation
457 * using PC2.
459 for (i=0; i<16; i++) {
461 * rotate.
463 for (k=0; k<shifts[i]; k++) {
464 t = C[0];
465 for (j=0; j<28-1; j++)
466 C[j] = C[j+1];
467 C[27] = t;
468 t = D[0];
469 for (j=0; j<28-1; j++)
470 D[j] = D[j+1];
471 D[27] = t;
474 * get Ki. Note C and D are concatenated.
476 for (j=0; j<24; j++) {
477 KS[i][j] = C[PC2_C[j]-1];
478 KS[i][j+24] = D[PC2_D[j]-28-1];
482 #if 0
483 for(i=0;i<48;i++) {
484 E[i] = e[i];
486 #else
487 memcpy(E, e, 48);
488 #endif
492 * The payoff: encrypt a block.
495 static void krb5_afs_encrypt(char *block, char *E, char (*KS)[48])
497 const long edflag = 0;
498 int i, ii;
499 int t, j, k;
500 char tempL[32];
501 char f[32];
503 * The current block, divided into 2 halves.
505 char L[64];
506 char *const R = &L[32];
508 * The combination of the key and the input, before selection.
510 char preS[48];
513 * First, permute the bits in the input
515 for (j=0; j<64; j++)
516 L[j] = block[IP[j]-1];
518 * Perform an encryption operation 16 times.
520 for (ii=0; ii<16; ii++) {
522 * Set direction
524 if (edflag)
525 i = 15-ii;
526 else
527 i = ii;
529 * Save the R array,
530 * which will be the new L.
532 #if 0
533 for (j=0; j<32; j++)
534 tempL[j] = R[j];
535 #else
536 memcpy(tempL, R, 32);
537 #endif
539 * Expand R to 48 bits using the E selector;
540 * exclusive-or with the current key bits.
542 for (j=0; j<48; j++)
543 preS[j] = R[E[j]-1] ^ KS[i][j];
545 * The pre-select bits are now considered
546 * in 8 groups of 6 bits each.
547 * The 8 selection functions map these
548 * 6-bit quantities into 4-bit quantities
549 * and the results permuted
550 * to make an f(R, K).
551 * The indexing into the selection functions
552 * is peculiar; it could be simplified by
553 * rewriting the tables.
555 for (j=0; j<8; j++) {
556 t = 6*j;
557 k = S[j][(preS[t+0]<<5)+
558 (preS[t+1]<<3)+
559 (preS[t+2]<<2)+
560 (preS[t+3]<<1)+
561 (preS[t+4]<<0)+
562 (preS[t+5]<<4)];
563 t = 4*j;
564 f[t+0] = (k>>3)&01;
565 f[t+1] = (k>>2)&01;
566 f[t+2] = (k>>1)&01;
567 f[t+3] = (k>>0)&01;
570 * The new R is L ^ f(R, K).
571 * The f here has to be permuted first, though.
573 for (j=0; j<32; j++)
574 R[j] = L[j] ^ f[P[j]-1];
576 * Finally, the new L (the original R)
577 * is copied back.
579 #if 0
580 for (j=0; j<32; j++)
581 L[j] = tempL[j];
582 #else
583 memcpy(L, tempL, 32);
584 #endif
587 * The output L and R are reversed.
589 for (j=0; j<32; j++) {
590 t = L[j];
591 L[j] = R[j];
592 R[j] = t;
595 * The final output
596 * gets the inverse permutation of the very original.
598 for (j=0; j<64; j++)
599 block[j] = L[FP[j]-1];