1 /*
2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #include <k5-int.h>
7 #include <rsa-md4.h>
8 #include <arcfour.h>
9 
asctouni(unsigned char * unicode,unsigned char * ascii,size_t len)10 static void asctouni(unsigned char *unicode, unsigned char *ascii, size_t len)
11 {
12 	int counter;
13 	for (counter=0;counter<len;counter++) {
14 		unicode[2*counter]=ascii[counter];
15 		unicode[2*counter + 1]=0x00;
16 	}
17 }
18 
19 krb5_error_code
krb5int_arcfour_string_to_key(krb5_context context,const struct krb5_enc_provider * enc,const krb5_data * string,const krb5_data * salt,const krb5_data * params,krb5_keyblock * key)20 krb5int_arcfour_string_to_key(krb5_context context,
21 	const struct krb5_enc_provider *enc,
22 	const krb5_data *string, const krb5_data *salt,
23 	const krb5_data *params, krb5_keyblock *key)
24 {
25   size_t len,slen;
26   unsigned char *copystr = NULL;
27   krb5_MD4_CTX md4_context;
28 
29   if (params != NULL)
30       return KRB5_ERR_BAD_S2K_PARAMS;
31 
32   if (key->length != 16)
33     return (KRB5_BAD_MSIZE);
34 
35   /* We ignore salt per the Microsoft spec*/
36 
37   /* compute the space needed for the new string.
38      Since the password must be stored in unicode, we need to increase
39      that number by 2x.
40 
41      This should be re-evauated in the future, it makes the assumption that
42      thes user's password is in ascii.
43   */
44   slen = ((string->length)>128)?128:string->length;
45   len=(slen)*2;
46 
47   copystr = malloc(len);
48   if (copystr == NULL)
49     return ENOMEM;
50 
51   /* make the string.  start by creating the unicode version of the password*/
52   asctouni(copystr, (uchar_t *)string->data, slen );
53 
54   /* the actual MD4 hash of the data */
55   krb5_MD4Init(&md4_context);
56   krb5_MD4Update(&md4_context, (unsigned char *)copystr, len);
57   krb5_MD4Final(&md4_context);
58   memcpy(key->contents, md4_context.digest, 16);
59 
60 #if 0
61   /* test the string_to_key function */
62   printf("Hash=");
63   {
64     int counter;
65     for(counter=0;counter<16;counter++)
66       printf("%02x", md4_context.digest[counter]);
67     printf("\n");
68   }
69 #endif /* 0 */
70 
71   /* Zero out the data behind us */
72   memset (copystr, 0, len);
73   memset(&md4_context, 0, sizeof(md4_context));
74 
75   if (copystr)
76 	free(copystr);
77 
78   return 0;
79 }
80