diff options
Diffstat (limited to 'linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/random.c')
-rw-r--r--[-rwxr-xr-x] | linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/random.c | 2372 |
1 files changed, 1186 insertions, 1186 deletions
diff --git a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/random.c b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/random.c index f31d8b0..907f95e 100755..100644 --- a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/random.c +++ b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/random.c | |||
@@ -1,1186 +1,1186 @@ | |||
1 | /* random.c - random number generator | 1 | /* random.c - random number generator |
2 | * Copyright (C) 1998, 2000, 2001, 2002, 2003, | 2 | * Copyright (C) 1998, 2000, 2001, 2002, 2003, |
3 | * 2004, 2005 Free Software Foundation, Inc. | 3 | * 2004, 2005 Free Software Foundation, Inc. |
4 | * | 4 | * |
5 | * This file is part of Libgcrypt. | 5 | * This file is part of Libgcrypt. |
6 | * | 6 | * |
7 | * Libgcrypt is free software; you can redistribute it and/or modify | 7 | * Libgcrypt is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU Lesser General Public License as | 8 | * it under the terms of the GNU Lesser General Public License as |
9 | * published by the Free Software Foundation; either version 2.1 of | 9 | * published by the Free Software Foundation; either version 2.1 of |
10 | * the License, or (at your option) any later version. | 10 | * the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * Libgcrypt is distributed in the hope that it will be useful, | 12 | * Libgcrypt is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU Lesser General Public License for more details. | 15 | * GNU Lesser General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU Lesser General Public | 17 | * You should have received a copy of the GNU Lesser General Public |
18 | * License along with this program; if not, write to the Free Software | 18 | * License along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | /**************** | 22 | /**************** |
23 | * This random number generator is modelled after the one described in | 23 | * This random number generator is modelled after the one described in |
24 | * Peter Gutmann's paper: "Software Generation of Practically Strong | 24 | * Peter Gutmann's paper: "Software Generation of Practically Strong |
25 | * Random Numbers". See also chapter 6 in his book "Cryptographic | 25 | * Random Numbers". See also chapter 6 in his book "Cryptographic |
26 | * Security Architecture", New York, 2004, ISBN 0-387-95387-6. | 26 | * Security Architecture", New York, 2004, ISBN 0-387-95387-6. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | 29 | ||
30 | #include <config.h> | 30 | #include <config.h> |
31 | #include <stdio.h> | 31 | #include <stdio.h> |
32 | #include <stdlib.h> | 32 | #include <stdlib.h> |
33 | #include <assert.h> | 33 | #include <assert.h> |
34 | #include <errno.h> | 34 | #include <errno.h> |
35 | #include <string.h> | 35 | #include <string.h> |
36 | #include <sys/time.h> | 36 | #include <sys/time.h> |
37 | #include <sys/types.h> | 37 | #include <sys/types.h> |
38 | #include <sys/stat.h> | 38 | #include <sys/stat.h> |
39 | #include <unistd.h> | 39 | #include <unistd.h> |
40 | #include <fcntl.h> | 40 | #include <fcntl.h> |
41 | #include <time.h> | 41 | #include <time.h> |
42 | #ifdef HAVE_GETHRTIME | 42 | #ifdef HAVE_GETHRTIME |
43 | #include <sys/times.h> | 43 | #include <sys/times.h> |
44 | #endif | 44 | #endif |
45 | #ifdef HAVE_GETTIMEOFDAY | 45 | #ifdef HAVE_GETTIMEOFDAY |
46 | #include <sys/times.h> | 46 | #include <sys/times.h> |
47 | #endif | 47 | #endif |
48 | #ifdef HAVE_GETRUSAGE | 48 | #ifdef HAVE_GETRUSAGE |
49 | #include <sys/resource.h> | 49 | #include <sys/resource.h> |
50 | #endif | 50 | #endif |
51 | #ifdef __MINGW32__ | 51 | #ifdef __MINGW32__ |
52 | #include <process.h> | 52 | #include <process.h> |
53 | #endif | 53 | #endif |
54 | #include "g10lib.h" | 54 | #include "g10lib.h" |
55 | #include "rmd.h" | 55 | #include "rmd.h" |
56 | #include "random.h" | 56 | #include "random.h" |
57 | #include "rand-internal.h" | 57 | #include "rand-internal.h" |
58 | #include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */ | 58 | #include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */ |
59 | #include "ath.h" | 59 | #include "ath.h" |
60 | 60 | ||
61 | #ifndef RAND_MAX /* for SunOS */ | 61 | #ifndef RAND_MAX /* for SunOS */ |
62 | #define RAND_MAX 32767 | 62 | #define RAND_MAX 32767 |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | 65 | ||
66 | #if SIZEOF_UNSIGNED_LONG == 8 | 66 | #if SIZEOF_UNSIGNED_LONG == 8 |
67 | #define ADD_VALUE 0xa5a5a5a5a5a5a5a5 | 67 | #define ADD_VALUE 0xa5a5a5a5a5a5a5a5 |
68 | #elif SIZEOF_UNSIGNED_LONG == 4 | 68 | #elif SIZEOF_UNSIGNED_LONG == 4 |
69 | #define ADD_VALUE 0xa5a5a5a5 | 69 | #define ADD_VALUE 0xa5a5a5a5 |
70 | #else | 70 | #else |
71 | #error weird size for an unsigned long | 71 | #error weird size for an unsigned long |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | #define BLOCKLEN 64 /* hash this amount of bytes */ | 74 | #define BLOCKLEN 64 /* hash this amount of bytes */ |
75 | #define DIGESTLEN 20 /* into a digest of this length (rmd160) */ | 75 | #define DIGESTLEN 20 /* into a digest of this length (rmd160) */ |
76 | /* poolblocks is the number of digests which make up the pool | 76 | /* poolblocks is the number of digests which make up the pool |
77 | * and poolsize must be a multiple of the digest length | 77 | * and poolsize must be a multiple of the digest length |
78 | * to make the AND operations faster, the size should also be | 78 | * to make the AND operations faster, the size should also be |
79 | * a multiple of ulong | 79 | * a multiple of ulong |
80 | */ | 80 | */ |
81 | #define POOLBLOCKS 30 | 81 | #define POOLBLOCKS 30 |
82 | #define POOLSIZE (POOLBLOCKS*DIGESTLEN) | 82 | #define POOLSIZE (POOLBLOCKS*DIGESTLEN) |
83 | #if (POOLSIZE % SIZEOF_UNSIGNED_LONG) | 83 | #if (POOLSIZE % SIZEOF_UNSIGNED_LONG) |
84 | #error Please make sure that poolsize is a multiple of ulong | 84 | #error Please make sure that poolsize is a multiple of ulong |
85 | #endif | 85 | #endif |
86 | #define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG) | 86 | #define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG) |
87 | 87 | ||
88 | 88 | ||
89 | static int is_initialized; | 89 | static int is_initialized; |
90 | #define MASK_LEVEL(a) do { (a) &= 3; } while(0) | 90 | #define MASK_LEVEL(a) do { (a) &= 3; } while(0) |
91 | static unsigned char *rndpool; /* allocated size is POOLSIZE+BLOCKLEN */ | 91 | static unsigned char *rndpool; /* allocated size is POOLSIZE+BLOCKLEN */ |
92 | static unsigned char *keypool; /* allocated size is POOLSIZE+BLOCKLEN */ | 92 | static unsigned char *keypool; /* allocated size is POOLSIZE+BLOCKLEN */ |
93 | static size_t pool_readpos; | 93 | static size_t pool_readpos; |
94 | static size_t pool_writepos; | 94 | static size_t pool_writepos; |
95 | static int pool_filled; | 95 | static int pool_filled; |
96 | static int pool_balance; | 96 | static int pool_balance; |
97 | static int just_mixed; | 97 | static int just_mixed; |
98 | static int did_initial_extra_seeding; | 98 | static int did_initial_extra_seeding; |
99 | static char *seed_file_name; | 99 | static char *seed_file_name; |
100 | static int allow_seed_file_update; | 100 | static int allow_seed_file_update; |
101 | 101 | ||
102 | static int secure_alloc; | 102 | static int secure_alloc; |
103 | static int quick_test; | 103 | static int quick_test; |
104 | static int faked_rng; | 104 | static int faked_rng; |
105 | 105 | ||
106 | static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER; | 106 | static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER; |
107 | static int pool_is_locked; /* only used for assertion */ | 107 | static int pool_is_locked; /* only used for assertion */ |
108 | 108 | ||
109 | static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER; | 109 | static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER; |
110 | 110 | ||
111 | static byte *get_random_bytes( size_t nbytes, int level, int secure ); | 111 | static byte *get_random_bytes( size_t nbytes, int level, int secure ); |
112 | static void read_pool( byte *buffer, size_t length, int level ); | 112 | static void read_pool( byte *buffer, size_t length, int level ); |
113 | static void add_randomness( const void *buffer, size_t length, int source ); | 113 | static void add_randomness( const void *buffer, size_t length, int source ); |
114 | static void random_poll(void); | 114 | static void random_poll(void); |
115 | static void do_fast_random_poll (void); | 115 | static void do_fast_random_poll (void); |
116 | static void read_random_source( int requester, size_t length, int level); | 116 | static void read_random_source( int requester, size_t length, int level); |
117 | static int gather_faked( void (*add)(const void*, size_t, int), int requester, | 117 | static int gather_faked( void (*add)(const void*, size_t, int), int requester, |
118 | size_t length, int level ); | 118 | size_t length, int level ); |
119 | 119 | ||
120 | static struct { | 120 | static struct { |
121 | ulong mixrnd; | 121 | ulong mixrnd; |
122 | ulong mixkey; | 122 | ulong mixkey; |
123 | ulong slowpolls; | 123 | ulong slowpolls; |
124 | ulong fastpolls; | 124 | ulong fastpolls; |
125 | ulong getbytes1; | 125 | ulong getbytes1; |
126 | ulong ngetbytes1; | 126 | ulong ngetbytes1; |
127 | ulong getbytes2; | 127 | ulong getbytes2; |
128 | ulong ngetbytes2; | 128 | ulong ngetbytes2; |
129 | ulong addbytes; | 129 | ulong addbytes; |
130 | ulong naddbytes; | 130 | ulong naddbytes; |
131 | } rndstats; | 131 | } rndstats; |
132 | 132 | ||
133 | static void (*progress_cb) (void *,const char*,int,int, int ); | 133 | static void (*progress_cb) (void *,const char*,int,int, int ); |
134 | static void *progress_cb_data; | 134 | static void *progress_cb_data; |
135 | 135 | ||
136 | /* Note, we assume that this function is used before any concurrent | 136 | /* Note, we assume that this function is used before any concurrent |
137 | access happens. */ | 137 | access happens. */ |
138 | static void | 138 | static void |
139 | initialize_basics(void) | 139 | initialize_basics(void) |
140 | { | 140 | { |
141 | static int initialized; | 141 | static int initialized; |
142 | int err; | 142 | int err; |
143 | 143 | ||
144 | if (!initialized) | 144 | if (!initialized) |
145 | { | 145 | { |
146 | initialized = 1; | 146 | initialized = 1; |
147 | err = ath_mutex_init (&pool_lock); | 147 | err = ath_mutex_init (&pool_lock); |
148 | if (err) | 148 | if (err) |
149 | log_fatal ("failed to create the pool lock: %s\n", strerror (err) ); | 149 | log_fatal ("failed to create the pool lock: %s\n", strerror (err) ); |
150 | 150 | ||
151 | err = ath_mutex_init (&nonce_buffer_lock); | 151 | err = ath_mutex_init (&nonce_buffer_lock); |
152 | if (err) | 152 | if (err) |
153 | log_fatal ("failed to create the nonce buffer lock: %s\n", | 153 | log_fatal ("failed to create the nonce buffer lock: %s\n", |
154 | strerror (err) ); | 154 | strerror (err) ); |
155 | } | 155 | } |
156 | } | 156 | } |
157 | 157 | ||
158 | 158 | ||
159 | static void | 159 | static void |
160 | initialize(void) | 160 | initialize(void) |
161 | { | 161 | { |
162 | initialize_basics (); | 162 | initialize_basics (); |
163 | /* The data buffer is allocated somewhat larger, so that we can use | 163 | /* The data buffer is allocated somewhat larger, so that we can use |
164 | this extra space (which is allocated in secure memory) as a | 164 | this extra space (which is allocated in secure memory) as a |
165 | temporary hash buffer */ | 165 | temporary hash buffer */ |
166 | rndpool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN) | 166 | rndpool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN) |
167 | : gcry_xcalloc(1,POOLSIZE+BLOCKLEN); | 167 | : gcry_xcalloc(1,POOLSIZE+BLOCKLEN); |
168 | keypool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN) | 168 | keypool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN) |
169 | : gcry_xcalloc(1,POOLSIZE+BLOCKLEN); | 169 | : gcry_xcalloc(1,POOLSIZE+BLOCKLEN); |
170 | is_initialized = 1; | 170 | is_initialized = 1; |
171 | 171 | ||
172 | } | 172 | } |
173 | 173 | ||
174 | 174 | ||
175 | /* Used to register a progress callback. */ | 175 | /* Used to register a progress callback. */ |
176 | void | 176 | void |
177 | _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int), | 177 | _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int), |
178 | void *cb_data ) | 178 | void *cb_data ) |
179 | { | 179 | { |
180 | progress_cb = cb; | 180 | progress_cb = cb; |
181 | progress_cb_data = cb_data; | 181 | progress_cb_data = cb_data; |
182 | } | 182 | } |
183 | 183 | ||
184 | 184 | ||
185 | /* This progress function is currently used by the random modules to give hint | 185 | /* This progress function is currently used by the random modules to give hint |
186 | on how much more entropy is required. */ | 186 | on how much more entropy is required. */ |
187 | void | 187 | void |
188 | _gcry_random_progress (const char *what, int printchar, int current, int total) | 188 | _gcry_random_progress (const char *what, int printchar, int current, int total) |
189 | { | 189 | { |
190 | if (progress_cb) | 190 | if (progress_cb) |
191 | progress_cb (progress_cb_data, what, printchar, current, total); | 191 | progress_cb (progress_cb_data, what, printchar, current, total); |
192 | } | 192 | } |
193 | 193 | ||
194 | 194 | ||
195 | /* Initialize this random subsystem. If FULL is false, this function | 195 | /* Initialize this random subsystem. If FULL is false, this function |
196 | merely calls the initialize and does not do anything more. Doing | 196 | merely calls the initialize and does not do anything more. Doing |
197 | this is not really required but when running in a threaded | 197 | this is not really required but when running in a threaded |
198 | environment we might get a race condition otherwise. */ | 198 | environment we might get a race condition otherwise. */ |
199 | void | 199 | void |
200 | _gcry_random_initialize (int full) | 200 | _gcry_random_initialize (int full) |
201 | { | 201 | { |
202 | if (!full) | 202 | if (!full) |
203 | initialize_basics (); | 203 | initialize_basics (); |
204 | else if (!is_initialized) | 204 | else if (!is_initialized) |
205 | initialize (); | 205 | initialize (); |
206 | } | 206 | } |
207 | 207 | ||
208 | void | 208 | void |
209 | _gcry_random_dump_stats() | 209 | _gcry_random_dump_stats() |
210 | { | 210 | { |
211 | log_info ( | 211 | log_info ( |
212 | "random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n" | 212 | "random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n" |
213 | " outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu\n", | 213 | " outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu\n", |
214 | POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls, | 214 | POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls, |
215 | rndstats.naddbytes, rndstats.addbytes, | 215 | rndstats.naddbytes, rndstats.addbytes, |
216 | rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1, | 216 | rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1, |
217 | rndstats.ngetbytes2, rndstats.getbytes2 ); | 217 | rndstats.ngetbytes2, rndstats.getbytes2 ); |
218 | } | 218 | } |
219 | 219 | ||
220 | void | 220 | void |
221 | _gcry_secure_random_alloc() | 221 | _gcry_secure_random_alloc() |
222 | { | 222 | { |
223 | secure_alloc = 1; | 223 | secure_alloc = 1; |
224 | } | 224 | } |
225 | 225 | ||
226 | 226 | ||
227 | int | 227 | int |
228 | _gcry_quick_random_gen( int onoff ) | 228 | _gcry_quick_random_gen( int onoff ) |
229 | { | 229 | { |
230 | int last; | 230 | int last; |
231 | 231 | ||
232 | /* No need to lock it here because we are only initializing. A | 232 | /* No need to lock it here because we are only initializing. A |
233 | prerequisite of the entire code is that it has already been | 233 | prerequisite of the entire code is that it has already been |
234 | initialized before any possible concurrent access */ | 234 | initialized before any possible concurrent access */ |
235 | read_random_source(0,0,0); /* init */ | 235 | read_random_source(0,0,0); /* init */ |
236 | last = quick_test; | 236 | last = quick_test; |
237 | if( onoff != -1 ) | 237 | if( onoff != -1 ) |
238 | quick_test = onoff; | 238 | quick_test = onoff; |
239 | return faked_rng? 1 : last; | 239 | return faked_rng? 1 : last; |
240 | } | 240 | } |
241 | 241 | ||
242 | int | 242 | int |
243 | _gcry_random_is_faked() | 243 | _gcry_random_is_faked() |
244 | { | 244 | { |
245 | if( !is_initialized ) | 245 | if( !is_initialized ) |
246 | initialize(); | 246 | initialize(); |
247 | return (faked_rng || quick_test); | 247 | return (faked_rng || quick_test); |
248 | } | 248 | } |
249 | 249 | ||
250 | /* | 250 | /* |
251 | * Return a pointer to a randomized buffer of LEVEL and NBYTES length. | 251 | * Return a pointer to a randomized buffer of LEVEL and NBYTES length. |
252 | * Caller must free the buffer. | 252 | * Caller must free the buffer. |
253 | */ | 253 | */ |
254 | static byte * | 254 | static byte * |
255 | get_random_bytes ( size_t nbytes, int level, int secure) | 255 | get_random_bytes ( size_t nbytes, int level, int secure) |
256 | { | 256 | { |
257 | byte *buf, *p; | 257 | byte *buf, *p; |
258 | int err; | 258 | int err; |
259 | 259 | ||
260 | /* First a hack toavoid the strong random using our regression test suite. */ | 260 | /* First a hack toavoid the strong random using our regression test suite. */ |
261 | if (quick_test && level > 1) | 261 | if (quick_test && level > 1) |
262 | level = 1; | 262 | level = 1; |
263 | 263 | ||
264 | /* Make sure the requested level is in range. */ | 264 | /* Make sure the requested level is in range. */ |
265 | MASK_LEVEL(level); | 265 | MASK_LEVEL(level); |
266 | 266 | ||
267 | /* Lock the pool. */ | 267 | /* Lock the pool. */ |
268 | err = ath_mutex_lock (&pool_lock); | 268 | err = ath_mutex_lock (&pool_lock); |
269 | if (err) | 269 | if (err) |
270 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | 270 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); |
271 | pool_is_locked = 1; | 271 | pool_is_locked = 1; |
272 | 272 | ||
273 | /* Keep some statistics. */ | 273 | /* Keep some statistics. */ |
274 | if (level >= 2) | 274 | if (level >= 2) |
275 | { | 275 | { |
276 | rndstats.getbytes2 += nbytes; | 276 | rndstats.getbytes2 += nbytes; |
277 | rndstats.ngetbytes2++; | 277 | rndstats.ngetbytes2++; |
278 | } | 278 | } |
279 | else | 279 | else |
280 | { | 280 | { |
281 | rndstats.getbytes1 += nbytes; | 281 | rndstats.getbytes1 += nbytes; |
282 | rndstats.ngetbytes1++; | 282 | rndstats.ngetbytes1++; |
283 | } | 283 | } |
284 | 284 | ||
285 | /* Allocate the return buffer. */ | 285 | /* Allocate the return buffer. */ |
286 | buf = secure && secure_alloc ? gcry_xmalloc_secure( nbytes ) | 286 | buf = secure && secure_alloc ? gcry_xmalloc_secure( nbytes ) |
287 | : gcry_xmalloc( nbytes ); | 287 | : gcry_xmalloc( nbytes ); |
288 | 288 | ||
289 | /* Fill that buffer with random. */ | 289 | /* Fill that buffer with random. */ |
290 | for (p = buf; nbytes > 0; ) | 290 | for (p = buf; nbytes > 0; ) |
291 | { | 291 | { |
292 | size_t n; | 292 | size_t n; |
293 | 293 | ||
294 | n = nbytes > POOLSIZE? POOLSIZE : nbytes; | 294 | n = nbytes > POOLSIZE? POOLSIZE : nbytes; |
295 | read_pool( p, n, level ); | 295 | read_pool( p, n, level ); |
296 | nbytes -= n; | 296 | nbytes -= n; |
297 | p += n; | 297 | p += n; |
298 | } | 298 | } |
299 | 299 | ||
300 | /* Release the pool lock. */ | 300 | /* Release the pool lock. */ |
301 | pool_is_locked = 0; | 301 | pool_is_locked = 0; |
302 | err = ath_mutex_unlock (&pool_lock); | 302 | err = ath_mutex_unlock (&pool_lock); |
303 | if (err) | 303 | if (err) |
304 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); | 304 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); |
305 | 305 | ||
306 | /* Return the buffer. */ | 306 | /* Return the buffer. */ |
307 | return buf; | 307 | return buf; |
308 | } | 308 | } |
309 | 309 | ||
310 | 310 | ||
311 | /* Add BUFLEN bytes from BUF to the internal random pool. QUALITY | 311 | /* Add BUFLEN bytes from BUF to the internal random pool. QUALITY |
312 | should be in the range of 0..100 to indicate the goodness of the | 312 | should be in the range of 0..100 to indicate the goodness of the |
313 | entropy added, or -1 for goodness not known. | 313 | entropy added, or -1 for goodness not known. |
314 | 314 | ||
315 | Note, that this function currently does nothing. | 315 | Note, that this function currently does nothing. |
316 | */ | 316 | */ |
317 | gcry_error_t | 317 | gcry_error_t |
318 | gcry_random_add_bytes (const void * buf, size_t buflen, int quality) | 318 | gcry_random_add_bytes (const void * buf, size_t buflen, int quality) |
319 | { | 319 | { |
320 | gcry_err_code_t err = GPG_ERR_NO_ERROR; | 320 | gcry_err_code_t err = GPG_ERR_NO_ERROR; |
321 | 321 | ||
322 | if (!buf || quality < -1 || quality > 100) | 322 | if (!buf || quality < -1 || quality > 100) |
323 | err = GPG_ERR_INV_ARG; | 323 | err = GPG_ERR_INV_ARG; |
324 | if (!buflen) | 324 | if (!buflen) |
325 | return 0; /* Shortcut this dummy case. */ | 325 | return 0; /* Shortcut this dummy case. */ |
326 | #if 0 | 326 | #if 0 |
327 | /* Before we actuall enable this code, we need to lock the pool, | 327 | /* Before we actuall enable this code, we need to lock the pool, |
328 | have a look at the quality and find a way to add them without | 328 | have a look at the quality and find a way to add them without |
329 | disturbing the real entropy (we have estimated). */ | 329 | disturbing the real entropy (we have estimated). */ |
330 | /*add_randomness( buf, buflen, 1 );*/ | 330 | /*add_randomness( buf, buflen, 1 );*/ |
331 | #endif | 331 | #endif |
332 | return err; | 332 | return err; |
333 | } | 333 | } |
334 | 334 | ||
335 | /* The public function to return random data of the quality LEVEL. */ | 335 | /* The public function to return random data of the quality LEVEL. */ |
336 | void * | 336 | void * |
337 | gcry_random_bytes( size_t nbytes, enum gcry_random_level level ) | 337 | gcry_random_bytes( size_t nbytes, enum gcry_random_level level ) |
338 | { | 338 | { |
339 | if (!is_initialized) | 339 | if (!is_initialized) |
340 | initialize(); | 340 | initialize(); |
341 | return get_random_bytes( nbytes, level, 0 ); | 341 | return get_random_bytes( nbytes, level, 0 ); |
342 | } | 342 | } |
343 | 343 | ||
344 | /* The public function to return random data of the quality LEVEL; | 344 | /* The public function to return random data of the quality LEVEL; |
345 | this version of the function retrun the random a buffer allocated | 345 | this version of the function retrun the random a buffer allocated |
346 | in secure memory. */ | 346 | in secure memory. */ |
347 | void * | 347 | void * |
348 | gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level ) | 348 | gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level ) |
349 | { | 349 | { |
350 | if (!is_initialized) | 350 | if (!is_initialized) |
351 | initialize(); | 351 | initialize(); |
352 | return get_random_bytes( nbytes, level, 1 ); | 352 | return get_random_bytes( nbytes, level, 1 ); |
353 | } | 353 | } |
354 | 354 | ||
355 | 355 | ||
356 | /* Public function to fill the buffer with LENGTH bytes of | 356 | /* Public function to fill the buffer with LENGTH bytes of |
357 | cryptographically strong random bytes. level 0 is not very strong, | 357 | cryptographically strong random bytes. level 0 is not very strong, |
358 | 1 is strong enough for most usage, 2 is good for key generation | 358 | 1 is strong enough for most usage, 2 is good for key generation |
359 | stuff but may be very slow. */ | 359 | stuff but may be very slow. */ |
360 | void | 360 | void |
361 | gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) | 361 | gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) |
362 | { | 362 | { |
363 | byte *p; | 363 | byte *p; |
364 | int err; | 364 | int err; |
365 | 365 | ||
366 | /* Make sure we are initialized. */ | 366 | /* Make sure we are initialized. */ |
367 | if (!is_initialized) | 367 | if (!is_initialized) |
368 | initialize (); | 368 | initialize (); |
369 | 369 | ||
370 | /* Handle our hack used for regression tests of Libgcrypt. */ | 370 | /* Handle our hack used for regression tests of Libgcrypt. */ |
371 | if( quick_test && level > 1 ) | 371 | if( quick_test && level > 1 ) |
372 | level = 1; | 372 | level = 1; |
373 | 373 | ||
374 | /* Make sure the level is okay. */ | 374 | /* Make sure the level is okay. */ |
375 | MASK_LEVEL(level); | 375 | MASK_LEVEL(level); |
376 | 376 | ||
377 | /* Acquire the pool lock. */ | 377 | /* Acquire the pool lock. */ |
378 | err = ath_mutex_lock (&pool_lock); | 378 | err = ath_mutex_lock (&pool_lock); |
379 | if (err) | 379 | if (err) |
380 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | 380 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); |
381 | pool_is_locked = 1; | 381 | pool_is_locked = 1; |
382 | 382 | ||
383 | /* Update the statistics. */ | 383 | /* Update the statistics. */ |
384 | if (level >= 2) | 384 | if (level >= 2) |
385 | { | 385 | { |
386 | rndstats.getbytes2 += length; | 386 | rndstats.getbytes2 += length; |
387 | rndstats.ngetbytes2++; | 387 | rndstats.ngetbytes2++; |
388 | } | 388 | } |
389 | else | 389 | else |
390 | { | 390 | { |
391 | rndstats.getbytes1 += length; | 391 | rndstats.getbytes1 += length; |
392 | rndstats.ngetbytes1++; | 392 | rndstats.ngetbytes1++; |
393 | } | 393 | } |
394 | 394 | ||
395 | /* Read the random into the provided buffer. */ | 395 | /* Read the random into the provided buffer. */ |
396 | for (p = buffer; length > 0;) | 396 | for (p = buffer; length > 0;) |
397 | { | 397 | { |
398 | size_t n; | 398 | size_t n; |
399 | 399 | ||
400 | n = length > POOLSIZE? POOLSIZE : length; | 400 | n = length > POOLSIZE? POOLSIZE : length; |
401 | read_pool (p, n, level); | 401 | read_pool (p, n, level); |
402 | length -= n; | 402 | length -= n; |
403 | p += n; | 403 | p += n; |
404 | } | 404 | } |
405 | 405 | ||
406 | /* Release the pool lock. */ | 406 | /* Release the pool lock. */ |
407 | pool_is_locked = 0; | 407 | pool_is_locked = 0; |
408 | err = ath_mutex_unlock (&pool_lock); | 408 | err = ath_mutex_unlock (&pool_lock); |
409 | if (err) | 409 | if (err) |
410 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); | 410 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); |
411 | 411 | ||
412 | } | 412 | } |
413 | 413 | ||
414 | 414 | ||
415 | 415 | ||
416 | 416 | ||
417 | /* | 417 | /* |
418 | Mix the pool: | 418 | Mix the pool: |
419 | 419 | ||
420 | |........blocks*20byte........|20byte|..44byte..| | 420 | |........blocks*20byte........|20byte|..44byte..| |
421 | <..44byte..> <20byte> | 421 | <..44byte..> <20byte> |
422 | | | | 422 | | | |
423 | | +------+ | 423 | | +------+ |
424 | +---------------------------|----------+ | 424 | +---------------------------|----------+ |
425 | v v | 425 | v v |
426 | |........blocks*20byte........|20byte|..44byte..| | 426 | |........blocks*20byte........|20byte|..44byte..| |
427 | <.....64bytes.....> | 427 | <.....64bytes.....> |
428 | | | 428 | | |
429 | +----------------------------------+ | 429 | +----------------------------------+ |
430 | Hash | 430 | Hash |
431 | v | 431 | v |
432 | |.............................|20byte|..44byte..| | 432 | |.............................|20byte|..44byte..| |
433 | <20byte><20byte><..44byte..> | 433 | <20byte><20byte><..44byte..> |
434 | | | | 434 | | | |
435 | | +---------------------+ | 435 | | +---------------------+ |
436 | +-----------------------------+ | | 436 | +-----------------------------+ | |
437 | v v | 437 | v v |
438 | |.............................|20byte|..44byte..| | 438 | |.............................|20byte|..44byte..| |
439 | <.....64byte......> | 439 | <.....64byte......> |
440 | | | 440 | | |
441 | +-------------------------+ | 441 | +-------------------------+ |
442 | Hash | 442 | Hash |
443 | v | 443 | v |
444 | |.............................|20byte|..44byte..| | 444 | |.............................|20byte|..44byte..| |
445 | <20byte><20byte><..44byte..> | 445 | <20byte><20byte><..44byte..> |
446 | 446 | ||
447 | and so on until we did this for all blocks. | 447 | and so on until we did this for all blocks. |
448 | 448 | ||
449 | To better protect against implementation errors in this code, we | 449 | To better protect against implementation errors in this code, we |
450 | xor a digest of the entire pool into the pool before mixing. | 450 | xor a digest of the entire pool into the pool before mixing. |
451 | 451 | ||
452 | Note, that this function muts only be called with a locked pool. | 452 | Note, that this function muts only be called with a locked pool. |
453 | */ | 453 | */ |
454 | static void | 454 | static void |
455 | mix_pool (unsigned char *pool) | 455 | mix_pool (unsigned char *pool) |
456 | { | 456 | { |
457 | static unsigned char failsafe_digest[DIGESTLEN]; | 457 | static unsigned char failsafe_digest[DIGESTLEN]; |
458 | static int failsafe_digest_valid; | 458 | static int failsafe_digest_valid; |
459 | 459 | ||
460 | unsigned char *hashbuf = pool + POOLSIZE; | 460 | unsigned char *hashbuf = pool + POOLSIZE; |
461 | unsigned char *p, *pend; | 461 | unsigned char *p, *pend; |
462 | int i, n; | 462 | int i, n; |
463 | RMD160_CONTEXT md; | 463 | RMD160_CONTEXT md; |
464 | 464 | ||
465 | #if DIGESTLEN != 20 | 465 | #if DIGESTLEN != 20 |
466 | #error must have a digest length of 20 for ripe-md-160 | 466 | #error must have a digest length of 20 for ripe-md-160 |
467 | #endif | 467 | #endif |
468 | 468 | ||
469 | assert (pool_is_locked); | 469 | assert (pool_is_locked); |
470 | _gcry_rmd160_init( &md ); | 470 | _gcry_rmd160_init( &md ); |
471 | 471 | ||
472 | /* loop over the pool */ | 472 | /* loop over the pool */ |
473 | pend = pool + POOLSIZE; | 473 | pend = pool + POOLSIZE; |
474 | memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN ); | 474 | memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN ); |
475 | memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); | 475 | memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); |
476 | _gcry_rmd160_mixblock( &md, (char*)hashbuf); | 476 | _gcry_rmd160_mixblock( &md, (char*)hashbuf); |
477 | memcpy(pool, hashbuf, 20 ); | 477 | memcpy(pool, hashbuf, 20 ); |
478 | 478 | ||
479 | if (failsafe_digest_valid && pool == rndpool) | 479 | if (failsafe_digest_valid && pool == rndpool) |
480 | { | 480 | { |
481 | for (i=0; i < 20; i++) | 481 | for (i=0; i < 20; i++) |
482 | pool[i] ^= failsafe_digest[i]; | 482 | pool[i] ^= failsafe_digest[i]; |
483 | } | 483 | } |
484 | 484 | ||
485 | p = pool; | 485 | p = pool; |
486 | for (n=1; n < POOLBLOCKS; n++) | 486 | for (n=1; n < POOLBLOCKS; n++) |
487 | { | 487 | { |
488 | memcpy (hashbuf, p, DIGESTLEN); | 488 | memcpy (hashbuf, p, DIGESTLEN); |
489 | 489 | ||
490 | p += DIGESTLEN; | 490 | p += DIGESTLEN; |
491 | if (p+DIGESTLEN+BLOCKLEN < pend) | 491 | if (p+DIGESTLEN+BLOCKLEN < pend) |
492 | memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); | 492 | memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); |
493 | else | 493 | else |
494 | { | 494 | { |
495 | unsigned char *pp = p + DIGESTLEN; | 495 | unsigned char *pp = p + DIGESTLEN; |
496 | 496 | ||
497 | for (i=DIGESTLEN; i < BLOCKLEN; i++ ) | 497 | for (i=DIGESTLEN; i < BLOCKLEN; i++ ) |
498 | { | 498 | { |
499 | if ( pp >= pend ) | 499 | if ( pp >= pend ) |
500 | pp = pool; | 500 | pp = pool; |
501 | hashbuf[i] = *pp++; | 501 | hashbuf[i] = *pp++; |
502 | } | 502 | } |
503 | } | 503 | } |
504 | 504 | ||
505 | _gcry_rmd160_mixblock( &md, (char*)hashbuf); | 505 | _gcry_rmd160_mixblock( &md, (char*)hashbuf); |
506 | memcpy(p, hashbuf, 20 ); | 506 | memcpy(p, hashbuf, 20 ); |
507 | } | 507 | } |
508 | 508 | ||
509 | /* Our hash implementation does only leave small parts (64 bytes) | 509 | /* Our hash implementation does only leave small parts (64 bytes) |
510 | of the pool on the stack, so it is okay not to require secure | 510 | of the pool on the stack, so it is okay not to require secure |
511 | memory here. Before we use this pool, it will be copied to the | 511 | memory here. Before we use this pool, it will be copied to the |
512 | help buffer anyway. */ | 512 | help buffer anyway. */ |
513 | if ( pool == rndpool) | 513 | if ( pool == rndpool) |
514 | { | 514 | { |
515 | _gcry_rmd160_hash_buffer ((char*)failsafe_digest, | 515 | _gcry_rmd160_hash_buffer ((char*)failsafe_digest, |
516 | (char*)pool, POOLSIZE); | 516 | (char*)pool, POOLSIZE); |
517 | failsafe_digest_valid = 1; | 517 | failsafe_digest_valid = 1; |
518 | } | 518 | } |
519 | 519 | ||
520 | _gcry_burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */ | 520 | _gcry_burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */ |
521 | } | 521 | } |
522 | 522 | ||
523 | 523 | ||
524 | void | 524 | void |
525 | _gcry_set_random_seed_file( const char *name ) | 525 | _gcry_set_random_seed_file( const char *name ) |
526 | { | 526 | { |
527 | if (seed_file_name) | 527 | if (seed_file_name) |
528 | BUG (); | 528 | BUG (); |
529 | seed_file_name = gcry_xstrdup (name); | 529 | seed_file_name = gcry_xstrdup (name); |
530 | } | 530 | } |
531 | 531 | ||
532 | 532 | ||
533 | /* | 533 | /* |
534 | Read in a seed form the random_seed file | 534 | Read in a seed form the random_seed file |
535 | and return true if this was successful. | 535 | and return true if this was successful. |
536 | */ | 536 | */ |
537 | static int | 537 | static int |
538 | read_seed_file (void) | 538 | read_seed_file (void) |
539 | { | 539 | { |
540 | int fd; | 540 | int fd; |
541 | struct stat sb; | 541 | struct stat sb; |
542 | unsigned char buffer[POOLSIZE]; | 542 | unsigned char buffer[POOLSIZE]; |
543 | int n; | 543 | int n; |
544 | 544 | ||
545 | assert (pool_is_locked); | 545 | assert (pool_is_locked); |
546 | 546 | ||
547 | if (!seed_file_name) | 547 | if (!seed_file_name) |
548 | return 0; | 548 | return 0; |
549 | 549 | ||
550 | #ifdef HAVE_DOSISH_SYSTEM | 550 | #ifdef HAVE_DOSISH_SYSTEM |
551 | fd = open( seed_file_name, O_RDONLY | O_BINARY ); | 551 | fd = open( seed_file_name, O_RDONLY | O_BINARY ); |
552 | #else | 552 | #else |
553 | fd = open( seed_file_name, O_RDONLY ); | 553 | fd = open( seed_file_name, O_RDONLY ); |
554 | #endif | 554 | #endif |
555 | if( fd == -1 && errno == ENOENT) | 555 | if( fd == -1 && errno == ENOENT) |
556 | { | 556 | { |
557 | allow_seed_file_update = 1; | 557 | allow_seed_file_update = 1; |
558 | return 0; | 558 | return 0; |
559 | } | 559 | } |
560 | 560 | ||
561 | if (fd == -1 ) | 561 | if (fd == -1 ) |
562 | { | 562 | { |
563 | log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) ); | 563 | log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) ); |
564 | return 0; | 564 | return 0; |
565 | } | 565 | } |
566 | if (fstat( fd, &sb ) ) | 566 | if (fstat( fd, &sb ) ) |
567 | { | 567 | { |
568 | log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) ); | 568 | log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) ); |
569 | close(fd); | 569 | close(fd); |
570 | return 0; | 570 | return 0; |
571 | } | 571 | } |
572 | if (!S_ISREG(sb.st_mode) ) | 572 | if (!S_ISREG(sb.st_mode) ) |
573 | { | 573 | { |
574 | log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name ); | 574 | log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name ); |
575 | close(fd); | 575 | close(fd); |
576 | return 0; | 576 | return 0; |
577 | } | 577 | } |
578 | if (!sb.st_size ) | 578 | if (!sb.st_size ) |
579 | { | 579 | { |
580 | log_info(_("note: random_seed file is empty\n") ); | 580 | log_info(_("note: random_seed file is empty\n") ); |
581 | close(fd); | 581 | close(fd); |
582 | allow_seed_file_update = 1; | 582 | allow_seed_file_update = 1; |
583 | return 0; | 583 | return 0; |
584 | } | 584 | } |
585 | if (sb.st_size != POOLSIZE ) | 585 | if (sb.st_size != POOLSIZE ) |
586 | { | 586 | { |
587 | log_info(_("warning: invalid size of random_seed file - not used\n") ); | 587 | log_info(_("warning: invalid size of random_seed file - not used\n") ); |
588 | close(fd); | 588 | close(fd); |
589 | return 0; | 589 | return 0; |
590 | } | 590 | } |
591 | 591 | ||
592 | do | 592 | do |
593 | { | 593 | { |
594 | n = read( fd, buffer, POOLSIZE ); | 594 | n = read( fd, buffer, POOLSIZE ); |
595 | } | 595 | } |
596 | while (n == -1 && errno == EINTR ); | 596 | while (n == -1 && errno == EINTR ); |
597 | 597 | ||
598 | if (n != POOLSIZE) | 598 | if (n != POOLSIZE) |
599 | { | 599 | { |
600 | log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) ); | 600 | log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) ); |
601 | close(fd);/*NOTREACHED*/ | 601 | close(fd);/*NOTREACHED*/ |
602 | return 0; | 602 | return 0; |
603 | } | 603 | } |
604 | 604 | ||
605 | close(fd); | 605 | close(fd); |
606 | 606 | ||
607 | add_randomness( buffer, POOLSIZE, 0 ); | 607 | add_randomness( buffer, POOLSIZE, 0 ); |
608 | /* add some minor entropy to the pool now (this will also force a mixing) */ | 608 | /* add some minor entropy to the pool now (this will also force a mixing) */ |
609 | { | 609 | { |
610 | pid_t x = getpid(); | 610 | pid_t x = getpid(); |
611 | add_randomness( &x, sizeof(x), 0 ); | 611 | add_randomness( &x, sizeof(x), 0 ); |
612 | } | 612 | } |
613 | { | 613 | { |
614 | time_t x = time(NULL); | 614 | time_t x = time(NULL); |
615 | add_randomness( &x, sizeof(x), 0 ); | 615 | add_randomness( &x, sizeof(x), 0 ); |
616 | } | 616 | } |
617 | { | 617 | { |
618 | clock_t x = clock(); | 618 | clock_t x = clock(); |
619 | add_randomness( &x, sizeof(x), 0 ); | 619 | add_randomness( &x, sizeof(x), 0 ); |
620 | } | 620 | } |
621 | 621 | ||
622 | /* And read a few bytes from our entropy source. By using a level | 622 | /* And read a few bytes from our entropy source. By using a level |
623 | * of 0 this will not block and might not return anything with some | 623 | * of 0 this will not block and might not return anything with some |
624 | * entropy drivers, however the rndlinux driver will use | 624 | * entropy drivers, however the rndlinux driver will use |
625 | * /dev/urandom and return some stuff - Do not read to much as we | 625 | * /dev/urandom and return some stuff - Do not read to much as we |
626 | * want to be friendly to the scare system entropy resource. */ | 626 | * want to be friendly to the scare system entropy resource. */ |
627 | read_random_source( 0, 16, 0 ); | 627 | read_random_source( 0, 16, 0 ); |
628 | 628 | ||
629 | allow_seed_file_update = 1; | 629 | allow_seed_file_update = 1; |
630 | return 1; | 630 | return 1; |
631 | } | 631 | } |
632 | 632 | ||
633 | 633 | ||
634 | void | 634 | void |
635 | _gcry_update_random_seed_file() | 635 | _gcry_update_random_seed_file() |
636 | { | 636 | { |
637 | unsigned long *sp, *dp; | 637 | unsigned long *sp, *dp; |
638 | int fd, i; | 638 | int fd, i; |
639 | int err; | 639 | int err; |
640 | 640 | ||
641 | if ( !seed_file_name || !is_initialized || !pool_filled ) | 641 | if ( !seed_file_name || !is_initialized || !pool_filled ) |
642 | return; | 642 | return; |
643 | if ( !allow_seed_file_update ) | 643 | if ( !allow_seed_file_update ) |
644 | { | 644 | { |
645 | log_info(_("note: random_seed file not updated\n")); | 645 | log_info(_("note: random_seed file not updated\n")); |
646 | return; | 646 | return; |
647 | } | 647 | } |
648 | 648 | ||
649 | err = ath_mutex_lock (&pool_lock); | 649 | err = ath_mutex_lock (&pool_lock); |
650 | if (err) | 650 | if (err) |
651 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | 651 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); |
652 | pool_is_locked = 1; | 652 | pool_is_locked = 1; |
653 | 653 | ||
654 | /* copy the entropy pool to a scratch pool and mix both of them */ | 654 | /* copy the entropy pool to a scratch pool and mix both of them */ |
655 | for (i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; | 655 | for (i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; |
656 | i < POOLWORDS; i++, dp++, sp++ ) | 656 | i < POOLWORDS; i++, dp++, sp++ ) |
657 | { | 657 | { |
658 | *dp = *sp + ADD_VALUE; | 658 | *dp = *sp + ADD_VALUE; |
659 | } | 659 | } |
660 | mix_pool(rndpool); rndstats.mixrnd++; | 660 | mix_pool(rndpool); rndstats.mixrnd++; |
661 | mix_pool(keypool); rndstats.mixkey++; | 661 | mix_pool(keypool); rndstats.mixkey++; |
662 | 662 | ||
663 | #ifdef HAVE_DOSISH_SYSTEM | 663 | #ifdef HAVE_DOSISH_SYSTEM |
664 | fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, | 664 | fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, |
665 | S_IRUSR|S_IWUSR ); | 665 | S_IRUSR|S_IWUSR ); |
666 | #else | 666 | #else |
667 | fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR ); | 667 | fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR ); |
668 | #endif | 668 | #endif |
669 | 669 | ||
670 | if (fd == -1 ) | 670 | if (fd == -1 ) |
671 | log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) ); | 671 | log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) ); |
672 | else | 672 | else |
673 | { | 673 | { |
674 | do | 674 | do |
675 | { | 675 | { |
676 | i = write (fd, keypool, POOLSIZE ); | 676 | i = write (fd, keypool, POOLSIZE ); |
677 | } | 677 | } |
678 | while( i == -1 && errno == EINTR ); | 678 | while( i == -1 && errno == EINTR ); |
679 | if (i != POOLSIZE) | 679 | if (i != POOLSIZE) |
680 | log_info (_("can't write `%s': %s\n"), | 680 | log_info (_("can't write `%s': %s\n"), |
681 | seed_file_name, strerror(errno) ); | 681 | seed_file_name, strerror(errno) ); |
682 | if (close(fd)) | 682 | if (close(fd)) |
683 | log_info(_("can't close `%s': %s\n"), | 683 | log_info(_("can't close `%s': %s\n"), |
684 | seed_file_name, strerror(errno) ); | 684 | seed_file_name, strerror(errno) ); |
685 | } | 685 | } |
686 | 686 | ||
687 | pool_is_locked = 0; | 687 | pool_is_locked = 0; |
688 | err = ath_mutex_unlock (&pool_lock); | 688 | err = ath_mutex_unlock (&pool_lock); |
689 | if (err) | 689 | if (err) |
690 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); | 690 | log_fatal ("failed to release the pool lock: %s\n", strerror (err)); |
691 | 691 | ||
692 | } | 692 | } |
693 | 693 | ||
694 | 694 | ||
695 | /* Read random out of the pool. This function is the core of the | 695 | /* Read random out of the pool. This function is the core of the |
696 | public random functions. Note that Level 0 is special and in fact | 696 | public random functions. Note that Level 0 is special and in fact |
697 | an alias for level 1. */ | 697 | an alias for level 1. */ |
698 | static void | 698 | static void |
699 | read_pool (byte *buffer, size_t length, int level) | 699 | read_pool (byte *buffer, size_t length, int level) |
700 | { | 700 | { |
701 | int i; | 701 | int i; |
702 | unsigned long *sp, *dp; | 702 | unsigned long *sp, *dp; |
703 | size_t n; | 703 | size_t n; |
704 | /* The volatile is there to make sure the compiler does not optimize | 704 | /* The volatile is there to make sure the compiler does not optimize |
705 | the code away in case the getpid function is badly attributed. | 705 | the code away in case the getpid function is badly attributed. |
706 | Note that we keep a pid in a static variable as well as in a | 706 | Note that we keep a pid in a static variable as well as in a |
707 | stack based one; the latter is to detect ill behaving thread | 707 | stack based one; the latter is to detect ill behaving thread |
708 | libraries, ignoring the pool mutexes. */ | 708 | libraries, ignoring the pool mutexes. */ |
709 | static volatile pid_t my_pid = (pid_t)(-1); | 709 | static volatile pid_t my_pid = (pid_t)(-1); |
710 | volatile pid_t my_pid2; | 710 | volatile pid_t my_pid2; |
711 | 711 | ||
712 | retry: | 712 | retry: |
713 | /* Get our own pid, so that we can detect a fork. */ | 713 | /* Get our own pid, so that we can detect a fork. */ |
714 | my_pid2 = getpid (); | 714 | my_pid2 = getpid (); |
715 | if (my_pid == (pid_t)(-1)) | 715 | if (my_pid == (pid_t)(-1)) |
716 | my_pid = my_pid2; | 716 | my_pid = my_pid2; |
717 | if ( my_pid != my_pid2 ) | 717 | if ( my_pid != my_pid2 ) |
718 | { | 718 | { |
719 | /* We detected a plain fork; i.e. we are now the child. Update | 719 | /* We detected a plain fork; i.e. we are now the child. Update |
720 | the static pid and add some randomness. */ | 720 | the static pid and add some randomness. */ |
721 | pid_t x; | 721 | pid_t x; |
722 | 722 | ||
723 | my_pid = my_pid2; | 723 | my_pid = my_pid2; |
724 | x = my_pid; | 724 | x = my_pid; |
725 | add_randomness (&x, sizeof(x), 0); | 725 | add_randomness (&x, sizeof(x), 0); |
726 | just_mixed = 0; /* Make sure it will get mixed. */ | 726 | just_mixed = 0; /* Make sure it will get mixed. */ |
727 | } | 727 | } |
728 | 728 | ||
729 | assert (pool_is_locked); | 729 | assert (pool_is_locked); |
730 | 730 | ||
731 | /* Our code does not allow to extract more than POOLSIZE. Better | 731 | /* Our code does not allow to extract more than POOLSIZE. Better |
732 | check it here. */ | 732 | check it here. */ |
733 | if (length > POOLSIZE) | 733 | if (length > POOLSIZE) |
734 | { | 734 | { |
735 | log_bug("too many random bits requested (%lu)\n", (unsigned long)length); | 735 | log_bug("too many random bits requested (%lu)\n", (unsigned long)length); |
736 | } | 736 | } |
737 | 737 | ||
738 | if (!pool_filled) | 738 | if (!pool_filled) |
739 | { | 739 | { |
740 | if (read_seed_file() ) | 740 | if (read_seed_file() ) |
741 | pool_filled = 1; | 741 | pool_filled = 1; |
742 | } | 742 | } |
743 | 743 | ||
744 | /* For level 2 quality (key generation) we always make sure that the | 744 | /* For level 2 quality (key generation) we always make sure that the |
745 | pool has been seeded enough initially. */ | 745 | pool has been seeded enough initially. */ |
746 | if (level == 2 && !did_initial_extra_seeding) | 746 | if (level == 2 && !did_initial_extra_seeding) |
747 | { | 747 | { |
748 | size_t needed; | 748 | size_t needed; |
749 | 749 | ||
750 | pool_balance = 0; | 750 | pool_balance = 0; |
751 | needed = length - pool_balance; | 751 | needed = length - pool_balance; |
752 | if (needed < POOLSIZE/2) | 752 | if (needed < POOLSIZE/2) |
753 | needed = POOLSIZE/2; | 753 | needed = POOLSIZE/2; |
754 | else if( needed > POOLSIZE ) | 754 | else if( needed > POOLSIZE ) |
755 | BUG (); | 755 | BUG (); |
756 | read_random_source (3, needed, 2); | 756 | read_random_source (3, needed, 2); |
757 | pool_balance += needed; | 757 | pool_balance += needed; |
758 | did_initial_extra_seeding = 1; | 758 | did_initial_extra_seeding = 1; |
759 | } | 759 | } |
760 | 760 | ||
761 | /* For level 2 make sure that there is enough random in the pool. */ | 761 | /* For level 2 make sure that there is enough random in the pool. */ |
762 | if (level == 2 && pool_balance < length) | 762 | if (level == 2 && pool_balance < length) |
763 | { | 763 | { |
764 | size_t needed; | 764 | size_t needed; |
765 | 765 | ||
766 | if (pool_balance < 0) | 766 | if (pool_balance < 0) |
767 | pool_balance = 0; | 767 | pool_balance = 0; |
768 | needed = length - pool_balance; | 768 | needed = length - pool_balance; |
769 | if (needed > POOLSIZE) | 769 | if (needed > POOLSIZE) |
770 | BUG (); | 770 | BUG (); |
771 | read_random_source( 3, needed, 2 ); | 771 | read_random_source( 3, needed, 2 ); |
772 | pool_balance += needed; | 772 | pool_balance += needed; |
773 | } | 773 | } |
774 | 774 | ||
775 | /* make sure the pool is filled */ | 775 | /* make sure the pool is filled */ |
776 | while (!pool_filled) | 776 | while (!pool_filled) |
777 | random_poll(); | 777 | random_poll(); |
778 | 778 | ||
779 | /* Always do a fast random poll (we have to use the unlocked version). */ | 779 | /* Always do a fast random poll (we have to use the unlocked version). */ |
780 | do_fast_random_poll(); | 780 | do_fast_random_poll(); |
781 | 781 | ||
782 | /* Mix the pid in so that we for sure won't deliver the same random | 782 | /* Mix the pid in so that we for sure won't deliver the same random |
783 | after a fork. */ | 783 | after a fork. */ |
784 | { | 784 | { |
785 | pid_t apid = my_pid; | 785 | pid_t apid = my_pid; |
786 | add_randomness (&apid, sizeof (apid), 0); | 786 | add_randomness (&apid, sizeof (apid), 0); |
787 | } | 787 | } |
788 | 788 | ||
789 | /* Mix the pool (if add_randomness() didn't it). */ | 789 | /* Mix the pool (if add_randomness() didn't it). */ |
790 | if (!just_mixed) | 790 | if (!just_mixed) |
791 | { | 791 | { |
792 | mix_pool(rndpool); | 792 | mix_pool(rndpool); |
793 | rndstats.mixrnd++; | 793 | rndstats.mixrnd++; |
794 | } | 794 | } |
795 | 795 | ||
796 | /* Create a new pool. */ | 796 | /* Create a new pool. */ |
797 | for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; | 797 | for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; |
798 | i < POOLWORDS; i++, dp++, sp++ ) | 798 | i < POOLWORDS; i++, dp++, sp++ ) |
799 | *dp = *sp + ADD_VALUE; | 799 | *dp = *sp + ADD_VALUE; |
800 | 800 | ||
801 | /* Mix both pools. */ | 801 | /* Mix both pools. */ |
802 | mix_pool(rndpool); rndstats.mixrnd++; | 802 | mix_pool(rndpool); rndstats.mixrnd++; |
803 | mix_pool(keypool); rndstats.mixkey++; | 803 | mix_pool(keypool); rndstats.mixkey++; |
804 | 804 | ||
805 | /* Read the required data. We use a readpointer to read from a | 805 | /* Read the required data. We use a readpointer to read from a |
806 | different position each time */ | 806 | different position each time */ |
807 | for (n=0; n < length; n++) | 807 | for (n=0; n < length; n++) |
808 | { | 808 | { |
809 | *buffer++ = keypool[pool_readpos++]; | 809 | *buffer++ = keypool[pool_readpos++]; |
810 | if (pool_readpos >= POOLSIZE) | 810 | if (pool_readpos >= POOLSIZE) |
811 | pool_readpos = 0; | 811 | pool_readpos = 0; |
812 | pool_balance--; | 812 | pool_balance--; |
813 | } | 813 | } |
814 | 814 | ||
815 | if (pool_balance < 0) | 815 | if (pool_balance < 0) |
816 | pool_balance = 0; | 816 | pool_balance = 0; |
817 | 817 | ||
818 | /* Clear the keypool. */ | 818 | /* Clear the keypool. */ |
819 | memset (keypool, 0, POOLSIZE); | 819 | memset (keypool, 0, POOLSIZE); |
820 | 820 | ||
821 | /* We need to detect whether a fork has happened. A fork might have | 821 | /* We need to detect whether a fork has happened. A fork might have |
822 | an identical pool and thus the child and the parent could emit | 822 | an identical pool and thus the child and the parent could emit |
823 | the very same random number. This test here is to detect forks | 823 | the very same random number. This test here is to detect forks |
824 | in a multi-threaded process. */ | 824 | in a multi-threaded process. */ |
825 | if ( getpid () != my_pid2 ) | 825 | if ( getpid () != my_pid2 ) |
826 | { | 826 | { |
827 | pid_t x = getpid(); | 827 | pid_t x = getpid(); |
828 | add_randomness (&x, sizeof(x), 0); | 828 | add_randomness (&x, sizeof(x), 0); |
829 | just_mixed = 0; /* Make sure it will get mixed. */ | 829 | just_mixed = 0; /* Make sure it will get mixed. */ |
830 | my_pid = x; /* Also update the static pid. */ | 830 | my_pid = x; /* Also update the static pid. */ |
831 | goto retry; | 831 | goto retry; |
832 | } | 832 | } |
833 | } | 833 | } |
834 | 834 | ||
835 | 835 | ||
836 | /* | 836 | /* |
837 | * Add LENGTH bytes of randomness from buffer to the pool. | 837 | * Add LENGTH bytes of randomness from buffer to the pool. |
838 | * source may be used to specify the randomness source. | 838 | * source may be used to specify the randomness source. |
839 | * Source is: | 839 | * Source is: |
840 | * 0 - used ony for initialization | 840 | * 0 - used ony for initialization |
841 | * 1 - fast random poll function | 841 | * 1 - fast random poll function |
842 | * 2 - normal poll function | 842 | * 2 - normal poll function |
843 | * 3 - used when level 2 random quality has been requested | 843 | * 3 - used when level 2 random quality has been requested |
844 | * to do an extra pool seed. | 844 | * to do an extra pool seed. |
845 | */ | 845 | */ |
846 | static void | 846 | static void |
847 | add_randomness( const void *buffer, size_t length, int source ) | 847 | add_randomness( const void *buffer, size_t length, int source ) |
848 | { | 848 | { |
849 | const byte *p = buffer; | 849 | const byte *p = buffer; |
850 | 850 | ||
851 | assert (pool_is_locked); | 851 | assert (pool_is_locked); |
852 | if (!is_initialized) | 852 | if (!is_initialized) |
853 | initialize (); | 853 | initialize (); |
854 | rndstats.addbytes += length; | 854 | rndstats.addbytes += length; |
855 | rndstats.naddbytes++; | 855 | rndstats.naddbytes++; |
856 | while (length-- ) | 856 | while (length-- ) |
857 | { | 857 | { |
858 | rndpool[pool_writepos++] ^= *p++; | 858 | rndpool[pool_writepos++] ^= *p++; |
859 | if (pool_writepos >= POOLSIZE ) | 859 | if (pool_writepos >= POOLSIZE ) |
860 | { | 860 | { |
861 | if (source > 1) | 861 | if (source > 1) |
862 | pool_filled = 1; | 862 | pool_filled = 1; |
863 | pool_writepos = 0; | 863 | pool_writepos = 0; |
864 | mix_pool(rndpool); rndstats.mixrnd++; | 864 | mix_pool(rndpool); rndstats.mixrnd++; |
865 | just_mixed = !length; | 865 | just_mixed = !length; |
866 | } | 866 | } |
867 | } | 867 | } |
868 | } | 868 | } |
869 | 869 | ||
870 | 870 | ||
871 | 871 | ||
872 | static void | 872 | static void |
873 | random_poll() | 873 | random_poll() |
874 | { | 874 | { |
875 | rndstats.slowpolls++; | 875 | rndstats.slowpolls++; |
876 | read_random_source (2, POOLSIZE/5, 1); | 876 | read_random_source (2, POOLSIZE/5, 1); |
877 | } | 877 | } |
878 | 878 | ||
879 | 879 | ||
880 | static int (* | 880 | static int (* |
881 | getfnc_gather_random (void))(void (*)(const void*, size_t, int), int, | 881 | getfnc_gather_random (void))(void (*)(const void*, size_t, int), int, |
882 | size_t, int) | 882 | size_t, int) |
883 | { | 883 | { |
884 | static int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int); | 884 | static int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int); |
885 | 885 | ||
886 | if (fnc) | 886 | if (fnc) |
887 | return fnc; | 887 | return fnc; |
888 | 888 | ||
889 | #if USE_RNDLINUX | 889 | #if USE_RNDLINUX |
890 | if ( !access (NAME_OF_DEV_RANDOM, R_OK) | 890 | if ( !access (NAME_OF_DEV_RANDOM, R_OK) |
891 | && !access (NAME_OF_DEV_URANDOM, R_OK)) | 891 | && !access (NAME_OF_DEV_URANDOM, R_OK)) |
892 | { | 892 | { |
893 | fnc = _gcry_rndlinux_gather_random; | 893 | fnc = _gcry_rndlinux_gather_random; |
894 | return fnc; | 894 | return fnc; |
895 | } | 895 | } |
896 | #endif | 896 | #endif |
897 | 897 | ||
898 | #if USE_RNDEGD | 898 | #if USE_RNDEGD |
899 | if ( _gcry_rndegd_connect_socket (1) != -1 ) | 899 | if ( _gcry_rndegd_connect_socket (1) != -1 ) |
900 | { | 900 | { |
901 | fnc = _gcry_rndegd_gather_random; | 901 | fnc = _gcry_rndegd_gather_random; |
902 | return fnc; | 902 | return fnc; |
903 | } | 903 | } |
904 | #endif | 904 | #endif |
905 | 905 | ||
906 | #if USE_RNDUNIX | 906 | #if USE_RNDUNIX |
907 | fnc = _gcry_rndunix_gather_random; | 907 | fnc = _gcry_rndunix_gather_random; |
908 | return fnc; | 908 | return fnc; |
909 | #endif | 909 | #endif |
910 | 910 | ||
911 | #if USE_RNDW32 | 911 | #if USE_RNDW32 |
912 | fnc = _gcry_rndw32_gather_random; | 912 | fnc = _gcry_rndw32_gather_random; |
913 | return fnc; | 913 | return fnc; |
914 | #endif | 914 | #endif |
915 | 915 | ||
916 | log_fatal (_("no entropy gathering module detected\n")); | 916 | log_fatal (_("no entropy gathering module detected\n")); |
917 | 917 | ||
918 | return NULL; /*NOTREACHED*/ | 918 | return NULL; /*NOTREACHED*/ |
919 | } | 919 | } |
920 | 920 | ||
921 | static void (* | 921 | static void (* |
922 | getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int) | 922 | getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int) |
923 | { | 923 | { |
924 | #if USE_RNDW32 | 924 | #if USE_RNDW32 |
925 | return _gcry_rndw32_gather_random_fast; | 925 | return _gcry_rndw32_gather_random_fast; |
926 | #endif | 926 | #endif |
927 | return NULL; | 927 | return NULL; |
928 | } | 928 | } |
929 | 929 | ||
930 | 930 | ||
931 | static void | 931 | static void |
932 | do_fast_random_poll (void) | 932 | do_fast_random_poll (void) |
933 | { | 933 | { |
934 | static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL; | 934 | static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL; |
935 | static int initialized = 0; | 935 | static int initialized = 0; |
936 | 936 | ||
937 | assert (pool_is_locked); | 937 | assert (pool_is_locked); |
938 | 938 | ||
939 | rndstats.fastpolls++; | 939 | rndstats.fastpolls++; |
940 | 940 | ||
941 | if (!initialized ) | 941 | if (!initialized ) |
942 | { | 942 | { |
943 | if (!is_initialized ) | 943 | if (!is_initialized ) |
944 | initialize(); | 944 | initialize(); |
945 | initialized = 1; | 945 | initialized = 1; |
946 | fnc = getfnc_fast_random_poll (); | 946 | fnc = getfnc_fast_random_poll (); |
947 | } | 947 | } |
948 | 948 | ||
949 | if (fnc) | 949 | if (fnc) |
950 | (*fnc)( add_randomness, 1 ); | 950 | (*fnc)( add_randomness, 1 ); |
951 | 951 | ||
952 | /* Continue with the generic functions. */ | 952 | /* Continue with the generic functions. */ |
953 | #if HAVE_GETHRTIME | 953 | #if HAVE_GETHRTIME |
954 | { | 954 | { |
955 | hrtime_t tv; | 955 | hrtime_t tv; |
956 | tv = gethrtime(); | 956 | tv = gethrtime(); |
957 | add_randomness( &tv, sizeof(tv), 1 ); | 957 | add_randomness( &tv, sizeof(tv), 1 ); |
958 | } | 958 | } |
959 | #elif HAVE_GETTIMEOFDAY | 959 | #elif HAVE_GETTIMEOFDAY |
960 | { | 960 | { |
961 | struct timeval tv; | 961 | struct timeval tv; |
962 | if( gettimeofday( &tv, NULL ) ) | 962 | if( gettimeofday( &tv, NULL ) ) |
963 | BUG(); | 963 | BUG(); |
964 | add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); | 964 | add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); |
965 | add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 ); | 965 | add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 ); |
966 | } | 966 | } |
967 | #elif HAVE_CLOCK_GETTIME | 967 | #elif HAVE_CLOCK_GETTIME |
968 | { struct timespec tv; | 968 | { struct timespec tv; |
969 | if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 ) | 969 | if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 ) |
970 | BUG(); | 970 | BUG(); |
971 | add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); | 971 | add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); |
972 | add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 ); | 972 | add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 ); |
973 | } | 973 | } |
974 | #else /* use times */ | 974 | #else /* use times */ |
975 | # ifndef HAVE_DOSISH_SYSTEM | 975 | # ifndef HAVE_DOSISH_SYSTEM |
976 | { struct tms buf; | 976 | { struct tms buf; |
977 | times( &buf ); | 977 | times( &buf ); |
978 | add_randomness( &buf, sizeof buf, 1 ); | 978 | add_randomness( &buf, sizeof buf, 1 ); |
979 | } | 979 | } |
980 | # endif | 980 | # endif |
981 | #endif | 981 | #endif |
982 | 982 | ||
983 | #ifdef HAVE_GETRUSAGE | 983 | #ifdef HAVE_GETRUSAGE |
984 | # ifdef RUSAGE_SELF | 984 | # ifdef RUSAGE_SELF |
985 | { | 985 | { |
986 | struct rusage buf; | 986 | struct rusage buf; |
987 | /* QNX/Neutrino does return ENOSYS - so we just ignore it and | 987 | /* QNX/Neutrino does return ENOSYS - so we just ignore it and |
988 | * add whatever is in buf. In a chroot environment it might not | 988 | * add whatever is in buf. In a chroot environment it might not |
989 | * work at all (i.e. because /proc/ is not accessible), so we better | 989 | * work at all (i.e. because /proc/ is not accessible), so we better |
990 | * ugnore all error codes and hope for the best | 990 | * ugnore all error codes and hope for the best |
991 | */ | 991 | */ |
992 | getrusage (RUSAGE_SELF, &buf ); | 992 | getrusage (RUSAGE_SELF, &buf ); |
993 | add_randomness( &buf, sizeof buf, 1 ); | 993 | add_randomness( &buf, sizeof buf, 1 ); |
994 | memset( &buf, 0, sizeof buf ); | 994 | memset( &buf, 0, sizeof buf ); |
995 | } | 995 | } |
996 | # else /*!RUSAGE_SELF*/ | 996 | # else /*!RUSAGE_SELF*/ |
997 | # ifdef __GCC__ | 997 | # ifdef __GCC__ |
998 | # warning There is no RUSAGE_SELF on this system | 998 | # warning There is no RUSAGE_SELF on this system |
999 | # endif | 999 | # endif |
1000 | # endif /*!RUSAGE_SELF*/ | 1000 | # endif /*!RUSAGE_SELF*/ |
1001 | #endif /*HAVE_GETRUSAGE*/ | 1001 | #endif /*HAVE_GETRUSAGE*/ |
1002 | 1002 | ||
1003 | /* time and clock are availabe on all systems - so we better do it | 1003 | /* time and clock are availabe on all systems - so we better do it |
1004 | just in case one of the above functions didn't work */ | 1004 | just in case one of the above functions didn't work */ |
1005 | { | 1005 | { |
1006 | time_t x = time(NULL); | 1006 | time_t x = time(NULL); |
1007 | add_randomness( &x, sizeof(x), 1 ); | 1007 | add_randomness( &x, sizeof(x), 1 ); |
1008 | } | 1008 | } |
1009 | { | 1009 | { |
1010 | clock_t x = clock(); | 1010 | clock_t x = clock(); |
1011 | add_randomness( &x, sizeof(x), 1 ); | 1011 | add_randomness( &x, sizeof(x), 1 ); |
1012 | } | 1012 | } |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | 1015 | ||
1016 | /* The fast random pool function as called at some places in | 1016 | /* The fast random pool function as called at some places in |
1017 | libgcrypt. This is merely a wrapper to make sure that this module | 1017 | libgcrypt. This is merely a wrapper to make sure that this module |
1018 | is initalized and to look the pool. Note, that this function is a | 1018 | is initalized and to look the pool. Note, that this function is a |
1019 | NOP unless a random function has been used or _gcry_initialize (1) | 1019 | NOP unless a random function has been used or _gcry_initialize (1) |
1020 | has been used. We use this hack so that the internal use of this | 1020 | has been used. We use this hack so that the internal use of this |
1021 | function in cipher_open and md_open won't start filling up the | 1021 | function in cipher_open and md_open won't start filling up the |
1022 | radnom pool, even if no random will be required by the process. */ | 1022 | radnom pool, even if no random will be required by the process. */ |
1023 | void | 1023 | void |
1024 | _gcry_fast_random_poll (void) | 1024 | _gcry_fast_random_poll (void) |
1025 | { | 1025 | { |
1026 | int err; | 1026 | int err; |
1027 | 1027 | ||
1028 | if (!is_initialized) | 1028 | if (!is_initialized) |
1029 | return; | 1029 | return; |
1030 | 1030 | ||
1031 | err = ath_mutex_lock (&pool_lock); | 1031 | err = ath_mutex_lock (&pool_lock); |
1032 | if (err) | 1032 | if (err) |
1033 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | 1033 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); |
1034 | pool_is_locked = 1; | 1034 | pool_is_locked = 1; |
1035 | 1035 | ||
1036 | do_fast_random_poll (); | 1036 | do_fast_random_poll (); |
1037 | 1037 | ||
1038 | pool_is_locked = 0; | 1038 | pool_is_locked = 0; |
1039 | err = ath_mutex_unlock (&pool_lock); | 1039 | err = ath_mutex_unlock (&pool_lock); |
1040 | if (err) | 1040 | if (err) |
1041 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); | 1041 | log_fatal ("failed to acquire the pool lock: %s\n", strerror (err)); |
1042 | 1042 | ||
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | 1045 | ||
1046 | 1046 | ||
1047 | static void | 1047 | static void |
1048 | read_random_source( int requester, size_t length, int level ) | 1048 | read_random_source( int requester, size_t length, int level ) |
1049 | { | 1049 | { |
1050 | static int (*fnc)(void (*)(const void*, size_t, int), int, | 1050 | static int (*fnc)(void (*)(const void*, size_t, int), int, |
1051 | size_t, int) = NULL; | 1051 | size_t, int) = NULL; |
1052 | if (!fnc ) | 1052 | if (!fnc ) |
1053 | { | 1053 | { |
1054 | if (!is_initialized ) | 1054 | if (!is_initialized ) |
1055 | initialize(); | 1055 | initialize(); |
1056 | 1056 | ||
1057 | fnc = getfnc_gather_random (); | 1057 | fnc = getfnc_gather_random (); |
1058 | 1058 | ||
1059 | if (!fnc) | 1059 | if (!fnc) |
1060 | { | 1060 | { |
1061 | faked_rng = 1; | 1061 | faked_rng = 1; |
1062 | fnc = gather_faked; | 1062 | fnc = gather_faked; |
1063 | } | 1063 | } |
1064 | if (!requester && !length && !level) | 1064 | if (!requester && !length && !level) |
1065 | return; /* Just the init was requested. */ | 1065 | return; /* Just the init was requested. */ |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | if ((*fnc)( add_randomness, requester, length, level ) < 0) | 1068 | if ((*fnc)( add_randomness, requester, length, level ) < 0) |
1069 | log_fatal ("No way to gather entropy for the RNG\n"); | 1069 | log_fatal ("No way to gather entropy for the RNG\n"); |
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | 1072 | ||
1073 | static int | 1073 | static int |
1074 | gather_faked( void (*add)(const void*, size_t, int), int requester, | 1074 | gather_faked( void (*add)(const void*, size_t, int), int requester, |
1075 | size_t length, int level ) | 1075 | size_t length, int level ) |
1076 | { | 1076 | { |
1077 | static int initialized=0; | 1077 | static int initialized=0; |
1078 | size_t n; | 1078 | size_t n; |
1079 | char *buffer, *p; | 1079 | char *buffer, *p; |
1080 | 1080 | ||
1081 | if( !initialized ) { | 1081 | if( !initialized ) { |
1082 | log_info(_("WARNING: using insecure random number generator!!\n")); | 1082 | log_info(_("WARNING: using insecure random number generator!!\n")); |
1083 | /* we can't use tty_printf here - do we need this function at | 1083 | /* we can't use tty_printf here - do we need this function at |
1084 | all - does it really make sense or canit be viewed as a potential | 1084 | all - does it really make sense or canit be viewed as a potential |
1085 | security problem ? wk 17.11.99 */ | 1085 | security problem ? wk 17.11.99 */ |
1086 | #if 0 | 1086 | #if 0 |
1087 | tty_printf(_("The random number generator is only a kludge to let\n" | 1087 | tty_printf(_("The random number generator is only a kludge to let\n" |
1088 | "it run - it is in no way a strong RNG!\n\n" | 1088 | "it run - it is in no way a strong RNG!\n\n" |
1089 | "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n")); | 1089 | "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n")); |
1090 | #endif | 1090 | #endif |
1091 | initialized=1; | 1091 | initialized=1; |
1092 | #ifdef HAVE_RAND | 1092 | #ifdef HAVE_RAND |
1093 | srand( time(NULL)*getpid()); | 1093 | srand( time(NULL)*getpid()); |
1094 | #else | 1094 | #else |
1095 | srandom( time(NULL)*getpid()); | 1095 | srandom( time(NULL)*getpid()); |
1096 | #endif | 1096 | #endif |
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | p = buffer = gcry_xmalloc( length ); | 1099 | p = buffer = gcry_xmalloc( length ); |
1100 | n = length; | 1100 | n = length; |
1101 | #ifdef HAVE_RAND | 1101 | #ifdef HAVE_RAND |
1102 | while( n-- ) | 1102 | while( n-- ) |
1103 | *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1); | 1103 | *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1); |
1104 | #else | 1104 | #else |
1105 | while( n-- ) | 1105 | while( n-- ) |
1106 | *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); | 1106 | *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); |
1107 | #endif | 1107 | #endif |
1108 | add_randomness( buffer, length, requester ); | 1108 | add_randomness( buffer, length, requester ); |
1109 | gcry_free(buffer); | 1109 | gcry_free(buffer); |
1110 | return 0; /* okay */ | 1110 | return 0; /* okay */ |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | 1113 | ||
1114 | /* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ | 1114 | /* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ |
1115 | void | 1115 | void |
1116 | gcry_create_nonce (void *buffer, size_t length) | 1116 | gcry_create_nonce (void *buffer, size_t length) |
1117 | { | 1117 | { |
1118 | static unsigned char nonce_buffer[20+8]; | 1118 | static unsigned char nonce_buffer[20+8]; |
1119 | static int nonce_buffer_initialized = 0; | 1119 | static int nonce_buffer_initialized = 0; |
1120 | static volatile pid_t my_pid; /* The volatile is there to make sure the | 1120 | static volatile pid_t my_pid; /* The volatile is there to make sure the |
1121 | compiler does not optimize the code away | 1121 | compiler does not optimize the code away |
1122 | in case the getpid function is badly | 1122 | in case the getpid function is badly |
1123 | attributed. */ | 1123 | attributed. */ |
1124 | unsigned char *p; | 1124 | unsigned char *p; |
1125 | size_t n; | 1125 | size_t n; |
1126 | int err; | 1126 | int err; |
1127 | 1127 | ||
1128 | /* Make sure we are initialized. */ | 1128 | /* Make sure we are initialized. */ |
1129 | if (!is_initialized) | 1129 | if (!is_initialized) |
1130 | initialize (); | 1130 | initialize (); |
1131 | 1131 | ||
1132 | /* Acquire the nonce buffer lock. */ | 1132 | /* Acquire the nonce buffer lock. */ |
1133 | err = ath_mutex_lock (&nonce_buffer_lock); | 1133 | err = ath_mutex_lock (&nonce_buffer_lock); |
1134 | if (err) | 1134 | if (err) |
1135 | log_fatal ("failed to acquire the nonce buffer lock: %s\n", | 1135 | log_fatal ("failed to acquire the nonce buffer lock: %s\n", |
1136 | strerror (err)); | 1136 | strerror (err)); |
1137 | 1137 | ||
1138 | /* The first time intialize our buffer. */ | 1138 | /* The first time intialize our buffer. */ |
1139 | if (!nonce_buffer_initialized) | 1139 | if (!nonce_buffer_initialized) |
1140 | { | 1140 | { |
1141 | pid_t apid = getpid (); | 1141 | pid_t apid = getpid (); |
1142 | time_t atime = time (NULL); | 1142 | time_t atime = time (NULL); |
1143 | 1143 | ||
1144 | my_pid = apid; | 1144 | my_pid = apid; |
1145 | 1145 | ||
1146 | if ((sizeof apid + sizeof atime) > sizeof nonce_buffer) | 1146 | if ((sizeof apid + sizeof atime) > sizeof nonce_buffer) |
1147 | BUG (); | 1147 | BUG (); |
1148 | 1148 | ||
1149 | /* Initialize the first 20 bytes with a reasonable value so that | 1149 | /* Initialize the first 20 bytes with a reasonable value so that |
1150 | a failure of gcry_randomize won't affect us too much. Don't | 1150 | a failure of gcry_randomize won't affect us too much. Don't |
1151 | care about the uninitialized remaining bytes. */ | 1151 | care about the uninitialized remaining bytes. */ |
1152 | p = nonce_buffer; | 1152 | p = nonce_buffer; |
1153 | memcpy (p, &apid, sizeof apid); | 1153 | memcpy (p, &apid, sizeof apid); |
1154 | p += sizeof apid; | 1154 | p += sizeof apid; |
1155 | memcpy (p, &atime, sizeof atime); | 1155 | memcpy (p, &atime, sizeof atime); |
1156 | 1156 | ||
1157 | /* Initialize the never changing private part of 64 bits. */ | 1157 | /* Initialize the never changing private part of 64 bits. */ |
1158 | gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); | 1158 | gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); |
1159 | 1159 | ||
1160 | nonce_buffer_initialized = 1; | 1160 | nonce_buffer_initialized = 1; |
1161 | } | 1161 | } |
1162 | else if ( my_pid != getpid () ) | 1162 | else if ( my_pid != getpid () ) |
1163 | { | 1163 | { |
1164 | /* We forked. Need to reseed the buffer - doing this for the | 1164 | /* We forked. Need to reseed the buffer - doing this for the |
1165 | private part should be sufficient. */ | 1165 | private part should be sufficient. */ |
1166 | gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); | 1166 | gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); |
1167 | } | 1167 | } |
1168 | 1168 | ||
1169 | /* Create the nonce by hashing the entire buffer, returning the hash | 1169 | /* Create the nonce by hashing the entire buffer, returning the hash |
1170 | and updating the first 20 bytes of the buffer with this hash. */ | 1170 | and updating the first 20 bytes of the buffer with this hash. */ |
1171 | for (p = buffer; length > 0; length -= n, p += n) | 1171 | for (p = buffer; length > 0; length -= n, p += n) |
1172 | { | 1172 | { |
1173 | _gcry_sha1_hash_buffer ((char*)nonce_buffer, | 1173 | _gcry_sha1_hash_buffer ((char*)nonce_buffer, |
1174 | (char*)nonce_buffer, sizeof nonce_buffer); | 1174 | (char*)nonce_buffer, sizeof nonce_buffer); |
1175 | n = length > 20? 20 : length; | 1175 | n = length > 20? 20 : length; |
1176 | memcpy (p, nonce_buffer, n); | 1176 | memcpy (p, nonce_buffer, n); |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | 1179 | ||
1180 | /* Release the nonce buffer lock. */ | 1180 | /* Release the nonce buffer lock. */ |
1181 | err = ath_mutex_unlock (&nonce_buffer_lock); | 1181 | err = ath_mutex_unlock (&nonce_buffer_lock); |
1182 | if (err) | 1182 | if (err) |
1183 | log_fatal ("failed to release the nonce buffer lock: %s\n", | 1183 | log_fatal ("failed to release the nonce buffer lock: %s\n", |
1184 | strerror (err)); | 1184 | strerror (err)); |
1185 | 1185 | ||
1186 | } | 1186 | } |