Remove spurious comma in enum.
[u/mdw/catacomb] / rand.h
1 /* -*-c-*-
2 *
3 * $Id: rand.h,v 1.7 2000/10/08 12:07:18 mdw Exp $
4 *
5 * Secure random number generator
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30 /*----- Revision history --------------------------------------------------*
31 *
32 * $Log: rand.h,v $
33 * Revision 1.7 2000/10/08 12:07:18 mdw
34 * Remove spurious comma in enum.
35 *
36 * Revision 1.6 2000/06/17 11:53:38 mdw
37 * Deprecate `rand_getgood'. Provide a new interface to ensure that a pool
38 * is well seeded.
39 *
40 * Revision 1.5 1999/12/13 15:34:15 mdw
41 * Fix a typo.
42 *
43 * Revision 1.4 1999/12/10 23:29:48 mdw
44 * Change header file guard names.
45 *
46 * Revision 1.3 1999/10/15 21:04:30 mdw
47 * Increase output buffer a bit for performance.
48 *
49 * Revision 1.2 1999/10/12 21:00:15 mdw
50 * Make pool and buffer sizes more sensible.
51 *
52 * Revision 1.1 1999/09/03 08:41:12 mdw
53 * Initial import.
54 *
55 */
56
57 /*----- Notes on the random number generator ------------------------------*
58 *
59 * The algorithm is one of the author's own devising. It may therefore be
60 * worth a certain amount of skepticism. However, I've thought about this
61 * method for over a year before actually considering it worth implementing.
62 * With a little bit of luck, it should have received some peer review by the
63 * time this code is actually properly released, and it'll be worth a bit
64 * more confidence. My earlier generator was very similar in structure to
65 * the Linux /dev/random device. This generator is intended to address
66 * concerns I expressed about the Linux generator in a Usenet article to
67 * sci.crypt.
68 *
69 * The generator is divided into two parts: an input pool and an output
70 * buffer. New random data is placed into the pool in the way described
71 * below, which is shamelessly stolen from the Linux /dev/random generator.
72 * The only interaction that the pool has on the output buffer is through the
73 * keyed `gating' operation, which mixes up and redistributes all of the
74 * generator's state in an irreversible manner. Random bytes, when
75 * requested, are extracted from the output buffer in a linear fashion.
76 *
77 * The input pool is best seen as being eight shift registers in parallel.
78 * Data is added to the pool one octet at a time. Each bit of a new octet is
79 * added to a different shift register, by adding it (mod 2) with other bits
80 * according to the coefficients of a primitive polynomial. Each new byte is
81 * rotated before being added into the pool, in a half-hearted attempt to
82 * protect against biases in the input data (e.g., top bits being clear on
83 * ASCII text).
84 *
85 * The gating operation takes a keyed hash of the entire generator state,
86 * uses it as the key for a symmetric cipher, and encrypts the state. The
87 * key is then discarded. The result is that every ouptut bit of the
88 * operation depends in a complex way on every input bit, but the operation
89 * cannot be reversed.
90 *
91 * As an added wrinkle, 160 bits of the output buffer are never actually
92 * output. They are used in the gating operation only, as an extra item that
93 * an adversary has to guess before predicting generator output.
94 */
95
96 #ifndef CATACOMB_RAND_H
97 #define CATACOMB_RAND_H
98
99 #ifdef __cplusplus
100 extern "C" {
101 #endif
102
103 /*----- Header files ------------------------------------------------------*/
104
105 #include <stddef.h>
106
107 #ifndef CATACOMB_GRAND_H
108 # include "grand.h"
109 #endif
110
111 #ifndef CATACOMB_RMD160_HMAC_H
112 # include "rmd160-hmac.h"
113 #endif
114
115 /*----- Magic numbers -----------------------------------------------------*/
116
117 #define RAND_POOLSZ 128 /* Input pool size in bytes */
118 #define RAND_BUFSZ 512 /* Output buffer size in bytes */
119 #define RAND_SECSZ 20 /* Secret octets in output buffer */
120
121 #define RAND_IBITS (RAND_POOLSZ * 8)
122 #define RAND_OBITS (RAND_BUFSZ * 8)
123
124 /*----- Data structures ---------------------------------------------------*/
125
126 /* --- A random number generator pool --- */
127
128 typedef struct rand_pool {
129 octet pool[RAND_POOLSZ]; /* Actual contents of the pool */
130 unsigned i; /* Current index into pool */
131 unsigned irot; /* Current rotation applied */
132 unsigned ibits; /* Number of good bits in pool */
133 octet buf[RAND_BUFSZ]; /* Random octet output buffer */
134 unsigned o; /* Current index into buffer */
135 unsigned obits; /* Number of good bits in buffer */
136 rmd160_mackey k; /* Secret key for this pool */
137 const struct rand_source *s; /* System-specific noise source */
138 } rand_pool;
139
140 #define RAND_GLOBAL ((rand_pool *)0) /* The global randomness pool */
141
142 /* --- A noise source --- */
143
144 typedef struct rand_source {
145 void (*getnoise)(rand_pool */*r*/); /* Acquire more noise */
146 int (*timer)(rand_pool */*r*/); /* Get noise from current time */
147 } rand_source;
148
149 /*----- Functions provided ------------------------------------------------*/
150
151 /* --- @rand_init@ --- *
152 *
153 * Arguments: @rand_pool *r@ = pointer to a randomness pool
154 *
155 * Returns: ---
156 *
157 * Use: Initializes a randomness pool. The pool doesn't start out
158 * very random: that's your job to sort out.
159 */
160
161 extern void rand_init(rand_pool */*r*/);
162
163 /* --- @rand_noisesrc@ --- *
164 *
165 * Arguments: @rand_pool *r@ = pointer to a randomness pool
166 * @const rand_source *s@ = pointer to source definition
167 *
168 * Returns: ---
169 *
170 * Use: Sets a noise source for a randomness pool. When the pool's
171 * estimate of good random bits falls to zero, the @getnoise@
172 * function is called, passing the pool handle as an argument.
173 * It is expected to increase the number of good bits by at
174 * least one, because it'll be called over and over again until
175 * there are enough bits to satisfy the caller. The @timer@
176 * function is called frequently throughout the generator's
177 * operation.
178 */
179
180 extern void rand_noisesrc(rand_pool */*r*/, const rand_source */*s*/);
181
182 /* --- @rand_seed@ --- *
183 *
184 * Arguments: @rand_pool *r@ = pointer to a randomness pool
185 * @unsigned bits@ = number of bits to ensure
186 *
187 * Returns: ---
188 *
189 * Use: Ensures that there are at least @bits@ good bits of entropy
190 * in the pool. It is recommended that you call this after
191 * initializing a new pool. Requesting @bits > RAND_IBITS@ is
192 * doomed to failure (and is an error).
193 */
194
195 extern void rand_seed(rand_pool */*r*/, unsigned /*bits*/);
196
197 /* --- @rand_key@ --- *
198 *
199 * Arguments: @rand_pool *r@ = pointer to a randomness pool
200 * @const void *k@ = pointer to key data
201 * @size_t sz@ = size of key data
202 *
203 * Returns: ---
204 *
205 * Use: Sets the secret key for a randomness pool. The key is used
206 * when mixing in new random bits.
207 */
208
209 extern void rand_key(rand_pool */*r*/, const void */*k*/, size_t /*sz*/);
210
211 /* --- @rand_add@ --- *
212 *
213 * Arguments: @rand_pool *r@ = pointer to a randomness pool
214 * @const void *p@ = pointer a buffer of data to add
215 * @size_t sz@ = size of the data buffer
216 * @unsigned goodbits@ = number of good bits estimated in buffer
217 *
218 * Returns: ---
219 *
220 * Use: Mixes the data in the buffer with the contents of the
221 * pool. The estimate of the number of good bits is added to
222 * the pool's own count. The mixing operation is not
223 * cryptographically strong. However, data in the input pool
224 * isn't output directly, only through the one-way gating
225 * operation, so that shouldn't matter.
226 */
227
228 extern void rand_add(rand_pool */*r*/,
229 const void */*p*/, size_t /*sz*/,
230 unsigned /*goodbits*/);
231
232 /* --- @rand_goodbits@ --- *
233 *
234 * Arguments: @rand_pool *r@ = pointer to a randomness pool
235 *
236 * Returns: Estimate of the number of good bits remaining in the pool.
237 */
238
239 extern unsigned rand_goodbits(rand_pool */*r*/);
240
241 /* --- @rand_gate@ --- *
242 *
243 * Arguments: @rand_pool *r@ = pointer to a randomness pool
244 *
245 * Returns: ---
246 *
247 * Use: Mixes up the entire state of the generator in a nonreversible
248 * way.
249 */
250
251 extern void rand_gate(rand_pool */*r*/);
252
253 /* --- @rand_stretch@ --- *
254 *
255 * Arguments: @rand_pool *r@ = pointer to a randomness pool
256 *
257 * Returns: ---
258 *
259 * Use: Stretches the contents of the output buffer by transforming
260 * it in a nonreversible way. This doesn't add any entropy
261 * worth speaking about, but it works well enough when the
262 * caller doesn't care about that sort of thing.
263 */
264
265 extern void rand_stretch(rand_pool */*r*/);
266
267 /* --- @rand_get@ --- *
268 *
269 * Arguments: @rand_pool *r@ = pointer to a randomness pool
270 * @void *p@ = pointer to output buffer
271 * @size_t sz@ = size of output buffer
272 *
273 * Returns: ---
274 *
275 * Use: Gets random data from the pool. The pool's contents can't be
276 * determined from the output of this function; nor can the
277 * output data be determined from a knowledge of the data input
278 * to the pool without also having knowledge of the secret key.
279 * The good bits counter is decremented, although no special
280 * action is taken if it reaches zero.
281 */
282
283 extern void rand_get(rand_pool */*r*/, void */*p*/, size_t /*sz*/);
284
285 /* --- @rand_getgood@ --- *
286 *
287 * Arguments: @rand_pool *r@ = pointer to a randomness pool
288 * @void *p@ = pointer to output buffer
289 * @size_t sz@ = size of output buffer
290 *
291 * Returns: ---
292 *
293 * Use: Gets random data from the pool. The pool's contents can't be
294 * determined from the output of this function; nor can the
295 * output data be determined from a knowledge of the data input
296 * to the pool wihtout also having knowledge of the secret key.
297 * If a noise source is attached to the pool in question, it is
298 * called to replenish the supply of good bits in the pool;
299 * otherwise this call is equivalent to @rand_get@.
300 */
301
302 extern void rand_getgood(rand_pool */*r*/, void */*p*/, size_t /*sz*/);
303
304 /*----- Generic random number generator interface -------------------------*/
305
306 /* --- Miscellaneous operations --- */
307
308 enum {
309 RAND_GATE = GRAND_SPECIFIC, /* No args */
310 RAND_STRETCH, /* No args */
311 RAND_KEY, /* @const void *k, size_t sz@ */
312 RAND_NOISESRC, /* @const rand_source *s@ */
313 RAND_SEED /* @unsigned bits@ */
314 };
315
316 /* --- Default random number generator --- */
317
318 extern grand rand_global;
319
320 /* --- @rand_create@ --- *
321 *
322 * Arguments: ---
323 *
324 * Returns: Pointer to a generic generator.
325 *
326 * Use: Constructs a generic generator interface over a Catacomb
327 * entropy pool generator.
328 */
329
330 extern grand *rand_create(void);
331
332 /*----- That's all, folks -------------------------------------------------*/
333
334 #ifdef __cplusplus
335 }
336 #endif
337
338 #endif