Improve PRNG robustness.
This commit is contained in:
parent
49528751b8
commit
361ee9733f
13
CHANGES
13
CHANGES
@ -4,6 +4,19 @@
|
|||||||
|
|
||||||
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
|
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
|
||||||
|
|
||||||
|
*) When generating bytes for the first time in md_rand.c, 'stir the pool'
|
||||||
|
by seeding with STATE_SIZE dummy bytes (with zero entropy count).
|
||||||
|
(The PRNG state consists of two parts, the large pool 'state' and 'md',
|
||||||
|
where all of 'md' is used each time the PRNG is used, but 'state'
|
||||||
|
is used only indexed by a cyclic counter. As entropy may not be
|
||||||
|
well distributed from the beginning, 'md' is important as a
|
||||||
|
chaining variable. However, the output function chains only half
|
||||||
|
of 'md', i.e. 80 bits. ssleay_rand_add, on the other hand, chains
|
||||||
|
all of 'md', and seeding with STATE_SIZE dummy bytes will result
|
||||||
|
in all of 'state' being rewritten, with the new values depending
|
||||||
|
on virtually all of 'md'. This overcomes the 80 bit limitation.)
|
||||||
|
[Bodo Moeller]
|
||||||
|
|
||||||
*) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
|
*) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
|
||||||
the handshake is continued after ssl_verify_cert_chain();
|
the handshake is continued after ssl_verify_cert_chain();
|
||||||
otherwise, if SSL_VERIFY_NONE is set, remaining error codes
|
otherwise, if SSL_VERIFY_NONE is set, remaining error codes
|
||||||
|
@ -109,7 +109,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ENTROPY_NEEDED 16 /* require 128 bits = 16 bytes of randomness */
|
#define ENTROPY_NEEDED 20 /* require 160 bits = 20 bytes of randomness */
|
||||||
|
|
||||||
#ifndef MD_RAND_DEBUG
|
#ifndef MD_RAND_DEBUG
|
||||||
# ifndef NDEBUG
|
# ifndef NDEBUG
|
||||||
@ -411,6 +411,7 @@ static void ssleay_rand_initialize(void)
|
|||||||
|
|
||||||
static int ssleay_rand_bytes(unsigned char *buf, int 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 i,j,k,st_num,st_idx;
|
||||||
int ok;
|
int ok;
|
||||||
long md_c[2];
|
long md_c[2];
|
||||||
@ -419,6 +420,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
|
|||||||
#ifndef GETPID_IS_MEANINGLESS
|
#ifndef GETPID_IS_MEANINGLESS
|
||||||
pid_t curr_pid = getpid();
|
pid_t curr_pid = getpid();
|
||||||
#endif
|
#endif
|
||||||
|
int do_stir_pool = 0;
|
||||||
|
|
||||||
#ifdef PREDICT
|
#ifdef PREDICT
|
||||||
if (rand_predictable)
|
if (rand_predictable)
|
||||||
@ -455,6 +457,9 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
|
|||||||
if (!initialized)
|
if (!initialized)
|
||||||
ssleay_rand_initialize();
|
ssleay_rand_initialize();
|
||||||
|
|
||||||
|
if (!stirred_pool)
|
||||||
|
do_stir_pool = 1;
|
||||||
|
|
||||||
ok = (entropy >= ENTROPY_NEEDED);
|
ok = (entropy >= ENTROPY_NEEDED);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
@ -464,12 +469,42 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
|
|||||||
* Once we've had enough initial seeding we don't bother to
|
* Once we've had enough initial seeding we don't bother to
|
||||||
* adjust the entropy count, though, because we're not ambitious
|
* adjust the entropy count, though, because we're not ambitious
|
||||||
* to provide *information-theoretic* randomness.
|
* 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;
|
entropy -= num;
|
||||||
if (entropy < 0)
|
if (entropy < 0)
|
||||||
entropy = 0;
|
entropy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_stir_pool)
|
||||||
|
{
|
||||||
|
/* Our output function chains only half of 'md', so we better
|
||||||
|
* make sure that the required entropy gets 'evenly distributed'
|
||||||
|
* through 'state', our randomness pool. The input function
|
||||||
|
* (ssleay_rand_add) chains all of 'md', which makes it more
|
||||||
|
* suitable for this purpose.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int n = STATE_SIZE; /* so that the complete pool gets accessed */
|
||||||
|
while (n > 0)
|
||||||
|
{
|
||||||
|
#if MD_DIGEST_LENGTH > 20
|
||||||
|
# error "Please adjust DUMMY_SEED."
|
||||||
|
#endif
|
||||||
|
#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
|
||||||
|
/* Note that the seed does not matter, it's just that
|
||||||
|
* ssleay_rand_add expects to have something to hash. */
|
||||||
|
ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
|
||||||
|
n -= MD_DIGEST_LENGTH;
|
||||||
|
}
|
||||||
|
if (ok)
|
||||||
|
stirred_pool = 1;
|
||||||
|
}
|
||||||
|
|
||||||
st_idx=state_index;
|
st_idx=state_index;
|
||||||
st_num=state_num;
|
st_num=state_num;
|
||||||
md_c[0] = md_count[0];
|
md_c[0] = md_count[0];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user