|
|
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.