Botan  2.19.1
Crypto and TLS for C++11
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 
13 namespace 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 
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
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Definition: bigint.h:1143
Stateful_RNG(RandomNumberGenerator &rng, size_t reseed_interval)
Definition: stateful_rng.h:50
Stateful_RNG(Entropy_Sources &entropy_sources, size_t reseed_interval)
Definition: stateful_rng.h:60
mutex_type m_mutex
Definition: oids.cpp:84
Definition: alg_id.cpp:13
int(* update)(CTX *, const void *, CC_LONG len)
Stateful_RNG(RandomNumberGenerator &rng, Entropy_Sources &entropy_sources, size_t reseed_interval)
Definition: stateful_rng.h:36