Generic interface.
[u/mdw/catacomb] / rand.h
CommitLineData
d03ab969 1/* -*-c-*-
2 *
dd985e0f 3 * $Id: rand.h,v 1.3 1999/10/15 21:04:30 mdw Exp $
d03ab969 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 $
dd985e0f 33 * Revision 1.3 1999/10/15 21:04:30 mdw
34 * Increase output buffer a bit for performance.
35 *
ba044e65 36 * Revision 1.2 1999/10/12 21:00:15 mdw
37 * Make pool and buffer sizes more sensible.
38 *
d03ab969 39 * Revision 1.1 1999/09/03 08:41:12 mdw
40 * Initial import.
41 *
42 */
43
44/*----- Notes on the random number generator ------------------------------*
45 *
46 * The algorithm is one of the author's own devising. It may therefore be
47 * worth a certain amount of skepticism. However, I've thought about this
48 * method for over a year before actually considering it worth implementing.
49 * With a little bit of luck, it should have received some peer review by the
50 * time this code is actually properly released, and it'll be worth a bit
51 * more confidence. My earlier generator was very similar in structure to
52 * the Linux /dev/random device. This generator is intended to address
53 * concerns I expressed about the Linux generator in a Usenet article to
54 * sci.crypt.
55 *
56 * The generator is divided into two parts: an input pool and an outpu
57 * buffer. New random data is placed into the pool in the way described
58 * below, which is shamelessly stolen from the Linux /dev/random generator.
59 * The only interaction that the pool has on the output buffer is through the
60 * keyed `gating' operation, which mixes up and redistributes all of the
61 * generator's state in an irreversible manner. Random bytes, when
62 * requested, are extracted from the output buffer in a linear fashion.
63 *
64 * The input pool is best seen as being eight shift registers in parallel.
65 * Data is added to the pool one octet at a time. Each bit of a new octet is
66 * added to a different shift register, by adding it (mod 2) with other bits
67 * according to the coefficients of a primitive polynomial. Each new byte is
68 * rotated before being added into the pool, in a half-hearted attempt to
69 * protect against biases in the input data (e.g., top bits being clear on
70 * ASCII text).
71 *
72 * The gating operation takes a keyed hash of the entire generator state,
73 * uses it as the key for a symmetric cipher, and encrypts the state. The
74 * key is then discarded. The result is that every ouptut bit of the
75 * operation depends in a complex way on every input bit, but the operation
76 * cannot be reversed.
77 *
78 * As an added wrinkle, 160 bits of the output buffer are never actually
79 * output. They are used in the gating operation only, as an extra item that
80 * an adversary has to guess before predicting generator output.
81 */
82
83#ifndef RAND_H
84#define RAND_H
85
86#ifdef __cplusplus
87 extern "C" {
88#endif
89
90/*----- Header files ------------------------------------------------------*/
91
92#include <stddef.h>
93
94#include "rmd160-hmac.h"
95
96/*----- Magic numbers -----------------------------------------------------*/
97
ba044e65 98#define RAND_POOLSZ 128 /* Input pool size in bytes */
dd985e0f 99#define RAND_BUFSZ 512 /* Output buffer size in bytes */
d03ab969 100#define RAND_SECSZ 20 /* Secret octets in output buffer */
101
102#define RAND_IBITS (RAND_POOLSZ * 8)
103#define RAND_OBITS (RAND_BUFSZ * 8)
104
105/*----- Data structures ---------------------------------------------------*/
106
107/* --- A random number generator pool --- */
108
109typedef struct rand_pool {
110 octet pool[RAND_POOLSZ]; /* Actual contents of the pool */
111 unsigned i; /* Current index into pool */
112 unsigned irot; /* Current rotation applied */
113 unsigned ibits; /* Number of good bits in pool */
114 octet buf[RAND_BUFSZ]; /* Random octet output buffer */
115 unsigned o; /* Current index into buffer */
116 unsigned obits; /* Number of good bits in buffer */
117 rmd160_mackey k; /* Secret key for this pool */
118 const struct rand_source *s; /* System-specific noise source */
119} rand_pool;
120
121#define RAND_GLOBAL ((rand_pool *)0) /* The global randomness pool */
122
123/* --- A noise source --- */
124
125typedef struct rand_source {
126 void (*getnoise)(rand_pool */*r*/); /* Acquire more noise */
127 int (*timer)(rand_pool */*r*/); /* Get noise from current time */
128} rand_source;
129
130/*----- Functions provided ------------------------------------------------*/
131
132/* --- @rand_init@ --- *
133 *
134 * Arguments: @rand_pool *r@ = pointer to a randomness pool
135 *
136 * Returns: ---
137 *
138 * Use: Initializes a randomness pool. The pool doesn't start out
139 * very random: that's your job to sort out.
140 */
141
142extern void rand_init(rand_pool */*r*/);
143
144/* --- @rand_noisesrc@ --- *
145 *
146 * Arguments: @rand_pool *r@ = pointer to a randomness pool
147 * @const rand_source *s@ = pointer to source definition
148 *
149 * Returns: ---
150 *
151 * Use: Sets a noise source for a randomness pool. When the pool's
152 * estimate of good random bits falls to zero, the @getnoise@
153 * function is called, passing the pool handle as an argument.
154 * It is expected to increase the number of good bits by at
155 * least one, because it'll be called over and over again until
156 * there are enough bits to satisfy the caller. The @timer@
157 * function is called frequently throughout the generator's
158 * operation.
159 */
160
161extern void rand_noisesrc(rand_pool */*r*/, const rand_source */*s*/);
162
163/* --- @rand_key@ --- *
164 *
165 * Arguments: @rand_pool *r@ = pointer to a randomness pool
166 * @const void *k@ = pointer to key data
167 * @size_t sz@ = size of key data
168 *
169 * Returns: ---
170 *
171 * Use: Sets the secret key for a randomness pool. The key is used
172 * when mixing in new random bits.
173 */
174
175extern void rand_key(rand_pool */*r*/, const void */*k*/, size_t /*sz*/);
176
177/* --- @rand_add@ --- *
178 *
179 * Arguments: @rand_pool *r@ = pointer to a randomness pool
180 * @const void *p@ = pointer a buffer of data to add
181 * @size_t sz@ = size of the data buffer
182 * @unsigned goodbits@ = number of good bits estimated in buffer
183 *
184 * Returns: ---
185 *
186 * Use: Mixes the data in the buffer with the contents of the
187 * pool. The estimate of the number of good bits is added to
188 * the pool's own count. The mixing operation is not
189 * cryptographically strong. However, data in the input pool
190 * isn't output directly, only through the one-way gating
191 * operation, so that shouldn't matter.
192 */
193
194extern void rand_add(rand_pool */*r*/,
195 const void */*p*/, size_t /*sz*/,
196 unsigned /*goodbits*/);
197
198/* --- @rand_goodbits@ --- *
199 *
200 * Arguments: @rand_pool *r@ = pointer to a randomness pool
201 *
202 * Returns: Estimate of the number of good bits remaining in the pool.
203 */
204
205extern unsigned rand_goodbits(rand_pool */*r*/);
206
207/* --- @rand_gate@ --- *
208 *
209 * Arguments: @rand_pool *r@ = pointer to a randomness pool
210 *
211 * Returns: ---
212 *
213 * Use: Mixes up the entire state of the generator in a nonreversible
214 * way.
215 */
216
217extern void rand_gate(rand_pool */*r*/);
218
219/* --- @rand_stretch@ --- *
220 *
221 * Arguments: @rand_pool *r@ = pointer to a randomness pool
222 *
223 * Returns: ---
224 *
225 * Use: Stretches the contents of the output buffer by transforming
226 * it in a nonreversible way. This doesn't add any entropy
227 * worth speaking about, but it works well enough when the
228 * caller doesn't care about that sort of thing.
229 */
230
231extern void rand_stretch(rand_pool */*r*/);
232
233/* --- @rand_get@ --- *
234 *
235 * Arguments: @rand_pool *r@ = pointer to a randomness pool
236 * @void *p@ = pointer to output buffer
237 * @size_t sz@ = size of output buffer
238 *
239 * Returns: ---
240 *
241 * Use: Gets random data from the pool. The pool's contents can't be
242 * determined from the output of this function; nor can the
243 * output data be determined from a knowledge of the data input
244 * to the pool wihtout also having knowledge of the secret key.
245 * The good bits counter is decremented, although no special
246 * action is taken if it reaches zero.
247 */
248
249extern void rand_get(rand_pool */*r*/, void */*p*/, size_t /*sz*/);
250
251/* --- @rand_getgood@ --- *
252 *
253 * Arguments: @rand_pool *r@ = pointer to a randomness pool
254 * @void *p@ = pointer to output buffer
255 * @size_t sz@ = size of output buffer
256 *
257 * Returns: ---
258 *
259 * Use: Gets random data from the pool. The pool's contents can't be
260 * determined from the output of this function; nor can the
261 * output data be determined from a knowledge of the data input
262 * to the pool wihtout also having knowledge of the secret key.
263 * If a noise source is attached to the pool in question, it is
264 * called to replenish the supply of good bits in the pool;
265 * otherwise this call is equivalent to @rand_get@.
266 */
267
268extern void rand_getgood(rand_pool */*r*/, void */*p*/, size_t /*sz*/);
269
270/*----- That's all, folks -------------------------------------------------*/
271
272#ifdef __cplusplus
273 }
274#endif
275
276#endif