17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate #include <k5-int.h>
77c478bd9Sstevel@tonic-gate #include <rsa-md4.h>
87c478bd9Sstevel@tonic-gate #include <arcfour.h>
97c478bd9Sstevel@tonic-gate 
asctouni(unsigned char * unicode,unsigned char * ascii,size_t len)107c478bd9Sstevel@tonic-gate static void asctouni(unsigned char *unicode, unsigned char *ascii, size_t len)
117c478bd9Sstevel@tonic-gate {
127c478bd9Sstevel@tonic-gate 	int counter;
137c478bd9Sstevel@tonic-gate 	for (counter=0;counter<len;counter++) {
147c478bd9Sstevel@tonic-gate 		unicode[2*counter]=ascii[counter];
157c478bd9Sstevel@tonic-gate 		unicode[2*counter + 1]=0x00;
167c478bd9Sstevel@tonic-gate 	}
177c478bd9Sstevel@tonic-gate }
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate 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)207c478bd9Sstevel@tonic-gate krb5int_arcfour_string_to_key(krb5_context context,
217c478bd9Sstevel@tonic-gate 	const struct krb5_enc_provider *enc,
227c478bd9Sstevel@tonic-gate 	const krb5_data *string, const krb5_data *salt,
237c478bd9Sstevel@tonic-gate 	const krb5_data *params, krb5_keyblock *key)
247c478bd9Sstevel@tonic-gate {
257c478bd9Sstevel@tonic-gate   size_t len,slen;
267c478bd9Sstevel@tonic-gate   unsigned char *copystr = NULL;
277c478bd9Sstevel@tonic-gate   krb5_MD4_CTX md4_context;
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate   if (params != NULL)
307c478bd9Sstevel@tonic-gate       return KRB5_ERR_BAD_S2K_PARAMS;
31*1da57d55SToomas Soome 
327c478bd9Sstevel@tonic-gate   if (key->length != 16)
337c478bd9Sstevel@tonic-gate     return (KRB5_BAD_MSIZE);
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate   /* We ignore salt per the Microsoft spec*/
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate   /* compute the space needed for the new string.
387c478bd9Sstevel@tonic-gate      Since the password must be stored in unicode, we need to increase
397c478bd9Sstevel@tonic-gate      that number by 2x.
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate      This should be re-evauated in the future, it makes the assumption that
427c478bd9Sstevel@tonic-gate      thes user's password is in ascii.
437c478bd9Sstevel@tonic-gate   */
447c478bd9Sstevel@tonic-gate   slen = ((string->length)>128)?128:string->length;
457c478bd9Sstevel@tonic-gate   len=(slen)*2;
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate   copystr = malloc(len);
487c478bd9Sstevel@tonic-gate   if (copystr == NULL)
497c478bd9Sstevel@tonic-gate     return ENOMEM;
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate   /* make the string.  start by creating the unicode version of the password*/
527c478bd9Sstevel@tonic-gate   asctouni(copystr, (uchar_t *)string->data, slen );
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate   /* the actual MD4 hash of the data */
557c478bd9Sstevel@tonic-gate   krb5_MD4Init(&md4_context);
567c478bd9Sstevel@tonic-gate   krb5_MD4Update(&md4_context, (unsigned char *)copystr, len);
577c478bd9Sstevel@tonic-gate   krb5_MD4Final(&md4_context);
587c478bd9Sstevel@tonic-gate   memcpy(key->contents, md4_context.digest, 16);
597c478bd9Sstevel@tonic-gate 
60*1da57d55SToomas Soome #if 0
617c478bd9Sstevel@tonic-gate   /* test the string_to_key function */
627c478bd9Sstevel@tonic-gate   printf("Hash=");
637c478bd9Sstevel@tonic-gate   {
647c478bd9Sstevel@tonic-gate     int counter;
657c478bd9Sstevel@tonic-gate     for(counter=0;counter<16;counter++)
667c478bd9Sstevel@tonic-gate       printf("%02x", md4_context.digest[counter]);
677c478bd9Sstevel@tonic-gate     printf("\n");
687c478bd9Sstevel@tonic-gate   }
697c478bd9Sstevel@tonic-gate #endif /* 0 */
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate   /* Zero out the data behind us */
727c478bd9Sstevel@tonic-gate   memset (copystr, 0, len);
737c478bd9Sstevel@tonic-gate   memset(&md4_context, 0, sizeof(md4_context));
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate   if (copystr)
767c478bd9Sstevel@tonic-gate 	free(copystr);
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate   return 0;
797c478bd9Sstevel@tonic-gate }
80