This commit is contained in:
Zhi Guan
2015-08-15 15:02:15 +08:00
parent 06df2fab54
commit 3bdc0ea895
2536 changed files with 417052 additions and 271997 deletions

View File

@@ -63,6 +63,8 @@ tests:
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
update: depend
depend:
@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)

View File

View File

@@ -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
@@ -109,9 +109,11 @@
*
*/
#define OPENSSL_FIPSEVP
#ifdef MD_RAND_DEBUG
# ifndef NDEBUG
# define NDEBUG
# define NDEBUG
# endif
#endif
@@ -121,473 +123,470 @@
#include "e_os.h"
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include "rand_lcl.h"
#include <openssl/crypto.h>
#include <openssl/err.h>
#ifdef BN_DEBUG
# 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);
static void ssleay_rand_add(const void *buf, int num, double add_entropy);
static int ssleay_rand_bytes(unsigned char *buf, int num);
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_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;
{
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;
/*
* (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.
*/
if (!num)
return;
/* 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;
/*
* (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.
*/
if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
st_idx=state_index;
/* 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;
/* 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];
if (!do_not_lock)
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
st_idx = state_index;
memcpy(local_md, md, sizeof md);
/*
* 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];
/* 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 */
memcpy(local_md, md, sizeof md);
/* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
* are what we will use now, but other threads may use them
* as well */
/* 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 */
md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
/*
* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we
* will use now, but other threads may use them as well
*/
if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
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;
if (!do_not_lock)
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
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);
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;
/* 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_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);
MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
MD_Final(&m,local_md);
md_c[1]++;
/* 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.
*/
buf=(const char *)buf + j;
MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
MD_Final(&m, local_md);
md_c[1]++;
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);
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 (!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);
}
static int ssleay_rand_bytes(unsigned char *buf, int num)
{
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;
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;
#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;
if (rand_predictable) {
static unsigned char val = 0;
for (i=0; i<num; i++)
buf[i]=val++;
return(1);
}
for (i = 0; i < num; i++)
buf[i] = val++;
return (1);
}
#endif
if (num <= 0)
return 1;
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);
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'.
*/
/*
* (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);
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;
/* 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 (!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 (!stirred_pool)
do_stir_pool = 1;
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.
*/
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;
}
int n = STATE_SIZE; /* so that the complete pool gets accessed */
while (n > 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;
}
/*
* 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);
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_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) */
/*
* 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;
md_count[0] += 1;
/* before unlocking, we must clear 'crypto_lock_rand' */
crypto_lock_rand = 0;
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
/* 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);
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));
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);
#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);
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];
}
}
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);
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
MD_Update(&m,md,MD_DIGEST_LENGTH);
MD_Final(&m,md);
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
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
{
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);
}
}
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);
}
}
/* pseudo-random bytes that are guaranteed to be unique but not
unpredictable */
static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
{
int ret;
unsigned long err;
static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
{
return ssleay_rand_bytes(buf, num, 0, 1);
}
ret = RAND_bytes(buf, num);
if (ret == 0)
{
err = ERR_peek_error();
if (ERR_GET_LIB(err) == ERR_LIB_RAND &&
ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED)
ERR_clear_error();
}
return (ret);
}
/*
* 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 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;
}
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;
ret = entropy >= ENTROPY_NEEDED;
if (!do_not_lock) {
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
if (!do_not_lock)
{
/* before unlocking, we must clear 'crypto_lock_rand' */
crypto_lock_rand = 0;
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
}
return ret;
}
/*
* 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;
}

Binary file not shown.

View File

@@ -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,70 +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);
};
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
# 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
void RAND_set_fips_drbg_type(int type, int flags);
int RAND_init_fips(void);
# endif
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
/*
* 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);
@@ -128,11 +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_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_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
}

View File

@@ -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);
}
int RAND_egd_bytes(const char *path,int bytes)
{
return(-1);
}
#else
#include <openssl/opensslconf.h>
#include OPENSSL_UNISTD
#include <sys/types.h>
#include <sys/socket.h>
#ifndef NO_SYS_UN_H
# ifdef OPENSSL_SYS_VXWORKS
# include <streams/un.h>
# else
# include <sys/un.h>
# endif
#else
struct sockaddr_un {
short sun_family; /* AF_UNIX */
char sun_path[108]; /* path name (gag) */
};
#endif /* NO_SYS_UN_H */
#include <string.h>
#include <errno.h>
#ifndef offsetof
# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
{
int ret = 0;
struct sockaddr_un addr;
int len, num, numbytes;
int fd = -1;
int success;
unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
if (strlen(path) >= sizeof(addr.sun_path))
return (-1);
BUF_strlcpy(addr.sun_path,path,sizeof addr.sun_path);
len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1) return (-1);
success = 0;
while (!success)
{
if (connect(fd, (struct sockaddr *)&addr, len) == 0)
success = 1;
else
{
switch (errno)
{
#ifdef EINTR
case EINTR:
#endif
#ifdef EAGAIN
case EAGAIN:
#endif
#ifdef EINPROGRESS
case EINPROGRESS:
#endif
#ifdef EALREADY
case EALREADY:
#endif
/* No error, try again */
break;
#ifdef EISCONN
case EISCONN:
success = 1;
break;
#endif
default:
goto err; /* failure */
}
}
}
while(bytes > 0)
{
egdbuf[0] = 1;
egdbuf[1] = bytes < 255 ? bytes : 255;
numbytes = 0;
while (numbytes != 2)
{
num = write(fd, egdbuf + numbytes, 2 - numbytes);
if (num >= 0)
numbytes += num;
else
{
switch (errno)
{
#ifdef EINTR
case EINTR:
#endif
#ifdef EAGAIN
case EAGAIN:
#endif
/* No error, try again */
break;
default:
ret = -1;
goto err; /* failure */
}
}
}
numbytes = 0;
while (numbytes != 1)
{
num = read(fd, egdbuf, 1);
if (num == 0)
goto err; /* descriptor closed */
else if (num > 0)
numbytes += num;
else
{
switch (errno)
{
#ifdef EINTR
case EINTR:
#endif
#ifdef EAGAIN
case EAGAIN:
#endif
/* No error, try again */
break;
default:
ret = -1;
goto err; /* failure */
}
}
}
if(egdbuf[0] == 0)
goto err;
if (buf)
retrievebuf = buf + ret;
else
retrievebuf = tempbuf;
numbytes = 0;
while (numbytes != egdbuf[0])
{
num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
if (num == 0)
goto err; /* descriptor closed */
else if (num > 0)
numbytes += num;
else
{
switch (errno)
{
#ifdef EINTR
case EINTR:
#endif
#ifdef EAGAIN
case EAGAIN:
#endif
/* No error, try again */
break;
default:
ret = -1;
goto err; /* failure */
}
}
}
ret += egdbuf[0];
bytes -= egdbuf[0];
if (!buf)
RAND_seed(tempbuf, egdbuf[0]);
}
err:
if (fd != -1) close(fd);
return(ret);
}
{
return (-1);
}
int RAND_egd_bytes(const char *path, int bytes)
{
int num, ret = 0;
{
return (-1);
}
#else
# 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
# include <sys/un.h>
# endif
# else
struct sockaddr_un {
short sun_family; /* AF_UNIX */
char sun_path[108]; /* path name (gag) */
};
# endif /* NO_SYS_UN_H */
# include <string.h>
# include <errno.h>
num = RAND_query_egd_bytes(path, NULL, bytes);
if (num < 1) goto err;
if (RAND_status() == 1)
ret = num;
# ifndef offsetof
# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
# endif
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
{
int ret = 0;
struct sockaddr_un addr;
int len, num, numbytes;
int fd = -1;
int success;
unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
if (strlen(path) >= sizeof(addr.sun_path))
return (-1);
BUF_strlcpy(addr.sun_path, path, sizeof addr.sun_path);
len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
return (-1);
success = 0;
while (!success) {
if (connect(fd, (struct sockaddr *)&addr, len) == 0)
success = 1;
else {
switch (errno) {
# ifdef EINTR
case EINTR:
# endif
# ifdef EAGAIN
case EAGAIN:
# endif
# ifdef EINPROGRESS
case EINPROGRESS:
# endif
# ifdef EALREADY
case EALREADY:
# endif
/* No error, try again */
break;
# ifdef EISCONN
case EISCONN:
success = 1;
break;
# endif
default:
goto err; /* failure */
}
}
}
while (bytes > 0) {
egdbuf[0] = 1;
egdbuf[1] = bytes < 255 ? bytes : 255;
numbytes = 0;
while (numbytes != 2) {
num = write(fd, egdbuf + numbytes, 2 - numbytes);
if (num >= 0)
numbytes += num;
else {
switch (errno) {
# ifdef EINTR
case EINTR:
# endif
# ifdef EAGAIN
case EAGAIN:
# endif
/* No error, try again */
break;
default:
ret = -1;
goto err; /* failure */
}
}
}
numbytes = 0;
while (numbytes != 1) {
num = read(fd, egdbuf, 1);
if (num == 0)
goto err; /* descriptor closed */
else if (num > 0)
numbytes += num;
else {
switch (errno) {
# ifdef EINTR
case EINTR:
# endif
# ifdef EAGAIN
case EAGAIN:
# endif
/* No error, try again */
break;
default:
ret = -1;
goto err; /* failure */
}
}
}
if (egdbuf[0] == 0)
goto err;
if (buf)
retrievebuf = buf + ret;
else
retrievebuf = tempbuf;
numbytes = 0;
while (numbytes != egdbuf[0]) {
num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
if (num == 0)
goto err; /* descriptor closed */
else if (num > 0)
numbytes += num;
else {
switch (errno) {
# ifdef EINTR
case EINTR:
# endif
# ifdef EAGAIN
case EAGAIN:
# endif
/* No error, try again */
break;
default:
ret = -1;
goto err; /* failure */
}
}
}
ret += egdbuf[0];
bytes -= egdbuf[0];
if (!buf)
RAND_seed(tempbuf, egdbuf[0]);
}
err:
return(ret);
}
if (fd != -1)
close(fd);
return (ret);
}
int RAND_egd_bytes(const char *path, int bytes)
{
int num, ret = 0;
num = RAND_query_egd_bytes(path, NULL, bytes);
if (num < 1)
goto err;
if (RAND_status() == 1)
ret = num;
err:
return (ret);
}
int RAND_egd(const char *path)
{
return (RAND_egd_bytes(path, 255));
}
{
return (RAND_egd_bytes(path, 255));
}
#endif

Binary file not shown.

View File

@@ -1,13 +1,13 @@
/* crypto/rand/rand_err.c */
/* ====================================================================
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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,32 +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_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_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
}
}

Binary file not shown.

View File

@@ -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,49 @@
*/
#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);
#endif

View File

@@ -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
@@ -60,117 +60,241 @@
#include <time.h>
#include "cryptlib.h"
#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"
#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.
*/
/*
* 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;
}
static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
{
if (out) {
OPENSSL_cleanse(out, olen);
OPENSSL_free(out);
}
}
/*
* Set "additional input" when generating random data. This uses the current
* PID, a time value and a counter.
*/
static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
{
/* Use of static variables is OK as this happens under a lock */
static unsigned char buf[16];
static unsigned long counter;
FIPS_get_timevec(buf, &counter);
*pout = buf;
return sizeof(buf);
}
/*
* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
* correctly seeded by RAND_poll().
*/
static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
double entropy)
{
RAND_SSLeay()->add(in, inlen, entropy);
return 1;
}
static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
{
RAND_SSLeay()->seed(in, inlen);
return 1;
}
# ifndef OPENSSL_DRBG_DEFAULT_TYPE
# define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr
# endif
# ifndef OPENSSL_DRBG_DEFAULT_FLAGS
# define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF
# endif
static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
void RAND_set_fips_drbg_type(int type, int flags)
{
fips_drbg_type = type;
fips_drbg_flags = flags;
}
int RAND_init_fips(void)
{
DRBG_CTX *dctx;
size_t plen;
unsigned char pers[32], *p;
# ifndef OPENSSL_ALLOW_DUAL_EC_DRBG
if (fips_drbg_type >> 16) {
RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED);
return 0;
}
# endif
dctx = FIPS_get_default_drbg();
if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0) {
RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
return 0;
}
FIPS_drbg_set_callbacks(dctx,
drbg_get_entropy, drbg_free_entropy, 20,
drbg_get_entropy, drbg_free_entropy);
FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
drbg_rand_seed, drbg_rand_add);
/* Personalisation string: a string followed by date time vector */
strcpy((char *)pers, "OpenSSL DRBG2.0");
plen = drbg_get_adin(dctx, &p);
memcpy(pers + 16, p, plen);
if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0) {
RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
return 0;
}
FIPS_rand_set_method(FIPS_drbg_method());
return 1;
}
#endif

Binary file not shown.

View File

@@ -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
@@ -115,69 +115,65 @@
#if defined (OPENSSL_SYS_NETWARE)
#if defined(NETWARE_LIBC)
#include <nks/thread.h>
#else
#include <nwthread.h>
#endif
# if defined(NETWARE_LIBC)
# include <nks/thread.h>
# else
# include <nwthread.h>
# endif
extern int GetProcessSwitchCount(void);
#if !defined(NETWARE_LIBC) || (CURRENT_NDK_THRESHOLD < 509220000)
extern void *RunningProcess; /* declare here same as found in newer NDKs */
# if !defined(NETWARE_LIBC) || (CURRENT_NDK_THRESHOLD < 509220000)
extern void *RunningProcess; /* declare here same as found in newer NDKs */
extern unsigned long GetSuperHighResolutionTimer(void);
#endif
# endif
/* the FAQ indicates we need to provide at least 20 bytes (160 bits) of seed
*/
/*
* the FAQ indicates we need to provide at least 20 bytes (160 bits) of
* seed
*/
int RAND_poll(void)
{
unsigned long l;
unsigned long tsc;
int i;
unsigned long l;
unsigned long tsc;
int i;
/* There are several options to gather miscellaneous data
* but for now we will loop checking the time stamp counter (rdtsc) and
* the SuperHighResolutionTimer. Each iteration will collect 8 bytes
* of data but it is treated as only 1 byte of entropy. The call to
* ThreadSwitchWithDelay() will introduce additional variability into
* the data returned by rdtsc.
*
* Applications can agument the seed material by adding additional
* stuff with RAND_add() and should probably do so.
*/
l = GetProcessSwitchCount();
RAND_add(&l,sizeof(l),1);
/* need to cast the void* to unsigned long here */
l = (unsigned long)RunningProcess;
RAND_add(&l,sizeof(l),1);
/*
* There are several options to gather miscellaneous data but for now we
* will loop checking the time stamp counter (rdtsc) and the
* SuperHighResolutionTimer. Each iteration will collect 8 bytes of data
* but it is treated as only 1 byte of entropy. The call to
* ThreadSwitchWithDelay() will introduce additional variability into the
* data returned by rdtsc. Applications can agument the seed material by
* adding additional stuff with RAND_add() and should probably do so.
*/
l = GetProcessSwitchCount();
RAND_add(&l, sizeof(l), 1);
for( i=2; i<ENTROPY_NEEDED; i++)
{
#ifdef __MWERKS__
asm
{
rdtsc
mov tsc, eax
}
#elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
asm volatile("rdtsc":"=a"(tsc)::"edx");
#endif
/* need to cast the void* to unsigned long here */
l = (unsigned long)RunningProcess;
RAND_add(&l, sizeof(l), 1);
RAND_add(&tsc, sizeof(tsc), 1);
for (i = 2; i < ENTROPY_NEEDED; i++) {
# ifdef __MWERKS__
asm {
rdtsc mov tsc, eax}
# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
asm volatile ("rdtsc":"=a" (tsc)::"edx");
# endif
l = GetSuperHighResolutionTimer();
RAND_add(&l, sizeof(l), 0);
RAND_add(&tsc, sizeof(tsc), 1);
l = GetSuperHighResolutionTimer();
RAND_add(&l, sizeof(l), 0);
# if defined(NETWARE_LIBC)
NXThreadYield();
# else /* NETWARE_CLIB */
ThreadSwitchWithDelay();
NXThreadYield();
# else /* NETWARE_CLIB */
ThreadSwitchWithDelay();
# endif
}
}
return 1;
return 1;
}
#endif
#endif

Binary file not shown.

View File

@@ -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
@@ -59,29 +59,32 @@
#ifdef OPENSSL_SYS_OS2
#define INCL_DOSPROCESS
#define INCL_DOSPROFILE
#define INCL_DOSMISC
#define INCL_DOSMODULEMGR
#include <os2.h>
# define INCL_DOSPROCESS
# define INCL_DOSPROFILE
# define INCL_DOSMISC
# define INCL_DOSMODULEMGR
# include <os2.h>
#define CMD_KI_RDCNT (0x63)
# define CMD_KI_RDCNT (0x63)
typedef struct _CPUUTIL {
ULONG ulTimeLow; /* Low 32 bits of time stamp */
ULONG ulTimeHigh; /* High 32 bits of time stamp */
ULONG ulIdleLow; /* Low 32 bits of idle time */
ULONG ulIdleHigh; /* High 32 bits of idle time */
ULONG ulBusyLow; /* Low 32 bits of busy time */
ULONG ulBusyHigh; /* High 32 bits of busy time */
ULONG ulIntrLow; /* Low 32 bits of interrupt time */
ULONG ulTimeLow; /* Low 32 bits of time stamp */
ULONG ulTimeHigh; /* High 32 bits of time stamp */
ULONG ulIdleLow; /* Low 32 bits of idle time */
ULONG ulIdleHigh; /* High 32 bits of idle time */
ULONG ulBusyLow; /* Low 32 bits of busy time */
ULONG ulBusyHigh; /* High 32 bits of busy time */
ULONG ulIntrLow; /* Low 32 bits of interrupt time */
ULONG ulIntrHigh; /* High 32 bits of interrupt time */
} CPUUTIL;
#ifndef __KLIBC__
APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, ULONG ulParm2, ULONG ulParm3) = NULL;
APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz) = NULL;
#endif
# ifndef __KLIBC__
APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1,
ULONG ulParm2, ULONG ulParm3) = NULL;
APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid,
ULONG _res_, PVOID buf, ULONG bufsz) =
NULL;
# endif
HMODULE hDoscalls = 0;
int RAND_poll(void)
@@ -91,56 +94,70 @@ int RAND_poll(void)
ULONG SysVars[QSV_FOREGROUND_PROCESS];
if (hDoscalls == 0) {
ULONG rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", &hDoscalls);
ULONG rc =
DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS",
&hDoscalls);
#ifndef __KLIBC__
# ifndef __KLIBC__
if (rc == 0) {
rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
rc = DosQueryProcAddr(hDoscalls, 976, NULL,
(PFN *) & DosPerfSysCall);
if (rc)
DosPerfSysCall = NULL;
rc = DosQueryProcAddr(hDoscalls, 368, NULL, (PFN *)&DosQuerySysState);
rc = DosQueryProcAddr(hDoscalls, 368, NULL,
(PFN *) & DosQuerySysState);
if (rc)
DosQuerySysState = NULL;
}
#endif
# endif
}
/* Sample the hi-res timer, runs at around 1.1 MHz */
DosTmrQueryTime(&qwTime);
RAND_add(&qwTime, sizeof(qwTime), 2);
/* Sample a bunch of system variables, includes various process & memory statistics */
/*
* Sample a bunch of system variables, includes various process & memory
* statistics
*/
DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars));
RAND_add(SysVars, sizeof(SysVars), 4);
/* If available, sample CPU registers that count at CPU MHz
* Only fairly new CPUs (PPro & K6 onwards) & OS/2 versions support this
/*
* If available, sample CPU registers that count at CPU MHz Only fairly
* new CPUs (PPro & K6 onwards) & OS/2 versions support this
*/
if (DosPerfSysCall) {
CPUUTIL util;
if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) {
if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG) & util, 0, 0) == 0) {
RAND_add(&util, sizeof(util), 10);
}
else {
#ifndef __KLIBC__
} else {
# ifndef __KLIBC__
DosPerfSysCall = NULL;
#endif
# endif
}
}
/* DosQuerySysState() gives us a huge quantity of process, thread, memory & handle stats */
/*
* DosQuerySysState() gives us a huge quantity of process, thread, memory
* & handle stats
*/
if (DosQuerySysState) {
char *buffer = OPENSSL_malloc(256 * 1024);
if (!buffer)
return 0;
if (DosQuerySysState(0x1F, 0, 0, 0, buffer, 256 * 1024) == 0) {
/* First 4 bytes in buffer is a pointer to the thread count
* there should be at least 1 byte of entropy per thread
/*
* First 4 bytes in buffer is a pointer to the thread count there
* should be at least 1 byte of entropy per thread
*/
RAND_add(buffer, 256 * 1024, **(ULONG **)buffer);
RAND_add(buffer, 256 * 1024, **(ULONG **) buffer);
}
OPENSSL_free(buffer);
@@ -150,4 +167,4 @@ int RAND_poll(void)
return 0;
}
#endif /* OPENSSL_SYS_OS2 */
#endif /* OPENSSL_SYS_OS2 */

Binary file not shown.

View File

@@ -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,274 +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
# 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.
*/
#ifdef __VOS__
int RAND_poll(void)
{
unsigned char buf[ENTROPY_NEEDED];
pid_t curr_pid;
uid_t curr_uid;
static int first=1;
int i;
long rnd = 0;
struct timespec ts;
unsigned seed;
short int code;
gid_t curr_gid;
pid_t curr_pid;
uid_t curr_uid;
int i, k;
struct timespec ts;
unsigned char v;
/* The VOS random() function starts from a static seed so its
initial value is predictable. If random() returns the
initial value, reseed it with dynamic data. The VOS
real-time clock has a granularity of 1 nsec so it should be
reasonably difficult to predict its exact value. Do not
gratuitously reseed the PRNG because other code in this
process or thread may be using it. */
# 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 */
if (first) {
first = 0;
rnd = random ();
if (rnd == 1804289383) {
clock_gettime (CLOCK_REALTIME, &ts);
curr_pid = getpid();
curr_uid = getuid();
seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid;
srandom (seed);
}
}
/*
* Seed with the gid, pid, and uid, to ensure *some* variation between
* different processes.
*/
for (i = 0; i < sizeof(buf); i++) {
if (i % 4 == 0)
rnd = random();
buf[i] = rnd;
rnd >>= 8;
}
RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
memset(buf, 0, sizeof(buf));
curr_gid = getgid();
RAND_add(&curr_gid, sizeof curr_gid, 1);
curr_gid = 0;
return 1;
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];
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));
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;
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
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. */
# 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];
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; }
/*
* 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;
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;
# 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;
# elif defined(OPENSSL_SYS_LINUX)
/* use poll() */
struct pollfd pset;
if (poll(&pset, 1, usec / 1000) < 0)
usec = 0;
else
try_read = (pset.revents & POLLIN) != 0;
pset.fd = fd;
pset.events = POLLIN;
pset.revents = 0;
#else
/* use select() */
fd_set fset;
struct timeval t;
t.tv_sec = 0;
t.tv_usec = usec;
if (poll(&pset, 1, usec / 1000) < 0)
usec = 0;
else
try_read = (pset.revents & POLLIN) != 0;
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);
# else
/* use select() */
fd_set fset;
struct timeval t;
close(fd);
}
}
#endif /* defined(DEVRANDOM) */
t.tv_sec = 0;
t.tv_usec = usec;
#ifdef DEVRANDOM_EGD
/* Use an EGD socket to read entropy from an EGD or PRNGD entropy
* collecting daemon. */
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);
for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++)
{
int r;
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
r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n,
ENTROPY_NEEDED-n);
if (r > 0)
n += r;
}
#endif /* defined(DEVRANDOM_EGD) */
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;
#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
if (n > 0)
{
RAND_add(tmpbuf,sizeof tmpbuf,(double)n);
OPENSSL_cleanse(tmpbuf,n);
}
#endif
/*
* 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);
/* 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);
close(fd);
}
}
# endif /* defined(DEVRANDOM) */
l=time(NULL);
RAND_add(&l,sizeof(l),0.0);
# ifdef DEVRANDOM_EGD
/*
* Use an EGD socket to read entropy from an EGD or PRNGD entropy
* collecting daemon.
*/
#if defined(OPENSSL_SYS_BEOS)
{
system_info sysInfo;
get_system_info(&sysInfo);
RAND_add(&sysInfo,sizeof(sysInfo),0);
}
#endif
for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED;
egdsocket++) {
int r;
#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
return 1;
#else
return 0;
#endif
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

Binary file not shown.

View File

@@ -1,6 +1,7 @@
/* crypto/rand/rand_vms.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
* project 2000.
/*
* Written by Richard Levitte <richard@levitte.org> for the OpenSSL project
* 2000.
*/
/* ====================================================================
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,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
@@ -61,76 +62,98 @@
#if defined(OPENSSL_SYS_VMS)
#include <descrip.h>
#include <jpidef.h>
#include <ssdef.h>
#include <starlet.h>
#ifdef __DECC
# pragma message disable DOLLARID
#endif
# include <descrip.h>
# include <jpidef.h>
# include <ssdef.h>
# include <starlet.h>
# ifdef __DECC
# pragma message disable DOLLARID
# endif
/*
* Use 32-bit pointers almost everywhere. Define the type to which to cast a
* pointer passed to an external function.
*/
# if __INITIAL_POINTER_SIZE == 64
# define PTR_T __void_ptr64
# pragma pointer_size save
# pragma pointer_size 32
# else /* __INITIAL_POINTER_SIZE == 64 */
# define PTR_T void *
# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
static struct items_data_st {
short length, code; /* length is amount of bytes */
} items_data[] = {
{
4, JPI$_BUFIO
},
{
4, JPI$_CPUTIM
},
{
4, JPI$_DIRIO
},
{
8, JPI$_LOGINTIM
},
{
4, JPI$_PAGEFLTS
},
{
4, JPI$_PID
},
{
4, JPI$_WSSIZE
},
{
0, 0
}
};
static struct items_data_st
{
short length, code; /* length is amount of bytes */
} items_data[] =
{ { 4, JPI$_BUFIO },
{ 4, JPI$_CPUTIM },
{ 4, JPI$_DIRIO },
{ 8, JPI$_LOGINTIM },
{ 4, JPI$_PAGEFLTS },
{ 4, JPI$_PID },
{ 4, JPI$_WSSIZE },
{ 0, 0 }
};
int RAND_poll(void)
{
long pid, iosb[2];
int status = 0;
struct
{
short length, code;
long *buffer;
int *retlen;
} item[32], *pitem;
unsigned char data_buffer[256];
short total_length = 0;
struct items_data_st *pitems_data;
{
long pid, iosb[2];
int status = 0;
struct {
short length, code;
long *buffer;
int *retlen;
} item[32], *pitem;
unsigned char data_buffer[256];
short total_length = 0;
struct items_data_st *pitems_data;
pitems_data = items_data;
pitem = item;
pitems_data = items_data;
pitem = item;
/* Setup */
while (pitems_data->length
&& (total_length + pitems_data->length <= 256))
{
pitem->length = pitems_data->length;
pitem->code = pitems_data->code;
pitem->buffer = (long *)&data_buffer[total_length];
pitem->retlen = 0;
total_length += pitems_data->length;
pitems_data++;
pitem++;
}
pitem->length = pitem->code = 0;
/* Setup */
while (pitems_data->length && (total_length + pitems_data->length <= 256)) {
pitem->length = pitems_data->length;
pitem->code = pitems_data->code;
pitem->buffer = (long *)&data_buffer[total_length];
pitem->retlen = 0;
total_length += pitems_data->length;
pitems_data++;
pitem ++;
}
pitem->length = pitem->code = 0;
/*
* Scan through all the processes in the system and add entropy with
* results from the processes that were possible to look at.
* However, view the information as only half trustable.
*/
pid = -1; /* search context */
while ((status = sys$getjpiw(0, &pid, 0, item, iosb, 0, 0))
!= SS$_NOMOREPROC)
{
if (status == SS$_NORMAL)
{
RAND_add(data_buffer, total_length, total_length/2);
}
}
sys$gettim(iosb);
RAND_add((unsigned char *)iosb, sizeof(iosb), sizeof(iosb)/2);
return 1;
/*
* Scan through all the processes in the system and add entropy with
* results from the processes that were possible to look at.
* However, view the information as only half trustable.
*/
pid = -1; /* search context */
while ((status = sys$getjpiw(0, &pid, 0, item, iosb, 0, 0))
!= SS$_NOMOREPROC) {
if (status == SS$_NORMAL) {
RAND_add((PTR_T) data_buffer, total_length, total_length / 2);
}
}
sys$gettim(iosb);
RAND_add((PTR_T) iosb, sizeof(iosb), sizeof(iosb) / 2);
return 1;
}
#endif

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -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,7 +57,9 @@
*/
/* We need to define this to get macros like S_IFBLK and S_IFCHR */
#define _XOPEN_SOURCE 500
#if !defined(OPENSSL_SYS_VXWORKS)
# define _XOPEN_SOURCE 500
#endif
#include <errno.h>
#include <stdio.h>
@@ -70,255 +72,266 @@
#include <openssl/buffer.h>
#ifdef OPENSSL_SYS_VMS
#include <unixio.h>
# include <unixio.h>
#endif
#ifndef NO_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifndef OPENSSL_NO_POSIX_IO
# include <sys/stat.h>
# include <fcntl.h>
#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));
# 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 (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 defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_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? */
setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
}
if (in == NULL)
goto err;
#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
/*
* this file is a device. we don't want read an infinite number of
* bytes from a random device, nor do we want to use buffered I/O
* because we will waste system entropy.
*/
bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
# ifndef OPENSSL_NO_SETVBUF_IONBF
setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
}
#endif
for (;;)
{
if (bytes > 0)
n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
else
n = BUFSIZE;
i=fread(buf,1,n,in);
if (i <= 0) break;
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);
}

Binary file not shown.

View File

@@ -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 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 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");
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);
}