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
the handshake is continued after ssl_verify_cert_chain();
otherwise, if SSL_VERIFY_NONE is set, remaining error codes
*
*/
-#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 NDEBUG
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 ok;
long md_c[2];
#ifndef GETPID_IS_MEANINGLESS
pid_t curr_pid = getpid();
#endif
+ int do_stir_pool = 0;
#ifdef PREDICT
if (rand_predictable)
if (!initialized)
ssleay_rand_initialize();
+ if (!stirred_pool)
+ do_stir_pool = 1;
+
ok = (entropy >= ENTROPY_NEEDED);
if (!ok)
{
* Once we've had enough initial seeding we don't bother to
* adjust the entropy count, though, because we're not ambitious
* to provide *information-theoretic* randomness.
+ *
+ * NOTE: This approach fails if the program forks before
+ * we have enough entropy. Entropy should be collected
+ * in a separate input pool and be transferred to the
+ * output pool only when the entropy limit has been reached.
*/
entropy -= num;
if (entropy < 0)
entropy = 0;
}
+ if (do_stir_pool)
+ {
+ /* 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_num=state_num;
md_c[0] = md_count[0];