diff options
-rw-r--r-- | lib/libcrypto/crypto/Makefile | 4 | ||||
-rw-r--r-- | lib/libssl/src/crypto/rand/md_rand.c | 607 | ||||
-rw-r--r-- | lib/libssl/src/crypto/rand/rand.h | 26 | ||||
-rw-r--r-- | lib/libssl/src/crypto/rand/rand_egd.c | 193 | ||||
-rw-r--r-- | lib/libssl/src/crypto/rand/rand_lcl.h | 158 | ||||
-rw-r--r-- | lib/libssl/src/crypto/rand/rand_lib.c | 129 | ||||
-rw-r--r-- | lib/libssl/src/crypto/rand/rand_unix.c | 308 | ||||
-rw-r--r-- | lib/libssl/src/crypto/rand/randfile.c | 152 | ||||
-rw-r--r-- | lib/libssl/src/crypto/rand/rc4_rand.c | 44 | ||||
-rw-r--r-- | lib/libssl/src/doc/crypto/RAND_add.pod | 57 | ||||
-rw-r--r-- | lib/libssl/src/doc/crypto/RAND_egd.pod | 69 | ||||
-rw-r--r-- | lib/libssl/src/doc/crypto/RAND_load_file.pod | 14 | ||||
-rw-r--r-- | lib/libssl/src/doc/crypto/rand.pod | 105 |
13 files changed, 73 insertions, 1793 deletions
diff --git a/lib/libcrypto/crypto/Makefile b/lib/libcrypto/crypto/Makefile index 116a3d4fd0f..26fe163249d 100644 --- a/lib/libcrypto/crypto/Makefile +++ b/lib/libcrypto/crypto/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.5 2014/04/14 04:27:50 miod Exp $ +# $OpenBSD: Makefile,v 1.6 2014/04/15 16:52:50 miod Exp $ LIB= crypto @@ -220,7 +220,7 @@ SRCS+= pk7_mime.c bio_pk7.c SRCS+= pqueue.c # rand/ -SRCS+= md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c +SRCS+= rc4_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c SRCS+= rand_unix.c # rc2/ diff --git a/lib/libssl/src/crypto/rand/md_rand.c b/lib/libssl/src/crypto/rand/md_rand.c deleted file mode 100644 index aee1c30b0a9..00000000000 --- a/lib/libssl/src/crypto/rand/md_rand.c +++ /dev/null @@ -1,607 +0,0 @@ -/* crypto/rand/md_rand.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#define OPENSSL_FIPSEVP - -#ifdef MD_RAND_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif - -#include <assert.h> -#include <stdio.h> -#include <string.h> - -#include "e_os.h" - -#include <openssl/crypto.h> -#include <openssl/rand.h> -#include "rand_lcl.h" - -#include <openssl/err.h> - -#ifdef BN_DEBUG -# define PREDICT -#endif - -/* #define PREDICT 1 */ - -#define STATE_SIZE 1023 -static int state_num=0,state_index=0; -static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH]; -static unsigned char md[MD_DIGEST_LENGTH]; -static long md_count[2]={0,0}; -static double entropy=0; -static int initialized=0; - -static unsigned int crypto_lock_rand = 0; /* may be set only when a thread - * holds CRYPTO_LOCK_RAND - * (to prevent double locking) */ -/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ -static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */ - - -#ifdef PREDICT -int rand_predictable=0; -#endif - -const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT; - -static void ssleay_rand_cleanup(void); -static void ssleay_rand_seed(const void *buf, int num); -static void ssleay_rand_add(const void *buf, int num, double add_entropy); -static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo); -static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num); -static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num); -static int ssleay_rand_status(void); - -RAND_METHOD rand_ssleay_meth={ - ssleay_rand_seed, - ssleay_rand_nopseudo_bytes, - ssleay_rand_cleanup, - ssleay_rand_add, - ssleay_rand_pseudo_bytes, - ssleay_rand_status - }; - -RAND_METHOD *RAND_SSLeay(void) - { - return(&rand_ssleay_meth); - } - -static void ssleay_rand_cleanup(void) - { - OPENSSL_cleanse(state,sizeof(state)); - state_num=0; - state_index=0; - OPENSSL_cleanse(md,MD_DIGEST_LENGTH); - md_count[0]=0; - md_count[1]=0; - entropy=0; - initialized=0; - } - -static void ssleay_rand_add(const void *buf, int num, double add) - { - int i,j,k,st_idx; - long md_c[2]; - unsigned char local_md[MD_DIGEST_LENGTH]; - EVP_MD_CTX m; - int do_not_lock; - - if (!num) - return; - - /* - * (Based on the rand(3) manpage) - * - * The input is chopped up into units of 20 bytes (or less for - * the last block). Each of these blocks is run through the hash - * function as follows: The data passed to the hash function - * is the current 'md', the same number of bytes from the 'state' - * (the location determined by in incremented looping index) as - * the current 'block', the new key data 'block', and 'count' - * (which is incremented after each use). - * The result of this is kept in 'md' and also xored into the - * 'state' at the same locations that were used as input into the - * hash function. - */ - - /* check if we already have the lock */ - if (crypto_lock_rand) - { - CRYPTO_THREADID cur; - CRYPTO_THREADID_current(&cur); - CRYPTO_r_lock(CRYPTO_LOCK_RAND2); - do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); - CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); - } - else - do_not_lock = 0; - - if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); - st_idx=state_index; - - /* use our own copies of the counters so that even - * if a concurrent thread seeds with exactly the - * same data and uses the same subarray there's _some_ - * difference */ - md_c[0] = md_count[0]; - md_c[1] = md_count[1]; - - memcpy(local_md, md, sizeof md); - - /* state_index <= state_num <= STATE_SIZE */ - state_index += num; - if (state_index >= STATE_SIZE) - { - state_index%=STATE_SIZE; - state_num=STATE_SIZE; - } - else if (state_num < STATE_SIZE) - { - if (state_index > state_num) - state_num=state_index; - } - /* state_index <= state_num <= STATE_SIZE */ - - /* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] - * are what we will use now, but other threads may use them - * as well */ - - md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0); - - if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - - EVP_MD_CTX_init(&m); - for (i=0; i<num; i+=MD_DIGEST_LENGTH) - { - j=(num-i); - j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j; - - MD_Init(&m); - MD_Update(&m,local_md,MD_DIGEST_LENGTH); - k=(st_idx+j)-STATE_SIZE; - if (k > 0) - { - MD_Update(&m,&(state[st_idx]),j-k); - MD_Update(&m,&(state[0]),k); - } - else - MD_Update(&m,&(state[st_idx]),j); - - /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ - MD_Update(&m,buf,j); - /* We know that line may cause programs such as - purify and valgrind to complain about use of - uninitialized data. The problem is not, it's - with the caller. Removing that line will make - sure you get really bad randomness and thereby - other problems such as very insecure keys. */ - - MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); - MD_Final(&m,local_md); - md_c[1]++; - - buf=(const char *)buf + j; - - for (k=0; k<j; k++) - { - /* Parallel threads may interfere with this, - * but always each byte of the new state is - * the XOR of some previous value of its - * and local_md (itermediate values may be lost). - * Alway using locking could hurt performance more - * than necessary given that conflicts occur only - * when the total seeding is longer than the random - * state. */ - state[st_idx++]^=local_md[k]; - if (st_idx >= STATE_SIZE) - st_idx=0; - } - } - EVP_MD_CTX_cleanup(&m); - - if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); - /* Don't just copy back local_md into md -- this could mean that - * other thread's seeding remains without effect (except for - * the incremented counter). By XORing it we keep at least as - * much entropy as fits into md. */ - for (k = 0; k < (int)sizeof(md); k++) - { - md[k] ^= local_md[k]; - } - if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */ - entropy += add; - if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - -#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) - assert(md_c[1] == md_count[1]); -#endif - } - -static void ssleay_rand_seed(const void *buf, int num) - { - ssleay_rand_add(buf, num, (double)num); - } - -static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo) - { - static volatile int stirred_pool = 0; - int i,j,k,st_num,st_idx; - int num_ceil; - int ok; - long md_c[2]; - unsigned char local_md[MD_DIGEST_LENGTH]; - EVP_MD_CTX m; -#ifndef GETPID_IS_MEANINGLESS - pid_t curr_pid = getpid(); -#endif - int do_stir_pool = 0; - -#ifdef PREDICT - if (rand_predictable) - { - static unsigned char val=0; - - for (i=0; i<num; i++) - buf[i]=val++; - return(1); - } -#endif - - if (num <= 0) - return 1; - - EVP_MD_CTX_init(&m); - /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ - num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2); - - /* - * (Based on the rand(3) manpage:) - * - * For each group of 10 bytes (or less), we do the following: - * - * Input into the hash function the local 'md' (which is initialized from - * the global 'md' before any bytes are generated), the bytes that are to - * be overwritten by the random bytes, and bytes from the 'state' - * (incrementing looping index). From this digest output (which is kept - * in 'md'), the top (up to) 10 bytes are returned to the caller and the - * bottom 10 bytes are xored into the 'state'. - * - * Finally, after we have finished 'num' random bytes for the - * caller, 'count' (which is incremented) and the local and global 'md' - * are fed into the hash function and the results are kept in the - * global 'md'. - */ -#ifdef OPENSSL_FIPS - /* NB: in FIPS mode we are already under a lock */ - if (!FIPS_mode()) -#endif - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - - /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ - CRYPTO_w_lock(CRYPTO_LOCK_RAND2); - CRYPTO_THREADID_current(&locking_threadid); - CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); - crypto_lock_rand = 1; - - if (!initialized) - { - RAND_poll(); - initialized = 1; - } - - if (!stirred_pool) - do_stir_pool = 1; - - ok = (entropy >= ENTROPY_NEEDED); - if (!ok) - { - /* If the PRNG state is not yet unpredictable, then seeing - * the PRNG output may help attackers to determine the new - * state; thus we have to decrease the entropy estimate. - * Once we've had enough initial seeding we don't bother to - * adjust the entropy count, though, because we're not ambitious - * to provide *information-theoretic* randomness. - * - * NOTE: This approach fails if the program forks before - * we have enough entropy. Entropy should be collected - * in a separate input pool and be transferred to the - * output pool only when the entropy limit has been reached. - */ - entropy -= num; - if (entropy < 0) - entropy = 0; - } - - if (do_stir_pool) - { - /* In the output function only half of 'md' remains secret, - * so we better make sure that the required entropy gets - * 'evenly distributed' through 'state', our randomness pool. - * The input function (ssleay_rand_add) chains all of 'md', - * which makes it more suitable for this purpose. - */ - - int n = STATE_SIZE; /* so that the complete pool gets accessed */ - while (n > 0) - { -#if MD_DIGEST_LENGTH > 20 -# error "Please adjust DUMMY_SEED." -#endif -#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */ - /* Note that the seed does not matter, it's just that - * ssleay_rand_add expects to have something to hash. */ - ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0); - n -= MD_DIGEST_LENGTH; - } - if (ok) - stirred_pool = 1; - } - - st_idx=state_index; - st_num=state_num; - md_c[0] = md_count[0]; - md_c[1] = md_count[1]; - memcpy(local_md, md, sizeof md); - - state_index+=num_ceil; - if (state_index > state_num) - state_index %= state_num; - - /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] - * are now ours (but other threads may use them too) */ - - md_count[0] += 1; - - /* before unlocking, we must clear 'crypto_lock_rand' */ - crypto_lock_rand = 0; -#ifdef OPENSSL_FIPS - if (!FIPS_mode()) -#endif - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - - while (num > 0) - { - /* num_ceil -= MD_DIGEST_LENGTH/2 */ - j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num; - num-=j; - MD_Init(&m); -#ifndef GETPID_IS_MEANINGLESS - if (curr_pid) /* just in the first iteration to save time */ - { - MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid); - curr_pid = 0; - } -#endif - MD_Update(&m,local_md,MD_DIGEST_LENGTH); - MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); - -#ifndef PURIFY /* purify complains */ - /* The following line uses the supplied buffer as a small - * source of entropy: since this buffer is often uninitialised - * it may cause programs such as purify or valgrind to - * complain. So for those builds it is not used: the removal - * of such a small source of entropy has negligible impact on - * security. - */ - MD_Update(&m,buf,j); -#endif - - k=(st_idx+MD_DIGEST_LENGTH/2)-st_num; - if (k > 0) - { - MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k); - MD_Update(&m,&(state[0]),k); - } - else - MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); - MD_Final(&m,local_md); - - for (i=0; i<MD_DIGEST_LENGTH/2; i++) - { - state[st_idx++]^=local_md[i]; /* may compete with other threads */ - if (st_idx >= st_num) - st_idx=0; - if (i < j) - *(buf++)=local_md[i+MD_DIGEST_LENGTH/2]; - } - } - - MD_Init(&m); - MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); - MD_Update(&m,local_md,MD_DIGEST_LENGTH); -#ifdef OPENSSL_FIPS - if (!FIPS_mode()) -#endif - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - MD_Update(&m,md,MD_DIGEST_LENGTH); - MD_Final(&m,md); -#ifdef OPENSSL_FIPS - if (!FIPS_mode()) -#endif - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - - EVP_MD_CTX_cleanup(&m); - if (ok) - return(1); - else if (pseudo) - return 0; - else - { - RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED); - ERR_add_error_data(1, "You need to read the OpenSSL FAQ, " - "http://www.openssl.org/support/faq.html"); - return(0); - } - } - -static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num) - { - return ssleay_rand_bytes(buf, num, 0); - } - -/* pseudo-random bytes that are guaranteed to be unique but not - unpredictable */ -static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) - { - return ssleay_rand_bytes(buf, num, 1); - } - -static int ssleay_rand_status(void) - { - CRYPTO_THREADID cur; - int ret; - int do_not_lock; - - CRYPTO_THREADID_current(&cur); - /* check if we already have the lock - * (could happen if a RAND_poll() implementation calls RAND_status()) */ - if (crypto_lock_rand) - { - CRYPTO_r_lock(CRYPTO_LOCK_RAND2); - do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); - CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); - } - else - do_not_lock = 0; - - if (!do_not_lock) - { - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - - /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ - CRYPTO_w_lock(CRYPTO_LOCK_RAND2); - CRYPTO_THREADID_cpy(&locking_threadid, &cur); - CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); - crypto_lock_rand = 1; - } - - if (!initialized) - { - RAND_poll(); - initialized = 1; - } - - ret = entropy >= ENTROPY_NEEDED; - - if (!do_not_lock) - { - /* before unlocking, we must clear 'crypto_lock_rand' */ - crypto_lock_rand = 0; - - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - } - - return ret; - } diff --git a/lib/libssl/src/crypto/rand/rand.h b/lib/libssl/src/crypto/rand/rand.h index bb5520e80ac..e65b4b2e35c 100644 --- a/lib/libssl/src/crypto/rand/rand.h +++ b/lib/libssl/src/crypto/rand/rand.h @@ -63,18 +63,10 @@ #include <openssl/ossl_typ.h> #include <openssl/e_os2.h> -#if defined(OPENSSL_SYS_WINDOWS) -#include <windows.h> -#endif - #ifdef __cplusplus extern "C" { #endif -#if defined(OPENSSL_FIPS) -#define FIPS_RAND_SIZE_T size_t -#endif - /* Already defined in ossl_typ.h */ /* typedef struct rand_meth_st RAND_METHOD; */ @@ -88,10 +80,6 @@ struct rand_meth_st int (*status)(void); }; -#ifdef BN_DEBUG -extern int rand_predictable; -#endif - int RAND_set_rand_method(const RAND_METHOD *meth); const RAND_METHOD *RAND_get_rand_method(void); #ifndef OPENSSL_NO_ENGINE @@ -112,25 +100,13 @@ int RAND_egd(const char *path); int RAND_egd_bytes(const char *path,int bytes); int RAND_poll(void); -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) - -void RAND_screen(void); -int RAND_event(UINT, WPARAM, LPARAM); - -#endif - -#ifdef OPENSSL_FIPS -void RAND_set_fips_drbg_type(int type, int flags); -int RAND_init_fips(void); -#endif - /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. */ void ERR_load_RAND_strings(void); -/* Error codes for the RAND functions. */ +/* Error codes for the RAND functions. (no longer used) */ /* Function codes. */ #define RAND_F_RAND_GET_RAND_METHOD 101 diff --git a/lib/libssl/src/crypto/rand/rand_egd.c b/lib/libssl/src/crypto/rand/rand_egd.c index d53b916ebee..a78aa90c469 100644 --- a/lib/libssl/src/crypto/rand/rand_egd.c +++ b/lib/libssl/src/crypto/rand/rand_egd.c @@ -95,7 +95,6 @@ * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. */ -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS) int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) { return(-1); @@ -109,195 +108,3 @@ int RAND_egd_bytes(const char *path,int bytes) { return(-1); } -#else -#include <openssl/opensslconf.h> -#include OPENSSL_UNISTD -#include <sys/types.h> -#include <sys/socket.h> -#ifndef NO_SYS_UN_H -# ifdef OPENSSL_SYS_VXWORKS -# include <streams/un.h> -# else -# include <sys/un.h> -# endif -#else -struct sockaddr_un { - short sun_family; /* AF_UNIX */ - char sun_path[108]; /* path name (gag) */ -}; -#endif /* NO_SYS_UN_H */ -#include <string.h> -#include <errno.h> - -#ifndef offsetof -# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - -int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) - { - int ret = 0; - struct sockaddr_un addr; - int len, num, numbytes; - int fd = -1; - int success; - unsigned char egdbuf[2], tempbuf[255], *retrievebuf; - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - if (strlen(path) >= sizeof(addr.sun_path)) - return (-1); - BUF_strlcpy(addr.sun_path,path,sizeof addr.sun_path); - len = offsetof(struct sockaddr_un, sun_path) + strlen(path); - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) return (-1); - success = 0; - while (!success) - { - if (connect(fd, (struct sockaddr *)&addr, len) == 0) - success = 1; - else - { - switch (errno) - { -#ifdef EINTR - case EINTR: -#endif -#ifdef EAGAIN - case EAGAIN: -#endif -#ifdef EINPROGRESS - case EINPROGRESS: -#endif -#ifdef EALREADY - case EALREADY: -#endif - /* No error, try again */ - break; -#ifdef EISCONN - case EISCONN: - success = 1; - break; -#endif - default: - goto err; /* failure */ - } - } - } - - while(bytes > 0) - { - egdbuf[0] = 1; - egdbuf[1] = bytes < 255 ? bytes : 255; - numbytes = 0; - while (numbytes != 2) - { - num = write(fd, egdbuf + numbytes, 2 - numbytes); - if (num >= 0) - numbytes += num; - else - { - switch (errno) - { -#ifdef EINTR - case EINTR: -#endif -#ifdef EAGAIN - case EAGAIN: -#endif - /* No error, try again */ - break; - default: - ret = -1; - goto err; /* failure */ - } - } - } - numbytes = 0; - while (numbytes != 1) - { - num = read(fd, egdbuf, 1); - if (num == 0) - goto err; /* descriptor closed */ - else if (num > 0) - numbytes += num; - else - { - switch (errno) - { -#ifdef EINTR - case EINTR: -#endif -#ifdef EAGAIN - case EAGAIN: -#endif - /* No error, try again */ - break; - default: - ret = -1; - goto err; /* failure */ - } - } - } - if(egdbuf[0] == 0) - goto err; - if (buf) - retrievebuf = buf + ret; - else - retrievebuf = tempbuf; - numbytes = 0; - while (numbytes != egdbuf[0]) - { - num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes); - if (num == 0) - goto err; /* descriptor closed */ - else if (num > 0) - numbytes += num; - else - { - switch (errno) - { -#ifdef EINTR - case EINTR: -#endif -#ifdef EAGAIN - case EAGAIN: -#endif - /* No error, try again */ - break; - default: - ret = -1; - goto err; /* failure */ - } - } - } - ret += egdbuf[0]; - bytes -= egdbuf[0]; - if (!buf) - RAND_seed(tempbuf, egdbuf[0]); - } - err: - if (fd != -1) close(fd); - return(ret); - } - - -int RAND_egd_bytes(const char *path, int bytes) - { - int num, ret = 0; - - num = RAND_query_egd_bytes(path, NULL, bytes); - if (num < 1) goto err; - if (RAND_status() == 1) - ret = num; - err: - return(ret); - } - - -int RAND_egd(const char *path) - { - return (RAND_egd_bytes(path, 255)); - } - - -#endif diff --git a/lib/libssl/src/crypto/rand/rand_lcl.h b/lib/libssl/src/crypto/rand/rand_lcl.h deleted file mode 100644 index 618a8ec899c..00000000000 --- a/lib/libssl/src/crypto/rand/rand_lcl.h +++ /dev/null @@ -1,158 +0,0 @@ -/* crypto/rand/rand_lcl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_RAND_LCL_H -#define HEADER_RAND_LCL_H - -#define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */ - - -#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) -#define USE_SHA1_RAND -#elif !defined(OPENSSL_NO_MD5) -#define USE_MD5_RAND -#elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES) -#define USE_MDC2_RAND -#elif !defined(OPENSSL_NO_MD2) -#define USE_MD2_RAND -#else -#error No message digest algorithm available -#endif -#endif - -#include <openssl/evp.h> -#define MD_Update(a,b,c) EVP_DigestUpdate(a,b,c) -#define MD_Final(a,b) EVP_DigestFinal_ex(a,b,NULL) -#if defined(USE_MD5_RAND) -#include <openssl/md5.h> -#define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH -#define MD_Init(a) EVP_DigestInit_ex(a,EVP_md5(), NULL) -#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md5(), NULL) -#elif defined(USE_SHA1_RAND) -#include <openssl/sha.h> -#define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH -#define MD_Init(a) EVP_DigestInit_ex(a,EVP_sha1(), NULL) -#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL) -#elif defined(USE_MDC2_RAND) -#include <openssl/mdc2.h> -#define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH -#define MD_Init(a) EVP_DigestInit_ex(a,EVP_mdc2(), NULL) -#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL) -#elif defined(USE_MD2_RAND) -#include <openssl/md2.h> -#define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH -#define MD_Init(a) EVP_DigestInit_ex(a,EVP_md2(), NULL) -#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL) -#endif - - -#endif diff --git a/lib/libssl/src/crypto/rand/rand_lib.c b/lib/libssl/src/crypto/rand/rand_lib.c index 5ac0e14caf0..243a87ddfbd 100644 --- a/lib/libssl/src/crypto/rand/rand_lib.c +++ b/lib/libssl/src/crypto/rand/rand_lib.c @@ -65,11 +65,6 @@ #include <openssl/engine.h> #endif -#ifdef OPENSSL_FIPS -#include <openssl/fips.h> -#include <openssl/fips_rand.h> -#endif - #ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ static ENGINE *funct_ref =NULL; @@ -180,127 +175,3 @@ int RAND_status(void) return meth->status(); return 0; } - -#ifdef OPENSSL_FIPS - -/* FIPS DRBG initialisation code. This sets up the DRBG for use by the - * rest of OpenSSL. - */ - -/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather - * entropy internally through RAND_poll(). - */ - -static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout, - int entropy, size_t min_len, size_t max_len) - { - /* Round up request to multiple of block size */ - min_len = ((min_len + 19) / 20) * 20; - *pout = OPENSSL_malloc(min_len); - if (!*pout) - return 0; - if (RAND_SSLeay()->bytes(*pout, min_len) <= 0) - { - OPENSSL_free(*pout); - *pout = NULL; - return 0; - } - return min_len; - } - -static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen) - { - if (out) - { - OPENSSL_cleanse(out, olen); - OPENSSL_free(out); - } - } - -/* Set "additional input" when generating random data. This uses the - * current PID, a time value and a counter. - */ - -static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout) - { - /* Use of static variables is OK as this happens under a lock */ - static unsigned char buf[16]; - static unsigned long counter; - FIPS_get_timevec(buf, &counter); - *pout = buf; - return sizeof(buf); - } - -/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is - * correctly seeded by RAND_poll(). - */ - -static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen, - double entropy) - { - RAND_SSLeay()->add(in, inlen, entropy); - return 1; - } - -static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen) - { - RAND_SSLeay()->seed(in, inlen); - return 1; - } - -#ifndef OPENSSL_DRBG_DEFAULT_TYPE -#define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr -#endif -#ifndef OPENSSL_DRBG_DEFAULT_FLAGS -#define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF -#endif - -static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE; -static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS; - -void RAND_set_fips_drbg_type(int type, int flags) - { - fips_drbg_type = type; - fips_drbg_flags = flags; - } - -int RAND_init_fips(void) - { - DRBG_CTX *dctx; - size_t plen; - unsigned char pers[32], *p; -#ifndef OPENSSL_ALLOW_DUAL_EC_DRBG - if (fips_drbg_type >> 16) - { - RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED); - return 0; - } -#endif - - dctx = FIPS_get_default_drbg(); - if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0) - { - RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG); - return 0; - } - - FIPS_drbg_set_callbacks(dctx, - drbg_get_entropy, drbg_free_entropy, 20, - drbg_get_entropy, drbg_free_entropy); - FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0, - drbg_rand_seed, drbg_rand_add); - /* Personalisation string: a string followed by date time vector */ - strcpy((char *)pers, "OpenSSL DRBG2.0"); - plen = drbg_get_adin(dctx, &p); - memcpy(pers + 16, p, plen); - - if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0) - { - RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG); - return 0; - } - FIPS_rand_set_method(FIPS_drbg_method()); - return 1; - } - -#endif diff --git a/lib/libssl/src/crypto/rand/rand_unix.c b/lib/libssl/src/crypto/rand/rand_unix.c index 3316388443e..a5b9b2a5299 100644 --- a/lib/libssl/src/crypto/rand/rand_unix.c +++ b/lib/libssl/src/crypto/rand/rand_unix.c @@ -108,318 +108,14 @@ * Hudson (tjh@cryptsoft.com). * */ -#include <stdio.h> - -#define USE_SOCKETS #include "e_os.h" #include "cryptlib.h" #include <openssl/rand.h> -#include "rand_lcl.h" - -#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/times.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <time.h> -#if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywhere */ -# include <poll.h> -#endif -#include <limits.h> -#ifndef FD_SETSIZE -# define FD_SETSIZE (8*sizeof(fd_set)) -#endif - -#if defined(OPENSSL_SYS_VOS) - -/* The following algorithm repeatedly samples the real-time clock - (RTC) to generate a sequence of unpredictable data. The algorithm - relies upon the uneven execution speed of the code (due to factors - such as cache misses, interrupts, bus activity, and scheduling) and - upon the rather large relative difference between the speed of the - clock and the rate at which it can be read. - - If this code is ported to an environment where execution speed is - more constant or where the RTC ticks at a much slower rate, or the - clock can be read with fewer instructions, it is likely that the - results would be far more predictable. - - As a precaution, we generate 4 times the minimum required amount of - seed data. */ - -int RAND_poll(void) -{ - short int code; - gid_t curr_gid; - pid_t curr_pid; - uid_t curr_uid; - int i, k; - struct timespec ts; - unsigned char v; - -#ifdef OPENSSL_SYS_VOS_HPPA - long duration; - extern void s$sleep (long *_duration, short int *_code); -#else -#ifdef OPENSSL_SYS_VOS_IA32 - long long duration; - extern void s$sleep2 (long long *_duration, short int *_code); -#else -#error "Unsupported Platform." -#endif /* OPENSSL_SYS_VOS_IA32 */ -#endif /* OPENSSL_SYS_VOS_HPPA */ - - /* Seed with the gid, pid, and uid, to ensure *some* - variation between different processes. */ - curr_gid = getgid(); - RAND_add (&curr_gid, sizeof curr_gid, 1); - curr_gid = 0; +#include <stdlib.h> +#include <string.h> - curr_pid = getpid(); - RAND_add (&curr_pid, sizeof curr_pid, 1); - curr_pid = 0; - - curr_uid = getuid(); - RAND_add (&curr_uid, sizeof curr_uid, 1); - curr_uid = 0; - - for (i=0; i<(ENTROPY_NEEDED*4); i++) - { - /* burn some cpu; hope for interrupts, cache - collisions, bus interference, etc. */ - for (k=0; k<99; k++) - ts.tv_nsec = random (); - -#ifdef OPENSSL_SYS_VOS_HPPA - /* sleep for 1/1024 of a second (976 us). */ - duration = 1; - s$sleep (&duration, &code); -#else -#ifdef OPENSSL_SYS_VOS_IA32 - /* sleep for 1/65536 of a second (15 us). */ - duration = 1; - s$sleep2 (&duration, &code); -#endif /* OPENSSL_SYS_VOS_IA32 */ -#endif /* OPENSSL_SYS_VOS_HPPA */ - - /* get wall clock time. */ - clock_gettime (CLOCK_REALTIME, &ts); - - /* take 8 bits */ - v = (unsigned char) (ts.tv_nsec % 256); - RAND_add (&v, sizeof v, 1); - v = 0; - } - return 1; -} -#elif defined __OpenBSD__ int RAND_poll(void) { - unsigned char buf[ENTROPY_NEEDED]; - - arc4random_buf(buf, sizeof(buf)); - RAND_add(buf, sizeof(buf), sizeof(buf)); - memset(buf, 0, sizeof(buf)); - return 1; } -#else /* !defined(__OpenBSD__) */ -int RAND_poll(void) -{ - unsigned long l; - pid_t curr_pid = getpid(); -#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) - unsigned char tmpbuf[ENTROPY_NEEDED]; - int n = 0; -#endif -#ifdef DEVRANDOM - static const char *randomfiles[] = { DEVRANDOM }; - struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])]; - int fd; - unsigned int i; -#endif -#ifdef DEVRANDOM_EGD - static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; - const char **egdsocket = NULL; -#endif - -#ifdef DEVRANDOM - memset(randomstats,0,sizeof(randomstats)); - /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD - * have this. Use /dev/urandom if you can as /dev/random may block - * if it runs out of random entries. */ - - for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) && - (n < ENTROPY_NEEDED); i++) - { - if ((fd = open(randomfiles[i], O_RDONLY -#ifdef O_NONBLOCK - |O_NONBLOCK -#endif -#ifdef O_BINARY - |O_BINARY -#endif -#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it - our controlling tty */ - |O_NOCTTY -#endif - )) >= 0) - { - int usec = 10*1000; /* spend 10ms on each file */ - int r; - unsigned int j; - struct stat *st=&randomstats[i]; - - /* Avoid using same input... Used to be O_NOFOLLOW - * above, but it's not universally appropriate... */ - if (fstat(fd,st) != 0) { close(fd); continue; } - for (j=0;j<i;j++) - { - if (randomstats[j].st_ino==st->st_ino && - randomstats[j].st_dev==st->st_dev) - break; - } - if (j<i) { close(fd); continue; } - - do - { - int try_read = 0; - -#if defined(OPENSSL_SYS_BEOS_R5) - /* select() is broken in BeOS R5, so we simply - * try to read something and snooze if we couldn't */ - try_read = 1; - -#elif defined(OPENSSL_SYS_LINUX) - /* use poll() */ - struct pollfd pset; - - pset.fd = fd; - pset.events = POLLIN; - pset.revents = 0; - - if (poll(&pset, 1, usec / 1000) < 0) - usec = 0; - else - try_read = (pset.revents & POLLIN) != 0; - -#else - /* use select() */ - fd_set fset; - struct timeval t; - - t.tv_sec = 0; - t.tv_usec = usec; - - if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) - { - /* can't use select, so just try to read once anyway */ - try_read = 1; - } - else - { - FD_ZERO(&fset); - FD_SET(fd, &fset); - - if (select(fd+1,&fset,NULL,NULL,&t) >= 0) - { - usec = t.tv_usec; - if (FD_ISSET(fd, &fset)) - try_read = 1; - } - else - usec = 0; - } -#endif - - if (try_read) - { - r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n); - if (r > 0) - n += r; -#if defined(OPENSSL_SYS_BEOS_R5) - if (r == 0) - snooze(t.tv_usec); -#endif - } - else - r = -1; - - /* Some Unixen will update t in select(), some - won't. For those who won't, or if we - didn't use select() in the first place, - give up here, otherwise, we will do - this once again for the remaining - time. */ - if (usec == 10*1000) - usec = 0; - } - while ((r > 0 || - (errno == EINTR || errno == EAGAIN)) && usec != 0 && n < ENTROPY_NEEDED); - - close(fd); - } - } -#endif /* defined(DEVRANDOM) */ - -#ifdef DEVRANDOM_EGD - /* Use an EGD socket to read entropy from an EGD or PRNGD entropy - * collecting daemon. */ - - for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++) - { - int r; - - r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n, - ENTROPY_NEEDED-n); - if (r > 0) - n += r; - } -#endif /* defined(DEVRANDOM_EGD) */ - -#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) - if (n > 0) - { - RAND_add(tmpbuf,sizeof tmpbuf,(double)n); - OPENSSL_cleanse(tmpbuf,n); - } -#endif - - /* put in some default random data, we need more than just this */ - l=curr_pid; - RAND_add(&l,sizeof(l),0.0); - l=getuid(); - RAND_add(&l,sizeof(l),0.0); - - l=time(NULL); - RAND_add(&l,sizeof(l),0.0); - -#if defined(OPENSSL_SYS_BEOS) - { - system_info sysInfo; - get_system_info(&sysInfo); - RAND_add(&sysInfo,sizeof(sysInfo),0); - } -#endif - -#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) - return 1; -#else - return 0; -#endif -} - -#endif /* defined(__OpenBSD__) */ -#endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) */ - - -#if defined(OPENSSL_SYS_VXWORKS) -int RAND_poll(void) - { - return 0; - } -#endif diff --git a/lib/libssl/src/crypto/rand/randfile.c b/lib/libssl/src/crypto/rand/randfile.c index 10d511b8e86..2cacebcf07a 100644 --- a/lib/libssl/src/crypto/rand/randfile.c +++ b/lib/libssl/src/crypto/rand/randfile.c @@ -56,11 +56,6 @@ * [including the GNU Public Licence.] */ -/* We need to define this to get macros like S_IFBLK and S_IFCHR */ -#if !defined(OPENSSL_SYS_VXWORKS) -#define _XOPEN_SOURCE 500 -#endif - #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -71,35 +66,14 @@ #include <openssl/rand.h> #include <openssl/buffer.h> -#ifdef OPENSSL_SYS_VMS -#include <unixio.h> -#endif -#ifndef NO_SYS_TYPES_H -# include <sys/types.h> -#endif -#ifndef OPENSSL_NO_POSIX_IO -# include <sys/stat.h> -#endif - -#ifdef _WIN32 -#define stat _stat -#define chmod _chmod -#define open _open -#define fdopen _fdopen -#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #undef BUFSIZE #define BUFSIZE 1024 #define RAND_DATA 1024 -#ifdef OPENSSL_SYS_VMS -/* This declaration is a nasty hack to get around vms' extension to fopen - * for passing in sharing options being disabled by our /STANDARD=ANSI89 */ -static FILE *(*const vms_fopen)(const char *, const char *, ...) = - (FILE *(*)(const char *, const char *, ...))fopen; -#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0" -#endif - /* #define RFILE ".rnd" - defined in ../../e_os.h */ /* Note that these functions are intended for seed files only. @@ -107,75 +81,7 @@ static FILE *(*const vms_fopen)(const char *, const char *, ...) = int RAND_load_file(const char *file, long bytes) { - /* If bytes >= 0, read up to 'bytes' bytes. - * if bytes == -1, read complete file. */ - - unsigned char buf[BUFSIZE]; -#ifndef OPENSSL_NO_POSIX_IO - struct stat sb; -#endif - int i,ret=0,n; - FILE *in; - - if (file == NULL) return(0); - -#ifndef OPENSSL_NO_POSIX_IO -#ifdef PURIFY - /* struct stat can have padding and unused fields that may not be - * initialized in the call to stat(). We need to clear the entire - * structure before calling RAND_add() to avoid complaints from - * applications such as Valgrind. - */ - memset(&sb, 0, sizeof(sb)); -#endif - if (stat(file,&sb) < 0) return(0); - RAND_add(&sb,sizeof(sb),0.0); -#endif - if (bytes == 0) return(ret); - -#ifdef OPENSSL_SYS_VMS - in=vms_fopen(file,"rb",VMS_OPEN_ATTRS); -#else - in=fopen(file,"rb"); -#endif - if (in == NULL) goto err; -#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO) - if (sb.st_mode & (S_IFBLK | S_IFCHR)) { - /* this file is a device. we don't want read an infinite number - * of bytes from a random device, nor do we want to use buffered - * I/O because we will waste system entropy. - */ - bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */ -#ifndef OPENSSL_NO_SETVBUF_IONBF - setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */ -#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ - } -#endif - for (;;) - { - if (bytes > 0) - n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE; - else - n = BUFSIZE; - i=fread(buf,1,n,in); - if (i <= 0) break; -#ifdef PURIFY - RAND_add(buf,i,(double)i); -#else - /* even if n != i, use the full array */ - RAND_add(buf,n,(double)i); -#endif - ret+=i; - if (bytes > 0) - { - bytes-=n; - if (bytes <= 0) break; - } - } - fclose(in); - OPENSSL_cleanse(buf,BUFSIZE); -err: - return(ret); + return(0); } int RAND_write_file(const char *file) @@ -184,12 +90,10 @@ int RAND_write_file(const char *file) int i,ret=0,rand_err=0; FILE *out = NULL; int n; -#ifndef OPENSSL_NO_POSIX_IO struct stat sb; i=stat(file,&sb); if (i != -1) { -#if defined(S_ISBLK) && defined(S_ISCHR) if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { /* this file is a device. we don't write back to it. * we "succeed" on the assumption this is some sort @@ -198,55 +102,21 @@ int RAND_write_file(const char *file) */ return(1); } -#endif } -#endif -#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS) { -#ifndef O_BINARY -#define O_BINARY 0 -#endif /* chmod(..., 0600) is too late to protect the file, * permissions should be restrictive from the start */ - int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600); + int fd = open(file, O_WRONLY|O_CREAT, 0600); if (fd != -1) out = fdopen(fd, "wb"); } -#endif - -#ifdef OPENSSL_SYS_VMS - /* VMS NOTE: Prior versions of this routine created a _new_ - * version of the rand file for each call into this routine, then - * deleted all existing versions named ;-1, and finally renamed - * the current version as ';1'. Under concurrent usage, this - * resulted in an RMS race condition in rename() which could - * orphan files (see vms message help for RMS$_REENT). With the - * fopen() calls below, openssl/VMS now shares the top-level - * version of the rand file. Note that there may still be - * conditions where the top-level rand file is locked. If so, this - * code will then create a new version of the rand file. Without - * the delete and rename code, this can result in ascending file - * versions that stop at version 32767, and this routine will then - * return an error. The remedy for this is to recode the calling - * application to avoid concurrent use of the rand file, or - * synchronize usage at the application level. Also consider - * whether or not you NEED a persistent rand file in a concurrent - * use situation. - */ - out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS); - if (out == NULL) - out = vms_fopen(file,"wb",VMS_OPEN_ATTRS); -#else if (out == NULL) out = fopen(file,"wb"); -#endif if (out == NULL) goto err; -#ifndef NO_CHMOD chmod(file,0600); -#endif n=RAND_DATA; for (;;) { @@ -273,9 +143,7 @@ err: const char *RAND_file_name(char *buf, size_t size) { char *s=NULL; -#ifdef __OpenBSD__ struct stat sb; -#endif if (OPENSSL_issetugid() == 0) s=getenv("RANDFILE"); @@ -288,25 +156,16 @@ const char *RAND_file_name(char *buf, size_t size) { if (OPENSSL_issetugid() == 0) s=getenv("HOME"); -#ifdef DEFAULT_HOME - if (s == NULL) - { - s = DEFAULT_HOME; - } -#endif if (s && *s && strlen(s)+strlen(RFILE)+2 < size) { BUF_strlcpy(buf,s,size); -#ifndef OPENSSL_SYS_VMS BUF_strlcat(buf,"/",size); -#endif BUF_strlcat(buf,RFILE,size); } else buf[0] = '\0'; /* no file name */ } -#ifdef __OpenBSD__ /* given that all random loads just fail if the file can't be * seen on a stat, we stat the file we're returning, if it * fails, use /dev/arandom instead. this allows the user to @@ -323,6 +182,5 @@ const char *RAND_file_name(char *buf, size_t size) return(NULL); } -#endif return(buf); } diff --git a/lib/libssl/src/crypto/rand/rc4_rand.c b/lib/libssl/src/crypto/rand/rc4_rand.c new file mode 100644 index 00000000000..ebfb241d538 --- /dev/null +++ b/lib/libssl/src/crypto/rand/rc4_rand.c @@ -0,0 +1,44 @@ +/* $OpenBSD: rc4_rand.c,v 1.1 2014/04/15 16:52:50 miod Exp $ */ + +/* + * Copyright (c) 2014 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> + +#include <openssl/rand.h> + +static int +arc4_rand_bytes(unsigned char *buf, int num) +{ + if (num > 0) + arc4random_buf(buf, (size_t)num); + + return 1; +} + +static RAND_METHOD rand_arc4_meth = { + .seed = NULL, /* no external seed allowed */ + .bytes = arc4_rand_bytes, + .cleanup = NULL, /* no cleanup necessary */ + .add = NULL, /* no external feed allowed */ + .pseudorand = arc4_rand_bytes, + .status = NULL /* no possible error condition */ +}; + +RAND_METHOD *RAND_SSLeay(void) +{ + return &rand_arc4_meth; +} diff --git a/lib/libssl/src/doc/crypto/RAND_add.pod b/lib/libssl/src/doc/crypto/RAND_add.pod index 67c66f3e0c9..d55dc125d39 100644 --- a/lib/libssl/src/doc/crypto/RAND_add.pod +++ b/lib/libssl/src/doc/crypto/RAND_add.pod @@ -2,8 +2,7 @@ =head1 NAME -RAND_add, RAND_seed, RAND_status, RAND_event, RAND_screen - add -entropy to the PRNG +RAND_add, RAND_seed, RAND_status - add entropy to the PRNG (DEPRECATED) =head1 SYNOPSIS @@ -15,63 +14,17 @@ entropy to the PRNG int RAND_status(void); - int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam); - void RAND_screen(void); - =head1 DESCRIPTION -RAND_add() mixes the B<num> bytes at B<buf> into the PRNG state. Thus, -if the data at B<buf> are unpredictable to an adversary, this -increases the uncertainty about the state and makes the PRNG output -less predictable. Suitable input comes from user interaction (random -key presses, mouse movements) and certain hardware events. The -B<entropy> argument is (the lower bound of) an estimate of how much -randomness is contained in B<buf>, measured in bytes. Details about -sources of randomness and how to estimate their entropy can be found -in the literature, e.g. RFC 1750. - -RAND_add() may be called with sensitive data such as user entered -passwords. The seed values cannot be recovered from the PRNG output. - -OpenSSL makes sure that the PRNG state is unique for each thread. On -systems that provide C</dev/urandom>, the randomness device is used -to seed the PRNG transparently. However, on all other systems, the -application is responsible for seeding the PRNG by calling RAND_add(), -L<RAND_egd(3)|RAND_egd(3)> -or L<RAND_load_file(3)|RAND_load_file(3)>. - -RAND_seed() is equivalent to RAND_add() when B<num == entropy>. - -RAND_event() collects the entropy from Windows events such as mouse -movements and other user interaction. It should be called with the -B<iMsg>, B<wParam> and B<lParam> arguments of I<all> messages sent to -the window procedure. It will estimate the entropy contained in the -event message (if any), and add it to the PRNG. The program can then -process the messages as usual. +These functions used to allow for the state of the random number generator +to be controlled by external sources. -The RAND_screen() function is available for the convenience of Windows -programmers. It adds the current contents of the screen to the PRNG. -For applications that can catch Windows events, seeding the PRNG by -calling RAND_event() is a significantly better source of -randomness. It should be noted that both methods cannot be used on -servers that run without user interaction. - -=head1 RETURN VALUES - -RAND_status() and RAND_event() return 1 if the PRNG has been seeded -with enough data, 0 otherwise. - -The other functions do not return values. +They are kept for ABI compatibility but are no longer functional, and +should not used in new programs. =head1 SEE ALSO L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>, L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> -=head1 HISTORY - -RAND_seed() and RAND_screen() are available in all versions of SSLeay -and OpenSSL. RAND_add() and RAND_status() have been added in OpenSSL -0.9.5, RAND_event() in OpenSSL 0.9.5a. - =cut diff --git a/lib/libssl/src/doc/crypto/RAND_egd.pod b/lib/libssl/src/doc/crypto/RAND_egd.pod index 8b8c61d161b..771f525df8d 100644 --- a/lib/libssl/src/doc/crypto/RAND_egd.pod +++ b/lib/libssl/src/doc/crypto/RAND_egd.pod @@ -2,7 +2,7 @@ =head1 NAME -RAND_egd - query entropy gathering daemon +RAND_egd - query entropy gathering daemon (DEPRECATED) =head1 SYNOPSIS @@ -15,74 +15,15 @@ RAND_egd - query entropy gathering daemon =head1 DESCRIPTION -RAND_egd() queries the entropy gathering daemon EGD on socket B<path>. -It queries 255 bytes and uses L<RAND_add(3)|RAND_add(3)> to seed the -OpenSSL built-in PRNG. RAND_egd(path) is a wrapper for -RAND_egd_bytes(path, 255); +These functions used to allow for the state of the random number generator +to be controlled by external sources. -RAND_egd_bytes() queries the entropy gathering daemon EGD on socket B<path>. -It queries B<bytes> bytes and uses L<RAND_add(3)|RAND_add(3)> to seed the -OpenSSL built-in PRNG. -This function is more flexible than RAND_egd(). -When only one secret key must -be generated, it is not necessary to request the full amount 255 bytes from -the EGD socket. This can be advantageous, since the amount of entropy -that can be retrieved from EGD over time is limited. - -RAND_query_egd_bytes() performs the actual query of the EGD daemon on socket -B<path>. If B<buf> is given, B<bytes> bytes are queried and written into -B<buf>. If B<buf> is NULL, B<bytes> bytes are queried and used to seed the -OpenSSL built-in PRNG using L<RAND_add(3)|RAND_add(3)>. - -=head1 NOTES - -On systems without /dev/*random devices providing entropy from the kernel, -the EGD entropy gathering daemon can be used to collect entropy. It provides -a socket interface through which entropy can be gathered in chunks up to -255 bytes. Several chunks can be queried during one connection. - -EGD is available from http://www.lothar.com/tech/crypto/ (C<perl -Makefile.PL; make; make install> to install). It is run as B<egd> -I<path>, where I<path> is an absolute path designating a socket. When -RAND_egd() is called with that path as an argument, it tries to read -random bytes that EGD has collected. RAND_egd() retrieves entropy from the -daemon using the daemon's "non-blocking read" command which shall -be answered immediately by the daemon without waiting for additional -entropy to be collected. The write and read socket operations in the -communication are blocking. - -Alternatively, the EGD-interface compatible daemon PRNGD can be used. It is -available from -http://prngd.sourceforge.net/ . -PRNGD does employ an internal PRNG itself and can therefore never run -out of entropy. - -OpenSSL automatically queries EGD when entropy is requested via RAND_bytes() -or the status is checked via RAND_status() for the first time, if the socket -is located at /var/run/egd-pool, /dev/egd-pool or /etc/egd-pool. - -=head1 RETURN VALUE - -RAND_egd() and RAND_egd_bytes() return the number of bytes read from the -daemon on success, and -1 if the connection failed or the daemon did not -return enough data to fully seed the PRNG. - -RAND_query_egd_bytes() returns the number of bytes read from the daemon on -success, and -1 if the connection failed. The PRNG state is not considered. +They are kept for ABI compatibility but are no longer functional, and +should not used in new programs. =head1 SEE ALSO L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> -=head1 HISTORY - -RAND_egd() is available since OpenSSL 0.9.5. - -RAND_egd_bytes() is available since OpenSSL 0.9.6. - -RAND_query_egd_bytes() is available since OpenSSL 0.9.7. - -The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7. - =cut diff --git a/lib/libssl/src/doc/crypto/RAND_load_file.pod b/lib/libssl/src/doc/crypto/RAND_load_file.pod index d8c134e621d..3f7e944d86b 100644 --- a/lib/libssl/src/doc/crypto/RAND_load_file.pod +++ b/lib/libssl/src/doc/crypto/RAND_load_file.pod @@ -22,18 +22,18 @@ filename. The seed file is $RANDFILE if that environment variable is set, $HOME/.rnd otherwise. If $HOME is not set either, or B<num> is too small for the path name, an error occurs. -RAND_load_file() reads a number of bytes from file B<filename> and -adds them to the PRNG. If B<max_bytes> is non-negative, -up to to B<max_bytes> are read; starting with OpenSSL 0.9.5, -if B<max_bytes> is -1, the complete file is read. +RAND_load_file() used to allow for the state of the random number generator +to be controlled by external sources. + +It is kept for ABI compatibility but is no longer functional, and +should not used in new programs. RAND_write_file() writes a number of random bytes (currently 1024) to -file B<filename> which can be used to initialize the PRNG by calling -RAND_load_file() in a later session. +file B<filename>. =head1 RETURN VALUES -RAND_load_file() returns the number of bytes read. +RAND_load_file() always returns 0. RAND_write_file() returns the number of bytes written, and -1 if the bytes written were generated without appropriate seed. diff --git a/lib/libssl/src/doc/crypto/rand.pod b/lib/libssl/src/doc/crypto/rand.pod index 1c068c85b34..e987414477d 100644 --- a/lib/libssl/src/doc/crypto/rand.pod +++ b/lib/libssl/src/doc/crypto/rand.pod @@ -29,10 +29,6 @@ rand - pseudo-random number generator void RAND_cleanup(void); - /* For Win32 only */ - void RAND_screen(void); - int RAND_event(UINT, WPARAM, LPARAM); - =head1 DESCRIPTION Since the introduction of the ENGINE API, the recommended way of controlling @@ -64,105 +60,8 @@ PRNG. =head1 INTERNALS -The RAND_SSLeay() method implements a PRNG based on a cryptographic -hash function. - -The following description of its design is based on the SSLeay -documentation: - -First up I will state the things I believe I need for a good RNG. - -=over 4 - -=item 1 - -A good hashing algorithm to mix things up and to convert the RNG 'state' -to random numbers. - -=item 2 - -An initial source of random 'state'. - -=item 3 - -The state should be very large. If the RNG is being used to generate -4096 bit RSA keys, 2 2048 bit random strings are required (at a minimum). -If your RNG state only has 128 bits, you are obviously limiting the -search space to 128 bits, not 2048. I'm probably getting a little -carried away on this last point but it does indicate that it may not be -a bad idea to keep quite a lot of RNG state. It should be easier to -break a cipher than guess the RNG seed data. - -=item 4 - -Any RNG seed data should influence all subsequent random numbers -generated. This implies that any random seed data entered will have -an influence on all subsequent random numbers generated. - -=item 5 - -When using data to seed the RNG state, the data used should not be -extractable from the RNG state. I believe this should be a -requirement because one possible source of 'secret' semi random -data would be a private key or a password. This data must -not be disclosed by either subsequent random numbers or a -'core' dump left by a program crash. - -=item 6 - -Given the same initial 'state', 2 systems should deviate in their RNG state -(and hence the random numbers generated) over time if at all possible. - -=item 7 - -Given the random number output stream, it should not be possible to determine -the RNG state or the next random number. - -=back - -The algorithm is as follows. - -There is global state made up of a 1023 byte buffer (the 'state'), a -working hash value ('md'), and a counter ('count'). - -Whenever seed data is added, it is inserted into the 'state' as -follows. - -The input is chopped up into units of 20 bytes (or less for -the last block). Each of these blocks is run through the hash -function as follows: The data passed to the hash function -is the current 'md', the same number of bytes from the 'state' -(the location determined by in incremented looping index) as -the current 'block', the new key data 'block', and 'count' -(which is incremented after each use). -The result of this is kept in 'md' and also xored into the -'state' at the same locations that were used as input into the -hash function. I -believe this system addresses points 1 (hash function; currently -SHA-1), 3 (the 'state'), 4 (via the 'md'), 5 (by the use of a hash -function and xor). - -When bytes are extracted from the RNG, the following process is used. -For each group of 10 bytes (or less), we do the following: - -Input into the hash function the local 'md' (which is initialized from -the global 'md' before any bytes are generated), the bytes that are to -be overwritten by the random bytes, and bytes from the 'state' -(incrementing looping index). From this digest output (which is kept -in 'md'), the top (up to) 10 bytes are returned to the caller and the -bottom 10 bytes are xored into the 'state'. - -Finally, after we have finished 'num' random bytes for the caller, -'count' (which is incremented) and the local and global 'md' are fed -into the hash function and the results are kept in the global 'md'. - -I believe the above addressed points 1 (use of SHA-1), 6 (by hashing -into the 'state' the 'old' data from the caller that is about to be -overwritten) and 7 (by not using the 10 bytes given to the caller to -update the 'state', but they are used to update 'md'). - -So of the points raised, only 2 is not addressed (but see -L<RAND_add(3)|RAND_add(3)>). +The RAND_SSLeay() method implements a PRNG based on the systems' +L<arc4random_buf(3)> random number generator. =head1 SEE ALSO |