void ANSI_X931_RNG::randomize(byte out[], size_t length) { if(!is_seeded()) { reseed(BOTAN_RNG_RESEED_POLL_BITS); if(!is_seeded()) throw PRNG_Unseeded(name()); } while(length) { if(m_R_pos == m_R.size()) update_buffer(); const size_t copied = std::min<size_t>(length, m_R.size() - m_R_pos); copy_mem(out, &m_R[m_R_pos], copied); out += copied; length -= copied; m_R_pos += copied; } }
void Stateful_RNG::reseed_check() { const uint32_t cur_pid = OS::get_process_id(); const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid); if(is_seeded() == false || fork_detected || (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval)) { m_reseed_counter = 0; m_last_pid = cur_pid; if(m_underlying_rng) { reseed_from_rng(*m_underlying_rng, security_level()); } if(m_entropy_sources) { reseed(*m_entropy_sources, security_level()); } if(!is_seeded()) { if(fork_detected) throw Exception("Detected use of fork but cannot reseed DRBG"); else throw PRNG_Unseeded(name()); } } else { BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded"); m_reseed_counter += 1; } }
/************************************************* * Add entropy to internal state * *************************************************/ void ANSI_X931_RNG::add_randomness(const byte data[], u32bit length) { prng->add_entropy(data, length); if(is_seeded()) { SecureVector<byte> key(cipher->MAXIMUM_KEYLENGTH); prng->randomize(key, key.size()); cipher->set_key(key, key.size()); prng->randomize(V, V.size()); update_buffer(); } }
/** * Generate a buffer of random bytes */ void ANSI_X931_RNG::randomize(byte out[], u32bit length) { if(!is_seeded()) throw PRNG_Unseeded(name()); while(length) { if(position == R.size()) update_buffer(); const u32bit copied = std::min(length, R.size() - position); copy_mem(out, R + position, copied); out += copied; length -= copied; position += copied; } }