os/ossrv/ssl/libcrypto/src/crypto/rand/md_rand.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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 	}