os/ossrv/ssl/libcrypto/src/crypto/rand/md_rand.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/rand/md_rand.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,630 @@
     1.4 +/* crypto/rand/md_rand.c */
     1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
     1.6 + * All rights reserved.
     1.7 + *
     1.8 + * This package is an SSL implementation written
     1.9 + * by Eric Young (eay@cryptsoft.com).
    1.10 + * The implementation was written so as to conform with Netscapes SSL.
    1.11 + * 
    1.12 + * This library is free for commercial and non-commercial use as long as
    1.13 + * the following conditions are aheared to.  The following conditions
    1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
    1.15 + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    1.16 + * included with this distribution is covered by the same copyright terms
    1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    1.18 + * 
    1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
    1.20 + * the code are not to be removed.
    1.21 + * If this package is used in a product, Eric Young should be given attribution
    1.22 + * as the author of the parts of the library used.
    1.23 + * This can be in the form of a textual message at program startup or
    1.24 + * in documentation (online or textual) provided with the package.
    1.25 + * 
    1.26 + * Redistribution and use in source and binary forms, with or without
    1.27 + * modification, are permitted provided that the following conditions
    1.28 + * are met:
    1.29 + * 1. Redistributions of source code must retain the copyright
    1.30 + *    notice, this list of conditions and the following disclaimer.
    1.31 + * 2. Redistributions in binary form must reproduce the above copyright
    1.32 + *    notice, this list of conditions and the following disclaimer in the
    1.33 + *    documentation and/or other materials provided with the distribution.
    1.34 + * 3. All advertising materials mentioning features or use of this software
    1.35 + *    must display the following acknowledgement:
    1.36 + *    "This product includes cryptographic software written by
    1.37 + *     Eric Young (eay@cryptsoft.com)"
    1.38 + *    The word 'cryptographic' can be left out if the rouines from the library
    1.39 + *    being used are not cryptographic related :-).
    1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from 
    1.41 + *    the apps directory (application code) you must include an acknowledgement:
    1.42 + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    1.43 + * 
    1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.47 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.54 + * SUCH DAMAGE.
    1.55 + * 
    1.56 + * The licence and distribution terms for any publically available version or
    1.57 + * derivative of this code cannot be changed.  i.e. this code cannot simply be
    1.58 + * copied and put under another distribution licence
    1.59 + * [including the GNU Public Licence.]
    1.60 + */
    1.61 +/* ====================================================================
    1.62 + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
    1.63 + *
    1.64 + * Redistribution and use in source and binary forms, with or without
    1.65 + * modification, are permitted provided that the following conditions
    1.66 + * are met:
    1.67 + *
    1.68 + * 1. Redistributions of source code must retain the above copyright
    1.69 + *    notice, this list of conditions and the following disclaimer. 
    1.70 + *
    1.71 + * 2. Redistributions in binary form must reproduce the above copyright
    1.72 + *    notice, this list of conditions and the following disclaimer in
    1.73 + *    the documentation and/or other materials provided with the
    1.74 + *    distribution.
    1.75 + *
    1.76 + * 3. All advertising materials mentioning features or use of this
    1.77 + *    software must display the following acknowledgment:
    1.78 + *    "This product includes software developed by the OpenSSL Project
    1.79 + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
    1.80 + *
    1.81 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    1.82 + *    endorse or promote products derived from this software without
    1.83 + *    prior written permission. For written permission, please contact
    1.84 + *    openssl-core@openssl.org.
    1.85 + *
    1.86 + * 5. Products derived from this software may not be called "OpenSSL"
    1.87 + *    nor may "OpenSSL" appear in their names without prior written
    1.88 + *    permission of the OpenSSL Project.
    1.89 + *
    1.90 + * 6. Redistributions of any form whatsoever must retain the following
    1.91 + *    acknowledgment:
    1.92 + *    "This product includes software developed by the OpenSSL Project
    1.93 + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
    1.94 + *
    1.95 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    1.96 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.97 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.98 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    1.99 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   1.100 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   1.101 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   1.102 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   1.103 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   1.104 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   1.105 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   1.106 + * OF THE POSSIBILITY OF SUCH DAMAGE.
   1.107 + * ====================================================================
   1.108 + *
   1.109 + * This product includes cryptographic software written by Eric Young
   1.110 + * (eay@cryptsoft.com).  This product includes software written by Tim
   1.111 + * Hudson (tjh@cryptsoft.com).
   1.112 + *
   1.113 + */
   1.114 + /*
   1.115 + © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
   1.116 + */
   1.117 +
   1.118 +
   1.119 +#ifdef MD_RAND_DEBUG
   1.120 +# ifndef NDEBUG
   1.121 +#   define NDEBUG
   1.122 +# endif
   1.123 +#endif
   1.124 +
   1.125 +#include <assert.h>
   1.126 +#include <stdio.h>
   1.127 +#include <string.h>
   1.128 +
   1.129 +#include "e_os.h"
   1.130 +
   1.131 +#include <openssl/rand.h>
   1.132 +#include "rand_lcl.h"
   1.133 +
   1.134 +#include <openssl/crypto.h>
   1.135 +#include <openssl/err.h>
   1.136 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
   1.137 +#include "libcrypto_wsd_macros.h"
   1.138 +#include "libcrypto_wsd.h"
   1.139 +#endif
   1.140 +
   1.141 +
   1.142 +#ifdef BN_DEBUG
   1.143 +# define PREDICT
   1.144 +#endif
   1.145 +
   1.146 +/* #define PREDICT	1 */
   1.147 +
   1.148 +#define STATE_SIZE	1023
   1.149 +
   1.150 +#ifndef EMULATOR
   1.151 +static int state_num=0,state_index=0;
   1.152 +static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
   1.153 +static unsigned char md[MD_DIGEST_LENGTH];
   1.154 +static long md_count[2]={0,0};
   1.155 +static double entropy=0;
   1.156 +static int initialized=0;
   1.157 +
   1.158 +static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
   1.159 +                                           * holds CRYPTO_LOCK_RAND
   1.160 +                                           * (to prevent double locking) */
   1.161 +/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
   1.162 +static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */
   1.163 +#else
   1.164 +GET_STATIC_VAR_FROM_TLS(state_num,md_rand,int)
   1.165 +#define state_num (*GET_WSD_VAR_NAME(state_num,md_rand, s)())
   1.166 +
   1.167 +GET_STATIC_VAR_FROM_TLS(state_index,md_rand,int)
   1.168 +#define state_index (*GET_WSD_VAR_NAME(state_index,md_rand, s)())
   1.169 +
   1.170 +GET_STATIC_ARRAY_FROM_TLS(state,md_rand,unsigned char)
   1.171 +#define state (GET_WSD_VAR_NAME(state,md_rand, s)())
   1.172 +
   1.173 +GET_STATIC_ARRAY_FROM_TLS(md,md_rand,unsigned char)
   1.174 +#define md (GET_WSD_VAR_NAME(md,md_rand, s)())
   1.175 + 
   1.176 +GET_STATIC_ARRAY_FROM_TLS(md_count,md_rand,unsigned char)
   1.177 +#define md_count (GET_WSD_VAR_NAME(md_count,md_rand, s)())
   1.178 + 
   1.179 +GET_STATIC_VAR_FROM_TLS(entropy,md_rand,double)
   1.180 +#define entropy (*GET_WSD_VAR_NAME(entropy,md_rand, s)())
   1.181 +
   1.182 +GET_STATIC_VAR_FROM_TLS(initialized,md_rand,int)
   1.183 +#define initialized (*GET_WSD_VAR_NAME(initialized,md_rand, s)())
   1.184 +
   1.185 +GET_STATIC_VAR_FROM_TLS(crypto_lock_rand,md_rand,unsigned int)
   1.186 +#define crypto_lock_rand (*GET_WSD_VAR_NAME(crypto_lock_rand,md_rand, s)())
   1.187 +
   1.188 +GET_STATIC_VAR_FROM_TLS(locking_thread,md_rand,unsigned long)
   1.189 +#define locking_thread  (*GET_WSD_VAR_NAME(locking_thread,md_rand, s)())
   1.190 +
   1.191 +#endif
   1.192 +
   1.193 +#ifdef PREDICT
   1.194 +int rand_predictable=0;
   1.195 +#endif
   1.196 +
   1.197 +const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
   1.198 +
   1.199 +static void ssleay_rand_cleanup(void);
   1.200 +static void ssleay_rand_seed(const void *buf, int num);
   1.201 +static void ssleay_rand_add(const void *buf, int num, double add_entropy);
   1.202 +static int ssleay_rand_bytes(unsigned char *buf, int num);
   1.203 +static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
   1.204 +static int ssleay_rand_status(void);
   1.205 +
   1.206 +#ifndef EMULATOR
   1.207 +RAND_METHOD rand_ssleay_meth={
   1.208 +	ssleay_rand_seed,
   1.209 +	ssleay_rand_bytes,
   1.210 +	ssleay_rand_cleanup,
   1.211 +	ssleay_rand_add,
   1.212 +	ssleay_rand_pseudo_bytes,
   1.213 +	ssleay_rand_status
   1.214 +	}; 
   1.215 +#else
   1.216 +
   1.217 +GET_GLOBAL_VAR_FROM_TLS(rand_ssleay_meth,md_rand, RAND_METHOD)
   1.218 +#define rand_ssleay_meth (*GET_WSD_VAR_NAME(rand_ssleay_meth,md_rand, g)())
   1.219 +const RAND_METHOD temp_g_rand_ssleay_meth={
   1.220 +	ssleay_rand_seed,
   1.221 +	ssleay_rand_bytes,
   1.222 +	ssleay_rand_cleanup,
   1.223 +	ssleay_rand_add,
   1.224 +	ssleay_rand_pseudo_bytes,
   1.225 +	ssleay_rand_status
   1.226 +	}; 
   1.227 +
   1.228 +#endif
   1.229 +EXPORT_C RAND_METHOD *RAND_SSLeay(void)
   1.230 +	{
   1.231 +	return(&rand_ssleay_meth);
   1.232 +	}
   1.233 +
   1.234 +static void ssleay_rand_cleanup(void)
   1.235 +	{
   1.236 +	OPENSSL_cleanse(state,sizeof(state));
   1.237 +	state_num=0;
   1.238 +	state_index=0;
   1.239 +	OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
   1.240 +	md_count[0]=0;
   1.241 +	md_count[1]=0;
   1.242 +	entropy=0;
   1.243 +	initialized=0;
   1.244 +	}
   1.245 +
   1.246 +static void ssleay_rand_add(const void *buf, int num, double add)
   1.247 +	{
   1.248 +	int i,j,k,st_idx;
   1.249 +	long md_c[2];
   1.250 +	unsigned char local_md[MD_DIGEST_LENGTH];
   1.251 +	EVP_MD_CTX m;
   1.252 +	int do_not_lock;
   1.253 +
   1.254 +	/*
   1.255 +	 * (Based on the rand(3) manpage)
   1.256 +	 *
   1.257 +	 * The input is chopped up into units of 20 bytes (or less for
   1.258 +	 * the last block).  Each of these blocks is run through the hash
   1.259 +	 * function as follows:  The data passed to the hash function
   1.260 +	 * is the current 'md', the same number of bytes from the 'state'
   1.261 +	 * (the location determined by in incremented looping index) as
   1.262 +	 * the current 'block', the new key data 'block', and 'count'
   1.263 +	 * (which is incremented after each use).
   1.264 +	 * The result of this is kept in 'md' and also xored into the
   1.265 +	 * 'state' at the same locations that were used as input into the
   1.266 +         * hash function.
   1.267 +	 */
   1.268 +
   1.269 +	/* check if we already have the lock */
   1.270 +	if (crypto_lock_rand)
   1.271 +		{
   1.272 +		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
   1.273 +		do_not_lock = (locking_thread == CRYPTO_thread_id());
   1.274 +		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
   1.275 +		}
   1.276 +	else
   1.277 +		do_not_lock = 0;
   1.278 +
   1.279 +	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
   1.280 +	st_idx=state_index;
   1.281 +
   1.282 +	/* use our own copies of the counters so that even
   1.283 +	 * if a concurrent thread seeds with exactly the
   1.284 +	 * same data and uses the same subarray there's _some_
   1.285 +	 * difference */
   1.286 +	md_c[0] = md_count[0];
   1.287 +	md_c[1] = md_count[1];
   1.288 +
   1.289 +	memcpy(local_md, md, sizeof md);
   1.290 +
   1.291 +	/* state_index <= state_num <= STATE_SIZE */
   1.292 +	state_index += num;
   1.293 +	if (state_index >= STATE_SIZE)
   1.294 +		{
   1.295 +		state_index%=STATE_SIZE;
   1.296 +		state_num=STATE_SIZE;
   1.297 +		}
   1.298 +	else if (state_num < STATE_SIZE)	
   1.299 +		{
   1.300 +		if (state_index > state_num)
   1.301 +			state_num=state_index;
   1.302 +		}
   1.303 +	/* state_index <= state_num <= STATE_SIZE */
   1.304 +
   1.305 +	/* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
   1.306 +	 * are what we will use now, but other threads may use them
   1.307 +	 * as well */
   1.308 +
   1.309 +	md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
   1.310 +
   1.311 +	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
   1.312 +
   1.313 +	EVP_MD_CTX_init(&m);
   1.314 +	for (i=0; i<num; i+=MD_DIGEST_LENGTH)
   1.315 +		{
   1.316 +		j=(num-i);
   1.317 +		j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
   1.318 +
   1.319 +		MD_Init(&m);
   1.320 +		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
   1.321 +		k=(st_idx+j)-STATE_SIZE;
   1.322 +		if (k > 0)
   1.323 +			{
   1.324 +			MD_Update(&m,&(state[st_idx]),j-k);
   1.325 +			MD_Update(&m,&(state[0]),k);
   1.326 +			}
   1.327 +		else
   1.328 +			MD_Update(&m,&(state[st_idx]),j);
   1.329 +			
   1.330 +		MD_Update(&m,buf,j);
   1.331 +		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
   1.332 +		MD_Final(&m,local_md);
   1.333 +		md_c[1]++;
   1.334 +
   1.335 +		buf=(const char *)buf + j;
   1.336 +
   1.337 +		for (k=0; k<j; k++)
   1.338 +			{
   1.339 +			/* Parallel threads may interfere with this,
   1.340 +			 * but always each byte of the new state is
   1.341 +			 * the XOR of some previous value of its
   1.342 +			 * and local_md (itermediate values may be lost).
   1.343 +			 * Alway using locking could hurt performance more
   1.344 +			 * than necessary given that conflicts occur only
   1.345 +			 * when the total seeding is longer than the random
   1.346 +			 * state. */
   1.347 +			state[st_idx++]^=local_md[k];
   1.348 +			if (st_idx >= STATE_SIZE)
   1.349 +				st_idx=0;
   1.350 +			}
   1.351 +		}
   1.352 +	EVP_MD_CTX_cleanup(&m);
   1.353 +
   1.354 +	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
   1.355 +	/* Don't just copy back local_md into md -- this could mean that
   1.356 +	 * other thread's seeding remains without effect (except for
   1.357 +	 * the incremented counter).  By XORing it we keep at least as
   1.358 +	 * much entropy as fits into md. */
   1.359 +	for (k = 0; k < (int)sizeof(md); k++)
   1.360 +		{
   1.361 +		md[k] ^= local_md[k];
   1.362 +		}
   1.363 +	if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
   1.364 +	    entropy += add;
   1.365 +	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
   1.366 +	
   1.367 +#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
   1.368 +	assert(md_c[1] == md_count[1]);
   1.369 +#endif
   1.370 +	}
   1.371 +
   1.372 +static void ssleay_rand_seed(const void *buf, int num)
   1.373 +	{
   1.374 +	ssleay_rand_add(buf, num, (double)num);
   1.375 +	}
   1.376 +#ifdef EMULATOR
   1.377 +GET_STATIC_VAR_FROM_TLS(stirred_pool,md_rand,volatile int)
   1.378 +#define stirred_pool (*GET_WSD_VAR_NAME(stirred_pool,md_rand, s)())
   1.379 +#endif
   1.380 +static int ssleay_rand_bytes(unsigned char *buf, int num)
   1.381 +	{
   1.382 +#ifndef EMULATOR	
   1.383 +	static volatile int stirred_pool = 0;
   1.384 +#endif	
   1.385 +	int i,j,k,st_num,st_idx;
   1.386 +	int num_ceil;
   1.387 +	int ok;
   1.388 +	long md_c[2];
   1.389 +	unsigned char local_md[MD_DIGEST_LENGTH];
   1.390 +	EVP_MD_CTX m;
   1.391 +#ifndef GETPID_IS_MEANINGLESS
   1.392 +	pid_t curr_pid = getpid();
   1.393 +#endif
   1.394 +	int do_stir_pool = 0;
   1.395 +
   1.396 +#ifdef PREDICT
   1.397 +	if (rand_predictable)
   1.398 +		{
   1.399 +		static unsigned char val=0;
   1.400 +
   1.401 +		for (i=0; i<num; i++)
   1.402 +			buf[i]=val++;
   1.403 +		return(1);
   1.404 +		}
   1.405 +#endif
   1.406 +
   1.407 +	if (num <= 0)
   1.408 +		return 1;
   1.409 +
   1.410 +	EVP_MD_CTX_init(&m);
   1.411 +	/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
   1.412 +	num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
   1.413 +
   1.414 +	/*
   1.415 +	 * (Based on the rand(3) manpage:)
   1.416 +	 *
   1.417 +	 * For each group of 10 bytes (or less), we do the following:
   1.418 +	 *
   1.419 +	 * Input into the hash function the local 'md' (which is initialized from
   1.420 +	 * the global 'md' before any bytes are generated), the bytes that are to
   1.421 +	 * be overwritten by the random bytes, and bytes from the 'state'
   1.422 +	 * (incrementing looping index). From this digest output (which is kept
   1.423 +	 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
   1.424 +	 * bottom 10 bytes are xored into the 'state'.
   1.425 +	 * 
   1.426 +	 * Finally, after we have finished 'num' random bytes for the
   1.427 +	 * caller, 'count' (which is incremented) and the local and global 'md'
   1.428 +	 * are fed into the hash function and the results are kept in the
   1.429 +	 * global 'md'.
   1.430 +	 */
   1.431 +
   1.432 +	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
   1.433 +
   1.434 +	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
   1.435 +	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
   1.436 +	locking_thread = CRYPTO_thread_id();
   1.437 +	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
   1.438 +	crypto_lock_rand = 1;
   1.439 +
   1.440 +	if (!initialized)
   1.441 +		{
   1.442 +		RAND_poll();
   1.443 +		initialized = 1;
   1.444 +		}
   1.445 +	
   1.446 +	if (!stirred_pool)
   1.447 +		do_stir_pool = 1;
   1.448 +	
   1.449 +	ok = (entropy >= ENTROPY_NEEDED);
   1.450 +	if (!ok)
   1.451 +		{
   1.452 +		/* If the PRNG state is not yet unpredictable, then seeing
   1.453 +		 * the PRNG output may help attackers to determine the new
   1.454 +		 * state; thus we have to decrease the entropy estimate.
   1.455 +		 * Once we've had enough initial seeding we don't bother to
   1.456 +		 * adjust the entropy count, though, because we're not ambitious
   1.457 +		 * to provide *information-theoretic* randomness.
   1.458 +		 *
   1.459 +		 * NOTE: This approach fails if the program forks before
   1.460 +		 * we have enough entropy. Entropy should be collected
   1.461 +		 * in a separate input pool and be transferred to the
   1.462 +		 * output pool only when the entropy limit has been reached.
   1.463 +		 */
   1.464 +		entropy -= num;
   1.465 +		if (entropy < 0)
   1.466 +			entropy = 0;
   1.467 +		}
   1.468 +
   1.469 +	if (do_stir_pool)
   1.470 +		{
   1.471 +		/* In the output function only half of 'md' remains secret,
   1.472 +		 * so we better make sure that the required entropy gets
   1.473 +		 * 'evenly distributed' through 'state', our randomness pool.
   1.474 +		 * The input function (ssleay_rand_add) chains all of 'md',
   1.475 +		 * which makes it more suitable for this purpose.
   1.476 +		 */
   1.477 +
   1.478 +		int n = STATE_SIZE; /* so that the complete pool gets accessed */
   1.479 +		while (n > 0)
   1.480 +			{
   1.481 +#if MD_DIGEST_LENGTH > 20
   1.482 +# error "Please adjust DUMMY_SEED."
   1.483 +#endif
   1.484 +#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
   1.485 +			/* Note that the seed does not matter, it's just that
   1.486 +			 * ssleay_rand_add expects to have something to hash. */
   1.487 +			ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
   1.488 +			n -= MD_DIGEST_LENGTH;
   1.489 +			}
   1.490 +		if (ok)
   1.491 +			stirred_pool = 1;
   1.492 +		}
   1.493 +
   1.494 +	st_idx=state_index;
   1.495 +	st_num=state_num;
   1.496 +	md_c[0] = md_count[0];
   1.497 +	md_c[1] = md_count[1];
   1.498 +	memcpy(local_md, md, sizeof md);
   1.499 +
   1.500 +	state_index+=num_ceil;
   1.501 +	if (state_index > state_num)
   1.502 +		state_index %= state_num;
   1.503 +
   1.504 +	/* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
   1.505 +	 * are now ours (but other threads may use them too) */
   1.506 +
   1.507 +	md_count[0] += 1;
   1.508 +
   1.509 +	/* before unlocking, we must clear 'crypto_lock_rand' */
   1.510 +	crypto_lock_rand = 0;
   1.511 +	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
   1.512 +
   1.513 +	while (num > 0)
   1.514 +		{
   1.515 +		/* num_ceil -= MD_DIGEST_LENGTH/2 */
   1.516 +		j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
   1.517 +		num-=j;
   1.518 +		MD_Init(&m);
   1.519 +#ifndef GETPID_IS_MEANINGLESS
   1.520 +		if (curr_pid) /* just in the first iteration to save time */
   1.521 +			{
   1.522 +			MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
   1.523 +			curr_pid = 0;
   1.524 +			}
   1.525 +#endif
   1.526 +		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
   1.527 +		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
   1.528 +#ifndef PURIFY
   1.529 +		MD_Update(&m,buf,j); /* purify complains */
   1.530 +#endif
   1.531 +		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
   1.532 +		if (k > 0)
   1.533 +			{
   1.534 +			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
   1.535 +			MD_Update(&m,&(state[0]),k);
   1.536 +			}
   1.537 +		else
   1.538 +			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
   1.539 +		MD_Final(&m,local_md);
   1.540 +
   1.541 +		for (i=0; i<MD_DIGEST_LENGTH/2; i++)
   1.542 +			{
   1.543 +			state[st_idx++]^=local_md[i]; /* may compete with other threads */
   1.544 +			if (st_idx >= st_num)
   1.545 +				st_idx=0;
   1.546 +			if (i < j)
   1.547 +				*(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
   1.548 +			}
   1.549 +		}
   1.550 +
   1.551 +	MD_Init(&m);
   1.552 +	MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
   1.553 +	MD_Update(&m,local_md,MD_DIGEST_LENGTH);
   1.554 +	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
   1.555 +	MD_Update(&m,md,MD_DIGEST_LENGTH);
   1.556 +	MD_Final(&m,md);
   1.557 +	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
   1.558 +
   1.559 +	EVP_MD_CTX_cleanup(&m);
   1.560 +	if (ok)
   1.561 +		return(1);
   1.562 +	else
   1.563 +		{
   1.564 +		RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
   1.565 +		ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
   1.566 +			"http://www.openssl.org/support/faq.html");
   1.567 +		return(0);
   1.568 +		}
   1.569 +	}
   1.570 +
   1.571 +/* pseudo-random bytes that are guaranteed to be unique but not
   1.572 +   unpredictable */
   1.573 +static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) 
   1.574 +	{
   1.575 +	int ret;
   1.576 +	unsigned long err;
   1.577 +
   1.578 +	ret = RAND_bytes(buf, num);
   1.579 +	if (ret == 0)
   1.580 +		{
   1.581 +		err = ERR_peek_error();
   1.582 +		if (ERR_GET_LIB(err) == ERR_LIB_RAND &&
   1.583 +		    ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED)
   1.584 +			ERR_clear_error();
   1.585 +		}
   1.586 +	return (ret);
   1.587 +	}
   1.588 +
   1.589 +static int ssleay_rand_status(void)
   1.590 +	{
   1.591 +	int ret;
   1.592 +	int do_not_lock;
   1.593 +
   1.594 +	/* check if we already have the lock
   1.595 +	 * (could happen if a RAND_poll() implementation calls RAND_status()) */
   1.596 +	if (crypto_lock_rand)
   1.597 +		{
   1.598 +		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
   1.599 +		do_not_lock = (locking_thread == CRYPTO_thread_id());
   1.600 +		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
   1.601 +		}
   1.602 +	else
   1.603 +		do_not_lock = 0;
   1.604 +	
   1.605 +	if (!do_not_lock)
   1.606 +		{
   1.607 +		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
   1.608 +		
   1.609 +		/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
   1.610 +		CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
   1.611 +		locking_thread = CRYPTO_thread_id();
   1.612 +		CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
   1.613 +		crypto_lock_rand = 1;
   1.614 +		}
   1.615 +	
   1.616 +	if (!initialized)
   1.617 +		{
   1.618 +		RAND_poll();
   1.619 +		initialized = 1;
   1.620 +		}
   1.621 +
   1.622 +	ret = entropy >= ENTROPY_NEEDED;
   1.623 +
   1.624 +	if (!do_not_lock)
   1.625 +		{
   1.626 +		/* before unlocking, we must clear 'crypto_lock_rand' */
   1.627 +		crypto_lock_rand = 0;
   1.628 +		
   1.629 +		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
   1.630 +		}
   1.631 +	
   1.632 +	return ret;
   1.633 +	}