155714Skris/* crypto/rand/md_rand.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8296465Sdelphij * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296465Sdelphij * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22296465Sdelphij * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296465Sdelphij * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52296465Sdelphij * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5859191Skris/* ==================================================================== 5989837Skris * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 6059191Skris * 6159191Skris * Redistribution and use in source and binary forms, with or without 6259191Skris * modification, are permitted provided that the following conditions 6359191Skris * are met: 6459191Skris * 6559191Skris * 1. Redistributions of source code must retain the above copyright 66296465Sdelphij * notice, this list of conditions and the following disclaimer. 6759191Skris * 6859191Skris * 2. Redistributions in binary form must reproduce the above copyright 6959191Skris * notice, this list of conditions and the following disclaimer in 7059191Skris * the documentation and/or other materials provided with the 7159191Skris * distribution. 7259191Skris * 7359191Skris * 3. All advertising materials mentioning features or use of this 7459191Skris * software must display the following acknowledgment: 7559191Skris * "This product includes software developed by the OpenSSL Project 7659191Skris * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 7759191Skris * 7859191Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 7959191Skris * endorse or promote products derived from this software without 8059191Skris * prior written permission. For written permission, please contact 8159191Skris * openssl-core@openssl.org. 8259191Skris * 8359191Skris * 5. Products derived from this software may not be called "OpenSSL" 8459191Skris * nor may "OpenSSL" appear in their names without prior written 8559191Skris * permission of the OpenSSL Project. 8659191Skris * 8759191Skris * 6. Redistributions of any form whatsoever must retain the following 8859191Skris * acknowledgment: 8959191Skris * "This product includes software developed by the OpenSSL Project 9059191Skris * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 9159191Skris * 9259191Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 9359191Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9459191Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 9559191Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 9659191Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 9759191Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 9859191Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 9959191Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 10059191Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 10159191Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10259191Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 10359191Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 10459191Skris * ==================================================================== 10559191Skris * 10659191Skris * This product includes cryptographic software written by Eric Young 10759191Skris * (eay@cryptsoft.com). This product includes software written by Tim 10859191Skris * Hudson (tjh@cryptsoft.com). 10959191Skris * 11059191Skris */ 11155714Skris 11268651Skris#ifdef MD_RAND_DEBUG 11359191Skris# ifndef NDEBUG 114296465Sdelphij# define NDEBUG 11559191Skris# endif 11659191Skris#endif 11759191Skris 11859191Skris#include <assert.h> 11955714Skris#include <stdio.h> 12055714Skris#include <string.h> 12155714Skris 122109998Smarkm#include "e_os.h" 12355714Skris 12468651Skris#include <openssl/rand.h> 12568651Skris#include "rand_lcl.h" 12668651Skris 12755714Skris#include <openssl/crypto.h> 12859191Skris#include <openssl/err.h> 129194206Ssimon#ifdef OPENSSL_FIPS 130296465Sdelphij# include <openssl/fips.h> 131194206Ssimon#endif 13255714Skris 13359191Skris#ifdef BN_DEBUG 13459191Skris# define PREDICT 13559191Skris#endif 13659191Skris 137296465Sdelphij/* #define PREDICT 1 */ 13855714Skris 139296465Sdelphij#define STATE_SIZE 1023 140296465Sdelphijstatic int state_num = 0, state_index = 0; 141296465Sdelphijstatic unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH]; 14255714Skrisstatic unsigned char md[MD_DIGEST_LENGTH]; 143296465Sdelphijstatic long md_count[2] = { 0, 0 }; 14455714Skris 145296465Sdelphijstatic double entropy = 0; 146296465Sdelphijstatic int initialized = 0; 147296465Sdelphij 14879998Skrisstatic unsigned int crypto_lock_rand = 0; /* may be set only when a thread 149296465Sdelphij * holds CRYPTO_LOCK_RAND (to 150296465Sdelphij * prevent double locking) */ 15189837Skris/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ 152296465Sdelphij/* valid iff crypto_lock_rand is set */ 153296465Sdelphijstatic unsigned long locking_thread = 0; 15468651Skris 15559191Skris#ifdef PREDICT 156296465Sdelphijint rand_predictable = 0; 15759191Skris#endif 15859191Skris 159296465Sdelphijconst char RAND_version[] = "RAND" OPENSSL_VERSION_PTEXT; 16055714Skris 16155714Skrisstatic void ssleay_rand_cleanup(void); 16255714Skrisstatic void ssleay_rand_seed(const void *buf, int num); 16359191Skrisstatic void ssleay_rand_add(const void *buf, int num, double add_entropy); 16459191Skrisstatic int ssleay_rand_bytes(unsigned char *buf, int num); 16559191Skrisstatic int ssleay_rand_pseudo_bytes(unsigned char *buf, int num); 16659191Skrisstatic int ssleay_rand_status(void); 16755714Skris 168296465SdelphijRAND_METHOD rand_ssleay_meth = { 169296465Sdelphij ssleay_rand_seed, 170296465Sdelphij ssleay_rand_bytes, 171296465Sdelphij ssleay_rand_cleanup, 172296465Sdelphij ssleay_rand_add, 173296465Sdelphij ssleay_rand_pseudo_bytes, 174296465Sdelphij ssleay_rand_status 175296465Sdelphij}; 17655714Skris 17755714SkrisRAND_METHOD *RAND_SSLeay(void) 178296465Sdelphij{ 179296465Sdelphij return (&rand_ssleay_meth); 180296465Sdelphij} 18155714Skris 18255714Skrisstatic void ssleay_rand_cleanup(void) 183296465Sdelphij{ 184296465Sdelphij OPENSSL_cleanse(state, sizeof(state)); 185296465Sdelphij state_num = 0; 186296465Sdelphij state_index = 0; 187296465Sdelphij OPENSSL_cleanse(md, MD_DIGEST_LENGTH); 188296465Sdelphij md_count[0] = 0; 189296465Sdelphij md_count[1] = 0; 190296465Sdelphij entropy = 0; 191296465Sdelphij initialized = 0; 192296465Sdelphij} 19355714Skris 19459191Skrisstatic void ssleay_rand_add(const void *buf, int num, double add) 195296465Sdelphij{ 196296465Sdelphij int i, j, k, st_idx; 197296465Sdelphij long md_c[2]; 198296465Sdelphij unsigned char local_md[MD_DIGEST_LENGTH]; 199296465Sdelphij EVP_MD_CTX m; 200296465Sdelphij int do_not_lock; 20155714Skris 202296465Sdelphij if (!num) 203296465Sdelphij return; 204264624Sdelphij 205296465Sdelphij /* 206296465Sdelphij * (Based on the rand(3) manpage) 207296465Sdelphij * 208296465Sdelphij * The input is chopped up into units of 20 bytes (or less for 209296465Sdelphij * the last block). Each of these blocks is run through the hash 210296465Sdelphij * function as follows: The data passed to the hash function 211296465Sdelphij * is the current 'md', the same number of bytes from the 'state' 212296465Sdelphij * (the location determined by in incremented looping index) as 213296465Sdelphij * the current 'block', the new key data 'block', and 'count' 214296465Sdelphij * (which is incremented after each use). 215296465Sdelphij * The result of this is kept in 'md' and also xored into the 216296465Sdelphij * 'state' at the same locations that were used as input into the 217296465Sdelphij * hash function. 218296465Sdelphij */ 21959191Skris 220296465Sdelphij /* check if we already have the lock */ 221296465Sdelphij if (crypto_lock_rand) { 222296465Sdelphij CRYPTO_r_lock(CRYPTO_LOCK_RAND2); 223296465Sdelphij do_not_lock = (locking_thread == CRYPTO_thread_id()); 224296465Sdelphij CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); 225296465Sdelphij } else 226296465Sdelphij do_not_lock = 0; 22779998Skris 228296465Sdelphij if (!do_not_lock) 229296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND); 230296465Sdelphij st_idx = state_index; 23155714Skris 232296465Sdelphij /* 233296465Sdelphij * use our own copies of the counters so that even if a concurrent thread 234296465Sdelphij * seeds with exactly the same data and uses the same subarray there's 235296465Sdelphij * _some_ difference 236296465Sdelphij */ 237296465Sdelphij md_c[0] = md_count[0]; 238296465Sdelphij md_c[1] = md_count[1]; 23959191Skris 240296465Sdelphij memcpy(local_md, md, sizeof md); 24159191Skris 242296465Sdelphij /* state_index <= state_num <= STATE_SIZE */ 243296465Sdelphij state_index += num; 244296465Sdelphij if (state_index >= STATE_SIZE) { 245296465Sdelphij state_index %= STATE_SIZE; 246296465Sdelphij state_num = STATE_SIZE; 247296465Sdelphij } else if (state_num < STATE_SIZE) { 248296465Sdelphij if (state_index > state_num) 249296465Sdelphij state_num = state_index; 250296465Sdelphij } 251296465Sdelphij /* state_index <= state_num <= STATE_SIZE */ 25259191Skris 253296465Sdelphij /* 254296465Sdelphij * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we 255296465Sdelphij * will use now, but other threads may use them as well 256296465Sdelphij */ 25759191Skris 258296465Sdelphij md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0); 25959191Skris 260296465Sdelphij if (!do_not_lock) 261296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 26255714Skris 263296465Sdelphij EVP_MD_CTX_init(&m); 264296465Sdelphij for (i = 0; i < num; i += MD_DIGEST_LENGTH) { 265296465Sdelphij j = (num - i); 266296465Sdelphij j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j; 26755714Skris 268296465Sdelphij MD_Init(&m); 269296465Sdelphij MD_Update(&m, local_md, MD_DIGEST_LENGTH); 270296465Sdelphij k = (st_idx + j) - STATE_SIZE; 271296465Sdelphij if (k > 0) { 272296465Sdelphij MD_Update(&m, &(state[st_idx]), j - k); 273296465Sdelphij MD_Update(&m, &(state[0]), k); 274296465Sdelphij } else 275296465Sdelphij MD_Update(&m, &(state[st_idx]), j); 27655714Skris 277296465Sdelphij MD_Update(&m, buf, j); 278296465Sdelphij MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); 279296465Sdelphij MD_Final(&m, local_md); 280296465Sdelphij md_c[1]++; 28155714Skris 282296465Sdelphij buf = (const char *)buf + j; 28359191Skris 284296465Sdelphij for (k = 0; k < j; k++) { 285296465Sdelphij /* 286296465Sdelphij * Parallel threads may interfere with this, but always each byte 287296465Sdelphij * of the new state is the XOR of some previous value of its and 288296465Sdelphij * local_md (itermediate values may be lost). Alway using locking 289296465Sdelphij * could hurt performance more than necessary given that 290296465Sdelphij * conflicts occur only when the total seeding is longer than the 291296465Sdelphij * random state. 292296465Sdelphij */ 293296465Sdelphij state[st_idx++] ^= local_md[k]; 294296465Sdelphij if (st_idx >= STATE_SIZE) 295296465Sdelphij st_idx = 0; 296296465Sdelphij } 297296465Sdelphij } 298296465Sdelphij EVP_MD_CTX_cleanup(&m); 299296465Sdelphij 300296465Sdelphij if (!do_not_lock) 301296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND); 302296465Sdelphij /* 303296465Sdelphij * Don't just copy back local_md into md -- this could mean that other 304296465Sdelphij * thread's seeding remains without effect (except for the incremented 305296465Sdelphij * counter). By XORing it we keep at least as much entropy as fits into 306296465Sdelphij * md. 307296465Sdelphij */ 308296465Sdelphij for (k = 0; k < (int)sizeof(md); k++) { 309296465Sdelphij md[k] ^= local_md[k]; 310296465Sdelphij } 311296465Sdelphij if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */ 312296465Sdelphij entropy += add; 313296465Sdelphij if (!do_not_lock) 314296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 315296465Sdelphij 316109998Smarkm#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) 317296465Sdelphij assert(md_c[1] == md_count[1]); 31859191Skris#endif 319296465Sdelphij} 32055714Skris 32159191Skrisstatic void ssleay_rand_seed(const void *buf, int num) 322296465Sdelphij{ 323296465Sdelphij ssleay_rand_add(buf, num, (double)num); 324296465Sdelphij} 32559191Skris 32659191Skrisstatic int ssleay_rand_bytes(unsigned char *buf, int num) 327296465Sdelphij{ 328296465Sdelphij static volatile int stirred_pool = 0; 329296465Sdelphij int i, j, k, st_num, st_idx; 330296465Sdelphij int num_ceil; 331296465Sdelphij int ok; 332296465Sdelphij long md_c[2]; 333296465Sdelphij unsigned char local_md[MD_DIGEST_LENGTH]; 334296465Sdelphij EVP_MD_CTX m; 33559191Skris#ifndef GETPID_IS_MEANINGLESS 336296465Sdelphij pid_t curr_pid = getpid(); 33759191Skris#endif 338296465Sdelphij int do_stir_pool = 0; 33959191Skris 340194206Ssimon#ifdef OPENSSL_FIPS 341296465Sdelphij if (FIPS_mode()) { 342296465Sdelphij FIPSerr(FIPS_F_SSLEAY_RAND_BYTES, FIPS_R_NON_FIPS_METHOD); 343296465Sdelphij return 0; 344296465Sdelphij } 345194206Ssimon#endif 346194206Ssimon 34759191Skris#ifdef PREDICT 348296465Sdelphij if (rand_predictable) { 349296465Sdelphij static unsigned char val = 0; 35059191Skris 351296465Sdelphij for (i = 0; i < num; i++) 352296465Sdelphij buf[i] = val++; 353296465Sdelphij return (1); 354296465Sdelphij } 35555714Skris#endif 35655714Skris 357296465Sdelphij if (num <= 0) 358296465Sdelphij return 1; 359109998Smarkm 360296465Sdelphij EVP_MD_CTX_init(&m); 361296465Sdelphij /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ 362296465Sdelphij num_ceil = 363296465Sdelphij (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2); 36479998Skris 365296465Sdelphij /* 366296465Sdelphij * (Based on the rand(3) manpage:) 367296465Sdelphij * 368296465Sdelphij * For each group of 10 bytes (or less), we do the following: 369296465Sdelphij * 370296465Sdelphij * Input into the hash function the local 'md' (which is initialized from 371296465Sdelphij * the global 'md' before any bytes are generated), the bytes that are to 372296465Sdelphij * be overwritten by the random bytes, and bytes from the 'state' 373296465Sdelphij * (incrementing looping index). From this digest output (which is kept 374296465Sdelphij * in 'md'), the top (up to) 10 bytes are returned to the caller and the 375296465Sdelphij * bottom 10 bytes are xored into the 'state'. 376296465Sdelphij * 377296465Sdelphij * Finally, after we have finished 'num' random bytes for the 378296465Sdelphij * caller, 'count' (which is incremented) and the local and global 'md' 379296465Sdelphij * are fed into the hash function and the results are kept in the 380296465Sdelphij * global 'md'. 381296465Sdelphij */ 38259191Skris 383296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND); 38479998Skris 385296465Sdelphij /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ 386296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND2); 387296465Sdelphij locking_thread = CRYPTO_thread_id(); 388296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); 389296465Sdelphij crypto_lock_rand = 1; 39079998Skris 391296465Sdelphij if (!initialized) { 392296465Sdelphij RAND_poll(); 393296465Sdelphij initialized = 1; 394296465Sdelphij } 39555714Skris 396296465Sdelphij if (!stirred_pool) 397296465Sdelphij do_stir_pool = 1; 39868651Skris 399296465Sdelphij ok = (entropy >= ENTROPY_NEEDED); 400296465Sdelphij if (!ok) { 401296465Sdelphij /* 402296465Sdelphij * If the PRNG state is not yet unpredictable, then seeing the PRNG 403296465Sdelphij * output may help attackers to determine the new state; thus we have 404296465Sdelphij * to decrease the entropy estimate. Once we've had enough initial 405296465Sdelphij * seeding we don't bother to adjust the entropy count, though, 406296465Sdelphij * because we're not ambitious to provide *information-theoretic* 407296465Sdelphij * randomness. NOTE: This approach fails if the program forks before 408296465Sdelphij * we have enough entropy. Entropy should be collected in a separate 409296465Sdelphij * input pool and be transferred to the output pool only when the 410296465Sdelphij * entropy limit has been reached. 411296465Sdelphij */ 412296465Sdelphij entropy -= num; 413296465Sdelphij if (entropy < 0) 414296465Sdelphij entropy = 0; 415296465Sdelphij } 416296465Sdelphij 417296465Sdelphij if (do_stir_pool) { 418296465Sdelphij /* 419296465Sdelphij * In the output function only half of 'md' remains secret, so we 420296465Sdelphij * better make sure that the required entropy gets 'evenly 421296465Sdelphij * distributed' through 'state', our randomness pool. The input 422296465Sdelphij * function (ssleay_rand_add) chains all of 'md', which makes it more 423296465Sdelphij * suitable for this purpose. 424296465Sdelphij */ 425296465Sdelphij 426296465Sdelphij int n = STATE_SIZE; /* so that the complete pool gets accessed */ 427296465Sdelphij while (n > 0) { 42868651Skris#if MD_DIGEST_LENGTH > 20 42968651Skris# error "Please adjust DUMMY_SEED." 43068651Skris#endif 43168651Skris#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */ 432296465Sdelphij /* 433296465Sdelphij * Note that the seed does not matter, it's just that 434296465Sdelphij * ssleay_rand_add expects to have something to hash. 435296465Sdelphij */ 436296465Sdelphij ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0); 437296465Sdelphij n -= MD_DIGEST_LENGTH; 438296465Sdelphij } 439296465Sdelphij if (ok) 440296465Sdelphij stirred_pool = 1; 441296465Sdelphij } 44268651Skris 443296465Sdelphij st_idx = state_index; 444296465Sdelphij st_num = state_num; 445296465Sdelphij md_c[0] = md_count[0]; 446296465Sdelphij md_c[1] = md_count[1]; 447296465Sdelphij memcpy(local_md, md, sizeof md); 44859191Skris 449296465Sdelphij state_index += num_ceil; 450296465Sdelphij if (state_index > state_num) 451296465Sdelphij state_index %= state_num; 45255714Skris 453296465Sdelphij /* 454296465Sdelphij * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now 455296465Sdelphij * ours (but other threads may use them too) 456296465Sdelphij */ 45759191Skris 458296465Sdelphij md_count[0] += 1; 45968651Skris 460296465Sdelphij /* before unlocking, we must clear 'crypto_lock_rand' */ 461296465Sdelphij crypto_lock_rand = 0; 462296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 46355714Skris 464296465Sdelphij while (num > 0) { 465296465Sdelphij /* num_ceil -= MD_DIGEST_LENGTH/2 */ 466296465Sdelphij j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num; 467296465Sdelphij num -= j; 468296465Sdelphij MD_Init(&m); 46959191Skris#ifndef GETPID_IS_MEANINGLESS 470296465Sdelphij if (curr_pid) { /* just in the first iteration to save time */ 471296465Sdelphij MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid); 472296465Sdelphij curr_pid = 0; 473296465Sdelphij } 47459191Skris#endif 475296465Sdelphij MD_Update(&m, local_md, MD_DIGEST_LENGTH); 476296465Sdelphij MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); 47755714Skris#ifndef PURIFY 478296465Sdelphij MD_Update(&m, buf, j); /* purify complains */ 47955714Skris#endif 480296465Sdelphij k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num; 481296465Sdelphij if (k > 0) { 482296465Sdelphij MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k); 483296465Sdelphij MD_Update(&m, &(state[0]), k); 484296465Sdelphij } else 485296465Sdelphij MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2); 486296465Sdelphij MD_Final(&m, local_md); 48755714Skris 488296465Sdelphij for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) { 489296465Sdelphij /* may compete with other threads */ 490296465Sdelphij state[st_idx++] ^= local_md[i]; 491296465Sdelphij if (st_idx >= st_num) 492296465Sdelphij st_idx = 0; 493296465Sdelphij if (i < j) 494296465Sdelphij *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2]; 495296465Sdelphij } 496296465Sdelphij } 49755714Skris 498296465Sdelphij MD_Init(&m); 499296465Sdelphij MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); 500296465Sdelphij MD_Update(&m, local_md, MD_DIGEST_LENGTH); 501296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND); 502296465Sdelphij MD_Update(&m, md, MD_DIGEST_LENGTH); 503296465Sdelphij MD_Final(&m, md); 504296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 50559191Skris 506296465Sdelphij EVP_MD_CTX_cleanup(&m); 507296465Sdelphij if (ok) 508296465Sdelphij return (1); 509296465Sdelphij else { 510296465Sdelphij RANDerr(RAND_F_SSLEAY_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED); 511296465Sdelphij ERR_add_error_data(1, "You need to read the OpenSSL FAQ, " 512296465Sdelphij "http://www.openssl.org/support/faq.html"); 513296465Sdelphij return (0); 514296465Sdelphij } 515296465Sdelphij} 51655714Skris 517296465Sdelphij/* 518296465Sdelphij * pseudo-random bytes that are guaranteed to be unique but not unpredictable 519296465Sdelphij */ 520296465Sdelphijstatic int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) 521296465Sdelphij{ 522296465Sdelphij int ret; 523296465Sdelphij unsigned long err; 52459191Skris 525296465Sdelphij ret = RAND_bytes(buf, num); 526296465Sdelphij if (ret == 0) { 527296465Sdelphij err = ERR_peek_error(); 528296465Sdelphij if (ERR_GET_LIB(err) == ERR_LIB_RAND && 529296465Sdelphij ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED) 530296465Sdelphij ERR_clear_error(); 531296465Sdelphij } 532296465Sdelphij return (ret); 533296465Sdelphij} 53459191Skris 53559191Skrisstatic int ssleay_rand_status(void) 536296465Sdelphij{ 537296465Sdelphij int ret; 538296465Sdelphij int do_not_lock; 53959191Skris 540296465Sdelphij /* 541296465Sdelphij * check if we already have the lock (could happen if a RAND_poll() 542296465Sdelphij * implementation calls RAND_status()) 543296465Sdelphij */ 544296465Sdelphij if (crypto_lock_rand) { 545296465Sdelphij CRYPTO_r_lock(CRYPTO_LOCK_RAND2); 546296465Sdelphij do_not_lock = (locking_thread == CRYPTO_thread_id()); 547296465Sdelphij CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); 548296465Sdelphij } else 549296465Sdelphij do_not_lock = 0; 55068651Skris 551296465Sdelphij if (!do_not_lock) { 552296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND); 55359191Skris 554296465Sdelphij /* 555296465Sdelphij * prevent ssleay_rand_bytes() from trying to obtain the lock again 556296465Sdelphij */ 557296465Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND2); 558296465Sdelphij locking_thread = CRYPTO_thread_id(); 559296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); 560296465Sdelphij crypto_lock_rand = 1; 561296465Sdelphij } 562296465Sdelphij 563296465Sdelphij if (!initialized) { 564296465Sdelphij RAND_poll(); 565296465Sdelphij initialized = 1; 566296465Sdelphij } 567296465Sdelphij 568296465Sdelphij ret = entropy >= ENTROPY_NEEDED; 569296465Sdelphij 570296465Sdelphij if (!do_not_lock) { 571296465Sdelphij /* before unlocking, we must clear 'crypto_lock_rand' */ 572296465Sdelphij crypto_lock_rand = 0; 573296465Sdelphij 574296465Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 575296465Sdelphij } 576296465Sdelphij 577296465Sdelphij return ret; 578296465Sdelphij} 579