From: Richard Basch Date: Tue, 7 May 1996 20:17:36 +0000 (+0000) Subject: New DES random number generation. For regular DES, it is nearly equivalent X-Git-Tag: krb5-1.0-beta6~132 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=4dac5ba6282a4d68076005c3e58b8d390df23383;p=krb5.git New DES random number generation. For regular DES, it is nearly equivalent (an extra DES encryption now happens). For 3des, it is a substantially better setup (the original one was a placeholder); it may not be the final one, but at least it is not as weak as the previous version. (This checkin does not include the proposed API changes.) git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7911 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/crypto/des/ChangeLog b/src/lib/crypto/des/ChangeLog index 15219e3ae..70063be98 100644 --- a/src/lib/crypto/des/ChangeLog +++ b/src/lib/crypto/des/ChangeLog @@ -1,3 +1,28 @@ +Thu May 2 18:29:01 1996 Richard Basch + + * d3_rndky.c new_rn_key.c: Removed (obsolete). + + * u_rn_key.c: New file + Support routines to set the seed/sequence number of the + random stream. + + * Makefile.in: new/removed file changes + + * des_int.h: Changed prototypes for all the random routines. + + * fin_rndkey.c: rewrote mit_des_finish_random_key to use the new + random state structure and to accept an eblock as arg 1. + + * init_rkey.c: rewritten to be a common DES, 3-DES random stream + initialization routine. it uses the eblock to determine + the random key type to generate. + + * random_key.c: rewritten to be a common DES, 3-DES random stream + generator, using the former DES algorithm (encrypting an + incrementing sequence number with a unique key schedule) + [3-DES uses DES3-CBC-CRC to increment a 192 bit sequence + number, instead of being only as secure as DES.] + Wed Apr 10 17:46:40 1996 Theodore Y. Ts'o * Makefile.in (SRCS,OBJS): Added afsstring2key.c to the list of diff --git a/src/lib/crypto/des/Makefile.in b/src/lib/crypto/des/Makefile.in index 281f449c9..6875c762d 100644 --- a/src/lib/crypto/des/Makefile.in +++ b/src/lib/crypto/des/Makefile.in @@ -21,7 +21,6 @@ OBJS= afsstring2key.$(OBJEXT) \ process_ky.$(OBJEXT) \ random_key.$(OBJEXT) \ string2key.$(OBJEXT) \ - new_rn_key.$(OBJEXT) \ key_sched.$(OBJEXT) \ weak_key.$(OBJEXT) \ f_cbc.$(OBJEXT) \ @@ -34,9 +33,9 @@ OBJS= afsstring2key.$(OBJEXT) \ d3_ecb.$(OBJEXT) \ d3_kysched.$(OBJEXT) \ d3_procky.$(OBJEXT) \ - d3_rndky.$(OBJEXT) \ - d3_str2ky.$(OBJEXT) \ - u_nfold.$(OBJEXT) + d3_str2ky.$(OBJEXT) \ + u_nfold.$(OBJEXT) \ + u_rn_key.$(OBJEXT) SRCS= $(srcdir)/afsstring2key.c \ $(srcdir)/cs_entry.c \ @@ -47,7 +46,6 @@ SRCS= $(srcdir)/afsstring2key.c \ $(srcdir)/process_ky.c \ $(srcdir)/random_key.c \ $(srcdir)/string2key.c \ - $(srcdir)/new_rn_key.c \ $(srcdir)/key_sched.c \ $(srcdir)/weak_key.c \ $(srcdir)/f_cbc.c \ @@ -60,9 +58,9 @@ SRCS= $(srcdir)/afsstring2key.c \ $(srcdir)/d3_ecb.c \ $(srcdir)/d3_kysched.c \ $(srcdir)/d3_procky.c \ - $(srcdir)/d3_rndky.c \ $(srcdir)/d3_str2ky.c \ - $(srcdir)/u_nfold.c + $(srcdir)/u_nfold.c \ + $(srcdir)/u_rn_key.c all:: $(OBJS) diff --git a/src/lib/crypto/des/d3_rndky.c b/src/lib/crypto/des/d3_rndky.c deleted file mode 100644 index 5edcf4d32..000000000 --- a/src/lib/crypto/des/d3_rndky.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 1995 by Richard P. Basch. All Rights Reserved. - * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -krb5_error_code -mit_des3_random_key (eblock, seed, keyblock) - const krb5_encrypt_block * eblock; - krb5_pointer seed; - krb5_keyblock ** keyblock; -{ - krb5_keyblock *randkey; - - if (!(randkey = (krb5_keyblock *)malloc(sizeof(*randkey)))) - return ENOMEM; - if (!(randkey->contents=(krb5_octet *)malloc(sizeof(mit_des3_cblock)))) { - krb5_xfree(randkey); - return ENOMEM; - } - randkey->magic = KV5M_KEYBLOCK; - randkey->length = sizeof(mit_des3_cblock); - randkey->enctype = eblock->crypto_entry->proto_enctype; - mit_des_new_random_key(*(mit_des_cblock *)randkey->contents, - (mit_des_random_key_seed *) seed); - mit_des_new_random_key(*((mit_des_cblock *)randkey->contents + 1), - (mit_des_random_key_seed *) seed); - mit_des_new_random_key(*((mit_des_cblock *)randkey->contents + 2), - (mit_des_random_key_seed *) seed); - *keyblock = randkey; - return 0; -} diff --git a/src/lib/crypto/des/des_int.h b/src/lib/crypto/des/des_int.h index 04332f706..db1a6b9b3 100644 --- a/src/lib/crypto/des/des_int.h +++ b/src/lib/crypto/des/des_int.h @@ -57,9 +57,9 @@ typedef mit_des_key_schedule mit_des3_key_schedule[3]; #define MIT_DES_DECRYPT 0 typedef struct mit_des_ran_key_seed { - krb5_octet sequence_number[8]; - mit_des_key_schedule random_sequence_key; -} mit_des_random_key_seed; + krb5_encrypt_block eblock; + krb5_data sequence; +} mit_des_random_state; /* the first byte of the key is already in the keyblock */ @@ -118,7 +118,8 @@ extern int mit_des_cbc_encrypt /* fin_rndkey.c */ extern krb5_error_code mit_des_finish_random_key - PROTOTYPE(( krb5_pointer FAR *)); + PROTOTYPE(( const krb5_encrypt_block FAR *, + krb5_pointer FAR *)); /* finish_key.c */ extern krb5_error_code mit_des_finish_key @@ -126,7 +127,9 @@ extern krb5_error_code mit_des_finish_key /* init_rkey.c */ extern krb5_error_code mit_des_init_random_key - PROTOTYPE(( const krb5_keyblock FAR *, krb5_pointer FAR *)); + PROTOTYPE(( const krb5_encrypt_block FAR *, + const krb5_keyblock FAR *, + krb5_pointer FAR *)); /* key_parity.c */ extern void mit_des_fixup_key_parity PROTOTYPE((mit_des_cblock )); @@ -136,18 +139,6 @@ extern int mit_des_check_key_parity PROTOTYPE((mit_des_cblock )); extern int mit_des_key_sched PROTOTYPE((mit_des_cblock , mit_des_key_schedule )); -/* new_rnd_key.c */ -extern int mit_des_new_random_key - PROTOTYPE((mit_des_cblock , mit_des_random_key_seed FAR *)); -extern void mit_des_init_random_number_generator - PROTOTYPE((mit_des_cblock, mit_des_random_key_seed FAR *)); -extern void mit_des_set_random_generator_seed - PROTOTYPE((mit_des_cblock , mit_des_random_key_seed FAR *)); -extern void mit_des_set_sequence_number - PROTOTYPE((mit_des_cblock , mit_des_random_key_seed FAR *)); -extern void mit_des_generate_random_block - PROTOTYPE((mit_des_cblock , mit_des_random_key_seed FAR *)); - /* process_ky.c */ extern krb5_error_code mit_des_process_key PROTOTYPE(( krb5_encrypt_block FAR *, const krb5_keyblock FAR *)); @@ -218,12 +209,6 @@ extern krb5_error_code mit_des3_process_key PROTOTYPE((krb5_encrypt_block * eblock, const krb5_keyblock * keyblock)); -/* d3_rndkey.c */ -extern krb5_error_code mit_des3_random_key - PROTOTYPE((const krb5_encrypt_block * eblock, - krb5_pointer seed, - krb5_keyblock ** keyblock)); - /* d3_kysched.c */ extern int mit_des3_key_sched PROTOTYPE((mit_des3_cblock key, @@ -243,4 +228,13 @@ extern krb5_error_code mit_des_n_fold krb5_octet * output, const size_t out_len)); +/* u_rn_key.c */ +extern krb5_error_code mit_des_set_random_generator_seed + PROTOTYPE((const krb5_data * seed, + krb5_pointer random_state)); + +extern krb5_error_code mit_des_set_random_sequence_number + PROTOTYPE((const krb5_data * sequence, + krb5_pointer random_state)); + #endif /*DES_INTERNAL_DEFS*/ diff --git a/src/lib/crypto/des/fin_rndkey.c b/src/lib/crypto/des/fin_rndkey.c index 943a27c5b..7b8a2c385 100644 --- a/src/lib/crypto/des/fin_rndkey.c +++ b/src/lib/crypto/des/fin_rndkey.c @@ -2,6 +2,7 @@ * lib/crypto/des/fin_rndkey.c * * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * Copyright 1996 by Lehman Brothers, Inc. * All Rights Reserved. * * Export of this software from the United States of America may @@ -14,13 +15,12 @@ * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * + * the name of M.I.T. or Lehman Brothers not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. M.I.T. and Lehman Brothers + * make no representations about the suitability of this software for + * any purpose. It is provided "as is" without express or implied + * warranty. */ #include "k5-int.h" @@ -30,11 +30,22 @@ free any resources held by "seed" and assigned by init_random_key() */ -krb5_error_code mit_des_finish_random_key (seed) - krb5_pointer * seed; +krb5_error_code mit_des_finish_random_key (eblock, p_state) + const krb5_encrypt_block * eblock; + krb5_pointer * p_state; { - memset((char *)*seed, 0, sizeof(mit_des_random_key_seed) ); - krb5_xfree(*seed); - *seed = 0; + mit_des_random_state * state = *p_state; + + if (! state) return 0; + + if (state->sequence.data) { + memset((char *)state->sequence.data, 0, state->sequence.length); + krb5_xfree(state->sequence.data); + } + + mit_des_finish_key(&state->eblock); + + krb5_xfree(state); + *p_state = 0; return 0; } diff --git a/src/lib/crypto/des/new_rn_key.c b/src/lib/crypto/des/new_rn_key.c deleted file mode 100644 index e10060272..000000000 --- a/src/lib/crypto/des/new_rn_key.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * lib/crypto/des/new_rn_key.c - * - * Copyright 1988,1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * New pseudo-random key generator, using DES encryption to make the - * pseudo-random cycle as hard to break as DES. - * - * Written by Mark Lillibridge, MIT Project Athena - * - * Under U.S. law, this software may not be exported outside the US - * without license from the U.S. Commerce department. - */ - -#include "k5-int.h" -#include "des_int.h" - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -/* - * mit_des_new_random_key: create a random des key - * - * Requires: mit_des_set_random_number_generater_seed must be at called least - * once before this routine is called. - * - * Notes: the returned key has correct parity and is guarenteed not - * to be a weak des key. Mit_Des_generate_random_block is used to - * provide the random bits. - */ -int -mit_des_new_random_key(key, p_seed) - mit_des_cblock key; - mit_des_random_key_seed *p_seed; -{ - do { - mit_des_generate_random_block(key, p_seed); - mit_des_fixup_key_parity(key); - } while (mit_des_is_weak_key(key)); - - return(0); -} - -/* - * mit_des_init_random_number_generator: - * - * This routine takes a secret key possibly shared by a number - * of servers and uses it to generate a random number stream that is - * not shared by any of the other servers. It does this by using the current - * process id, host id, and the current time to the nearest second. The - * resulting stream seed is not useful information for cracking the secret - * key. Moreover, this routine keeps no copy of the secret key. - * This routine is used for example, by the kerberos server(s) with the - * key in question being the kerberos master key. - * - * Note: this routine calls mit_des_set_random_generator_seed. - */ - -void -mit_des_init_random_number_generator(key,p_seed) - mit_des_cblock key; - mit_des_random_key_seed *p_seed; -{ - mit_des_cblock seed; /* This must be 64 bits exactly */ - struct tval { - krb5_int32 seconds; - krb5_int32 microseconds; - } timenow; - mit_des_cblock new_key; - - krb5_address **addrs = 0; - - /* - * use a host id in generating the seed to ensure - * that different servers have different streams: - */ - memset((char *)seed, 0, sizeof(seed)); - if (!krb5_crypto_os_localaddr(&addrs) && addrs && *addrs) { - memcpy((char *)seed, (char *)addrs[0]->contents, - min(sizeof(seed), addrs[0]->length)); - /* XXX may not do all of the seed. */ - } - if (addrs) { - /* can't use krb5_free_addresses due to circular dependencies in - libraries */ - register krb5_address **addr2; - for (addr2 = addrs; *addr2; addr2++) { - krb5_xfree((*addr2)->contents); - krb5_xfree(*addr2); - } - krb5_xfree(addrs); - } - /* - * Generate a temporary value that depends on the key and host_id - * such that it gives no useful information about the key: - */ - mit_des_set_random_generator_seed(key, p_seed); - mit_des_set_sequence_number(seed, p_seed); - mit_des_new_random_key(new_key, p_seed); - - /* - * use it to select a random stream: - */ - mit_des_set_random_generator_seed(new_key, p_seed); - - /* - * use a time stamp to ensure that a server started later does not reuse - * an old stream: - */ - /* XXX return value */ - (void) krb5_crypto_us_timeofday(&timenow.seconds, - &timenow.microseconds); - mit_des_set_sequence_number((unsigned char *)&timenow, p_seed); - - /* - * use the time stamp finally to select the final seed using the - * current random number stream: - */ - mit_des_new_random_key(new_key, p_seed); - mit_des_set_random_generator_seed(new_key, p_seed); -} - -/* - * This module implements a random number generator faculty such that the next - * number in any random number stream is very hard to predict without knowing - * the seed for that stream even given the preceeding random numbers. - */ - -/* - * mit_des_set_random_generator_seed: this routine is used to select a random - * number stream. The stream that results is - * totally determined by the passed in key. - * (I.e., calling this routine again with the - * same key allows repeating a sequence of - * random numbers) - * - * Requires: key is a valid des key. I.e., has correct parity and is not a - * weak des key. - * [Note: I have changed this so that even if it is not a valid - * DES key, this function will do something rational --- that is, - * we fix up the key parity and make it a non-weak key. This - * still won't help us if the input value is guessable, but at - * least we won't get screwed if the key-parity is wrong... --- TYT] - */ -void -mit_des_set_random_generator_seed(key, p_seed) - mit_des_cblock key; - mit_des_random_key_seed *p_seed; -{ - register int i; - mit_des_cblock fixed_key; - - memcpy(fixed_key, key, sizeof(mit_des_cblock)); - mit_des_fixup_key_parity(fixed_key); - if (mit_des_is_weak_key(fixed_key)) { - fixed_key[0] ^= 0xF0; - mit_des_fixup_key_parity(fixed_key); - } - - /* select the new stream: (note errors are not possible here...) */ - mit_des_key_sched(fixed_key, p_seed->random_sequence_key); - - /* "seek" to the start of the stream: */ - for (i=0; i<8; i++) - p_seed->sequence_number[i] = 0; -} - -/* - * mit_des_set_sequence_number: this routine is used to set the sequence number - * of the current random number stream. This routine - * may be used to "seek" within the current random - * number stream. - * - * Note that mit_des_set_random_generator_seed resets the sequence number to 0. - */ -void -mit_des_set_sequence_number(new_sequence_number, p_seed) - mit_des_cblock new_sequence_number; - mit_des_random_key_seed *p_seed; -{ - memcpy((char *)p_seed->sequence_number, (char *)new_sequence_number, - sizeof(p_seed->sequence_number)); -} - -/* - * mit_des_generate_random_block: routine to return the next random number - * from the current random number stream. - * The returned number is 64 bits long. - * - * Requires: mit_des_set_random_generator_seed must have been called at least once - * before this routine is called. - */ -void -mit_des_generate_random_block(block, p_seed) - mit_des_cblock block; - mit_des_random_key_seed *p_seed; -{ - int i; - - /* - * Encrypt the sequence number to get the new random block: - */ - mit_des_ecb_encrypt((const mit_des_cblock *)p_seed->sequence_number, - (mit_des_cblock *)block, - p_seed->random_sequence_key, 1); - - /* - * Increment the sequence number as an 8 byte unsigned number with wrap: - * (using LSB here) - */ - for (i=0; i<8; i++) { - p_seed->sequence_number[i] = (p_seed->sequence_number[i] + 1) & 0xff; - if (p_seed->sequence_number[i]) - break; - } -} diff --git a/src/lib/crypto/des/random_key.c b/src/lib/crypto/des/random_key.c index 3a8758f2b..b24ec51ef 100644 --- a/src/lib/crypto/des/random_key.c +++ b/src/lib/crypto/des/random_key.c @@ -2,6 +2,7 @@ * lib/crypto/des/random_key.c * * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * Copyright 1996 by Lehman Brothers, Inc. * All Rights Reserved. * * Export of this software from the United States of America may @@ -14,39 +15,80 @@ * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. + * the name of M.I.T. or Lehman Brothers not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. M.I.T. and Lehman Brothers + * make no representations about the suitability of this software for + * any purpose. It is provided "as is" without express or implied + * warranty. */ #include "k5-int.h" #include "des_int.h" +static void mit_des_generate_random_key + PROTOTYPE((mit_des_random_state * state, krb5_keyblock * randkey)); + + /* generate a random encryption key, allocating storage for it and filling in the keyblock address in *keyblock */ krb5_error_code -mit_des_random_key (eblock, seed, keyblock) +mit_des_random_key (eblock, state, keyblock) const krb5_encrypt_block * eblock; - krb5_pointer seed; + krb5_pointer state; krb5_keyblock ** keyblock; { krb5_keyblock *randkey; + int keysize = ((mit_des_random_state *)state)->eblock.crypto_entry->keysize; + + if (eblock == NULL) + /* We are being called from the random number initialization routine */ + eblock = &((mit_des_random_state *)state)->eblock; if (!(randkey = (krb5_keyblock *)malloc(sizeof(*randkey)))) return ENOMEM; - if (!(randkey->contents = (krb5_octet *)malloc(sizeof(mit_des_cblock)))) { + if (!(randkey->contents = (krb5_octet *)malloc(keysize))) { krb5_xfree(randkey); return ENOMEM; } randkey->magic = KV5M_KEYBLOCK; - randkey->length = sizeof(mit_des_cblock); + randkey->length = keysize; randkey->enctype = eblock->crypto_entry->proto_enctype; - mit_des_new_random_key(randkey->contents, (mit_des_random_key_seed *) seed); + + do { + mit_des_generate_random_key(state, randkey); + mit_des_fixup_keyblock_parity(randkey); + } while (mit_des_is_weak_keyblock(randkey)); + *keyblock = randkey; return 0; } + +static mit_des_cblock zero_ivec = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +static void +mit_des_generate_random_key(state, randkey) + mit_des_random_state * state; + krb5_keyblock * randkey; +{ + krb5_encrypt_block *eblock = &state->eblock; + int i; + + (* state->eblock.crypto_entry->encrypt_func) + (state->sequence.data /*in*/, randkey->contents /*out*/, + state->sequence.length, eblock, zero_ivec); + (* state->eblock.crypto_entry->encrypt_func) + (randkey->contents /*in*/, randkey->contents /*out*/, + randkey->length, eblock, + randkey->contents + randkey->length - sizeof(mit_des_cblock)); + + /* Increment the sequence number, with wraparound (LSB) */ + for (i = 0; i < state->sequence.length; i++) { + state->sequence.data[i] = (state->sequence.data[i] + 1) & 0xff; + if (state->sequence.data[i]) + break; + } +} diff --git a/src/lib/crypto/des/u_rn_key.c b/src/lib/crypto/des/u_rn_key.c new file mode 100644 index 000000000..44d3c7383 --- /dev/null +++ b/src/lib/crypto/des/u_rn_key.c @@ -0,0 +1,139 @@ +/* + * Copyright 1996 by Richard P. Basch. All Rights Reserved. + * Copyright 1996 by Lehman Brothers, Inc. All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Richard P. Basch, + * Lehman Brothers and M.I.T. make no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + * + * Based on the version written by Mark Lillibridge, MIT Project Athena. + * + * Under U.S. law, this software may not be exported outside the US + * without license from the U.S. Commerce department. + */ + +#include "k5-int.h" +#include "des_int.h" + +int +mit_des_is_weak_keyblock(keyblock) + krb5_keyblock * keyblock; +{ + int i; + + for (i = 0; i < keyblock->length/sizeof(mit_des_cblock); i++) + if (mit_des_is_weak_key(*((mit_des_cblock *)keyblock->contents + i))) + return 1; + return 0; +} + +void +mit_des_fixup_keyblock_parity(keyblock) + krb5_keyblock * keyblock; +{ + int i; + + for (i = 0; i < keyblock->length/sizeof(mit_des_cblock); i++) + mit_des_fixup_key_parity(*((mit_des_cblock *)keyblock->contents + i)); +} + +/* + * mit_des_set_random_generator_seed: this routine is used to select a random + * number stream. The stream that results is + * totally determined by the passed in key. + * (I.e., calling this routine again with the + * same key allows repeating a sequence of + * random numbers) + */ +krb5_error_code +mit_des_set_random_generator_seed(seed, p_state) + const krb5_data * seed; + krb5_pointer p_state; +{ + krb5_error_code kret; + register int i; + mit_des_cblock *new_key; + mit_des_random_state *state = p_state; + + if (state->eblock.key) { + if (state->eblock.key->contents) { + memset(state->eblock.key->contents, 0, state->eblock.key->length); + krb5_xfree(state->eblock.key->contents); + } + } + + state->eblock.key = (krb5_keyblock *)malloc(sizeof(krb5_keyblock)); + if (! state->eblock.key) + return ENOMEM; + + state->eblock.key->enctype = state->eblock.crypto_entry->proto_enctype; + state->eblock.key->length = state->eblock.crypto_entry->keysize; + state->eblock.key->contents = (krb5_octet *)malloc(state->eblock.key->length); + if (! state->eblock.key->contents) { + krb5_xfree(state->eblock.key); + state->eblock.key = 0; + return ENOMEM; + } + + kret = mit_des_n_fold(seed->data, seed->length, + state->eblock.key->contents, state->eblock.key->length); + if (kret) return kret; + + mit_des_fixup_keyblock_parity(state->eblock.key); + + for (i = 0; i < state->eblock.key->length/sizeof(mit_des_cblock); i++) { + new_key = (mit_des_cblock *)state->eblock.key->contents + i; + if (mit_des_is_weak_key(*new_key)) { + (*new_key)[0] ^= 0xF0; + mit_des_fixup_key_parity(*new_key); + } + } + + /* destroy any old key schedule */ + mit_des_finish_key(&state->eblock); + + /* compute the key schedule */ + (* state->eblock.crypto_entry->process_key) + (&state->eblock, state->eblock.key); + + /* now we can destroy the key... */ + memset(state->eblock.key->contents, 0, state->eblock.key->length); + krb5_xfree(state->eblock.key->contents); + krb5_xfree(state->eblock.key); + state->eblock.key = (krb5_keyblock *) 0; + + /* "seek" to the start of the stream: */ + memset(state->sequence.data, 0, state->sequence.length); + + return 0; +} + +krb5_error_code +mit_des_set_random_sequence_number(sequence, p_state) + const krb5_data *sequence; + krb5_pointer p_state; +{ + mit_des_random_state *state = p_state; + int length = state->eblock.crypto_entry->keysize; + + if (length > sequence->length) + length = sequence->length; + + memcpy(state->sequence.data, sequence->data, length); + + return 0; +}