md_rand.c 21.2 KB
Newer Older
1
/* crypto/rand/md_rand.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
B
Bodo Möller 已提交
58
/* ====================================================================
B
Bodo Möller 已提交
59
 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
B
Bodo Möller 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
111

112
#define OPENSSL_FIPSAPI
113

114
#ifdef MD_RAND_DEBUG
B
Bodo Möller 已提交
115 116 117 118 119 120
# ifndef NDEBUG
#   define NDEBUG
# endif
#endif

#include <assert.h>
121
#include <stdio.h>
B
Ben Laurie 已提交
122
#include <string.h>
123

124
#include "e_os.h"
125

126 127 128 129 130 131 132
#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYSNAME_DSPBIOS))
# include <sys/time.h>
#endif
#if defined(OPENSSL_SYS_VXWORKS)
# include <time.h>
#endif

133
#include <openssl/crypto.h>
134 135 136
#include <openssl/rand.h>
#include "rand_lcl.h"

137
#include <openssl/err.h>
138

139 140 141 142
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#endif

143 144 145 146
#ifdef BN_DEBUG
# define PREDICT
#endif

147
/* #define PREDICT	1 */
148 149 150

#define STATE_SIZE	1023
static int state_num=0,state_index=0;
151
static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
152
static unsigned char md[MD_DIGEST_LENGTH];
153
static long md_count[2]={0,0};
154
static double entropy=0;
U
Ulf Möller 已提交
155
static int initialized=0;
156

B
Bodo Möller 已提交
157 158 159
static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
                                           * holds CRYPTO_LOCK_RAND
                                           * (to prevent double locking) */
B
Bodo Möller 已提交
160
/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
161
static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
B
Bodo Möller 已提交
162

163

164 165 166 167
#ifdef PREDICT
int rand_predictable=0;
#endif

168
const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
169

170 171
static void rand_hw_seed(EVP_MD_CTX *ctx);

172
static void ssleay_rand_cleanup(void);
173 174
static int ssleay_rand_seed(const void *buf, int num);
static int ssleay_rand_add(const void *buf, int num, double add_entropy);
175 176
static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo);
static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
177
static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
178
static int ssleay_rand_status(void);
179

180
static RAND_METHOD rand_ssleay_meth={
181
	ssleay_rand_seed,
182
	ssleay_rand_nopseudo_bytes,
183
	ssleay_rand_cleanup,
184
	ssleay_rand_add,
185
	ssleay_rand_pseudo_bytes,
186
	ssleay_rand_status
187 188
	}; 

U
Ulf Möller 已提交
189
RAND_METHOD *RAND_SSLeay(void)
190
	{
191
	return(&rand_ssleay_meth);
192 193
	}

U
Ulf Möller 已提交
194
static void ssleay_rand_cleanup(void)
195
	{
196
	OPENSSL_cleanse(state,sizeof(state));
197 198
	state_num=0;
	state_index=0;
199
	OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
200 201
	md_count[0]=0;
	md_count[1]=0;
202
	entropy=0;
203
	initialized=0;
204 205
	}

206
static int ssleay_rand_add(const void *buf, int num, double add)
207
	{
208
	int i,j,k,st_idx;
B
Bodo Möller 已提交
209 210
	long md_c[2];
	unsigned char local_md[MD_DIGEST_LENGTH];
211
	EVP_MD_CTX m;
B
Bodo Möller 已提交
212
	int do_not_lock;
213
	int rv = 0;
214

B
Bodo Möller 已提交
215
	/*
U
Ulf Möller 已提交
216
	 * (Based on the rand(3) manpage)
B
Bodo Möller 已提交
217
	 *
218
	 * The input is chopped up into units of 20 bytes (or less for
U
Ulf Möller 已提交
219
	 * the last block).  Each of these blocks is run through the hash
220
	 * function as follows:  The data passed to the hash function
B
Bodo Möller 已提交
221 222 223 224 225
	 * is the current 'md', the same number of bytes from the 'state'
	 * (the location determined by in incremented looping index) as
	 * the current 'block', the new key data 'block', and 'count'
	 * (which is incremented after each use).
	 * The result of this is kept in 'md' and also xored into the
U
Ulf Möller 已提交
226 227
	 * 'state' at the same locations that were used as input into the
         * hash function.
B
Bodo Möller 已提交
228 229
	 */

230
	EVP_MD_CTX_init(&m);
B
Bodo Möller 已提交
231
	/* check if we already have the lock */
B
Bodo Möller 已提交
232 233
	if (crypto_lock_rand)
		{
234 235
		CRYPTO_THREADID cur;
		CRYPTO_THREADID_current(&cur);
B
Bodo Möller 已提交
236
		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
237
		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
B
Bodo Möller 已提交
238 239 240 241
		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
		}
	else
		do_not_lock = 0;
B
Bodo Möller 已提交
242 243

	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
244 245
	st_idx=state_index;

B
Bodo Möller 已提交
246 247 248 249 250 251 252 253 254 255 256
	/* use our own copies of the counters so that even
	 * if a concurrent thread seeds with exactly the
	 * same data and uses the same subarray there's _some_
	 * difference */
	md_c[0] = md_count[0];
	md_c[1] = md_count[1];

	memcpy(local_md, md, sizeof md);

	/* state_index <= state_num <= STATE_SIZE */
	state_index += num;
257
	if (state_index >= STATE_SIZE)
258 259 260 261 262 263 264 265 266
		{
		state_index%=STATE_SIZE;
		state_num=STATE_SIZE;
		}
	else if (state_num < STATE_SIZE)	
		{
		if (state_index > state_num)
			state_num=state_index;
		}
B
Bodo Möller 已提交
267 268 269 270 271 272 273 274
	/* state_index <= state_num <= STATE_SIZE */

	/* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
	 * are what we will use now, but other threads may use them
	 * as well */

	md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);

B
Bodo Möller 已提交
275
	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
276 277 278 279 280 281

	for (i=0; i<num; i+=MD_DIGEST_LENGTH)
		{
		j=(num-i);
		j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;

282 283 284 285
		if (!MD_Init(&m))
			goto err;
		if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
			goto err;
286 287 288
		k=(st_idx+j)-STATE_SIZE;
		if (k > 0)
			{
289 290 291 292
			if (!MD_Update(&m,&(state[st_idx]),j-k))
				goto err;
			if (!MD_Update(&m,&(state[0]),k))
				goto err;
293 294
			}
		else
295 296
			if (!MD_Update(&m,&(state[st_idx]),j))
				goto err;
R
Richard Levitte 已提交
297 298

		/* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
299 300
		if (!MD_Update(&m,buf,j))
			goto err;
R
Richard Levitte 已提交
301 302 303 304 305 306 307
		/* We know that line may cause programs such as
		   purify and valgrind to complain about use of
		   uninitialized data.  The problem is not, it's
		   with the caller.  Removing that line will make
		   sure you get really bad randomness and thereby
		   other problems such as very insecure keys. */

308 309 310 311
		if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)))
			goto err;
		if (!MD_Final(&m,local_md))
			goto err;
B
Bodo Möller 已提交
312
		md_c[1]++;
313

B
Ben Laurie 已提交
314
		buf=(const char *)buf + j;
315 316 317

		for (k=0; k<j; k++)
			{
B
Bodo Möller 已提交
318 319 320 321 322 323 324 325 326
			/* Parallel threads may interfere with this,
			 * but always each byte of the new state is
			 * the XOR of some previous value of its
			 * and local_md (itermediate values may be lost).
			 * Alway using locking could hurt performance more
			 * than necessary given that conflicts occur only
			 * when the total seeding is longer than the random
			 * state. */
			state[st_idx++]^=local_md[k];
327 328 329 330
			if (st_idx >= STATE_SIZE)
				st_idx=0;
			}
		}
B
Bodo Möller 已提交
331

B
Bodo Möller 已提交
332
	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
B
Bodo Möller 已提交
333 334 335 336
	/* Don't just copy back local_md into md -- this could mean that
	 * other thread's seeding remains without effect (except for
	 * the incremented counter).  By XORing it we keep at least as
	 * much entropy as fits into md. */
337
	for (k = 0; k < (int)sizeof(md); k++)
B
Bodo Möller 已提交
338 339 340
		{
		md[k] ^= local_md[k];
		}
B
Bodo Möller 已提交
341 342
	if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
	    entropy += add;
B
Bodo Möller 已提交
343
	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
B
Bodo Möller 已提交
344
	
345
#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
B
Bodo Möller 已提交
346 347
	assert(md_c[1] == md_count[1]);
#endif
348 349 350 351
	rv = 1;
	err:
	EVP_MD_CTX_cleanup(&m);
	return rv;
352 353
	}

354
static int ssleay_rand_seed(const void *buf, int num)
355
	{
356
	return ssleay_rand_add(buf, num, (double)num);
357 358
	}

359
static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
360
	{
B
Bodo Möller 已提交
361
	static volatile int stirred_pool = 0;
362
	int i,j,k,st_num,st_idx;
B
Bodo Möller 已提交
363
	int num_ceil;
364
	int ok;
B
Bodo Möller 已提交
365 366
	long md_c[2];
	unsigned char local_md[MD_DIGEST_LENGTH];
367
	EVP_MD_CTX m;
A
Andy Polyakov 已提交
368
#ifndef GETPID_IS_MEANINGLESS
369
	pid_t curr_pid = getpid();
B
Bodo Möller 已提交
370
#endif
371
	time_t curr_time = time(NULL);
B
Bodo Möller 已提交
372
	int do_stir_pool = 0;
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
/* time value for various platforms */
#ifdef OPENSSL_SYS_WIN32
	FILETIME tv;
# ifdef _WIN32_WCE
	SYSTEMTIME t;
	GetSystemTime(&t);
	SystemTimeToFileTime(&t, &tv);
# else
	GetSystemTimeAsFileTime(&tv);
# endif
#elif defined(OPENSSL_SYS_VXWORKS)
	struct timespec tv;
	clock_gettime(CLOCK_REALTIME, &ts);
#elif defined(OPENSSL_SYSNAME_DSPBIOS)
	unsigned long long tv, OPENSSL_rdtsc();
	tv = OPENSSL_rdtsc();
#else
	struct timeval tv;
391
	gettimeofday(&tv, NULL);
392
#endif
393

394
#ifdef PREDICT
395 396 397
	if (rand_predictable)
		{
		static unsigned char val=0;
398

399 400 401 402
		for (i=0; i<num; i++)
			buf[i]=val++;
		return(1);
		}
403 404
#endif

B
Bodo Möller 已提交
405 406
	if (num <= 0)
		return 1;
407 408

	EVP_MD_CTX_init(&m);
B
Bodo Möller 已提交
409 410 411
	/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
	num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);

B
Bodo Möller 已提交
412
	/*
B
Bodo Möller 已提交
413
	 * (Based on the rand(3) manpage:)
B
Bodo Möller 已提交
414
	 *
415
	 * For each group of 10 bytes (or less), we do the following:
B
Bodo Möller 已提交
416
	 *
B
Bodo Möller 已提交
417 418 419 420 421 422 423
	 * Input into the hash function the local 'md' (which is initialized from
	 * the global 'md' before any bytes are generated), the bytes that are to
	 * be overwritten by the random bytes, and bytes from the 'state'
	 * (incrementing looping index). From this digest output (which is kept
	 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
	 * bottom 10 bytes are xored into the 'state'.
	 * 
B
Bodo Möller 已提交
424
	 * Finally, after we have finished 'num' random bytes for the
B
Bodo Möller 已提交
425 426 427
	 * caller, 'count' (which is incremented) and the local and global 'md'
	 * are fed into the hash function and the results are kept in the
	 * global 'md'.
B
Bodo Möller 已提交
428 429
	 */

430
	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
431

B
Bodo Möller 已提交
432
	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
B
Bodo Möller 已提交
433
	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
434
	CRYPTO_THREADID_current(&locking_threadid);
B
Bodo Möller 已提交
435
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
B
Bodo Möller 已提交
436
	crypto_lock_rand = 1;
B
Bodo Möller 已提交
437 438 439 440 441 442 443

	if (!initialized)
		{
		RAND_poll();
		initialized = 1;
		}
	
B
Bodo Möller 已提交
444 445 446
	if (!stirred_pool)
		do_stir_pool = 1;
	
447
	ok = (entropy >= ENTROPY_NEEDED);
B
Bodo Möller 已提交
448 449 450 451 452 453 454 455
	if (!ok)
		{
		/* If the PRNG state is not yet unpredictable, then seeing
		 * the PRNG output may help attackers to determine the new
		 * state; thus we have to decrease the entropy estimate.
		 * Once we've had enough initial seeding we don't bother to
		 * adjust the entropy count, though, because we're not ambitious
		 * to provide *information-theoretic* randomness.
B
Bodo Möller 已提交
456 457 458 459 460
		 *
		 * NOTE: This approach fails if the program forks before
		 * we have enough entropy. Entropy should be collected
		 * in a separate input pool and be transferred to the
		 * output pool only when the entropy limit has been reached.
B
Bodo Möller 已提交
461 462 463 464 465
		 */
		entropy -= num;
		if (entropy < 0)
			entropy = 0;
		}
466

B
Bodo Möller 已提交
467 468
	if (do_stir_pool)
		{
B
Bodo Möller 已提交
469 470 471 472 473
		/* In the output function only half of 'md' remains secret,
		 * so we better make sure that the required entropy gets
		 * 'evenly distributed' through 'state', our randomness pool.
		 * The input function (ssleay_rand_add) chains all of 'md',
		 * which makes it more suitable for this purpose.
B
Bodo Möller 已提交
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
		 */

		int n = STATE_SIZE; /* so that the complete pool gets accessed */
		while (n > 0)
			{
#if MD_DIGEST_LENGTH > 20
# error "Please adjust DUMMY_SEED."
#endif
#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
			/* Note that the seed does not matter, it's just that
			 * ssleay_rand_add expects to have something to hash. */
			ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
			n -= MD_DIGEST_LENGTH;
			}
		if (ok)
			stirred_pool = 1;
		}

492 493
	st_idx=state_index;
	st_num=state_num;
B
Bodo Möller 已提交
494 495 496 497
	md_c[0] = md_count[0];
	md_c[1] = md_count[1];
	memcpy(local_md, md, sizeof md);

B
Bodo Möller 已提交
498
	state_index+=num_ceil;
499
	if (state_index > state_num)
B
Bodo Möller 已提交
500 501
		state_index %= state_num;

B
Bodo Möller 已提交
502
	/* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
B
Bodo Möller 已提交
503
	 * are now ours (but other threads may use them too) */
504

B
Bodo Möller 已提交
505
	md_count[0] += 1;
506

B
Bodo Möller 已提交
507 508
	/* before unlocking, we must clear 'crypto_lock_rand' */
	crypto_lock_rand = 0;
509 510 511 512
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	while (num > 0)
		{
B
Bodo Möller 已提交
513
		/* num_ceil -= MD_DIGEST_LENGTH/2 */
514 515
		j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
		num-=j;
516 517
		if (!MD_Init(&m))
			goto err;
A
Andy Polyakov 已提交
518
#ifndef GETPID_IS_MEANINGLESS
519 520
		if (curr_pid) /* just in the first iteration to save time */
			{
521 522
			if (!MD_Update(&m,(unsigned char*)&curr_pid,
				       sizeof curr_pid))
523
				goto err;
524 525 526
			curr_pid = 0;
			}
#endif
527 528 529 530 531 532 533 534
		if (curr_time) /* just in the first iteration to save time */
			{
			if (!MD_Update(&m,(unsigned char*)&curr_time,
				       sizeof curr_time))
				goto err;
			if (!MD_Update(&m,(unsigned char*)&tv,
				       sizeof tv))
				goto err;
535
			curr_time = 0;
536
			rand_hw_seed(&m);
537
			}
538 539 540 541
		if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
			goto err;
		if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)))
			goto err;
R
Richard Levitte 已提交
542 543

#ifndef PURIFY /* purify complains */
D
Dr. Stephen Henson 已提交
544 545 546 547 548 549 550
		/* The following line uses the supplied buffer as a small
		 * source of entropy: since this buffer is often uninitialised
		 * it may cause programs such as purify or valgrind to
		 * complain. So for those builds it is not used: the removal
		 * of such a small source of entropy has negligible impact on
		 * security.
		 */
551 552
		if (!MD_Update(&m,buf,j))
			goto err;
553
#endif
R
Richard Levitte 已提交
554

B
Bodo Möller 已提交
555
		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
556 557
		if (k > 0)
			{
558 559 560 561
			if (!MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k))
				goto err;
			if (!MD_Update(&m,&(state[0]),k))
				goto err;
562 563
			}
		else
564 565 566 567
			if (!MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2))
				goto err;
		if (!MD_Final(&m,local_md))
			goto err;
568

B
Bodo Möller 已提交
569
		for (i=0; i<MD_DIGEST_LENGTH/2; i++)
570
			{
B
Bodo Möller 已提交
571
			state[st_idx++]^=local_md[i]; /* may compete with other threads */
572 573
			if (st_idx >= st_num)
				st_idx=0;
B
Bodo Möller 已提交
574 575
			if (i < j)
				*(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
576 577 578
			}
		}

579 580 581 582
	if (!MD_Init(&m)
		|| !MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c))
		|| !MD_Update(&m,local_md,MD_DIGEST_LENGTH))
		goto err;
B
Bodo Möller 已提交
583
	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
584 585 586 587 588
	if (!MD_Update(&m,md,MD_DIGEST_LENGTH) || !MD_Final(&m,md))
		{
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
		goto err;
		}
B
Bodo Möller 已提交
589 590
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

591
	EVP_MD_CTX_cleanup(&m);
592 593
	if (ok)
		return(1);
594 595 596
	else if (pseudo)
		return 0;
	else 
597 598
		{
		RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
599 600
		ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
			"http://www.openssl.org/support/faq.html");
601 602
		return(0);
		}
603 604 605 606 607
	err:
	EVP_MD_CTX_cleanup(&m);
	RANDerr(RAND_F_SSLEAY_RAND_BYTES,ERR_R_EVP_LIB);
	return 0;

608 609
	}

610 611 612 613 614
static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
	{
	return ssleay_rand_bytes(buf, num, 0);
	}

615 616
/* pseudo-random bytes that are guaranteed to be unique but not
   unpredictable */
617
static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) 
618
	{
619
	return ssleay_rand_bytes(buf, num, 1);
620 621
	}

622
static int ssleay_rand_status(void)
U
Ulf Möller 已提交
623
	{
624
	CRYPTO_THREADID cur;
625
	int ret;
B
Bodo Möller 已提交
626
	int do_not_lock;
627

628
	CRYPTO_THREADID_current(&cur);
B
Bodo Möller 已提交
629 630
	/* check if we already have the lock
	 * (could happen if a RAND_poll() implementation calls RAND_status()) */
B
Bodo Möller 已提交
631 632 633
	if (crypto_lock_rand)
		{
		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
634
		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
B
Bodo Möller 已提交
635 636 637 638
		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
		}
	else
		do_not_lock = 0;
B
Bodo Möller 已提交
639 640 641 642 643 644
	
	if (!do_not_lock)
		{
		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
		
		/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
B
Bodo Möller 已提交
645
		CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
646
		CRYPTO_THREADID_cpy(&locking_threadid, &cur);
B
Bodo Möller 已提交
647
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
B
Bodo Möller 已提交
648
		crypto_lock_rand = 1;
B
Bodo Möller 已提交
649 650
		}
	
U
Ulf Möller 已提交
651
	if (!initialized)
B
Bodo Möller 已提交
652
		{
653
		RAND_poll();
B
Bodo Möller 已提交
654 655
		initialized = 1;
		}
656

657
	ret = entropy >= ENTROPY_NEEDED;
658

B
Bodo Möller 已提交
659 660 661 662 663 664 665 666
	if (!do_not_lock)
		{
		/* before unlocking, we must clear 'crypto_lock_rand' */
		crypto_lock_rand = 0;
		
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
		}
	
667
	return ret;
U
Ulf Möller 已提交
668
	}
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695

/* rand_hw_seed: get seed data from any available hardware RNG.
 * only currently supports rdrand.
 */

/* Adapted from eng_rdrand.c */

#if (defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
     defined(__x86_64) || defined(__x86_64__) || \
     defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)

#define RDRAND_CALLS	4

size_t OPENSSL_ia32_rdrand(void);
extern unsigned int OPENSSL_ia32cap_P[];

static void rand_hw_seed(EVP_MD_CTX *ctx)
	{
	int i;
	if (!(OPENSSL_ia32cap_P[1] & (1<<(62-32))))
		return;
	for (i = 0; i < RDRAND_CALLS; i++)
		{
		size_t rnd;
		rnd = OPENSSL_ia32_rdrand();
		if (rnd == 0)
			return;
D
typo  
Dr. Stephen Henson 已提交
696
		MD_Update(ctx, (unsigned char *)&rnd, sizeof(size_t));
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
		}
	}

/* XOR an existing buffer with random data */

void rand_hw_xor(unsigned char *buf, size_t num)
	{
	size_t rnd;
	if (!(OPENSSL_ia32cap_P[1] & (1<<(62-32))))
		return;
	while (num >= sizeof(size_t))
		{
		rnd = OPENSSL_ia32_rdrand();
		if (rnd == 0)
			return;
		*((size_t *)buf) ^= rnd;
		buf += sizeof(size_t);
		num -= sizeof(size_t);
		}
	if (num)
		{
		rnd = OPENSSL_ia32_rdrand();
		if (rnd == 0)
			return;
		while(num)
			{
			*buf ^= rnd & 0xff;
			rnd >>= 8;
			buf++;
			num--;
			}
		}
	}


#else

static void rand_hw_seed(EVP_MD_CTX *ctx)
	{
	return;
	}

void rand_hw_xor(unsigned char *buf, size_t num)
	{
	return;
	}

#endif