f0666aaf160b7f8a54964d8c544b91fc3682dd7d
[silc.git] / lib / silccrypt / silcrng.h
1 /*
2
3   silcrng.h
4  
5   COPYRIGHT
6  
7   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
8  
9   Copyright (C) 1997 - 2001 Pekka Riikonen
10  
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 2 of the License, or
14   (at your option) any later version.
15  
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20  
21 */
22
23 /****h* silccrypt/SilcRNGAPI
24  *
25  * DESCRIPTION
26  *
27  * SILC Random Number Generator is cryptographically strong pseudo random
28  * number generator. It is used to generate all the random numbers needed
29  * in the SILC sessions. All key material and other sources needing random
30  * numbers use this generator.
31  *
32  * The RNG has a random pool of 1024 bytes of size that provides the actual
33  * random numbers for the application. The pool is initialized when the
34  * RNG is allocated and initialized with silc_rng_alloc and silc_rng_init
35  * functions, respectively. 
36  *
37  *
38  * Random Pool Initialization
39  *
40  * The RNG's random pool is the source of all random output data. The pool is
41  * initialized with silc_rng_init and application can reseed it at any time
42  * by calling the silc_rng_add_noise function.
43  *
44  * The initializing phase attempts to set the random pool in a state that it
45  * is impossible to learn the input data to the RNG or any random output
46  * data. This is achieved by acquiring noise from various system sources. The
47  * first source is called to provide "soft noise". This noise is various
48  * data from system's processes. The second source is called to provide
49  * "medium noise". This noise is various output data from executed commands.
50  * Usually the commands are Unix `ps' and `ls' commands with various options.
51  * The last source is called to provide "hard noise" and is noise from
52  * system's /dev/random, if it exists.
53  *
54  *
55  * Stirring the Random Pool
56  *
57  * Every time data is acquired from any source, the pool is stirred. The
58  * stirring process performs an CFB (cipher feedback) encryption with SHA1
59  * algorithm to the entire random pool. First it acquires an IV (Initial
60  * Vector) from the constant location of the pool and performs the first CFB
61  * pass. Then it acquires a new encryption key from variable location of the
62  * pool and performs the second CFB pass. The encryption key thus is always
63  * acquired from unguessable data.
64  *
65  * The encryption process to the entire random pool assures that it is
66  * impossible to learn the input data to the random pool without breaking the
67  * encryption process. This would effectively mean breaking the SHA1 hash
68  * function. The encryption process also assures that each random output from
69  * the random pool is secured with cryptographically strong function, the
70  * SHA1 in this case.
71  *
72  * The random pool can be restirred by the application at any point by
73  * calling the silc_rng_add_noise function. This function adds new noise to
74  * the pool and then stirs the entire pool.
75  *
76  *
77  * Stirring Threshholds
78  *
79  * The random pool has two threshholds that controls when the random pool
80  * needs more new noise and requires restirring. As previously mentioned, the
81  * application may do this by calling the silc_rng_add_noise. However, the
82  * RNG performs this also automatically.
83  *
84  * The first threshhold gets soft noise from system and stirs the random pool.
85  * The threshhold is reached after 64 bits of random data has been fetched
86  * from the RNG. After the 64 bits, the soft noise acquiring and restirring
87  * process is performed every 8 bits of random output data until the second
88  * threshhold is reached.
89  *
90  * The second threshhold gets hard noise from system and stirs the random
91  * pool. The threshhold is reached after 160 bits of random output. After the
92  * noise is acquired (from /dev/random) the random pool is stirred and the
93  * threshholds are set to zero. The process is repeated again after 64 bits of
94  * output for first threshhold and after 160 bits of output for the second
95  * threshhold.
96  *
97  *
98  * Internal State of the Random Pool
99  *
100  * The random pool has also internal state that provides several variable
101  * distinct points to the random pool where the data is fetched. The state
102  * changes every 8 bits of output data and it is guaranteed that the fetched
103  * 8 bits of data is from distinct location compared to the previous 8 bits.
104  * It is also guaranteed that the internal state never wraps before
105  * restirring the entire random pool. The internal state means that the data
106  * is not fetched linearly from the pool, eg. starting from zero and wrapping
107  * at the end of the pool. The internal state is not dependent of any random
108  * data in the pool. The internal states are initialized (by default the pool
109  * is splitted to four different sections (states)) at the RNG
110  * initialization phase. The state's current position is added linearly and
111  * wraps at the the start of the next state. The states provides the distinct
112  * locations.
113  *
114  *
115  * Security Considerations
116  *
117  * The security of this random number generator, like of any other RNG's,
118  * depends of the initial state of the RNG. The initial state of the random
119  * number generators must be unknown to an adversary. This means that after
120  * the RNG is initialized it is required that the input data to the RNG and
121  * the output data to the application has no correlation of any kind that
122  * could be used to compromise the acquired random numbers or any future
123  * random numbers. 
124  *
125  * It is, however, clear that the correlation exists but it needs to be
126  * hard to solve for an adversary. To accomplish this the input data to the
127  * random number generator needs to be secret. Usually this is impossible to
128  * achieve. That is why SILC's RNG acquires the noise from three different
129  * sources and provides for the application an interface to add more noise at
130  * any time. The first source ("soft noise") is known to the adversary but
131  * requires exact timing to get all of the input data. However, getting only
132  * partial data is easy. The second source ("medium noise") depends on the
133  * place of execution of the application. Getting at least partial data is
134  * easy but securing for example the user's home directory from outside access
135  * makes it harder. The last source ("hard noise") is considered to be the
136  * most secure source of data. An adversary is not considered to have any
137  * access on this data. This of course greatly depends on the operating system.
138  *
139  * These three sources are considered to be adequate since the random pool is
140  * relatively large and the output of each bit of the random pool is secured
141  * by cryptographically secure function, the SHA1 in CFB mode encryption.
142  * Furthermore the application may provide other random data, such as random
143  * key strokes or mouse movement to the RNG. However, it is recommended that
144  * the application would not be the single point of source for the RNG, in
145  * either intializing or reseeding phases later in the session. Good solution
146  * is probably to use both, the application's seeds and the RNG's own
147  * sources, equally.
148  *
149  * The RNG must also assure that any old or future random numbers are not
150  * compromised if an adversary would learn the initial input data (or any
151  * input data for that matter). The SILC's RNG provides good protection for
152  * this even if the some of the input bits would be compromised for old or
153  * future random numbers. The RNG reinitalizes (reseeds) itself using the
154  * threshholds after every 64 and 160 bits of output. This is considered to be
155  * adequate even if some of the bits would get compromised. Also, the
156  * applications that use the RNG usually fetches at least 256 bits from the
157  * RNG. This means that everytime RNG is accessed both of the threshholds are
158  * reached. This should mean that the RNG is never too long in an compromised
159  * state and recovers as fast as possible.
160  *
161  * Currently the SILC's RNG does not use random seed files to store some
162  * random data for future initializing. This is important and must be
163  * implemented in the future.
164  *
165  * The caller must be cautios when using this RNG with native WIN32 system.
166  * The RNG most likely is impossible to set in unguessable state just by
167  * using the RNG's input data sources.  On WIN32 it is stronly suggested
168  * that caller would add more random noise after the initialization of the
169  * RNG using the silc_rng_add_noise function.  For example, random mouse
170  * movements may be used.
171  *
172  ***/
173
174 #ifndef SILCRNG_H
175 #define SILCRNG_H
176
177 /* Forward declaration. Actual object is in source file. */
178 typedef struct SilcRngObjectStruct *SilcRng;
179
180 /* Prototypes */
181 SilcRng silc_rng_alloc();
182 void silc_rng_free(SilcRng rng);
183 void silc_rng_init(SilcRng rng);
184 unsigned char silc_rng_get_byte(SilcRng rng);
185 uint16 silc_rng_get_rn16(SilcRng rng);
186 uint32 silc_rng_get_rn32(SilcRng rng);
187 unsigned char *silc_rng_get_rn_string(SilcRng rng, uint32 len);
188 unsigned char *silc_rng_get_rn_data(SilcRng rng, uint32 len);
189 void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, uint32 len);
190
191 int silc_rng_global_init(SilcRng rng);
192 int silc_rng_global_uninit();
193 unsigned char silc_rng_global_get_byte();
194 uint16 silc_rng_global_get_rn16();
195 uint32 silc_rng_global_get_rn32();
196 unsigned char *silc_rng_global_get_rn_string(uint32 len);
197 unsigned char *silc_rng_global_get_rn_data(uint32 len);
198 void silc_rng_global_add_noise(unsigned char *buffer, uint32 len);
199
200 #endif