3 * $Id: rand.h,v 1.6 2000/06/17 11:53:38 mdw Exp $
5 * Secure random number generator
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Revision history --------------------------------------------------*
33 * Revision 1.6 2000/06/17 11:53:38 mdw
34 * Deprecate `rand_getgood'. Provide a new interface to ensure that a pool
37 * Revision 1.5 1999/12/13 15:34:15 mdw
40 * Revision 1.4 1999/12/10 23:29:48 mdw
41 * Change header file guard names.
43 * Revision 1.3 1999/10/15 21:04:30 mdw
44 * Increase output buffer a bit for performance.
46 * Revision 1.2 1999/10/12 21:00:15 mdw
47 * Make pool and buffer sizes more sensible.
49 * Revision 1.1 1999/09/03 08:41:12 mdw
54 /*----- Notes on the random number generator ------------------------------*
56 * The algorithm is one of the author's own devising. It may therefore be
57 * worth a certain amount of skepticism. However, I've thought about this
58 * method for over a year before actually considering it worth implementing.
59 * With a little bit of luck, it should have received some peer review by the
60 * time this code is actually properly released, and it'll be worth a bit
61 * more confidence. My earlier generator was very similar in structure to
62 * the Linux /dev/random device. This generator is intended to address
63 * concerns I expressed about the Linux generator in a Usenet article to
66 * The generator is divided into two parts: an input pool and an output
67 * buffer. New random data is placed into the pool in the way described
68 * below, which is shamelessly stolen from the Linux /dev/random generator.
69 * The only interaction that the pool has on the output buffer is through the
70 * keyed `gating' operation, which mixes up and redistributes all of the
71 * generator's state in an irreversible manner. Random bytes, when
72 * requested, are extracted from the output buffer in a linear fashion.
74 * The input pool is best seen as being eight shift registers in parallel.
75 * Data is added to the pool one octet at a time. Each bit of a new octet is
76 * added to a different shift register, by adding it (mod 2) with other bits
77 * according to the coefficients of a primitive polynomial. Each new byte is
78 * rotated before being added into the pool, in a half-hearted attempt to
79 * protect against biases in the input data (e.g., top bits being clear on
82 * The gating operation takes a keyed hash of the entire generator state,
83 * uses it as the key for a symmetric cipher, and encrypts the state. The
84 * key is then discarded. The result is that every ouptut bit of the
85 * operation depends in a complex way on every input bit, but the operation
88 * As an added wrinkle, 160 bits of the output buffer are never actually
89 * output. They are used in the gating operation only, as an extra item that
90 * an adversary has to guess before predicting generator output.
93 #ifndef CATACOMB_RAND_H
94 #define CATACOMB_RAND_H
100 /*----- Header files ------------------------------------------------------*/
104 #ifndef CATACOMB_GRAND_H
108 #ifndef CATACOMB_RMD160_HMAC_H
109 # include "rmd160-hmac.h"
112 /*----- Magic numbers -----------------------------------------------------*/
114 #define RAND_POOLSZ 128 /* Input pool size in bytes */
115 #define RAND_BUFSZ 512 /* Output buffer size in bytes */
116 #define RAND_SECSZ 20 /* Secret octets in output buffer */
118 #define RAND_IBITS (RAND_POOLSZ * 8)
119 #define RAND_OBITS (RAND_BUFSZ * 8)
121 /*----- Data structures ---------------------------------------------------*/
123 /* --- A random number generator pool --- */
125 typedef struct rand_pool
{
126 octet pool
[RAND_POOLSZ
]; /* Actual contents of the pool */
127 unsigned i
; /* Current index into pool */
128 unsigned irot
; /* Current rotation applied */
129 unsigned ibits
; /* Number of good bits in pool */
130 octet buf
[RAND_BUFSZ
]; /* Random octet output buffer */
131 unsigned o
; /* Current index into buffer */
132 unsigned obits
; /* Number of good bits in buffer */
133 rmd160_mackey k
; /* Secret key for this pool */
134 const struct rand_source
*s
; /* System-specific noise source */
137 #define RAND_GLOBAL ((rand_pool *)0) /* The global randomness pool */
139 /* --- A noise source --- */
141 typedef struct rand_source
{
142 void (*getnoise
)(rand_pool */
*r*/
); /* Acquire more noise */
143 int (*timer
)(rand_pool */
*r*/
); /* Get noise from current time */
146 /*----- Functions provided ------------------------------------------------*/
148 /* --- @rand_init@ --- *
150 * Arguments: @rand_pool *r@ = pointer to a randomness pool
154 * Use: Initializes a randomness pool. The pool doesn't start out
155 * very random: that's your job to sort out.
158 extern void rand_init(rand_pool */
*r*/
);
160 /* --- @rand_noisesrc@ --- *
162 * Arguments: @rand_pool *r@ = pointer to a randomness pool
163 * @const rand_source *s@ = pointer to source definition
167 * Use: Sets a noise source for a randomness pool. When the pool's
168 * estimate of good random bits falls to zero, the @getnoise@
169 * function is called, passing the pool handle as an argument.
170 * It is expected to increase the number of good bits by at
171 * least one, because it'll be called over and over again until
172 * there are enough bits to satisfy the caller. The @timer@
173 * function is called frequently throughout the generator's
177 extern void rand_noisesrc(rand_pool */
*r*/
, const rand_source */
*s*/
);
179 /* --- @rand_seed@ --- *
181 * Arguments: @rand_pool *r@ = pointer to a randomness pool
182 * @unsigned bits@ = number of bits to ensure
186 * Use: Ensures that there are at least @bits@ good bits of entropy
187 * in the pool. It is recommended that you call this after
188 * initializing a new pool. Requesting @bits > RAND_IBITS@ is
189 * doomed to failure (and is an error).
192 extern void rand_seed(rand_pool */
*r*/
, unsigned /*bits*/);
194 /* --- @rand_key@ --- *
196 * Arguments: @rand_pool *r@ = pointer to a randomness pool
197 * @const void *k@ = pointer to key data
198 * @size_t sz@ = size of key data
202 * Use: Sets the secret key for a randomness pool. The key is used
203 * when mixing in new random bits.
206 extern void rand_key(rand_pool */
*r*/
, const void */
*k*/
, size_t /*sz*/);
208 /* --- @rand_add@ --- *
210 * Arguments: @rand_pool *r@ = pointer to a randomness pool
211 * @const void *p@ = pointer a buffer of data to add
212 * @size_t sz@ = size of the data buffer
213 * @unsigned goodbits@ = number of good bits estimated in buffer
217 * Use: Mixes the data in the buffer with the contents of the
218 * pool. The estimate of the number of good bits is added to
219 * the pool's own count. The mixing operation is not
220 * cryptographically strong. However, data in the input pool
221 * isn't output directly, only through the one-way gating
222 * operation, so that shouldn't matter.
225 extern void rand_add(rand_pool */
*r*/
,
226 const void */
*p*/
, size_t /*sz*/,
227 unsigned /*goodbits*/);
229 /* --- @rand_goodbits@ --- *
231 * Arguments: @rand_pool *r@ = pointer to a randomness pool
233 * Returns: Estimate of the number of good bits remaining in the pool.
236 extern unsigned rand_goodbits(rand_pool */
*r*/
);
238 /* --- @rand_gate@ --- *
240 * Arguments: @rand_pool *r@ = pointer to a randomness pool
244 * Use: Mixes up the entire state of the generator in a nonreversible
248 extern void rand_gate(rand_pool */
*r*/
);
250 /* --- @rand_stretch@ --- *
252 * Arguments: @rand_pool *r@ = pointer to a randomness pool
256 * Use: Stretches the contents of the output buffer by transforming
257 * it in a nonreversible way. This doesn't add any entropy
258 * worth speaking about, but it works well enough when the
259 * caller doesn't care about that sort of thing.
262 extern void rand_stretch(rand_pool */
*r*/
);
264 /* --- @rand_get@ --- *
266 * Arguments: @rand_pool *r@ = pointer to a randomness pool
267 * @void *p@ = pointer to output buffer
268 * @size_t sz@ = size of output buffer
272 * Use: Gets random data from the pool. The pool's contents can't be
273 * determined from the output of this function; nor can the
274 * output data be determined from a knowledge of the data input
275 * to the pool without also having knowledge of the secret key.
276 * The good bits counter is decremented, although no special
277 * action is taken if it reaches zero.
280 extern void rand_get(rand_pool */
*r*/
, void */
*p*/
, size_t /*sz*/);
282 /* --- @rand_getgood@ --- *
284 * Arguments: @rand_pool *r@ = pointer to a randomness pool
285 * @void *p@ = pointer to output buffer
286 * @size_t sz@ = size of output buffer
290 * Use: Gets random data from the pool. The pool's contents can't be
291 * determined from the output of this function; nor can the
292 * output data be determined from a knowledge of the data input
293 * to the pool wihtout also having knowledge of the secret key.
294 * If a noise source is attached to the pool in question, it is
295 * called to replenish the supply of good bits in the pool;
296 * otherwise this call is equivalent to @rand_get@.
299 extern void rand_getgood(rand_pool */
*r*/
, void */
*p*/
, size_t /*sz*/);
301 /*----- Generic random number generator interface -------------------------*/
303 /* --- Miscellaneous operations --- */
306 RAND_GATE
= GRAND_SPECIFIC
, /* No args */
307 RAND_STRETCH
, /* No args */
308 RAND_KEY
, /* @const void *k, size_t sz@ */
309 RAND_NOISESRC
, /* @const rand_source *s@ */
310 RAND_SEED
, /* @unsigned bits@ */
313 /* --- Default random number generator --- */
315 extern grand rand_global
;
317 /* --- @rand_create@ --- *
321 * Returns: Pointer to a generic generator.
323 * Use: Constructs a generic generator interface over a Catacomb
324 * entropy pool generator.
327 extern grand
*rand_create(void);
329 /*----- That's all, folks -------------------------------------------------*/