aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/random.c
diff options
context:
space:
mode:
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.c2372
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
89static int is_initialized; 89static int is_initialized;
90#define MASK_LEVEL(a) do { (a) &= 3; } while(0) 90#define MASK_LEVEL(a) do { (a) &= 3; } while(0)
91static unsigned char *rndpool; /* allocated size is POOLSIZE+BLOCKLEN */ 91static unsigned char *rndpool; /* allocated size is POOLSIZE+BLOCKLEN */
92static unsigned char *keypool; /* allocated size is POOLSIZE+BLOCKLEN */ 92static unsigned char *keypool; /* allocated size is POOLSIZE+BLOCKLEN */
93static size_t pool_readpos; 93static size_t pool_readpos;
94static size_t pool_writepos; 94static size_t pool_writepos;
95static int pool_filled; 95static int pool_filled;
96static int pool_balance; 96static int pool_balance;
97static int just_mixed; 97static int just_mixed;
98static int did_initial_extra_seeding; 98static int did_initial_extra_seeding;
99static char *seed_file_name; 99static char *seed_file_name;
100static int allow_seed_file_update; 100static int allow_seed_file_update;
101 101
102static int secure_alloc; 102static int secure_alloc;
103static int quick_test; 103static int quick_test;
104static int faked_rng; 104static int faked_rng;
105 105
106static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER; 106static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
107static int pool_is_locked; /* only used for assertion */ 107static int pool_is_locked; /* only used for assertion */
108 108
109static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER; 109static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER;
110 110
111static byte *get_random_bytes( size_t nbytes, int level, int secure ); 111static byte *get_random_bytes( size_t nbytes, int level, int secure );
112static void read_pool( byte *buffer, size_t length, int level ); 112static void read_pool( byte *buffer, size_t length, int level );
113static void add_randomness( const void *buffer, size_t length, int source ); 113static void add_randomness( const void *buffer, size_t length, int source );
114static void random_poll(void); 114static void random_poll(void);
115static void do_fast_random_poll (void); 115static void do_fast_random_poll (void);
116static void read_random_source( int requester, size_t length, int level); 116static void read_random_source( int requester, size_t length, int level);
117static int gather_faked( void (*add)(const void*, size_t, int), int requester, 117static 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
120static struct { 120static 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
133static void (*progress_cb) (void *,const char*,int,int, int ); 133static void (*progress_cb) (void *,const char*,int,int, int );
134static void *progress_cb_data; 134static 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. */
138static void 138static void
139initialize_basics(void) 139initialize_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
159static void 159static void
160initialize(void) 160initialize(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. */
176void 176void
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. */
187void 187void
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. */
199void 199void
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
208void 208void
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
220void 220void
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
227int 227int
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
242int 242int
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 */
254static byte * 254static byte *
255get_random_bytes ( size_t nbytes, int level, int secure) 255get_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*/
317gcry_error_t 317gcry_error_t
318gcry_random_add_bytes (const void * buf, size_t buflen, int quality) 318gcry_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. */
336void * 336void *
337gcry_random_bytes( size_t nbytes, enum gcry_random_level level ) 337gcry_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. */
347void * 347void *
348gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level ) 348gcry_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. */
360void 360void
361gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) 361gcry_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 */
454static void 454static void
455mix_pool (unsigned char *pool) 455mix_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
524void 524void
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 */
537static int 537static int
538read_seed_file (void) 538read_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
634void 634void
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. */
698static void 698static void
699read_pool (byte *buffer, size_t length, int level) 699read_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 */
846static void 846static void
847add_randomness( const void *buffer, size_t length, int source ) 847add_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
872static void 872static void
873random_poll() 873random_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
880static int (* 880static int (*
881getfnc_gather_random (void))(void (*)(const void*, size_t, int), int, 881getfnc_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
921static void (* 921static void (*
922getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int) 922getfnc_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
931static void 931static void
932do_fast_random_poll (void) 932do_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. */
1023void 1023void
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
1047static void 1047static void
1048read_random_source( int requester, size_t length, int level ) 1048read_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
1073static int 1073static int
1074gather_faked( void (*add)(const void*, size_t, int), int requester, 1074gather_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. */
1115void 1115void
1116gcry_create_nonce (void *buffer, size_t length) 1116gcry_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}