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.
8296341Sdelphij *
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).
15296341Sdelphij *
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.
22296341Sdelphij *
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 :-).
37296341Sdelphij * 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)"
40296341Sdelphij *
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.
52296341Sdelphij *
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
66296341Sdelphij *    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
116296341Sdelphij#  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
136296341Sdelphij/* #define PREDICT      1 */
13755714Skris
138296341Sdelphij#define STATE_SIZE      1023
139296341Sdelphijstatic int state_num = 0, state_index = 0;
140296341Sdelphijstatic unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH];
14155714Skrisstatic unsigned char md[MD_DIGEST_LENGTH];
142296341Sdelphijstatic long md_count[2] = { 0, 0 };
14355714Skris
144296341Sdelphijstatic double entropy = 0;
145296341Sdelphijstatic int initialized = 0;
146296341Sdelphij
14779998Skrisstatic unsigned int crypto_lock_rand = 0; /* may be set only when a thread
148296341Sdelphij                                           * holds CRYPTO_LOCK_RAND (to
149296341Sdelphij                                           * prevent double locking) */
15089837Skris/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
151296341Sdelphij/* valid iff crypto_lock_rand is set */
152296341Sdelphijstatic CRYPTO_THREADID locking_threadid;
15368651Skris
15459191Skris#ifdef PREDICT
155296341Sdelphijint rand_predictable = 0;
15659191Skris#endif
15759191Skris
158296341Sdelphijconst char RAND_version[] = "RAND" OPENSSL_VERSION_PTEXT;
15955714Skris
16055714Skrisstatic void ssleay_rand_cleanup(void);
16155714Skrisstatic void ssleay_rand_seed(const void *buf, int num);
16259191Skrisstatic void ssleay_rand_add(const void *buf, int num, double add_entropy);
163238405Sjkimstatic int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
16459191Skrisstatic int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
16559191Skrisstatic int ssleay_rand_status(void);
16655714Skris
167296341SdelphijRAND_METHOD rand_ssleay_meth = {
168296341Sdelphij    ssleay_rand_seed,
169296341Sdelphij    ssleay_rand_nopseudo_bytes,
170296341Sdelphij    ssleay_rand_cleanup,
171296341Sdelphij    ssleay_rand_add,
172296341Sdelphij    ssleay_rand_pseudo_bytes,
173296341Sdelphij    ssleay_rand_status
174296341Sdelphij};
17555714Skris
17655714SkrisRAND_METHOD *RAND_SSLeay(void)
177296341Sdelphij{
178296341Sdelphij    return (&rand_ssleay_meth);
179296341Sdelphij}
18055714Skris
18155714Skrisstatic void ssleay_rand_cleanup(void)
182296341Sdelphij{
183296341Sdelphij    OPENSSL_cleanse(state, sizeof(state));
184296341Sdelphij    state_num = 0;
185296341Sdelphij    state_index = 0;
186296341Sdelphij    OPENSSL_cleanse(md, MD_DIGEST_LENGTH);
187296341Sdelphij    md_count[0] = 0;
188296341Sdelphij    md_count[1] = 0;
189296341Sdelphij    entropy = 0;
190296341Sdelphij    initialized = 0;
191296341Sdelphij}
19255714Skris
19359191Skrisstatic void ssleay_rand_add(const void *buf, int num, double add)
194296341Sdelphij{
195296341Sdelphij    int i, j, k, st_idx;
196296341Sdelphij    long md_c[2];
197296341Sdelphij    unsigned char local_md[MD_DIGEST_LENGTH];
198296341Sdelphij    EVP_MD_CTX m;
199296341Sdelphij    int do_not_lock;
20055714Skris
201296341Sdelphij    if (!num)
202296341Sdelphij        return;
203264331Sjkim
204296341Sdelphij    /*
205296341Sdelphij     * (Based on the rand(3) manpage)
206296341Sdelphij     *
207296341Sdelphij     * The input is chopped up into units of 20 bytes (or less for
208296341Sdelphij     * the last block).  Each of these blocks is run through the hash
209296341Sdelphij     * function as follows:  The data passed to the hash function
210296341Sdelphij     * is the current 'md', the same number of bytes from the 'state'
211296341Sdelphij     * (the location determined by in incremented looping index) as
212296341Sdelphij     * the current 'block', the new key data 'block', and 'count'
213296341Sdelphij     * (which is incremented after each use).
214296341Sdelphij     * The result of this is kept in 'md' and also xored into the
215296341Sdelphij     * 'state' at the same locations that were used as input into the
216296341Sdelphij     * hash function.
217296341Sdelphij     */
21859191Skris
219296341Sdelphij    /* check if we already have the lock */
220296341Sdelphij    if (crypto_lock_rand) {
221296341Sdelphij        CRYPTO_THREADID cur;
222296341Sdelphij        CRYPTO_THREADID_current(&cur);
223296341Sdelphij        CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
224296341Sdelphij        do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
225296341Sdelphij        CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
226296341Sdelphij    } else
227296341Sdelphij        do_not_lock = 0;
22879998Skris
229296341Sdelphij    if (!do_not_lock)
230296341Sdelphij        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
231296341Sdelphij    st_idx = state_index;
23255714Skris
233296341Sdelphij    /*
234296341Sdelphij     * use our own copies of the counters so that even if a concurrent thread
235296341Sdelphij     * seeds with exactly the same data and uses the same subarray there's
236296341Sdelphij     * _some_ difference
237296341Sdelphij     */
238296341Sdelphij    md_c[0] = md_count[0];
239296341Sdelphij    md_c[1] = md_count[1];
24059191Skris
241296341Sdelphij    memcpy(local_md, md, sizeof md);
24259191Skris
243296341Sdelphij    /* state_index <= state_num <= STATE_SIZE */
244296341Sdelphij    state_index += num;
245296341Sdelphij    if (state_index >= STATE_SIZE) {
246296341Sdelphij        state_index %= STATE_SIZE;
247296341Sdelphij        state_num = STATE_SIZE;
248296341Sdelphij    } else if (state_num < STATE_SIZE) {
249296341Sdelphij        if (state_index > state_num)
250296341Sdelphij            state_num = state_index;
251296341Sdelphij    }
252296341Sdelphij    /* state_index <= state_num <= STATE_SIZE */
25359191Skris
254296341Sdelphij    /*
255296341Sdelphij     * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we
256296341Sdelphij     * will use now, but other threads may use them as well
257296341Sdelphij     */
25859191Skris
259296341Sdelphij    md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
26059191Skris
261296341Sdelphij    if (!do_not_lock)
262296341Sdelphij        CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
26355714Skris
264296341Sdelphij    EVP_MD_CTX_init(&m);
265296341Sdelphij    for (i = 0; i < num; i += MD_DIGEST_LENGTH) {
266296341Sdelphij        j = (num - i);
267296341Sdelphij        j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j;
26855714Skris
269296341Sdelphij        MD_Init(&m);
270296341Sdelphij        MD_Update(&m, local_md, MD_DIGEST_LENGTH);
271296341Sdelphij        k = (st_idx + j) - STATE_SIZE;
272296341Sdelphij        if (k > 0) {
273296341Sdelphij            MD_Update(&m, &(state[st_idx]), j - k);
274296341Sdelphij            MD_Update(&m, &(state[0]), k);
275296341Sdelphij        } else
276296341Sdelphij            MD_Update(&m, &(state[st_idx]), j);
277238405Sjkim
278296341Sdelphij        /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
279296341Sdelphij        MD_Update(&m, buf, j);
280296341Sdelphij        /*
281296341Sdelphij         * We know that line may cause programs such as purify and valgrind
282296341Sdelphij         * to complain about use of uninitialized data.  The problem is not,
283296341Sdelphij         * it's with the caller.  Removing that line will make sure you get
284296341Sdelphij         * really bad randomness and thereby other problems such as very
285296341Sdelphij         * insecure keys.
286296341Sdelphij         */
287238405Sjkim
288296341Sdelphij        MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
289296341Sdelphij        MD_Final(&m, local_md);
290296341Sdelphij        md_c[1]++;
29155714Skris
292296341Sdelphij        buf = (const char *)buf + j;
29355714Skris
294296341Sdelphij        for (k = 0; k < j; k++) {
295296341Sdelphij            /*
296296341Sdelphij             * Parallel threads may interfere with this, but always each byte
297296341Sdelphij             * of the new state is the XOR of some previous value of its and
298296341Sdelphij             * local_md (itermediate values may be lost). Alway using locking
299296341Sdelphij             * could hurt performance more than necessary given that
300296341Sdelphij             * conflicts occur only when the total seeding is longer than the
301296341Sdelphij             * random state.
302296341Sdelphij             */
303296341Sdelphij            state[st_idx++] ^= local_md[k];
304296341Sdelphij            if (st_idx >= STATE_SIZE)
305296341Sdelphij                st_idx = 0;
306296341Sdelphij        }
307296341Sdelphij    }
308296341Sdelphij    EVP_MD_CTX_cleanup(&m);
30959191Skris
310296341Sdelphij    if (!do_not_lock)
311296341Sdelphij        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
312296341Sdelphij    /*
313296341Sdelphij     * Don't just copy back local_md into md -- this could mean that other
314296341Sdelphij     * thread's seeding remains without effect (except for the incremented
315296341Sdelphij     * counter).  By XORing it we keep at least as much entropy as fits into
316296341Sdelphij     * md.
317296341Sdelphij     */
318296341Sdelphij    for (k = 0; k < (int)sizeof(md); k++) {
319296341Sdelphij        md[k] ^= local_md[k];
320296341Sdelphij    }
321296341Sdelphij    if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
322296341Sdelphij        entropy += add;
323296341Sdelphij    if (!do_not_lock)
324296341Sdelphij        CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
325296341Sdelphij
326109998Smarkm#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
327296341Sdelphij    assert(md_c[1] == md_count[1]);
32859191Skris#endif
329296341Sdelphij}
33055714Skris
33159191Skrisstatic void ssleay_rand_seed(const void *buf, int num)
332296341Sdelphij{
333296341Sdelphij    ssleay_rand_add(buf, num, (double)num);
334296341Sdelphij}
33559191Skris
336269686Sjkimint ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
337296341Sdelphij{
338296341Sdelphij    static volatile int stirred_pool = 0;
339296341Sdelphij    int i, j, k, st_num, st_idx;
340296341Sdelphij    int num_ceil;
341296341Sdelphij    int ok;
342296341Sdelphij    long md_c[2];
343296341Sdelphij    unsigned char local_md[MD_DIGEST_LENGTH];
344296341Sdelphij    EVP_MD_CTX m;
34559191Skris#ifndef GETPID_IS_MEANINGLESS
346296341Sdelphij    pid_t curr_pid = getpid();
34759191Skris#endif
348296341Sdelphij    int do_stir_pool = 0;
34959191Skris
35059191Skris#ifdef PREDICT
351296341Sdelphij    if (rand_predictable) {
352296341Sdelphij        static unsigned char val = 0;
35359191Skris
354296341Sdelphij        for (i = 0; i < num; i++)
355296341Sdelphij            buf[i] = val++;
356296341Sdelphij        return (1);
357296341Sdelphij    }
35855714Skris#endif
35955714Skris
360296341Sdelphij    if (num <= 0)
361296341Sdelphij        return 1;
362109998Smarkm
363296341Sdelphij    EVP_MD_CTX_init(&m);
364296341Sdelphij    /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
365296341Sdelphij    num_ceil =
366296341Sdelphij        (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2);
36779998Skris
368296341Sdelphij    /*
369296341Sdelphij     * (Based on the rand(3) manpage:)
370296341Sdelphij     *
371296341Sdelphij     * For each group of 10 bytes (or less), we do the following:
372296341Sdelphij     *
373296341Sdelphij     * Input into the hash function the local 'md' (which is initialized from
374296341Sdelphij     * the global 'md' before any bytes are generated), the bytes that are to
375296341Sdelphij     * be overwritten by the random bytes, and bytes from the 'state'
376296341Sdelphij     * (incrementing looping index). From this digest output (which is kept
377296341Sdelphij     * in 'md'), the top (up to) 10 bytes are returned to the caller and the
378296341Sdelphij     * bottom 10 bytes are xored into the 'state'.
379296341Sdelphij     *
380296341Sdelphij     * Finally, after we have finished 'num' random bytes for the
381296341Sdelphij     * caller, 'count' (which is incremented) and the local and global 'md'
382296341Sdelphij     * are fed into the hash function and the results are kept in the
383296341Sdelphij     * global 'md'.
384296341Sdelphij     */
385296341Sdelphij    if (lock)
386296341Sdelphij        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
38759191Skris
388296341Sdelphij    /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
389296341Sdelphij    CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
390296341Sdelphij    CRYPTO_THREADID_current(&locking_threadid);
391296341Sdelphij    CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
392296341Sdelphij    crypto_lock_rand = 1;
39379998Skris
394296341Sdelphij    if (!initialized) {
395296341Sdelphij        RAND_poll();
396296341Sdelphij        initialized = 1;
397296341Sdelphij    }
39855714Skris
399296341Sdelphij    if (!stirred_pool)
400296341Sdelphij        do_stir_pool = 1;
40168651Skris
402296341Sdelphij    ok = (entropy >= ENTROPY_NEEDED);
403296341Sdelphij    if (!ok) {
404296341Sdelphij        /*
405296341Sdelphij         * If the PRNG state is not yet unpredictable, then seeing the PRNG
406296341Sdelphij         * output may help attackers to determine the new state; thus we have
407296341Sdelphij         * to decrease the entropy estimate. Once we've had enough initial
408296341Sdelphij         * seeding we don't bother to adjust the entropy count, though,
409296341Sdelphij         * because we're not ambitious to provide *information-theoretic*
410296341Sdelphij         * randomness. NOTE: This approach fails if the program forks before
411296341Sdelphij         * we have enough entropy. Entropy should be collected in a separate
412296341Sdelphij         * input pool and be transferred to the output pool only when the
413296341Sdelphij         * entropy limit has been reached.
414296341Sdelphij         */
415296341Sdelphij        entropy -= num;
416296341Sdelphij        if (entropy < 0)
417296341Sdelphij            entropy = 0;
418296341Sdelphij    }
419296341Sdelphij
420296341Sdelphij    if (do_stir_pool) {
421296341Sdelphij        /*
422296341Sdelphij         * In the output function only half of 'md' remains secret, so we
423296341Sdelphij         * better make sure that the required entropy gets 'evenly
424296341Sdelphij         * distributed' through 'state', our randomness pool. The input
425296341Sdelphij         * function (ssleay_rand_add) chains all of 'md', which makes it more
426296341Sdelphij         * suitable for this purpose.
427296341Sdelphij         */
428296341Sdelphij
429296341Sdelphij        int n = STATE_SIZE;     /* so that the complete pool gets accessed */
430296341Sdelphij        while (n > 0) {
43168651Skris#if MD_DIGEST_LENGTH > 20
43268651Skris# error "Please adjust DUMMY_SEED."
43368651Skris#endif
43468651Skris#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
435296341Sdelphij            /*
436296341Sdelphij             * Note that the seed does not matter, it's just that
437296341Sdelphij             * ssleay_rand_add expects to have something to hash.
438296341Sdelphij             */
439296341Sdelphij            ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
440296341Sdelphij            n -= MD_DIGEST_LENGTH;
441296341Sdelphij        }
442296341Sdelphij        if (ok)
443296341Sdelphij            stirred_pool = 1;
444296341Sdelphij    }
44568651Skris
446296341Sdelphij    st_idx = state_index;
447296341Sdelphij    st_num = state_num;
448296341Sdelphij    md_c[0] = md_count[0];
449296341Sdelphij    md_c[1] = md_count[1];
450296341Sdelphij    memcpy(local_md, md, sizeof md);
45159191Skris
452296341Sdelphij    state_index += num_ceil;
453296341Sdelphij    if (state_index > state_num)
454296341Sdelphij        state_index %= state_num;
45555714Skris
456296341Sdelphij    /*
457296341Sdelphij     * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now
458296341Sdelphij     * ours (but other threads may use them too)
459296341Sdelphij     */
46059191Skris
461296341Sdelphij    md_count[0] += 1;
46268651Skris
463296341Sdelphij    /* before unlocking, we must clear 'crypto_lock_rand' */
464296341Sdelphij    crypto_lock_rand = 0;
465296341Sdelphij    if (lock)
466296341Sdelphij        CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
46755714Skris
468296341Sdelphij    while (num > 0) {
469296341Sdelphij        /* num_ceil -= MD_DIGEST_LENGTH/2 */
470296341Sdelphij        j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num;
471296341Sdelphij        num -= j;
472296341Sdelphij        MD_Init(&m);
47359191Skris#ifndef GETPID_IS_MEANINGLESS
474296341Sdelphij        if (curr_pid) {         /* just in the first iteration to save time */
475296341Sdelphij            MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid);
476296341Sdelphij            curr_pid = 0;
477296341Sdelphij        }
47859191Skris#endif
479296341Sdelphij        MD_Update(&m, local_md, MD_DIGEST_LENGTH);
480296341Sdelphij        MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
481238405Sjkim
482296341Sdelphij#ifndef PURIFY                  /* purify complains */
483296341Sdelphij        /*
484296341Sdelphij         * The following line uses the supplied buffer as a small source of
485296341Sdelphij         * entropy: since this buffer is often uninitialised it may cause
486296341Sdelphij         * programs such as purify or valgrind to complain. So for those
487296341Sdelphij         * builds it is not used: the removal of such a small source of
488296341Sdelphij         * entropy has negligible impact on security.
489296341Sdelphij         */
490296341Sdelphij        MD_Update(&m, buf, j);
49155714Skris#endif
492238405Sjkim
493296341Sdelphij        k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num;
494296341Sdelphij        if (k > 0) {
495296341Sdelphij            MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k);
496296341Sdelphij            MD_Update(&m, &(state[0]), k);
497296341Sdelphij        } else
498296341Sdelphij            MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2);
499296341Sdelphij        MD_Final(&m, local_md);
50055714Skris
501296341Sdelphij        for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) {
502296341Sdelphij            /* may compete with other threads */
503296341Sdelphij            state[st_idx++] ^= local_md[i];
504296341Sdelphij            if (st_idx >= st_num)
505296341Sdelphij                st_idx = 0;
506296341Sdelphij            if (i < j)
507296341Sdelphij                *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2];
508296341Sdelphij        }
509296341Sdelphij    }
51055714Skris
511296341Sdelphij    MD_Init(&m);
512296341Sdelphij    MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
513296341Sdelphij    MD_Update(&m, local_md, MD_DIGEST_LENGTH);
514296341Sdelphij    if (lock)
515296341Sdelphij        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
516296341Sdelphij    MD_Update(&m, md, MD_DIGEST_LENGTH);
517296341Sdelphij    MD_Final(&m, md);
518296341Sdelphij    if (lock)
519296341Sdelphij        CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
52059191Skris
521296341Sdelphij    EVP_MD_CTX_cleanup(&m);
522296341Sdelphij    if (ok)
523296341Sdelphij        return (1);
524296341Sdelphij    else if (pseudo)
525296341Sdelphij        return 0;
526296341Sdelphij    else {
527296341Sdelphij        RANDerr(RAND_F_SSLEAY_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED);
528296341Sdelphij        ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
529296341Sdelphij                           "http://www.openssl.org/support/faq.html");
530296341Sdelphij        return (0);
531296341Sdelphij    }
532296341Sdelphij}
53355714Skris
534238405Sjkimstatic int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
535296341Sdelphij{
536296341Sdelphij    return ssleay_rand_bytes(buf, num, 0, 1);
537296341Sdelphij}
538238405Sjkim
539296341Sdelphij/*
540296341Sdelphij * pseudo-random bytes that are guaranteed to be unique but not unpredictable
541296341Sdelphij */
542296341Sdelphijstatic int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
543296341Sdelphij{
544296341Sdelphij    return ssleay_rand_bytes(buf, num, 1, 1);
545296341Sdelphij}
54659191Skris
54759191Skrisstatic int ssleay_rand_status(void)
548296341Sdelphij{
549296341Sdelphij    CRYPTO_THREADID cur;
550296341Sdelphij    int ret;
551296341Sdelphij    int do_not_lock;
55259191Skris
553296341Sdelphij    CRYPTO_THREADID_current(&cur);
554296341Sdelphij    /*
555296341Sdelphij     * check if we already have the lock (could happen if a RAND_poll()
556296341Sdelphij     * implementation calls RAND_status())
557296341Sdelphij     */
558296341Sdelphij    if (crypto_lock_rand) {
559296341Sdelphij        CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
560296341Sdelphij        do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
561296341Sdelphij        CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
562296341Sdelphij    } else
563296341Sdelphij        do_not_lock = 0;
56468651Skris
565296341Sdelphij    if (!do_not_lock) {
566296341Sdelphij        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
56759191Skris
568296341Sdelphij        /*
569296341Sdelphij         * prevent ssleay_rand_bytes() from trying to obtain the lock again
570296341Sdelphij         */
571296341Sdelphij        CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
572296341Sdelphij        CRYPTO_THREADID_cpy(&locking_threadid, &cur);
573296341Sdelphij        CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
574296341Sdelphij        crypto_lock_rand = 1;
575296341Sdelphij    }
576296341Sdelphij
577296341Sdelphij    if (!initialized) {
578296341Sdelphij        RAND_poll();
579296341Sdelphij        initialized = 1;
580296341Sdelphij    }
581296341Sdelphij
582296341Sdelphij    ret = entropy >= ENTROPY_NEEDED;
583296341Sdelphij
584296341Sdelphij    if (!do_not_lock) {
585296341Sdelphij        /* before unlocking, we must clear 'crypto_lock_rand' */
586296341Sdelphij        crypto_lock_rand = 0;
587296341Sdelphij
588296341Sdelphij        CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
589296341Sdelphij    }
590296341Sdelphij
591296341Sdelphij    return ret;
592296341Sdelphij}
593