- /* If we don't have enough, try to get more. */
- CRYPTO_THREAD_write_lock(rand_bytes.lock);
- for (i = RAND_POLL_RETRIES; rand_bytes.curr < min_len && --i >= 0; ) {
- CRYPTO_THREAD_unlock(rand_bytes.lock);
- RAND_poll();
- CRYPTO_THREAD_write_lock(rand_bytes.lock);
- }
+ if (drbg->parent != NULL) {
+ size_t bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
+ unsigned char *buffer = rand_pool_add_begin(pool, bytes_needed);
+
+ if (buffer != NULL) {
+ size_t bytes = 0;
+
+ /*
+ * Get random data from parent. Include our address as additional input,
+ * in order to provide some additional distinction between different
+ * DRBG child instances.
+ * Our lock is already held, but we need to lock our parent before
+ * generating bits from it. (Note: taking the lock will be a no-op
+ * if locking if drbg->parent->lock == NULL.)
+ */
+ rand_drbg_lock(drbg->parent);
+ if (RAND_DRBG_generate(drbg->parent,
+ buffer, bytes_needed,
+ prediction_resistance,
+ (unsigned char *)&drbg, sizeof(drbg)) != 0)
+ bytes = bytes_needed;
+ drbg->reseed_next_counter
+ = tsan_load(&drbg->parent->reseed_prop_counter);
+ rand_drbg_unlock(drbg->parent);
+
+ rand_pool_add_end(pool, bytes, 8 * bytes);
+ entropy_available = rand_pool_entropy_available(pool);
+ }