|
|
1.1 ! root 1: /* ! 2: * $Source: /mit/kerberos/src/lib/des/RCS/new_rnd_key.c,v $ ! 3: * $Author: jtkohl $ ! 4: * ! 5: * Copyright 1988 by the Massachusetts Institute of Technology. ! 6: * ! 7: * For copying and distribution information, please see the file ! 8: * <mit-copyright.h>. ! 9: * ! 10: * New pseudo-random key generator, using DES encryption to make the ! 11: * pseudo-random cycle as hard to break as DES. ! 12: * ! 13: * Written by Mark Lillibridge, MIT Project Athena ! 14: * ! 15: * Under U.S. law, this software may not be exported outside the US ! 16: * without license from the U.S. Commerce department. ! 17: */ ! 18: ! 19: #ifndef lint ! 20: static char rcsid_new_rnd_key_c[] = ! 21: "$Header: new_rnd_key.c,v 4.1 89/01/22 13:13:31 jtkohl Exp $"; ! 22: #endif lint ! 23: ! 24: #include <mit-copyright.h> ! 25: ! 26: #include <des.h> ! 27: #include "des_internal.h" ! 28: ! 29: extern void des_fixup_key_parity(); ! 30: extern int des_is_weak_key(); ! 31: ! 32: void des_set_random_generator_seed(), des_set_sequence_number(); ! 33: void des_generate_random_block(); ! 34: ! 35: /* ! 36: * des_new_random_key: create a random des key ! 37: * ! 38: * Requires: des_set_random_number_generater_seed must be at called least ! 39: * once before this routine is called. ! 40: * ! 41: * Notes: the returned key has correct parity and is guarenteed not ! 42: * to be a weak des key. Des_generate_random_block is used to ! 43: * provide the random bits. ! 44: */ ! 45: int ! 46: des_new_random_key(key) ! 47: des_cblock key; ! 48: { ! 49: do { ! 50: des_generate_random_block(key); ! 51: des_fixup_key_parity(key); ! 52: } while (des_is_weak_key(key)); ! 53: ! 54: return(0); ! 55: } ! 56: ! 57: /* ! 58: * des_init_random_number_generator: ! 59: * ! 60: * This routine takes a secret key possibly shared by a number ! 61: * of servers and uses it to generate a random number stream that is ! 62: * not shared by any of the other servers. It does this by using the current ! 63: * process id, host id, and the current time to the nearest second. The ! 64: * resulting stream seed is not useful information for cracking the secret ! 65: * key. Moreover, this routine keeps no copy of the secret key. ! 66: * This routine is used for example, by the kerberos server(s) with the ! 67: * key in question being the kerberos master key. ! 68: * ! 69: * Note: this routine calls des_set_random_generator_seed. ! 70: */ ! 71: #ifndef BSDUNIX ! 72: you lose... (aka, you get to implement an analog of this for your ! 73: system...) ! 74: #else ! 75: ! 76: #include <sys/time.h> ! 77: ! 78: void des_init_random_number_generator(key) ! 79: des_cblock key; ! 80: { ! 81: struct { /* This must be 64 bits exactly */ ! 82: long process_id; ! 83: long host_id; ! 84: } seed; ! 85: struct timeval time; /* this must also be 64 bits exactly */ ! 86: des_cblock new_key; ! 87: long gethostid(); ! 88: ! 89: /* ! 90: * use a host id and process id in generating the seed to ensure ! 91: * that different servers have different streams: ! 92: */ ! 93: seed.host_id = gethostid(); ! 94: seed.process_id = getpid(); ! 95: ! 96: /* ! 97: * Generate a tempory value that depends on the key, host_id, and ! 98: * process_id such that it gives no useful information about the key: ! 99: */ ! 100: des_set_random_generator_seed(key); ! 101: des_set_sequence_number((unsigned char *)&seed); ! 102: des_new_random_key(new_key); ! 103: ! 104: /* ! 105: * use it to select a random stream: ! 106: */ ! 107: des_set_random_generator_seed(new_key); ! 108: ! 109: /* ! 110: * use a time stamp to ensure that a server started later does not reuse ! 111: * an old stream: ! 112: */ ! 113: gettimeofday(&time, (struct timeval *)0); ! 114: des_set_sequence_number((unsigned char *)&time); ! 115: ! 116: /* ! 117: * use the time stamp finally to select the final seed using the ! 118: * current random number stream: ! 119: */ ! 120: des_new_random_key(new_key); ! 121: des_set_random_generator_seed(new_key); ! 122: } ! 123: ! 124: #endif /* ifdef BSDUNIX */ ! 125: ! 126: /* ! 127: * This module implements a random number generator faculty such that the next ! 128: * number in any random number stream is very hard to predict without knowing ! 129: * the seed for that stream even given the preceeding random numbers. ! 130: */ ! 131: ! 132: /* ! 133: * The secret des key schedule for the current stream of random numbers: ! 134: */ ! 135: static des_key_schedule random_sequence_key; ! 136: ! 137: /* ! 138: * The sequence # in the current stream of random numbers: ! 139: */ ! 140: static unsigned char sequence_number[8]; ! 141: ! 142: /* ! 143: * des_set_random_generator_seed: this routine is used to select a random ! 144: * number stream. The stream that results is ! 145: * totally determined by the passed in key. ! 146: * (I.e., calling this routine again with the ! 147: * same key allows repeating a sequence of ! 148: * random numbers) ! 149: * ! 150: * Requires: key is a valid des key. I.e., has correct parity and is not a ! 151: * weak des key. ! 152: */ ! 153: void ! 154: des_set_random_generator_seed(key) ! 155: des_cblock key; ! 156: { ! 157: register int i; ! 158: ! 159: /* select the new stream: (note errors are not possible here...) */ ! 160: des_key_sched(key, random_sequence_key); ! 161: ! 162: /* "seek" to the start of the stream: */ ! 163: for (i=0; i<8; i++) ! 164: sequence_number[i] = 0; ! 165: } ! 166: ! 167: /* ! 168: * des_set_sequence_number: this routine is used to set the sequence number ! 169: * of the current random number stream. This routine ! 170: * may be used to "seek" within the current random ! 171: * number stream. ! 172: * ! 173: * Note that des_set_random_generator_seed resets the sequence number to 0. ! 174: */ ! 175: void ! 176: des_set_sequence_number(new_sequence_number) ! 177: des_cblock new_sequence_number; ! 178: { ! 179: bcopy((char *)new_sequence_number, (char *)sequence_number, ! 180: sizeof(sequence_number)); ! 181: } ! 182: ! 183: /* ! 184: * des_generate_random_block: routine to return the next random number ! 185: * from the current random number stream. ! 186: * The returned number is 64 bits long. ! 187: * ! 188: * Requires: des_set_random_generator_seed must have been called at least once ! 189: * before this routine is called. ! 190: */ ! 191: void des_generate_random_block(block) ! 192: des_cblock block; ! 193: { ! 194: int i; ! 195: ! 196: /* ! 197: * Encrypt the sequence number to get the new random block: ! 198: */ ! 199: des_ecb_encrypt(sequence_number, block, random_sequence_key, 1); ! 200: ! 201: /* ! 202: * Increment the sequence number as an 8 byte unsigned number with wrap: ! 203: * (using LSB here) ! 204: */ ! 205: for (i=0; i<8; i++) { ! 206: sequence_number[i] = (sequence_number[i] + 1) & 0xff; ! 207: if (sequence_number[i]) ! 208: break; ! 209: } ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.