chiark / gitweb /
Add some more vectors, and a whinge about how Skipjack test vectors are.
[catacomb] / rand.h
1 /* -*-c-*-
2  *
3  * $Id: rand.h,v 1.6 2000/06/17 11:53:38 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.6  2000/06/17 11:53:38  mdw
34  * Deprecate `rand_getgood'.  Provide a new interface to ensure that a pool
35  * is well seeded.
36  *
37  * Revision 1.5  1999/12/13 15:34:15  mdw
38  * Fix a typo.
39  *
40  * Revision 1.4  1999/12/10 23:29:48  mdw
41  * Change header file guard names.
42  *
43  * Revision 1.3  1999/10/15 21:04:30  mdw
44  * Increase output buffer a bit for performance.
45  *
46  * Revision 1.2  1999/10/12 21:00:15  mdw
47  * Make pool and buffer sizes more sensible.
48  *
49  * Revision 1.1  1999/09/03 08:41:12  mdw
50  * Initial import.
51  *
52  */
53
54 /*----- Notes on the random number generator ------------------------------*
55  *
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
64  * sci.crypt.
65  *
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.
73  *
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
80  * ASCII text).
81  *
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
86  * cannot be reversed.
87  *
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.
91  */
92
93 #ifndef CATACOMB_RAND_H
94 #define CATACOMB_RAND_H
95
96 #ifdef __cplusplus
97   extern "C" {
98 #endif
99
100 /*----- Header files ------------------------------------------------------*/
101
102 #include <stddef.h>
103
104 #ifndef CATACOMB_GRAND_H
105 #  include "grand.h"
106 #endif
107
108 #ifndef CATACOMB_RMD160_HMAC_H
109 #  include "rmd160-hmac.h"
110 #endif
111
112 /*----- Magic numbers -----------------------------------------------------*/
113
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 */
117
118 #define RAND_IBITS (RAND_POOLSZ * 8)
119 #define RAND_OBITS (RAND_BUFSZ * 8)
120
121 /*----- Data structures ---------------------------------------------------*/
122
123 /* --- A random number generator pool --- */
124
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 */
135 } rand_pool;
136
137 #define RAND_GLOBAL ((rand_pool *)0)    /* The global randomness pool */
138
139 /* --- A noise source --- */
140
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 */
144 } rand_source;
145
146 /*----- Functions provided ------------------------------------------------*/
147
148 /* --- @rand_init@ --- *
149  *
150  * Arguments:   @rand_pool *r@ = pointer to a randomness pool
151  *
152  * Returns:     ---
153  *
154  * Use:         Initializes a randomness pool.  The pool doesn't start out
155  *              very random: that's your job to sort out.
156  */
157
158 extern void rand_init(rand_pool */*r*/);
159
160 /* --- @rand_noisesrc@ --- *
161  *
162  * Arguments:   @rand_pool *r@ = pointer to a randomness pool
163  *              @const rand_source *s@ = pointer to source definition
164  *
165  * Returns:     ---
166  *
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
174  *              operation.
175  */
176
177 extern void rand_noisesrc(rand_pool */*r*/, const rand_source */*s*/);
178
179 /* --- @rand_seed@ --- *
180  *
181  * Arguments:   @rand_pool *r@ = pointer to a randomness pool
182  *              @unsigned bits@ = number of bits to ensure
183  *
184  * Returns:     ---
185  *
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).
190  */
191
192 extern void rand_seed(rand_pool */*r*/, unsigned /*bits*/);
193
194 /* --- @rand_key@ --- *
195  *
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
199  *
200  * Returns:     ---
201  *
202  * Use:         Sets the secret key for a randomness pool.  The key is used
203  *              when mixing in new random bits.
204  */
205
206 extern void rand_key(rand_pool */*r*/, const void */*k*/, size_t /*sz*/);
207
208 /* --- @rand_add@ --- *
209  *
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
214  *
215  * Returns:     ---
216  *
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.
223  */
224
225 extern void rand_add(rand_pool */*r*/,
226                      const void */*p*/, size_t /*sz*/,
227                      unsigned /*goodbits*/);
228
229 /* --- @rand_goodbits@ --- *
230  *
231  * Arguments:   @rand_pool *r@ = pointer to a randomness pool
232  *
233  * Returns:     Estimate of the number of good bits remaining in the pool.
234  */
235
236 extern unsigned rand_goodbits(rand_pool */*r*/);
237
238 /* --- @rand_gate@ --- *
239  *
240  * Arguments:   @rand_pool *r@ = pointer to a randomness pool
241  *
242  * Returns:     ---
243  *
244  * Use:         Mixes up the entire state of the generator in a nonreversible
245  *              way.
246  */
247
248 extern void rand_gate(rand_pool */*r*/);
249
250 /* --- @rand_stretch@ --- *
251  *
252  * Arguments:   @rand_pool *r@ = pointer to a randomness pool
253  *
254  * Returns:     ---
255  *
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.
260  */
261
262 extern void rand_stretch(rand_pool */*r*/);
263
264 /* --- @rand_get@ --- *
265  *
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
269  *
270  * Returns:     ---
271  *
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.
278  */
279
280 extern void rand_get(rand_pool */*r*/, void */*p*/, size_t /*sz*/);
281
282 /* --- @rand_getgood@ --- *
283  *
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
287  *
288  * Returns:     ---
289  *
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@.
297  */
298
299 extern void rand_getgood(rand_pool */*r*/, void */*p*/, size_t /*sz*/);
300
301 /*----- Generic random number generator interface -------------------------*/
302
303 /* --- Miscellaneous operations --- */
304
305 enum {
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@ */
311 };
312
313 /* --- Default random number generator --- */
314
315 extern grand rand_global;
316
317 /* --- @rand_create@ --- *
318  *
319  * Arguments:   ---
320  *
321  * Returns:     Pointer to a generic generator.
322  *
323  * Use:         Constructs a generic generator interface over a Catacomb
324  *              entropy pool generator.
325  */
326
327 extern grand *rand_create(void);
328
329 /*----- That's all, folks -------------------------------------------------*/
330
331 #ifdef __cplusplus
332   }
333 #endif
334
335 #endif