Botan 3.11.0
Crypto and TLS for C&
stateful_rng.cpp
Go to the documentation of this file.
1/*
2* (C) 2016,2020 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/stateful_rng.h>
8
9#include <botan/assert.h>
10#include <botan/exceptn.h>
11#include <botan/internal/os_utils.h>
12
13namespace Botan {
14
17 m_reseed_counter = 0;
18 m_last_pid = 0;
20}
21
24 m_reseed_counter = 0;
25}
26
29 return m_reseed_counter > 0;
30}
31
32void Stateful_RNG::initialize_with(std::span<const uint8_t> input) {
34
35 clear();
36 add_entropy(input);
37}
38
39void Stateful_RNG::generate_batched_output(std::span<uint8_t> output, std::span<const uint8_t> input) {
40 BOTAN_ASSERT_NOMSG(!output.empty());
41
42 const size_t max_per_request = max_number_of_bytes_per_request();
43
44 if(max_per_request == 0) {
45 // no limit
47 this->generate_output(output, input);
48 } else {
49 while(!output.empty()) {
50 const size_t this_req = std::min(max_per_request, output.size());
51
53 this->generate_output(output.subspan(0, this_req), input);
54
55 // only include the input for the first iteration
56 input = {};
57
58 output = output.subspan(this_req);
59 }
60 }
61}
62
63void Stateful_RNG::fill_bytes_with_input(std::span<uint8_t> output, std::span<const uint8_t> input) {
65
66 if(output.empty()) {
67 // Special case for exclusively adding entropy to the stateful RNG.
68 this->update(input);
69
70 if(8 * input.size() >= security_level()) {
71 reset_reseed_counter();
72 }
73 } else {
74 generate_batched_output(output, input);
75 }
76}
77
78size_t Stateful_RNG::reseed_from_sources(Entropy_Sources& srcs, size_t poll_bits) {
80
81 const size_t bits_collected = RandomNumberGenerator::reseed_from_sources(srcs, poll_bits);
82
83 if(bits_collected >= security_level()) {
84 reset_reseed_counter();
85 }
86
87 return bits_collected;
88}
89
92
94
95 if(poll_bits >= security_level()) {
96 reset_reseed_counter();
97 }
98}
99
100void Stateful_RNG::reset_reseed_counter() {
101 // Lock is held whenever this function is called
102 m_reseed_counter = 1;
103}
104
106 // Lock is held whenever this function is called
107
108 const uint32_t cur_pid = OS::get_process_id();
109
110 const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid);
111
112 if(is_seeded() == false || fork_detected || (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval)) {
113 m_reseed_counter = 0;
114 m_last_pid = cur_pid;
115
116 if(m_underlying_rng != nullptr) {
117 reseed_from_rng(*m_underlying_rng, security_level());
118 }
119
120 if(m_entropy_sources != nullptr) {
121 reseed_from_sources(*m_entropy_sources, security_level());
122 }
123
124 if(!is_seeded()) {
125 if(fork_detected) {
126 throw Invalid_State("Detected use of fork but cannot reseed DRBG");
127 } else {
128 throw PRNG_Unseeded(name());
129 }
130 }
131 } else {
132 BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded");
133 m_reseed_counter += 1;
134 }
135}
136
137} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
void add_entropy(std::span< const uint8_t > input)
Definition rng.h:98
virtual size_t reseed_from_sources(Entropy_Sources &srcs, size_t poll_bits=RandomNumberGenerator::DefaultPollBits)
Definition rng.cpp:52
virtual std::string name() const =0
virtual void reseed_from_rng(RandomNumberGenerator &rng, size_t poll_bits=RandomNumberGenerator::DefaultPollBits)
Definition rng.cpp:64
bool is_seeded() const final
void reseed_from_rng(RandomNumberGenerator &rng, size_t poll_bits=RandomNumberGenerator::DefaultPollBits) final
virtual size_t security_level() const =0
size_t reseed_from_sources(Entropy_Sources &srcs, size_t poll_bits=RandomNumberGenerator::DefaultPollBits) final
virtual void clear_state()=0
virtual void generate_output(std::span< uint8_t > output, std::span< const uint8_t > input)=0
virtual size_t max_number_of_bytes_per_request() const =0
virtual void update(std::span< const uint8_t > input)=0
void initialize_with(std::span< const uint8_t > input)
uint32_t BOTAN_TEST_API get_process_id()
Definition os_utils.cpp:76
secure_vector< T > lock(const std::vector< T > &in)
Definition secmem.h:80
lock_guard< T > lock_guard_type
Definition mutex.h:55