4
* Botan is released under the Simplified BSD License (see license.txt)
7
#ifndef BOTAN_STATEFUL_RNG_H_
8
#define BOTAN_STATEFUL_RNG_H_
10
#include <botan/rng.h>
15
* Inherited by RNGs which maintain in-process state, like HMAC_DRBG.
16
* On Unix these RNGs are vulnerable to problems with fork, where the
17
* RNG state is duplicated, and the parent and child process RNGs will
18
* produce identical output until one of them reseeds. Stateful_RNG
19
* reseeds itself whenever a fork is detected, or after a set number of
20
* bytes have been output.
22
* Not implemented by RNGs which access an external RNG, such as the
23
* system PRNG or a hardware RNG.
25
class BOTAN_PUBLIC_API(2,0) Stateful_RNG : public RandomNumberGenerator
29
* @param rng is a reference to some RNG which will be used
30
* to perform the periodic reseeding
31
* @param entropy_sources will be polled to perform reseeding periodically
32
* @param reseed_interval specifies a limit of how many times
33
* the RNG will be called before automatic reseeding is performed
35
Stateful_RNG(RandomNumberGenerator& rng,
36
Entropy_Sources& entropy_sources,
37
size_t reseed_interval) :
38
m_underlying_rng(&rng),
39
m_entropy_sources(&entropy_sources),
40
m_reseed_interval(reseed_interval)
44
* @param rng is a reference to some RNG which will be used
45
* to perform the periodic reseeding
46
* @param reseed_interval specifies a limit of how many times
47
* the RNG will be called before automatic reseeding is performed
49
Stateful_RNG(RandomNumberGenerator& rng, size_t reseed_interval) :
50
m_underlying_rng(&rng),
51
m_reseed_interval(reseed_interval)
55
* @param entropy_sources will be polled to perform reseeding periodically
56
* @param reseed_interval specifies a limit of how many times
57
* the RNG will be called before automatic reseeding is performed
59
Stateful_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval) :
60
m_entropy_sources(&entropy_sources),
61
m_reseed_interval(reseed_interval)
65
* In this case, automatic reseeding is impossible
67
Stateful_RNG() : m_reseed_interval(0) {}
70
* Consume this input and mark the RNG as initialized regardless
71
* of the length of the input or the current seeded state of
74
void initialize_with(const uint8_t input[], size_t length);
76
bool is_seeded() const override final;
79
* Mark state as requiring a reseed on next use
83
void reseed_from_rng(RandomNumberGenerator& rng,
84
size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS) override final;
87
* Overrides default implementation and also includes the current
88
* process ID and the reseed counter.
90
void randomize_with_ts_input(uint8_t output[], size_t output_len) override final;
93
* Poll provided sources for up to poll_bits bits of entropy
94
* or until the timeout expires. Returns estimate of the number
97
size_t reseed(Entropy_Sources& srcs,
98
size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
99
std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override;
102
* @return intended security level of this DRBG
104
virtual size_t security_level() const = 0;
107
* Some DRBGs have a notion of the maximum number of bytes per
108
* request. Longer requests (to randomize) will be treated as
109
* multiple requests, and may initiate reseeding multiple times,
110
* depending on the values of max_number_of_bytes_per_request and
111
* reseed_interval(). This function returns zero if the RNG in
112
* question does not have such a notion.
114
* @return max number of bytes per request (or zero)
116
virtual size_t max_number_of_bytes_per_request() const = 0;
118
size_t reseed_interval() const { return m_reseed_interval; }
120
void clear() override;
126
* Called by a subclass to notify that a reseed has been
127
* successfully performed.
129
void reset_reseed_counter() { m_reseed_counter = 1; }
132
// A non-owned and possibly null pointer to shared RNG
133
RandomNumberGenerator* m_underlying_rng = nullptr;
135
// A non-owned and possibly null pointer to a shared Entropy_Source
136
Entropy_Sources* m_entropy_sources = nullptr;
138
const size_t m_reseed_interval;
139
uint32_t m_last_pid = 0;
142
* Set to 1 after a successful seeding, then incremented. Reset
143
* to 0 by clear() or a fork. This logic is used even if
144
* automatic reseeding is disabled (via m_reseed_interval = 0)
146
size_t m_reseed_counter = 0;