Botan 2.19.2
Crypto and TLS for C&
stateful_rng.h
Go to the documentation of this file.
1/*
2* (C) 2016 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#ifndef BOTAN_STATEFUL_RNG_H_
8#define BOTAN_STATEFUL_RNG_H_
9
10#include <botan/rng.h>
11#include <botan/mutex.h>
12
13namespace Botan {
14
15/**
16* Inherited by RNGs which maintain in-process state, like HMAC_DRBG.
17* On Unix these RNGs are vulnerable to problems with fork, where the
18* RNG state is duplicated, and the parent and child process RNGs will
19* produce identical output until one of them reseeds. Stateful_RNG
20* reseeds itself whenever a fork is detected, or after a set number of
21* bytes have been output.
22*
23* Not implemented by RNGs which access an external RNG, such as the
24* system PRNG or a hardware RNG.
25*/
27 {
28 public:
29 /**
30 * @param rng is a reference to some RNG which will be used
31 * to perform the periodic reseeding
32 * @param entropy_sources will be polled to perform reseeding periodically
33 * @param reseed_interval specifies a limit of how many times
34 * the RNG will be called before automatic reseeding is performed
35 */
37 Entropy_Sources& entropy_sources,
38 size_t reseed_interval) :
39 m_underlying_rng(&rng),
40 m_entropy_sources(&entropy_sources),
41 m_reseed_interval(reseed_interval)
42 {}
43
44 /**
45 * @param rng is a reference to some RNG which will be used
46 * to perform the periodic reseeding
47 * @param reseed_interval specifies a limit of how many times
48 * the RNG will be called before automatic reseeding is performed
49 */
50 Stateful_RNG(RandomNumberGenerator& rng, size_t reseed_interval) :
51 m_underlying_rng(&rng),
52 m_reseed_interval(reseed_interval)
53 {}
54
55 /**
56 * @param entropy_sources will be polled to perform reseeding periodically
57 * @param reseed_interval specifies a limit of how many times
58 * the RNG will be called before automatic reseeding is performed
59 */
60 Stateful_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval) :
61 m_entropy_sources(&entropy_sources),
62 m_reseed_interval(reseed_interval)
63 {}
64
65 /**
66 * In this case, automatic reseeding is impossible
67 */
68 Stateful_RNG() : m_reseed_interval(0) {}
69
70 /**
71 * Consume this input and mark the RNG as initialized regardless
72 * of the length of the input or the current seeded state of
73 * the RNG.
74 */
75 void initialize_with(const uint8_t input[], size_t length);
76
77 bool is_seeded() const override final;
78
79 bool accepts_input() const override final { return true; }
80
81 /**
82 * Mark state as requiring a reseed on next use
83 */
84 void force_reseed();
85
86 void reseed_from_rng(RandomNumberGenerator& rng,
87 size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS) override final;
88
89 void add_entropy(const uint8_t input[], size_t input_len) override final;
90
91 void randomize(uint8_t output[], size_t output_len) override final;
92
93 void randomize_with_input(uint8_t output[], size_t output_len,
94 const uint8_t input[], size_t input_len) override final;
95
96 /**
97 * Overrides default implementation and also includes the current
98 * process ID and the reseed counter.
99 */
100 void randomize_with_ts_input(uint8_t output[], size_t output_len) override final;
101
102 /**
103 * Poll provided sources for up to poll_bits bits of entropy
104 * or until the timeout expires. Returns estimate of the number
105 * of bits collected.
106 */
107 size_t reseed(Entropy_Sources& srcs,
108 size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
109 std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override;
110
111 /**
112 * @return intended security level of this DRBG
113 */
114 virtual size_t security_level() const = 0;
115
116 /**
117 * Some DRBGs have a notion of the maximum number of bytes per
118 * request. Longer requests (to randomize) will be treated as
119 * multiple requests, and may initiate reseeding multiple times,
120 * depending on the values of max_number_of_bytes_per_request and
121 * reseed_interval(). This function returns zero if the RNG in
122 * question does not have such a notion.
123 *
124 * @return max number of bytes per request (or zero)
125 */
126 virtual size_t max_number_of_bytes_per_request() const = 0;
127
128 size_t reseed_interval() const { return m_reseed_interval; }
129
130 void clear() override final;
131
132 protected:
133 void reseed_check();
134
135 virtual void generate_output(uint8_t output[], size_t output_len,
136 const uint8_t input[], size_t input_len) = 0;
137
138 virtual void update(const uint8_t input[], size_t input_len) = 0;
139
140 virtual void clear_state() = 0;
141
142 private:
143 void reset_reseed_counter();
144
145 mutable recursive_mutex_type m_mutex;
146
147 // A non-owned and possibly null pointer to shared RNG
148 RandomNumberGenerator* m_underlying_rng = nullptr;
149
150 // A non-owned and possibly null pointer to a shared Entropy_Source
151 Entropy_Sources* m_entropy_sources = nullptr;
152
153 const size_t m_reseed_interval;
154 uint32_t m_last_pid = 0;
155
156 /*
157 * Set to 1 after a successful seeding, then incremented. Reset
158 * to 0 by clear() or a fork. This logic is used even if
159 * automatic reseeding is disabled (via m_reseed_interval = 0)
160 */
161 size_t m_reseed_counter = 0;
162 };
163
164}
165
166#endif
size_t reseed_interval() const
Definition: stateful_rng.h:128
virtual size_t security_level() const =0
Stateful_RNG(RandomNumberGenerator &rng, size_t reseed_interval)
Definition: stateful_rng.h:50
Stateful_RNG(RandomNumberGenerator &rng, Entropy_Sources &entropy_sources, size_t reseed_interval)
Definition: stateful_rng.h:36
Stateful_RNG(Entropy_Sources &entropy_sources, size_t reseed_interval)
Definition: stateful_rng.h:60
virtual size_t max_number_of_bytes_per_request() const =0
int(* update)(CTX *, const void *, CC_LONG len)
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Definition: alg_id.cpp:13