ssl/libcrypto/src/crypto/rand/md_rand.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* crypto/rand/md_rand.c */
       
     2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       
     3  * All rights reserved.
       
     4  *
       
     5  * This package is an SSL implementation written
       
     6  * by Eric Young (eay@cryptsoft.com).
       
     7  * The implementation was written so as to conform with Netscapes SSL.
       
     8  * 
       
     9  * This library is free for commercial and non-commercial use as long as
       
    10  * the following conditions are aheared to.  The following conditions
       
    11  * apply to all code found in this distribution, be it the RC4, RSA,
       
    12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
       
    13  * included with this distribution is covered by the same copyright terms
       
    14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
       
    15  * 
       
    16  * Copyright remains Eric Young's, and as such any Copyright notices in
       
    17  * the code are not to be removed.
       
    18  * If this package is used in a product, Eric Young should be given attribution
       
    19  * as the author of the parts of the library used.
       
    20  * This can be in the form of a textual message at program startup or
       
    21  * in documentation (online or textual) provided with the package.
       
    22  * 
       
    23  * Redistribution and use in source and binary forms, with or without
       
    24  * modification, are permitted provided that the following conditions
       
    25  * are met:
       
    26  * 1. Redistributions of source code must retain the copyright
       
    27  *    notice, this list of conditions and the following disclaimer.
       
    28  * 2. Redistributions in binary form must reproduce the above copyright
       
    29  *    notice, this list of conditions and the following disclaimer in the
       
    30  *    documentation and/or other materials provided with the distribution.
       
    31  * 3. All advertising materials mentioning features or use of this software
       
    32  *    must display the following acknowledgement:
       
    33  *    "This product includes cryptographic software written by
       
    34  *     Eric Young (eay@cryptsoft.com)"
       
    35  *    The word 'cryptographic' can be left out if the rouines from the library
       
    36  *    being used are not cryptographic related :-).
       
    37  * 4. If you include any Windows specific code (or a derivative thereof) from 
       
    38  *    the apps directory (application code) you must include an acknowledgement:
       
    39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
       
    40  * 
       
    41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
       
    42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
       
    45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
    47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
       
    49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
    51  * SUCH DAMAGE.
       
    52  * 
       
    53  * The licence and distribution terms for any publically available version or
       
    54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
       
    55  * copied and put under another distribution licence
       
    56  * [including the GNU Public Licence.]
       
    57  */
       
    58 /* ====================================================================
       
    59  * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
       
    60  *
       
    61  * Redistribution and use in source and binary forms, with or without
       
    62  * modification, are permitted provided that the following conditions
       
    63  * are met:
       
    64  *
       
    65  * 1. Redistributions of source code must retain the above copyright
       
    66  *    notice, this list of conditions and the following disclaimer. 
       
    67  *
       
    68  * 2. Redistributions in binary form must reproduce the above copyright
       
    69  *    notice, this list of conditions and the following disclaimer in
       
    70  *    the documentation and/or other materials provided with the
       
    71  *    distribution.
       
    72  *
       
    73  * 3. All advertising materials mentioning features or use of this
       
    74  *    software must display the following acknowledgment:
       
    75  *    "This product includes software developed by the OpenSSL Project
       
    76  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
       
    77  *
       
    78  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
       
    79  *    endorse or promote products derived from this software without
       
    80  *    prior written permission. For written permission, please contact
       
    81  *    openssl-core@openssl.org.
       
    82  *
       
    83  * 5. Products derived from this software may not be called "OpenSSL"
       
    84  *    nor may "OpenSSL" appear in their names without prior written
       
    85  *    permission of the OpenSSL Project.
       
    86  *
       
    87  * 6. Redistributions of any form whatsoever must retain the following
       
    88  *    acknowledgment:
       
    89  *    "This product includes software developed by the OpenSSL Project
       
    90  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
       
    91  *
       
    92  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
       
    93  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    94  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    95  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
       
    96  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    97  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
       
    98  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    99  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
   100  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
       
   101  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
   102  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
       
   103  * OF THE POSSIBILITY OF SUCH DAMAGE.
       
   104  * ====================================================================
       
   105  *
       
   106  * This product includes cryptographic software written by Eric Young
       
   107  * (eay@cryptsoft.com).  This product includes software written by Tim
       
   108  * Hudson (tjh@cryptsoft.com).
       
   109  *
       
   110  */
       
   111  /*
       
   112  © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
       
   113  */
       
   114 
       
   115 
       
   116 #ifdef MD_RAND_DEBUG
       
   117 # ifndef NDEBUG
       
   118 #   define NDEBUG
       
   119 # endif
       
   120 #endif
       
   121 
       
   122 #include <assert.h>
       
   123 #include <stdio.h>
       
   124 #include <string.h>
       
   125 
       
   126 #include "e_os.h"
       
   127 
       
   128 #include <openssl/rand.h>
       
   129 #include "rand_lcl.h"
       
   130 
       
   131 #include <openssl/crypto.h>
       
   132 #include <openssl/err.h>
       
   133 #if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
       
   134 #include "libcrypto_wsd_macros.h"
       
   135 #include "libcrypto_wsd.h"
       
   136 #endif
       
   137 
       
   138 
       
   139 #ifdef BN_DEBUG
       
   140 # define PREDICT
       
   141 #endif
       
   142 
       
   143 /* #define PREDICT	1 */
       
   144 
       
   145 #define STATE_SIZE	1023
       
   146 
       
   147 #ifndef EMULATOR
       
   148 static int state_num=0,state_index=0;
       
   149 static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
       
   150 static unsigned char md[MD_DIGEST_LENGTH];
       
   151 static long md_count[2]={0,0};
       
   152 static double entropy=0;
       
   153 static int initialized=0;
       
   154 
       
   155 static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
       
   156                                            * holds CRYPTO_LOCK_RAND
       
   157                                            * (to prevent double locking) */
       
   158 /* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
       
   159 static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */
       
   160 #else
       
   161 GET_STATIC_VAR_FROM_TLS(state_num,md_rand,int)
       
   162 #define state_num (*GET_WSD_VAR_NAME(state_num,md_rand, s)())
       
   163 
       
   164 GET_STATIC_VAR_FROM_TLS(state_index,md_rand,int)
       
   165 #define state_index (*GET_WSD_VAR_NAME(state_index,md_rand, s)())
       
   166 
       
   167 GET_STATIC_ARRAY_FROM_TLS(state,md_rand,unsigned char)
       
   168 #define state (GET_WSD_VAR_NAME(state,md_rand, s)())
       
   169 
       
   170 GET_STATIC_ARRAY_FROM_TLS(md,md_rand,unsigned char)
       
   171 #define md (GET_WSD_VAR_NAME(md,md_rand, s)())
       
   172  
       
   173 GET_STATIC_ARRAY_FROM_TLS(md_count,md_rand,unsigned char)
       
   174 #define md_count (GET_WSD_VAR_NAME(md_count,md_rand, s)())
       
   175  
       
   176 GET_STATIC_VAR_FROM_TLS(entropy,md_rand,double)
       
   177 #define entropy (*GET_WSD_VAR_NAME(entropy,md_rand, s)())
       
   178 
       
   179 GET_STATIC_VAR_FROM_TLS(initialized,md_rand,int)
       
   180 #define initialized (*GET_WSD_VAR_NAME(initialized,md_rand, s)())
       
   181 
       
   182 GET_STATIC_VAR_FROM_TLS(crypto_lock_rand,md_rand,unsigned int)
       
   183 #define crypto_lock_rand (*GET_WSD_VAR_NAME(crypto_lock_rand,md_rand, s)())
       
   184 
       
   185 GET_STATIC_VAR_FROM_TLS(locking_thread,md_rand,unsigned long)
       
   186 #define locking_thread  (*GET_WSD_VAR_NAME(locking_thread,md_rand, s)())
       
   187 
       
   188 #endif
       
   189 
       
   190 #ifdef PREDICT
       
   191 int rand_predictable=0;
       
   192 #endif
       
   193 
       
   194 const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
       
   195 
       
   196 static void ssleay_rand_cleanup(void);
       
   197 static void ssleay_rand_seed(const void *buf, int num);
       
   198 static void ssleay_rand_add(const void *buf, int num, double add_entropy);
       
   199 static int ssleay_rand_bytes(unsigned char *buf, int num);
       
   200 static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
       
   201 static int ssleay_rand_status(void);
       
   202 
       
   203 #ifndef EMULATOR
       
   204 RAND_METHOD rand_ssleay_meth={
       
   205 	ssleay_rand_seed,
       
   206 	ssleay_rand_bytes,
       
   207 	ssleay_rand_cleanup,
       
   208 	ssleay_rand_add,
       
   209 	ssleay_rand_pseudo_bytes,
       
   210 	ssleay_rand_status
       
   211 	}; 
       
   212 #else
       
   213 
       
   214 GET_GLOBAL_VAR_FROM_TLS(rand_ssleay_meth,md_rand, RAND_METHOD)
       
   215 #define rand_ssleay_meth (*GET_WSD_VAR_NAME(rand_ssleay_meth,md_rand, g)())
       
   216 const RAND_METHOD temp_g_rand_ssleay_meth={
       
   217 	ssleay_rand_seed,
       
   218 	ssleay_rand_bytes,
       
   219 	ssleay_rand_cleanup,
       
   220 	ssleay_rand_add,
       
   221 	ssleay_rand_pseudo_bytes,
       
   222 	ssleay_rand_status
       
   223 	}; 
       
   224 
       
   225 #endif
       
   226 EXPORT_C RAND_METHOD *RAND_SSLeay(void)
       
   227 	{
       
   228 	return(&rand_ssleay_meth);
       
   229 	}
       
   230 
       
   231 static void ssleay_rand_cleanup(void)
       
   232 	{
       
   233 	OPENSSL_cleanse(state,sizeof(state));
       
   234 	state_num=0;
       
   235 	state_index=0;
       
   236 	OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
       
   237 	md_count[0]=0;
       
   238 	md_count[1]=0;
       
   239 	entropy=0;
       
   240 	initialized=0;
       
   241 	}
       
   242 
       
   243 static void ssleay_rand_add(const void *buf, int num, double add)
       
   244 	{
       
   245 	int i,j,k,st_idx;
       
   246 	long md_c[2];
       
   247 	unsigned char local_md[MD_DIGEST_LENGTH];
       
   248 	EVP_MD_CTX m;
       
   249 	int do_not_lock;
       
   250 
       
   251 	/*
       
   252 	 * (Based on the rand(3) manpage)
       
   253 	 *
       
   254 	 * The input is chopped up into units of 20 bytes (or less for
       
   255 	 * the last block).  Each of these blocks is run through the hash
       
   256 	 * function as follows:  The data passed to the hash function
       
   257 	 * is the current 'md', the same number of bytes from the 'state'
       
   258 	 * (the location determined by in incremented looping index) as
       
   259 	 * the current 'block', the new key data 'block', and 'count'
       
   260 	 * (which is incremented after each use).
       
   261 	 * The result of this is kept in 'md' and also xored into the
       
   262 	 * 'state' at the same locations that were used as input into the
       
   263          * hash function.
       
   264 	 */
       
   265 
       
   266 	/* check if we already have the lock */
       
   267 	if (crypto_lock_rand)
       
   268 		{
       
   269 		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
       
   270 		do_not_lock = (locking_thread == CRYPTO_thread_id());
       
   271 		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
       
   272 		}
       
   273 	else
       
   274 		do_not_lock = 0;
       
   275 
       
   276 	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
       
   277 	st_idx=state_index;
       
   278 
       
   279 	/* use our own copies of the counters so that even
       
   280 	 * if a concurrent thread seeds with exactly the
       
   281 	 * same data and uses the same subarray there's _some_
       
   282 	 * difference */
       
   283 	md_c[0] = md_count[0];
       
   284 	md_c[1] = md_count[1];
       
   285 
       
   286 	memcpy(local_md, md, sizeof md);
       
   287 
       
   288 	/* state_index <= state_num <= STATE_SIZE */
       
   289 	state_index += num;
       
   290 	if (state_index >= STATE_SIZE)
       
   291 		{
       
   292 		state_index%=STATE_SIZE;
       
   293 		state_num=STATE_SIZE;
       
   294 		}
       
   295 	else if (state_num < STATE_SIZE)	
       
   296 		{
       
   297 		if (state_index > state_num)
       
   298 			state_num=state_index;
       
   299 		}
       
   300 	/* state_index <= state_num <= STATE_SIZE */
       
   301 
       
   302 	/* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
       
   303 	 * are what we will use now, but other threads may use them
       
   304 	 * as well */
       
   305 
       
   306 	md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
       
   307 
       
   308 	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
       
   309 
       
   310 	EVP_MD_CTX_init(&m);
       
   311 	for (i=0; i<num; i+=MD_DIGEST_LENGTH)
       
   312 		{
       
   313 		j=(num-i);
       
   314 		j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
       
   315 
       
   316 		MD_Init(&m);
       
   317 		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
       
   318 		k=(st_idx+j)-STATE_SIZE;
       
   319 		if (k > 0)
       
   320 			{
       
   321 			MD_Update(&m,&(state[st_idx]),j-k);
       
   322 			MD_Update(&m,&(state[0]),k);
       
   323 			}
       
   324 		else
       
   325 			MD_Update(&m,&(state[st_idx]),j);
       
   326 			
       
   327 		MD_Update(&m,buf,j);
       
   328 		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
       
   329 		MD_Final(&m,local_md);
       
   330 		md_c[1]++;
       
   331 
       
   332 		buf=(const char *)buf + j;
       
   333 
       
   334 		for (k=0; k<j; k++)
       
   335 			{
       
   336 			/* Parallel threads may interfere with this,
       
   337 			 * but always each byte of the new state is
       
   338 			 * the XOR of some previous value of its
       
   339 			 * and local_md (itermediate values may be lost).
       
   340 			 * Alway using locking could hurt performance more
       
   341 			 * than necessary given that conflicts occur only
       
   342 			 * when the total seeding is longer than the random
       
   343 			 * state. */
       
   344 			state[st_idx++]^=local_md[k];
       
   345 			if (st_idx >= STATE_SIZE)
       
   346 				st_idx=0;
       
   347 			}
       
   348 		}
       
   349 	EVP_MD_CTX_cleanup(&m);
       
   350 
       
   351 	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
       
   352 	/* Don't just copy back local_md into md -- this could mean that
       
   353 	 * other thread's seeding remains without effect (except for
       
   354 	 * the incremented counter).  By XORing it we keep at least as
       
   355 	 * much entropy as fits into md. */
       
   356 	for (k = 0; k < (int)sizeof(md); k++)
       
   357 		{
       
   358 		md[k] ^= local_md[k];
       
   359 		}
       
   360 	if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
       
   361 	    entropy += add;
       
   362 	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
       
   363 	
       
   364 #if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
       
   365 	assert(md_c[1] == md_count[1]);
       
   366 #endif
       
   367 	}
       
   368 
       
   369 static void ssleay_rand_seed(const void *buf, int num)
       
   370 	{
       
   371 	ssleay_rand_add(buf, num, (double)num);
       
   372 	}
       
   373 #ifdef EMULATOR
       
   374 GET_STATIC_VAR_FROM_TLS(stirred_pool,md_rand,volatile int)
       
   375 #define stirred_pool (*GET_WSD_VAR_NAME(stirred_pool,md_rand, s)())
       
   376 #endif
       
   377 static int ssleay_rand_bytes(unsigned char *buf, int num)
       
   378 	{
       
   379 #ifndef EMULATOR	
       
   380 	static volatile int stirred_pool = 0;
       
   381 #endif	
       
   382 	int i,j,k,st_num,st_idx;
       
   383 	int num_ceil;
       
   384 	int ok;
       
   385 	long md_c[2];
       
   386 	unsigned char local_md[MD_DIGEST_LENGTH];
       
   387 	EVP_MD_CTX m;
       
   388 #ifndef GETPID_IS_MEANINGLESS
       
   389 	pid_t curr_pid = getpid();
       
   390 #endif
       
   391 	int do_stir_pool = 0;
       
   392 
       
   393 #ifdef PREDICT
       
   394 	if (rand_predictable)
       
   395 		{
       
   396 		static unsigned char val=0;
       
   397 
       
   398 		for (i=0; i<num; i++)
       
   399 			buf[i]=val++;
       
   400 		return(1);
       
   401 		}
       
   402 #endif
       
   403 
       
   404 	if (num <= 0)
       
   405 		return 1;
       
   406 
       
   407 	EVP_MD_CTX_init(&m);
       
   408 	/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
       
   409 	num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
       
   410 
       
   411 	/*
       
   412 	 * (Based on the rand(3) manpage:)
       
   413 	 *
       
   414 	 * For each group of 10 bytes (or less), we do the following:
       
   415 	 *
       
   416 	 * Input into the hash function the local 'md' (which is initialized from
       
   417 	 * the global 'md' before any bytes are generated), the bytes that are to
       
   418 	 * be overwritten by the random bytes, and bytes from the 'state'
       
   419 	 * (incrementing looping index). From this digest output (which is kept
       
   420 	 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
       
   421 	 * bottom 10 bytes are xored into the 'state'.
       
   422 	 * 
       
   423 	 * Finally, after we have finished 'num' random bytes for the
       
   424 	 * caller, 'count' (which is incremented) and the local and global 'md'
       
   425 	 * are fed into the hash function and the results are kept in the
       
   426 	 * global 'md'.
       
   427 	 */
       
   428 
       
   429 	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
       
   430 
       
   431 	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
       
   432 	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
       
   433 	locking_thread = CRYPTO_thread_id();
       
   434 	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
       
   435 	crypto_lock_rand = 1;
       
   436 
       
   437 	if (!initialized)
       
   438 		{
       
   439 		RAND_poll();
       
   440 		initialized = 1;
       
   441 		}
       
   442 	
       
   443 	if (!stirred_pool)
       
   444 		do_stir_pool = 1;
       
   445 	
       
   446 	ok = (entropy >= ENTROPY_NEEDED);
       
   447 	if (!ok)
       
   448 		{
       
   449 		/* If the PRNG state is not yet unpredictable, then seeing
       
   450 		 * the PRNG output may help attackers to determine the new
       
   451 		 * state; thus we have to decrease the entropy estimate.
       
   452 		 * Once we've had enough initial seeding we don't bother to
       
   453 		 * adjust the entropy count, though, because we're not ambitious
       
   454 		 * to provide *information-theoretic* randomness.
       
   455 		 *
       
   456 		 * NOTE: This approach fails if the program forks before
       
   457 		 * we have enough entropy. Entropy should be collected
       
   458 		 * in a separate input pool and be transferred to the
       
   459 		 * output pool only when the entropy limit has been reached.
       
   460 		 */
       
   461 		entropy -= num;
       
   462 		if (entropy < 0)
       
   463 			entropy = 0;
       
   464 		}
       
   465 
       
   466 	if (do_stir_pool)
       
   467 		{
       
   468 		/* In the output function only half of 'md' remains secret,
       
   469 		 * so we better make sure that the required entropy gets
       
   470 		 * 'evenly distributed' through 'state', our randomness pool.
       
   471 		 * The input function (ssleay_rand_add) chains all of 'md',
       
   472 		 * which makes it more suitable for this purpose.
       
   473 		 */
       
   474 
       
   475 		int n = STATE_SIZE; /* so that the complete pool gets accessed */
       
   476 		while (n > 0)
       
   477 			{
       
   478 #if MD_DIGEST_LENGTH > 20
       
   479 # error "Please adjust DUMMY_SEED."
       
   480 #endif
       
   481 #define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
       
   482 			/* Note that the seed does not matter, it's just that
       
   483 			 * ssleay_rand_add expects to have something to hash. */
       
   484 			ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
       
   485 			n -= MD_DIGEST_LENGTH;
       
   486 			}
       
   487 		if (ok)
       
   488 			stirred_pool = 1;
       
   489 		}
       
   490 
       
   491 	st_idx=state_index;
       
   492 	st_num=state_num;
       
   493 	md_c[0] = md_count[0];
       
   494 	md_c[1] = md_count[1];
       
   495 	memcpy(local_md, md, sizeof md);
       
   496 
       
   497 	state_index+=num_ceil;
       
   498 	if (state_index > state_num)
       
   499 		state_index %= state_num;
       
   500 
       
   501 	/* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
       
   502 	 * are now ours (but other threads may use them too) */
       
   503 
       
   504 	md_count[0] += 1;
       
   505 
       
   506 	/* before unlocking, we must clear 'crypto_lock_rand' */
       
   507 	crypto_lock_rand = 0;
       
   508 	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
       
   509 
       
   510 	while (num > 0)
       
   511 		{
       
   512 		/* num_ceil -= MD_DIGEST_LENGTH/2 */
       
   513 		j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
       
   514 		num-=j;
       
   515 		MD_Init(&m);
       
   516 #ifndef GETPID_IS_MEANINGLESS
       
   517 		if (curr_pid) /* just in the first iteration to save time */
       
   518 			{
       
   519 			MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
       
   520 			curr_pid = 0;
       
   521 			}
       
   522 #endif
       
   523 		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
       
   524 		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
       
   525 #ifndef PURIFY
       
   526 		MD_Update(&m,buf,j); /* purify complains */
       
   527 #endif
       
   528 		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
       
   529 		if (k > 0)
       
   530 			{
       
   531 			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
       
   532 			MD_Update(&m,&(state[0]),k);
       
   533 			}
       
   534 		else
       
   535 			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
       
   536 		MD_Final(&m,local_md);
       
   537 
       
   538 		for (i=0; i<MD_DIGEST_LENGTH/2; i++)
       
   539 			{
       
   540 			state[st_idx++]^=local_md[i]; /* may compete with other threads */
       
   541 			if (st_idx >= st_num)
       
   542 				st_idx=0;
       
   543 			if (i < j)
       
   544 				*(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
       
   545 			}
       
   546 		}
       
   547 
       
   548 	MD_Init(&m);
       
   549 	MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
       
   550 	MD_Update(&m,local_md,MD_DIGEST_LENGTH);
       
   551 	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
       
   552 	MD_Update(&m,md,MD_DIGEST_LENGTH);
       
   553 	MD_Final(&m,md);
       
   554 	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
       
   555 
       
   556 	EVP_MD_CTX_cleanup(&m);
       
   557 	if (ok)
       
   558 		return(1);
       
   559 	else
       
   560 		{
       
   561 		RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
       
   562 		ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
       
   563 			"http://www.openssl.org/support/faq.html");
       
   564 		return(0);
       
   565 		}
       
   566 	}
       
   567 
       
   568 /* pseudo-random bytes that are guaranteed to be unique but not
       
   569    unpredictable */
       
   570 static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) 
       
   571 	{
       
   572 	int ret;
       
   573 	unsigned long err;
       
   574 
       
   575 	ret = RAND_bytes(buf, num);
       
   576 	if (ret == 0)
       
   577 		{
       
   578 		err = ERR_peek_error();
       
   579 		if (ERR_GET_LIB(err) == ERR_LIB_RAND &&
       
   580 		    ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED)
       
   581 			ERR_clear_error();
       
   582 		}
       
   583 	return (ret);
       
   584 	}
       
   585 
       
   586 static int ssleay_rand_status(void)
       
   587 	{
       
   588 	int ret;
       
   589 	int do_not_lock;
       
   590 
       
   591 	/* check if we already have the lock
       
   592 	 * (could happen if a RAND_poll() implementation calls RAND_status()) */
       
   593 	if (crypto_lock_rand)
       
   594 		{
       
   595 		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
       
   596 		do_not_lock = (locking_thread == CRYPTO_thread_id());
       
   597 		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
       
   598 		}
       
   599 	else
       
   600 		do_not_lock = 0;
       
   601 	
       
   602 	if (!do_not_lock)
       
   603 		{
       
   604 		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
       
   605 		
       
   606 		/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
       
   607 		CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
       
   608 		locking_thread = CRYPTO_thread_id();
       
   609 		CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
       
   610 		crypto_lock_rand = 1;
       
   611 		}
       
   612 	
       
   613 	if (!initialized)
       
   614 		{
       
   615 		RAND_poll();
       
   616 		initialized = 1;
       
   617 		}
       
   618 
       
   619 	ret = entropy >= ENTROPY_NEEDED;
       
   620 
       
   621 	if (!do_not_lock)
       
   622 		{
       
   623 		/* before unlocking, we must clear 'crypto_lock_rand' */
       
   624 		crypto_lock_rand = 0;
       
   625 		
       
   626 		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
       
   627 		}
       
   628 	
       
   629 	return ret;
       
   630 	}