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. 855714Skris * 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). 1555714Skris * 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. 2255714Skris * 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 :-). 3755714Skris * 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)" 4055714Skris * 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. 5255714Skris * 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 6659191Skris * 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 112238405Sjkim#define OPENSSL_FIPSEVP 113238405Sjkim 11468651Skris#ifdef MD_RAND_DEBUG 11559191Skris# ifndef NDEBUG 11659191Skris# define NDEBUG 11759191Skris# endif 11859191Skris#endif 11959191Skris 12059191Skris#include <assert.h> 12155714Skris#include <stdio.h> 12255714Skris#include <string.h> 12355714Skris 124109998Smarkm#include "e_os.h" 12555714Skris 126246772Sjkim#include <openssl/crypto.h> 12768651Skris#include <openssl/rand.h> 12868651Skris#include "rand_lcl.h" 12968651Skris 13059191Skris#include <openssl/err.h> 13155714Skris 13259191Skris#ifdef BN_DEBUG 13359191Skris# define PREDICT 13459191Skris#endif 13559191Skris 13655714Skris/* #define PREDICT 1 */ 13755714Skris 13855714Skris#define STATE_SIZE 1023 13955714Skrisstatic int state_num=0,state_index=0; 14055714Skrisstatic unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH]; 14155714Skrisstatic unsigned char md[MD_DIGEST_LENGTH]; 14255714Skrisstatic long md_count[2]={0,0}; 14359191Skrisstatic double entropy=0; 14459191Skrisstatic int initialized=0; 14555714Skris 14679998Skrisstatic unsigned int crypto_lock_rand = 0; /* may be set only when a thread 14779998Skris * holds CRYPTO_LOCK_RAND 14879998Skris * (to prevent double locking) */ 14989837Skris/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ 150238405Sjkimstatic CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */ 15168651Skris 15279998Skris 15359191Skris#ifdef PREDICT 15459191Skrisint rand_predictable=0; 15559191Skris#endif 15659191Skris 157167612Ssimonconst char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT; 15855714Skris 15955714Skrisstatic void ssleay_rand_cleanup(void); 16055714Skrisstatic void ssleay_rand_seed(const void *buf, int num); 16159191Skrisstatic void ssleay_rand_add(const void *buf, int num, double add_entropy); 162238405Sjkimstatic int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num); 16359191Skrisstatic int ssleay_rand_pseudo_bytes(unsigned char *buf, int num); 16459191Skrisstatic int ssleay_rand_status(void); 16555714Skris 16655714SkrisRAND_METHOD rand_ssleay_meth={ 16755714Skris ssleay_rand_seed, 168238405Sjkim ssleay_rand_nopseudo_bytes, 16955714Skris ssleay_rand_cleanup, 17059191Skris ssleay_rand_add, 17159191Skris ssleay_rand_pseudo_bytes, 17259191Skris ssleay_rand_status 17355714Skris }; 17455714Skris 17555714SkrisRAND_METHOD *RAND_SSLeay(void) 17655714Skris { 17755714Skris return(&rand_ssleay_meth); 17855714Skris } 17955714Skris 18055714Skrisstatic void ssleay_rand_cleanup(void) 18155714Skris { 182109998Smarkm OPENSSL_cleanse(state,sizeof(state)); 18355714Skris state_num=0; 18455714Skris state_index=0; 185109998Smarkm OPENSSL_cleanse(md,MD_DIGEST_LENGTH); 18655714Skris md_count[0]=0; 18755714Skris md_count[1]=0; 18859191Skris entropy=0; 18968651Skris initialized=0; 19055714Skris } 19155714Skris 19259191Skrisstatic void ssleay_rand_add(const void *buf, int num, double add) 19355714Skris { 19459191Skris int i,j,k,st_idx; 19559191Skris long md_c[2]; 19659191Skris unsigned char local_md[MD_DIGEST_LENGTH]; 197109998Smarkm EVP_MD_CTX m; 19879998Skris int do_not_lock; 19955714Skris 200279264Sdelphij if (!num) 201279264Sdelphij return; 202279264Sdelphij 20359191Skris /* 20459191Skris * (Based on the rand(3) manpage) 20559191Skris * 20659191Skris * The input is chopped up into units of 20 bytes (or less for 20759191Skris * the last block). Each of these blocks is run through the hash 20859191Skris * function as follows: The data passed to the hash function 20959191Skris * is the current 'md', the same number of bytes from the 'state' 21059191Skris * (the location determined by in incremented looping index) as 21159191Skris * the current 'block', the new key data 'block', and 'count' 21259191Skris * (which is incremented after each use). 21359191Skris * The result of this is kept in 'md' and also xored into the 21459191Skris * 'state' at the same locations that were used as input into the 21559191Skris * hash function. 21659191Skris */ 21759191Skris 21879998Skris /* check if we already have the lock */ 21989837Skris if (crypto_lock_rand) 22089837Skris { 221238405Sjkim CRYPTO_THREADID cur; 222238405Sjkim CRYPTO_THREADID_current(&cur); 22389837Skris CRYPTO_r_lock(CRYPTO_LOCK_RAND2); 224238405Sjkim do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); 22589837Skris CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); 22689837Skris } 22789837Skris else 22889837Skris do_not_lock = 0; 22979998Skris 23079998Skris if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); 23155714Skris st_idx=state_index; 23255714Skris 23359191Skris /* use our own copies of the counters so that even 23459191Skris * if a concurrent thread seeds with exactly the 23559191Skris * same data and uses the same subarray there's _some_ 23659191Skris * difference */ 23759191Skris md_c[0] = md_count[0]; 23859191Skris md_c[1] = md_count[1]; 23959191Skris 24059191Skris memcpy(local_md, md, sizeof md); 24159191Skris 24259191Skris /* state_index <= state_num <= STATE_SIZE */ 24359191Skris state_index += num; 24455714Skris if (state_index >= STATE_SIZE) 24555714Skris { 24655714Skris state_index%=STATE_SIZE; 24755714Skris state_num=STATE_SIZE; 24855714Skris } 24955714Skris else if (state_num < STATE_SIZE) 25055714Skris { 25155714Skris if (state_index > state_num) 25255714Skris state_num=state_index; 25355714Skris } 25459191Skris /* state_index <= state_num <= STATE_SIZE */ 25559191Skris 25659191Skris /* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] 25759191Skris * are what we will use now, but other threads may use them 25859191Skris * as well */ 25959191Skris 26059191Skris md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0); 26159191Skris 26279998Skris if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 26355714Skris 264109998Smarkm EVP_MD_CTX_init(&m); 26555714Skris for (i=0; i<num; i+=MD_DIGEST_LENGTH) 26655714Skris { 26755714Skris j=(num-i); 26855714Skris j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j; 26955714Skris 27055714Skris MD_Init(&m); 27159191Skris MD_Update(&m,local_md,MD_DIGEST_LENGTH); 27255714Skris k=(st_idx+j)-STATE_SIZE; 27355714Skris if (k > 0) 27455714Skris { 27555714Skris MD_Update(&m,&(state[st_idx]),j-k); 27655714Skris MD_Update(&m,&(state[0]),k); 27755714Skris } 27855714Skris else 27955714Skris MD_Update(&m,&(state[st_idx]),j); 280238405Sjkim 281238405Sjkim /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ 28255714Skris MD_Update(&m,buf,j); 283238405Sjkim /* We know that line may cause programs such as 284238405Sjkim purify and valgrind to complain about use of 285238405Sjkim uninitialized data. The problem is not, it's 286238405Sjkim with the caller. Removing that line will make 287238405Sjkim sure you get really bad randomness and thereby 288238405Sjkim other problems such as very insecure keys. */ 289238405Sjkim 29059191Skris MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); 291109998Smarkm MD_Final(&m,local_md); 29259191Skris md_c[1]++; 29355714Skris 29455714Skris buf=(const char *)buf + j; 29555714Skris 29655714Skris for (k=0; k<j; k++) 29755714Skris { 29859191Skris /* Parallel threads may interfere with this, 29959191Skris * but always each byte of the new state is 30059191Skris * the XOR of some previous value of its 30159191Skris * and local_md (itermediate values may be lost). 30259191Skris * Alway using locking could hurt performance more 30359191Skris * than necessary given that conflicts occur only 30459191Skris * when the total seeding is longer than the random 30559191Skris * state. */ 30659191Skris state[st_idx++]^=local_md[k]; 30755714Skris if (st_idx >= STATE_SIZE) 30855714Skris st_idx=0; 30955714Skris } 31055714Skris } 311109998Smarkm EVP_MD_CTX_cleanup(&m); 31259191Skris 31379998Skris if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); 31459191Skris /* Don't just copy back local_md into md -- this could mean that 31559191Skris * other thread's seeding remains without effect (except for 31659191Skris * the incremented counter). By XORing it we keep at least as 31759191Skris * much entropy as fits into md. */ 318160814Ssimon for (k = 0; k < (int)sizeof(md); k++) 31959191Skris { 32059191Skris md[k] ^= local_md[k]; 32159191Skris } 32259191Skris if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */ 32359191Skris entropy += add; 32479998Skris if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 32559191Skris 326109998Smarkm#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) 32759191Skris assert(md_c[1] == md_count[1]); 32859191Skris#endif 32955714Skris } 33055714Skris 33159191Skrisstatic void ssleay_rand_seed(const void *buf, int num) 33255714Skris { 333160814Ssimon ssleay_rand_add(buf, num, (double)num); 33459191Skris } 33559191Skris 336279264Sdelphijint ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) 33759191Skris { 33868651Skris static volatile int stirred_pool = 0; 33959191Skris int i,j,k,st_num,st_idx; 34079998Skris int num_ceil; 34159191Skris int ok; 34259191Skris long md_c[2]; 34359191Skris unsigned char local_md[MD_DIGEST_LENGTH]; 344109998Smarkm EVP_MD_CTX m; 34559191Skris#ifndef GETPID_IS_MEANINGLESS 34659191Skris pid_t curr_pid = getpid(); 34759191Skris#endif 34868651Skris int do_stir_pool = 0; 34959191Skris 35059191Skris#ifdef PREDICT 35159191Skris if (rand_predictable) 35255714Skris { 35359191Skris static unsigned char val=0; 35459191Skris 35559191Skris for (i=0; i<num; i++) 35659191Skris buf[i]=val++; 35759191Skris return(1); 35859191Skris } 35955714Skris#endif 36055714Skris 36179998Skris if (num <= 0) 36279998Skris return 1; 363109998Smarkm 364109998Smarkm EVP_MD_CTX_init(&m); 36579998Skris /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ 36679998Skris num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2); 36779998Skris 36859191Skris /* 36959191Skris * (Based on the rand(3) manpage:) 37059191Skris * 37159191Skris * For each group of 10 bytes (or less), we do the following: 37259191Skris * 37379998Skris * Input into the hash function the local 'md' (which is initialized from 37479998Skris * the global 'md' before any bytes are generated), the bytes that are to 37579998Skris * be overwritten by the random bytes, and bytes from the 'state' 37679998Skris * (incrementing looping index). From this digest output (which is kept 37779998Skris * in 'md'), the top (up to) 10 bytes are returned to the caller and the 37879998Skris * bottom 10 bytes are xored into the 'state'. 37979998Skris * 38059191Skris * Finally, after we have finished 'num' random bytes for the 38159191Skris * caller, 'count' (which is incremented) and the local and global 'md' 38259191Skris * are fed into the hash function and the results are kept in the 38359191Skris * global 'md'. 38459191Skris */ 385279264Sdelphij if (lock) 386279264Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND); 38759191Skris 38879998Skris /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ 38989837Skris CRYPTO_w_lock(CRYPTO_LOCK_RAND2); 390238405Sjkim CRYPTO_THREADID_current(&locking_threadid); 39189837Skris CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); 39279998Skris crypto_lock_rand = 1; 39379998Skris 39468651Skris if (!initialized) 39579998Skris { 39668651Skris RAND_poll(); 39779998Skris initialized = 1; 39879998Skris } 39979998Skris 40068651Skris if (!stirred_pool) 40168651Skris do_stir_pool = 1; 40268651Skris 40359191Skris ok = (entropy >= ENTROPY_NEEDED); 40459191Skris if (!ok) 40559191Skris { 40659191Skris /* If the PRNG state is not yet unpredictable, then seeing 40759191Skris * the PRNG output may help attackers to determine the new 40859191Skris * state; thus we have to decrease the entropy estimate. 40959191Skris * Once we've had enough initial seeding we don't bother to 41059191Skris * adjust the entropy count, though, because we're not ambitious 41159191Skris * to provide *information-theoretic* randomness. 41268651Skris * 41368651Skris * NOTE: This approach fails if the program forks before 41468651Skris * we have enough entropy. Entropy should be collected 41568651Skris * in a separate input pool and be transferred to the 41668651Skris * output pool only when the entropy limit has been reached. 41755714Skris */ 41859191Skris entropy -= num; 41959191Skris if (entropy < 0) 42059191Skris entropy = 0; 42155714Skris } 42255714Skris 42368651Skris if (do_stir_pool) 42468651Skris { 42579998Skris /* In the output function only half of 'md' remains secret, 42679998Skris * so we better make sure that the required entropy gets 42779998Skris * 'evenly distributed' through 'state', our randomness pool. 42879998Skris * The input function (ssleay_rand_add) chains all of 'md', 42979998Skris * which makes it more suitable for this purpose. 43068651Skris */ 43168651Skris 43268651Skris int n = STATE_SIZE; /* so that the complete pool gets accessed */ 43368651Skris while (n > 0) 43468651Skris { 43568651Skris#if MD_DIGEST_LENGTH > 20 43668651Skris# error "Please adjust DUMMY_SEED." 43768651Skris#endif 43868651Skris#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */ 43968651Skris /* Note that the seed does not matter, it's just that 44068651Skris * ssleay_rand_add expects to have something to hash. */ 44168651Skris ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0); 44268651Skris n -= MD_DIGEST_LENGTH; 44368651Skris } 44468651Skris if (ok) 44568651Skris stirred_pool = 1; 44668651Skris } 44768651Skris 44855714Skris st_idx=state_index; 44955714Skris st_num=state_num; 45059191Skris md_c[0] = md_count[0]; 45159191Skris md_c[1] = md_count[1]; 45259191Skris memcpy(local_md, md, sizeof md); 45359191Skris 45479998Skris state_index+=num_ceil; 45555714Skris if (state_index > state_num) 45659191Skris state_index %= state_num; 45755714Skris 45879998Skris /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] 45959191Skris * are now ours (but other threads may use them too) */ 46059191Skris 46159191Skris md_count[0] += 1; 46268651Skris 46379998Skris /* before unlocking, we must clear 'crypto_lock_rand' */ 46479998Skris crypto_lock_rand = 0; 465279264Sdelphij if (lock) 466279264Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 46755714Skris 46855714Skris while (num > 0) 46955714Skris { 47079998Skris /* num_ceil -= MD_DIGEST_LENGTH/2 */ 47155714Skris j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num; 47255714Skris num-=j; 47355714Skris MD_Init(&m); 47459191Skris#ifndef GETPID_IS_MEANINGLESS 47559191Skris if (curr_pid) /* just in the first iteration to save time */ 47659191Skris { 47759191Skris MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid); 47859191Skris curr_pid = 0; 47959191Skris } 48059191Skris#endif 48179998Skris MD_Update(&m,local_md,MD_DIGEST_LENGTH); 48259191Skris MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); 483238405Sjkim 484238405Sjkim#ifndef PURIFY /* purify complains */ 485238405Sjkim /* The following line uses the supplied buffer as a small 486238405Sjkim * source of entropy: since this buffer is often uninitialised 487238405Sjkim * it may cause programs such as purify or valgrind to 488238405Sjkim * complain. So for those builds it is not used: the removal 489238405Sjkim * of such a small source of entropy has negligible impact on 490238405Sjkim * security. 491238405Sjkim */ 492238405Sjkim MD_Update(&m,buf,j); 49355714Skris#endif 494238405Sjkim 49579998Skris k=(st_idx+MD_DIGEST_LENGTH/2)-st_num; 49655714Skris if (k > 0) 49755714Skris { 49879998Skris MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k); 49955714Skris MD_Update(&m,&(state[0]),k); 50055714Skris } 50155714Skris else 50279998Skris MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); 503109998Smarkm MD_Final(&m,local_md); 50455714Skris 50579998Skris for (i=0; i<MD_DIGEST_LENGTH/2; i++) 50655714Skris { 50759191Skris state[st_idx++]^=local_md[i]; /* may compete with other threads */ 50855714Skris if (st_idx >= st_num) 50955714Skris st_idx=0; 51079998Skris if (i < j) 51179998Skris *(buf++)=local_md[i+MD_DIGEST_LENGTH/2]; 51255714Skris } 51355714Skris } 51455714Skris 51555714Skris MD_Init(&m); 51659191Skris MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); 51759191Skris MD_Update(&m,local_md,MD_DIGEST_LENGTH); 518279264Sdelphij if (lock) 519279264Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_RAND); 52055714Skris MD_Update(&m,md,MD_DIGEST_LENGTH); 521109998Smarkm MD_Final(&m,md); 522279264Sdelphij if (lock) 523279264Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 52459191Skris 525109998Smarkm EVP_MD_CTX_cleanup(&m); 52659191Skris if (ok) 52759191Skris return(1); 528238405Sjkim else if (pseudo) 529238405Sjkim return 0; 530238405Sjkim else 53159191Skris { 53259191Skris RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED); 53368651Skris ERR_add_error_data(1, "You need to read the OpenSSL FAQ, " 53468651Skris "http://www.openssl.org/support/faq.html"); 53559191Skris return(0); 53659191Skris } 53755714Skris } 53855714Skris 539238405Sjkimstatic int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num) 540238405Sjkim { 541279264Sdelphij return ssleay_rand_bytes(buf, num, 0, 1); 542238405Sjkim } 543238405Sjkim 54459191Skris/* pseudo-random bytes that are guaranteed to be unique but not 54559191Skris unpredictable */ 54659191Skrisstatic int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) 54759191Skris { 548279264Sdelphij return ssleay_rand_bytes(buf, num, 1, 1); 54959191Skris } 55059191Skris 55159191Skrisstatic int ssleay_rand_status(void) 55259191Skris { 553238405Sjkim CRYPTO_THREADID cur; 55459191Skris int ret; 55579998Skris int do_not_lock; 55659191Skris 557238405Sjkim CRYPTO_THREADID_current(&cur); 55879998Skris /* check if we already have the lock 55979998Skris * (could happen if a RAND_poll() implementation calls RAND_status()) */ 56089837Skris if (crypto_lock_rand) 56189837Skris { 56289837Skris CRYPTO_r_lock(CRYPTO_LOCK_RAND2); 563238405Sjkim do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); 56489837Skris CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); 56589837Skris } 56689837Skris else 56789837Skris do_not_lock = 0; 56879998Skris 56979998Skris if (!do_not_lock) 57079998Skris { 57179998Skris CRYPTO_w_lock(CRYPTO_LOCK_RAND); 57279998Skris 57379998Skris /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ 57489837Skris CRYPTO_w_lock(CRYPTO_LOCK_RAND2); 575238405Sjkim CRYPTO_THREADID_cpy(&locking_threadid, &cur); 57689837Skris CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); 57779998Skris crypto_lock_rand = 1; 57879998Skris } 57979998Skris 58068651Skris if (!initialized) 58179998Skris { 58268651Skris RAND_poll(); 58379998Skris initialized = 1; 58479998Skris } 58568651Skris 58659191Skris ret = entropy >= ENTROPY_NEEDED; 58759191Skris 58879998Skris if (!do_not_lock) 58979998Skris { 59079998Skris /* before unlocking, we must clear 'crypto_lock_rand' */ 59179998Skris crypto_lock_rand = 0; 59279998Skris 59379998Skris CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 59479998Skris } 59579998Skris 59659191Skris return ret; 59759191Skris } 598