diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2015-03-20 15:28:40 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2015-03-20 15:28:40 +0000 |
commit | 3d2030852da420b820a661e7b19bb757487e2599 (patch) | |
tree | 787cdff35e35be75e53f378b098bba3237a8deb7 /crypto/rand | |
parent | 8f5086671f06c811be16442eb6d6fe68e5ba71fc (diff) | |
download | src-3d2030852da420b820a661e7b19bb757487e2599.tar.gz src-3d2030852da420b820a661e7b19bb757487e2599.zip |
Import OpenSSL 1.0.1m.vendor/openssl/1.0.1m
Notes
Notes:
svn path=/vendor-crypto/openssl/dist/; revision=280288
svn path=/vendor-crypto/openssl/1.0.1m/; revision=280289; tag=vendor/openssl/1.0.1m
Diffstat (limited to 'crypto/rand')
-rw-r--r-- | crypto/rand/md_rand.c | 839 | ||||
-rw-r--r-- | crypto/rand/rand.h | 104 | ||||
-rw-r--r-- | crypto/rand/rand_egd.c | 359 | ||||
-rw-r--r-- | crypto/rand/rand_err.c | 53 | ||||
-rwxr-xr-x | crypto/rand/rand_lcl.h | 93 | ||||
-rw-r--r-- | crypto/rand/rand_lib.c | 359 | ||||
-rw-r--r-- | crypto/rand/rand_unix.c | 622 | ||||
-rw-r--r-- | crypto/rand/randfile.c | 394 | ||||
-rw-r--r-- | crypto/rand/randtest.c | 278 |
9 files changed, 1545 insertions, 1556 deletions
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c index 888b4eb8dd0b..5c13d57765b0 100644 --- a/crypto/rand/md_rand.c +++ b/crypto/rand/md_rand.c @@ -5,21 +5,21 @@ * 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: @@ -34,10 +34,10 @@ * 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 + * 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 @@ -49,7 +49,7 @@ * 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 @@ -63,7 +63,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 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 @@ -113,7 +113,7 @@ #ifdef MD_RAND_DEBUG # ifndef NDEBUG -# define NDEBUG +# define NDEBUG # endif #endif @@ -133,28 +133,29 @@ # define PREDICT #endif -/* #define PREDICT 1 */ +/* #define PREDICT 1 */ -#define STATE_SIZE 1023 -static int state_num=0,state_index=0; -static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH]; +#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 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) */ + * 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 */ - +/* valid iff crypto_lock_rand is set */ +static CRYPTO_THREADID locking_threadid; #ifdef PREDICT -int rand_predictable=0; +int rand_predictable = 0; #endif -const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT; +const char RAND_version[] = "RAND" OPENSSL_VERSION_PTEXT; static void ssleay_rand_cleanup(void); static void ssleay_rand_seed(const void *buf, int num); @@ -163,435 +164,429 @@ 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_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); - } +{ + 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; - } +{ + 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); - +{ + 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]); + 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); - } +{ + ssleay_rand_add(buf, num, (double)num); +} int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) - { - 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; +{ + 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(); + pid_t curr_pid = getpid(); #endif - int do_stir_pool = 0; + 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); - } + 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'. - */ - if (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_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 (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'. + */ + if (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_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; - if (lock) - 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); + /* + * 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; + if (lock) + 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; - } + 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); + 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); - if (lock) - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - MD_Update(&m,md,MD_DIGEST_LENGTH); - MD_Final(&m,md); - if (lock) - 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); - } - } + 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++) { + /* may compete with other threads */ + state[st_idx++] ^= local_md[i]; + 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); + if (lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + MD_Update(&m, md, MD_DIGEST_LENGTH); + MD_Final(&m, md); + if (lock) + 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, 1); - } +{ + return ssleay_rand_bytes(buf, num, 0, 1); +} -/* 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, 1); - } +/* + * 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, 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; - } +{ + 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/crypto/rand/rand.h b/crypto/rand/rand.h index bb5520e80ac1..2553afda2001 100644 --- a/crypto/rand/rand.h +++ b/crypto/rand/rand.h @@ -5,21 +5,21 @@ * 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: @@ -34,10 +34,10 @@ * 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 + * 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 @@ -49,7 +49,7 @@ * 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 @@ -57,75 +57,75 @@ */ #ifndef HEADER_RAND_H -#define HEADER_RAND_H +# define HEADER_RAND_H -#include <stdlib.h> -#include <openssl/ossl_typ.h> -#include <openssl/e_os2.h> +# include <stdlib.h> +# include <openssl/ossl_typ.h> +# include <openssl/e_os2.h> -#if defined(OPENSSL_SYS_WINDOWS) -#include <windows.h> -#endif +# 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 +# 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; */ -struct rand_meth_st - { - void (*seed)(const void *buf, int num); - int (*bytes)(unsigned char *buf, int num); - void (*cleanup)(void); - void (*add)(const void *buf, int num, double entropy); - int (*pseudorand)(unsigned char *buf, int num); - int (*status)(void); - }; - -#ifdef BN_DEBUG +struct rand_meth_st { + void (*seed) (const void *buf, int num); + int (*bytes) (unsigned char *buf, int num); + void (*cleanup) (void); + void (*add) (const void *buf, int num, double entropy); + int (*pseudorand) (unsigned char *buf, int num); + int (*status) (void); +}; + +# ifdef BN_DEBUG extern int rand_predictable; -#endif +# endif int RAND_set_rand_method(const RAND_METHOD *meth); const RAND_METHOD *RAND_get_rand_method(void); -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE int RAND_set_rand_engine(ENGINE *engine); -#endif +# endif RAND_METHOD *RAND_SSLeay(void); -void RAND_cleanup(void ); -int RAND_bytes(unsigned char *buf,int num); -int RAND_pseudo_bytes(unsigned char *buf,int num); -void RAND_seed(const void *buf,int num); -void RAND_add(const void *buf,int num,double entropy); -int RAND_load_file(const char *file,long max_bytes); -int RAND_write_file(const char *file); -const char *RAND_file_name(char *file,size_t num); +void RAND_cleanup(void); +int RAND_bytes(unsigned char *buf, int num); +int RAND_pseudo_bytes(unsigned char *buf, int num); +void RAND_seed(const void *buf, int num); +void RAND_add(const void *buf, int num, double entropy); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); int RAND_status(void); int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); int RAND_egd(const char *path); -int RAND_egd_bytes(const char *path,int bytes); +int RAND_egd_bytes(const char *path, int bytes); int RAND_poll(void); -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) void RAND_screen(void); int RAND_event(UINT, WPARAM, LPARAM); -#endif +# endif -#ifdef OPENSSL_FIPS +# ifdef OPENSSL_FIPS void RAND_set_fips_drbg_type(int type, int flags); int RAND_init_fips(void); -#endif +# endif /* BEGIN ERROR CODES */ -/* The following lines are auto generated by the script mkerr.pl. Any changes +/* + * 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); @@ -133,16 +133,16 @@ void ERR_load_RAND_strings(void); /* Error codes for the RAND functions. */ /* Function codes. */ -#define RAND_F_RAND_GET_RAND_METHOD 101 -#define RAND_F_RAND_INIT_FIPS 102 -#define RAND_F_SSLEAY_RAND_BYTES 100 +# define RAND_F_RAND_GET_RAND_METHOD 101 +# define RAND_F_RAND_INIT_FIPS 102 +# define RAND_F_SSLEAY_RAND_BYTES 100 /* Reason codes. */ -#define RAND_R_DUAL_EC_DRBG_DISABLED 104 -#define RAND_R_ERROR_INITIALISING_DRBG 102 -#define RAND_R_ERROR_INSTANTIATING_DRBG 103 -#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 -#define RAND_R_PRNG_NOT_SEEDED 100 +# define RAND_R_DUAL_EC_DRBG_DISABLED 104 +# define RAND_R_ERROR_INITIALISING_DRBG 102 +# define RAND_R_ERROR_INSTANTIATING_DRBG 103 +# define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 +# define RAND_R_PRNG_NOT_SEEDED 100 #ifdef __cplusplus } diff --git a/crypto/rand/rand_egd.c b/crypto/rand/rand_egd.c index d53b916ebee8..737aebfa22fe 100644 --- a/crypto/rand/rand_egd.c +++ b/crypto/rand/rand_egd.c @@ -8,7 +8,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 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 @@ -58,7 +58,7 @@ #include <openssl/rand.h> #include <openssl/buffer.h> -/* +/*- * Query the EGD <URL: http://www.lothar.com/tech/crypto/>. * * This module supplies three routines: @@ -97,207 +97,196 @@ #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); - } +{ + return (-1); +} + int RAND_egd(const char *path) - { - return(-1); - } +{ + return (-1); +} -int RAND_egd_bytes(const char *path,int bytes) - { - return(-1); - } +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 <openssl/opensslconf.h> +# include OPENSSL_UNISTD +# include <stddef.h> +# include <sys/types.h> +# include <sys/socket.h> +# ifndef NO_SYS_UN_H +# ifdef OPENSSL_SYS_VXWORKS # include <streams/un.h> -# else +# else # include <sys/un.h> -# endif -#else -struct sockaddr_un { - short sun_family; /* AF_UNIX */ - char sun_path[108]; /* path name (gag) */ +# 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> +# endif /* NO_SYS_UN_H */ +# include <string.h> +# include <errno.h> -#ifndef offsetof +# ifndef offsetof # define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif +# 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; +{ + 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 */ - } - } - } + 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]); - } + 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); - } - + if (fd != -1) + close(fd); + return (ret); +} int RAND_egd_bytes(const char *path, int bytes) - { - int num, ret = 0; +{ + int num, ret = 0; - num = RAND_query_egd_bytes(path, NULL, bytes); - if (num < 1) goto err; - if (RAND_status() == 1) - ret = num; + num = RAND_query_egd_bytes(path, NULL, bytes); + if (num < 1) + goto err; + if (RAND_status() == 1) + ret = num; err: - return(ret); - } - + return (ret); +} int RAND_egd(const char *path) - { - return (RAND_egd_bytes(path, 255)); - } - +{ + return (RAND_egd_bytes(path, 255)); +} #endif diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index c4c80fc8ccad..55d86ea8a385 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -7,7 +7,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 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 @@ -53,7 +53,8 @@ * */ -/* NOTE: this file was auto generated by the mkerr.pl script: any changes +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes * made to it will be overwritten when the script next updates this file, * only reason strings will be preserved. */ @@ -65,37 +66,35 @@ /* BEGIN ERROR CODES */ #ifndef OPENSSL_NO_ERR -#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0) -#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason) +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason) -static ERR_STRING_DATA RAND_str_functs[]= - { -{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, -{ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"}, -{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, -{0,NULL} - }; +static ERR_STRING_DATA RAND_str_functs[] = { + {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, + {ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"}, + {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, + {0, NULL} +}; -static ERR_STRING_DATA RAND_str_reasons[]= - { -{ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED),"dual ec drbg disabled"}, -{ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG),"error initialising drbg"}, -{ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"}, -{ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET),"no fips random method set"}, -{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"}, -{0,NULL} - }; +static ERR_STRING_DATA RAND_str_reasons[] = { + {ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED), "dual ec drbg disabled"}, + {ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, + {ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, + {ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET), + "no fips random method set"}, + {ERR_REASON(RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"}, + {0, NULL} +}; #endif void ERR_load_RAND_strings(void) - { +{ #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) - { - ERR_load_strings(0,RAND_str_functs); - ERR_load_strings(0,RAND_str_reasons); - } + if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) { + ERR_load_strings(0, RAND_str_functs); + ERR_load_strings(0, RAND_str_reasons); + } #endif - } +} diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h index 0fabf8dc5d90..f9fda3eb89c9 100755 --- a/crypto/rand/rand_lcl.h +++ b/crypto/rand/rand_lcl.h @@ -5,21 +5,21 @@ * 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: @@ -34,10 +34,10 @@ * 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 + * 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 @@ -49,7 +49,7 @@ * 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 @@ -63,7 +63,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 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 @@ -110,49 +110,48 @@ */ #ifndef HEADER_RAND_LCL_H -#define HEADER_RAND_LCL_H +# define HEADER_RAND_LCL_H -#define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */ +# 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 -#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 +# 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 int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock); diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 239a1cde8189..88a78d350656 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -5,21 +5,21 @@ * 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: @@ -34,10 +34,10 @@ * 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 + * 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 @@ -49,7 +49,7 @@ * 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 @@ -62,246 +62,239 @@ #include <openssl/rand.h> #ifndef OPENSSL_NO_ENGINE -#include <openssl/engine.h> +# include <openssl/engine.h> #endif #ifdef OPENSSL_FIPS -#include <openssl/fips.h> -#include <openssl/fips_rand.h> -#include "rand_lcl.h" +# include <openssl/fips.h> +# include <openssl/fips_rand.h> +# include "rand_lcl.h" #endif #ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ -static ENGINE *funct_ref =NULL; +static ENGINE *funct_ref = NULL; #endif static const RAND_METHOD *default_RAND_meth = NULL; int RAND_set_rand_method(const RAND_METHOD *meth) - { +{ #ifndef OPENSSL_NO_ENGINE - if(funct_ref) - { - ENGINE_finish(funct_ref); - funct_ref = NULL; - } + if (funct_ref) { + ENGINE_finish(funct_ref); + funct_ref = NULL; + } #endif - default_RAND_meth = meth; - return 1; - } + default_RAND_meth = meth; + return 1; +} const RAND_METHOD *RAND_get_rand_method(void) - { - if (!default_RAND_meth) - { +{ + if (!default_RAND_meth) { #ifndef OPENSSL_NO_ENGINE - ENGINE *e = ENGINE_get_default_RAND(); - if(e) - { - default_RAND_meth = ENGINE_get_RAND(e); - if(!default_RAND_meth) - { - ENGINE_finish(e); - e = NULL; - } - } - if(e) - funct_ref = e; - else + ENGINE *e = ENGINE_get_default_RAND(); + if (e) { + default_RAND_meth = ENGINE_get_RAND(e); + if (!default_RAND_meth) { + ENGINE_finish(e); + e = NULL; + } + } + if (e) + funct_ref = e; + else #endif - default_RAND_meth = RAND_SSLeay(); - } - return default_RAND_meth; - } + default_RAND_meth = RAND_SSLeay(); + } + return default_RAND_meth; +} #ifndef OPENSSL_NO_ENGINE int RAND_set_rand_engine(ENGINE *engine) - { - const RAND_METHOD *tmp_meth = NULL; - if(engine) - { - if(!ENGINE_init(engine)) - return 0; - tmp_meth = ENGINE_get_RAND(engine); - if(!tmp_meth) - { - ENGINE_finish(engine); - return 0; - } - } - /* This function releases any prior ENGINE so call it first */ - RAND_set_rand_method(tmp_meth); - funct_ref = engine; - return 1; - } +{ + const RAND_METHOD *tmp_meth = NULL; + if (engine) { + if (!ENGINE_init(engine)) + return 0; + tmp_meth = ENGINE_get_RAND(engine); + if (!tmp_meth) { + ENGINE_finish(engine); + return 0; + } + } + /* This function releases any prior ENGINE so call it first */ + RAND_set_rand_method(tmp_meth); + funct_ref = engine; + return 1; +} #endif void RAND_cleanup(void) - { - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->cleanup) - meth->cleanup(); - RAND_set_rand_method(NULL); - } +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->cleanup) + meth->cleanup(); + RAND_set_rand_method(NULL); +} void RAND_seed(const void *buf, int num) - { - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->seed) - meth->seed(buf,num); - } +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->seed) + meth->seed(buf, num); +} void RAND_add(const void *buf, int num, double entropy) - { - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->add) - meth->add(buf,num,entropy); - } +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->add) + meth->add(buf, num, entropy); +} int RAND_bytes(unsigned char *buf, int num) - { - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->bytes) - return meth->bytes(buf,num); - return(-1); - } +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->bytes) + return meth->bytes(buf, num); + return (-1); +} int RAND_pseudo_bytes(unsigned char *buf, int num) - { - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->pseudorand) - return meth->pseudorand(buf,num); - return(-1); - } +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->pseudorand) + return meth->pseudorand(buf, num); + return (-1); +} int RAND_status(void) - { - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->status) - return meth->status(); - return 0; - } +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->status) + return meth->status(); + return 0; +} #ifdef OPENSSL_FIPS -/* FIPS DRBG initialisation code. This sets up the DRBG for use by the - * rest of OpenSSL. +/* + * 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 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 (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 0) - { - OPENSSL_free(*pout); - *pout = NULL; - return 0; - } - return min_len; - } + 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 (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 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); - } - } +{ + 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. +/* + * 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); - } +{ + /* 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 +/* + * 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; - } + 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; - } +{ + 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 +# 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; - } +{ + 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); +{ + 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; - } + 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/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c index e3a65571c8df..266111edda8c 100644 --- a/crypto/rand/rand_unix.c +++ b/crypto/rand/rand_unix.c @@ -5,21 +5,21 @@ * 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: @@ -34,10 +34,10 @@ * 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 + * 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 @@ -49,7 +49,7 @@ * 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 @@ -63,7 +63,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 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 @@ -118,314 +118,330 @@ #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. */ +# 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; - - 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; + 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; + + 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__ +# elif defined __OpenBSD__ int RAND_poll(void) { - u_int32_t rnd = 0, i; - unsigned char buf[ENTROPY_NEEDED]; - - for (i = 0; i < sizeof(buf); i++) { - if (i % 4 == 0) - rnd = arc4random(); - buf[i] = rnd; - rnd >>= 8; - } - RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); - memset(buf, 0, sizeof(buf)); - - return 1; + u_int32_t rnd = 0, i; + unsigned char buf[ENTROPY_NEEDED]; + + for (i = 0; i < sizeof(buf); i++) { + if (i % 4 == 0) + rnd = arc4random(); + buf[i] = rnd; + rnd >>= 8; + } + RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); + memset(buf, 0, sizeof(buf)); + + return 1; } -#else /* !defined(__OpenBSD__) */ +# 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 + 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)) */ - +# 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; - } +{ + return 0; +} #endif diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index 14ba69d4c694..9537c56a7895 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -5,21 +5,21 @@ * 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: @@ -34,10 +34,10 @@ * 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 + * 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 @@ -49,7 +49,7 @@ * 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 @@ -58,7 +58,7 @@ /* We need to define this to get macros like S_IFBLK and S_IFCHR */ #if !defined(OPENSSL_SYS_VXWORKS) -#define _XOPEN_SOURCE 500 +# define _XOPEN_SOURCE 500 #endif #include <errno.h> @@ -72,7 +72,7 @@ #include <openssl/buffer.h> #ifdef OPENSSL_SYS_VMS -#include <unixio.h> +# include <unixio.h> #endif #ifndef NO_SYS_TYPES_H # include <sys/types.h> @@ -83,247 +83,255 @@ #endif #ifdef _WIN32 -#define stat _stat -#define chmod _chmod -#define open _open -#define fdopen _fdopen +# define stat _stat +# define chmod _chmod +# define open _open +# define fdopen _fdopen #endif #undef BUFSIZE -#define BUFSIZE 1024 +#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 */ +/* + * 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" +# 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. - * Entropy devices and EGD sockets are handled in rand_unix.c */ +/* + * Note that these functions are intended for seed files only. Entropy + * devices and EGD sockets are handled in rand_unix.c + */ int RAND_load_file(const char *file, long bytes) - { - /* If bytes >= 0, read up to 'bytes' bytes. - * if bytes == -1, read complete file. */ +{ + /*- + * If bytes >= 0, read up to 'bytes' bytes. + * if bytes == -1, read complete file. + */ - MS_STATIC unsigned char buf[BUFSIZE]; + MS_STATIC unsigned char buf[BUFSIZE]; #ifndef OPENSSL_NO_POSIX_IO - struct stat sb; + struct stat sb; #endif - int i,ret=0,n; - FILE *in; + int i, ret = 0, n; + FILE *in; - if (file == NULL) return(0); + 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); +# 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); + if (bytes == 0) + return (ret); #ifdef OPENSSL_SYS_VMS - in=vms_fopen(file,"rb",VMS_OPEN_ATTRS); + in = vms_fopen(file, "rb", VMS_OPEN_ATTRS); #else - in=fopen(file,"rb"); + in = fopen(file, "rb"); #endif - if (in == NULL) goto err; + 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 */ - } + 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; + 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); + RAND_add(buf, i, (double)i); #else - /* even if n != i, use the full array */ - RAND_add(buf,n,(double)i); + /* 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); - } + ret += i; + if (bytes > 0) { + bytes -= n; + if (bytes <= 0) + break; + } + } + fclose(in); + OPENSSL_cleanse(buf, BUFSIZE); + err: + return (ret); +} int RAND_write_file(const char *file) - { - unsigned char buf[BUFSIZE]; - int i,ret=0,rand_err=0; - FILE *out = NULL; - int n; +{ + unsigned char buf[BUFSIZE]; + 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 - * of random device. Otherwise attempting to write to - * and chmod the device causes problems. - */ - return(1); - } -#endif - } + 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 of random + * device. Otherwise attempting to write to and chmod the device + * causes problems. + */ + 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); - if (fd != -1) - out = fdopen(fd, "wb"); - } + { +# 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); + 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. - */ + /* + * 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); + 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"); + if (out == NULL) + out = fopen(file, "wb"); #endif - if (out == NULL) goto err; + if (out == NULL) + goto err; #ifndef NO_CHMOD - chmod(file,0600); + chmod(file, 0600); #endif - n=RAND_DATA; - for (;;) - { - i=(n > BUFSIZE)?BUFSIZE:n; - n-=BUFSIZE; - if (RAND_bytes(buf,i) <= 0) - rand_err=1; - i=fwrite(buf,1,i,out); - if (i <= 0) - { - ret=0; - break; - } - ret+=i; - if (n <= 0) break; - } + n = RAND_DATA; + for (;;) { + i = (n > BUFSIZE) ? BUFSIZE : n; + n -= BUFSIZE; + if (RAND_bytes(buf, i) <= 0) + rand_err = 1; + i = fwrite(buf, 1, i, out); + if (i <= 0) { + ret = 0; + break; + } + ret += i; + if (n <= 0) + break; + } - fclose(out); - OPENSSL_cleanse(buf,BUFSIZE); -err: - return (rand_err ? -1 : ret); - } + fclose(out); + OPENSSL_cleanse(buf, BUFSIZE); + err: + return (rand_err ? -1 : ret); +} const char *RAND_file_name(char *buf, size_t size) - { - char *s=NULL; +{ + char *s = NULL; #ifdef __OpenBSD__ - struct stat sb; + struct stat sb; #endif - if (OPENSSL_issetugid() == 0) - s=getenv("RANDFILE"); - if (s != NULL && *s && strlen(s) + 1 < size) - { - if (BUF_strlcpy(buf,s,size) >= size) - return NULL; - } - else - { - if (OPENSSL_issetugid() == 0) - s=getenv("HOME"); + if (OPENSSL_issetugid() == 0) + s = getenv("RANDFILE"); + if (s != NULL && *s && strlen(s) + 1 < size) { + if (BUF_strlcpy(buf, s, size) >= size) + return NULL; + } else { + if (OPENSSL_issetugid() == 0) + s = getenv("HOME"); #ifdef DEFAULT_HOME - if (s == NULL) - { - s = DEFAULT_HOME; - } + if (s == NULL) { + s = DEFAULT_HOME; + } #endif - if (s && *s && strlen(s)+strlen(RFILE)+2 < size) - { - BUF_strlcpy(buf,s,size); + if (s && *s && strlen(s) + strlen(RFILE) + 2 < size) { + BUF_strlcpy(buf, s, size); #ifndef OPENSSL_SYS_VMS - BUF_strlcat(buf,"/",size); + BUF_strlcat(buf, "/", size); #endif - BUF_strlcat(buf,RFILE,size); - } - else - buf[0] = '\0'; /* no file name */ - } + 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 - * use their own source for good random data, but defaults - * to something hopefully decent if that isn't available. - */ - - if (!buf[0]) - if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) { - return(NULL); - } - if (stat(buf,&sb) == -1) - if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) { - return(NULL); - } + /* + * 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 use their own source for good random + * data, but defaults to something hopefully decent if that isn't + * available. + */ + if (!buf[0]) + if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) { + return (NULL); + } + if (stat(buf, &sb) == -1) + if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) { + return (NULL); + } #endif - return(buf); - } + return (buf); +} diff --git a/crypto/rand/randtest.c b/crypto/rand/randtest.c index 9e92a70b033c..91bcac9906b2 100644 --- a/crypto/rand/randtest.c +++ b/crypto/rand/randtest.c @@ -5,21 +5,21 @@ * 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: @@ -34,10 +34,10 @@ * 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 + * 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 @@ -49,7 +49,7 @@ * 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 @@ -65,155 +65,145 @@ /* some FIPS 140-1 random number test */ /* some simple tests */ -int main(int argc,char **argv) - { - unsigned char buf[2500]; - int i,j,k,s,sign,nsign,err=0; - unsigned long n1; - unsigned long n2[16]; - unsigned long runs[2][34]; - /*double d; */ - long d; +int main(int argc, char **argv) +{ + unsigned char buf[2500]; + int i, j, k, s, sign, nsign, err = 0; + unsigned long n1; + unsigned long n2[16]; + unsigned long runs[2][34]; + /* + * double d; + */ + long d; - i = RAND_pseudo_bytes(buf,2500); - if (i < 0) - { - printf ("init failed, the rand method is not properly installed\n"); - err++; - goto err; - } + i = RAND_pseudo_bytes(buf, 2500); + if (i < 0) { + printf("init failed, the rand method is not properly installed\n"); + err++; + goto err; + } - n1=0; - for (i=0; i<16; i++) n2[i]=0; - for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0; + n1 = 0; + for (i = 0; i < 16; i++) + n2[i] = 0; + for (i = 0; i < 34; i++) + runs[0][i] = runs[1][i] = 0; - /* test 1 and 2 */ - sign=0; - nsign=0; - for (i=0; i<2500; i++) - { - j=buf[i]; + /* test 1 and 2 */ + sign = 0; + nsign = 0; + for (i = 0; i < 2500; i++) { + j = buf[i]; - n2[j&0x0f]++; - n2[(j>>4)&0x0f]++; + n2[j & 0x0f]++; + n2[(j >> 4) & 0x0f]++; - for (k=0; k<8; k++) - { - s=(j&0x01); - if (s == sign) - nsign++; - else - { - if (nsign > 34) nsign=34; - if (nsign != 0) - { - runs[sign][nsign-1]++; - if (nsign > 6) - runs[sign][5]++; - } - sign=s; - nsign=1; - } + for (k = 0; k < 8; k++) { + s = (j & 0x01); + if (s == sign) + nsign++; + else { + if (nsign > 34) + nsign = 34; + if (nsign != 0) { + runs[sign][nsign - 1]++; + if (nsign > 6) + runs[sign][5]++; + } + sign = s; + nsign = 1; + } - if (s) n1++; - j>>=1; - } - } - if (nsign > 34) nsign=34; - if (nsign != 0) runs[sign][nsign-1]++; + if (s) + n1++; + j >>= 1; + } + } + if (nsign > 34) + nsign = 34; + if (nsign != 0) + runs[sign][nsign - 1]++; - /* test 1 */ - if (!((9654 < n1) && (n1 < 10346))) - { - printf("test 1 failed, X=%lu\n",n1); - err++; - } - printf("test 1 done\n"); + /* test 1 */ + if (!((9654 < n1) && (n1 < 10346))) { + printf("test 1 failed, X=%lu\n", n1); + err++; + } + printf("test 1 done\n"); - /* test 2 */ + /* test 2 */ #ifdef undef - d=0; - for (i=0; i<16; i++) - d+=n2[i]*n2[i]; - d=d*16.0/5000.0-5000.0; - if (!((1.03 < d) && (d < 57.4))) - { - printf("test 2 failed, X=%.2f\n",d); - err++; - } + d = 0; + for (i = 0; i < 16; i++) + d += n2[i] * n2[i]; + d = d * 16.0 / 5000.0 - 5000.0; + if (!((1.03 < d) && (d < 57.4))) { + printf("test 2 failed, X=%.2f\n", d); + err++; + } #endif - d=0; - for (i=0; i<16; i++) - d+=n2[i]*n2[i]; - d=(d*8)/25-500000; - if (!((103 < d) && (d < 5740))) - { - printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L); - err++; - } - printf("test 2 done\n"); + d = 0; + for (i = 0; i < 16; i++) + d += n2[i] * n2[i]; + d = (d * 8) / 25 - 500000; + if (!((103 < d) && (d < 5740))) { + printf("test 2 failed, X=%ld.%02ld\n", d / 100L, d % 100L); + err++; + } + printf("test 2 done\n"); + + /* test 3 */ + for (i = 0; i < 2; i++) { + if (!((2267 < runs[i][0]) && (runs[i][0] < 2733))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 1, runs[i][0]); + err++; + } + if (!((1079 < runs[i][1]) && (runs[i][1] < 1421))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 2, runs[i][1]); + err++; + } + if (!((502 < runs[i][2]) && (runs[i][2] < 748))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 3, runs[i][2]); + err++; + } + if (!((223 < runs[i][3]) && (runs[i][3] < 402))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 4, runs[i][3]); + err++; + } + if (!((90 < runs[i][4]) && (runs[i][4] < 223))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 5, runs[i][4]); + err++; + } + if (!((90 < runs[i][5]) && (runs[i][5] < 223))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 6, runs[i][5]); + err++; + } + } + printf("test 3 done\n"); - /* test 3 */ - for (i=0; i<2; i++) - { - if (!((2267 < runs[i][0]) && (runs[i][0] < 2733))) - { - printf("test 3 failed, bit=%d run=%d num=%lu\n", - i,1,runs[i][0]); - err++; - } - if (!((1079 < runs[i][1]) && (runs[i][1] < 1421))) - { - printf("test 3 failed, bit=%d run=%d num=%lu\n", - i,2,runs[i][1]); - err++; - } - if (!(( 502 < runs[i][2]) && (runs[i][2] < 748))) - { - printf("test 3 failed, bit=%d run=%d num=%lu\n", - i,3,runs[i][2]); - err++; - } - if (!(( 223 < runs[i][3]) && (runs[i][3] < 402))) - { - printf("test 3 failed, bit=%d run=%d num=%lu\n", - i,4,runs[i][3]); - err++; - } - if (!(( 90 < runs[i][4]) && (runs[i][4] < 223))) - { - printf("test 3 failed, bit=%d run=%d num=%lu\n", - i,5,runs[i][4]); - err++; - } - if (!(( 90 < runs[i][5]) && (runs[i][5] < 223))) - { - printf("test 3 failed, bit=%d run=%d num=%lu\n", - i,6,runs[i][5]); - err++; - } - } - printf("test 3 done\n"); - - /* test 4 */ - if (runs[0][33] != 0) - { - printf("test 4 failed, bit=%d run=%d num=%lu\n", - 0,34,runs[0][33]); - err++; - } - if (runs[1][33] != 0) - { - printf("test 4 failed, bit=%d run=%d num=%lu\n", - 1,34,runs[1][33]); - err++; - } - printf("test 4 done\n"); + /* test 4 */ + if (runs[0][33] != 0) { + printf("test 4 failed, bit=%d run=%d num=%lu\n", 0, 34, runs[0][33]); + err++; + } + if (runs[1][33] != 0) { + printf("test 4 failed, bit=%d run=%d num=%lu\n", 1, 34, runs[1][33]); + err++; + } + printf("test 4 done\n"); err: - err=((err)?1:0); + err = ((err) ? 1 : 0); #ifdef OPENSSL_SYS_NETWARE - if (err) printf("ERROR: %d\n", err); + if (err) + printf("ERROR: %d\n", err); #endif - EXIT(err); - return(err); - } + EXIT(err); + return (err); +} |