Botan  2.1.0
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 
12 namespace Botan {
13 
14 /**
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.
21 *
22 * Not implemented by RNGs which access an external RNG, such as the
23 * system PRNG or a hardware RNG.
24 */
25 class BOTAN_DLL Stateful_RNG : public RandomNumberGenerator
26  {
27  public:
28  /**
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
34  */
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)
41  {}
42 
43  /**
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
48  */
49  Stateful_RNG(RandomNumberGenerator& rng, size_t reseed_interval) :
50  m_underlying_rng(&rng),
51  m_reseed_interval(reseed_interval)
52  {}
53 
54  /**
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
58  */
59  Stateful_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval) :
60  m_entropy_sources(&entropy_sources),
61  m_reseed_interval(reseed_interval)
62  {}
63 
64  /**
65  * In this case, automatic reseeding is impossible
66  */
67  Stateful_RNG() : m_reseed_interval(0) {}
68 
69  /**
70  * Consume this input and mark the RNG as initialized regardless
71  * of the length of the input or the current seeded state of
72  * the RNG.
73  */
74  void initialize_with(const uint8_t input[], size_t length);
75 
76  bool is_seeded() const override final;
77 
78  /**
79  * Mark state as requiring a reseed on next use
80  */
81  void force_reseed();
82 
83  void reseed_from_rng(RandomNumberGenerator& rng,
84  size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS) override final;
85 
86  /**
87  * Overrides default implementation and also includes the current
88  * process ID and the reseed counter.
89  */
90  void randomize_with_ts_input(uint8_t output[], size_t output_len) override final;
91 
92  /**
93  * Poll provided sources for up to poll_bits bits of entropy
94  * or until the timeout expires. Returns estimate of the number
95  * of bits collected.
96  */
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;
100 
101  /**
102  * @return intended security level of this DRBG
103  */
104  virtual size_t security_level() const = 0;
105 
106  void clear() override;
107 
108  protected:
109  /**
110  * Called with lock held
111  */
112  void reseed_check();
113 
114  uint32_t last_pid() const { return m_last_pid; }
115 
116  private:
117  // A non-owned and possibly null pointer to shared RNG
118  RandomNumberGenerator* m_underlying_rng = nullptr;
119 
120  // A non-owned and possibly null pointer to a shared Entropy_Source
121  Entropy_Sources* m_entropy_sources = nullptr;
122 
123  const size_t m_reseed_interval;
124  uint32_t m_last_pid = 0;
125 
126  protected:
127  /*
128  * Set to 1 after a successful seeding, then incremented. Reset
129  * to 0 by clear() or a fork. This logic is used even if
130  * automatic reseeding is disabled (via m_reseed_interval = 0)
131  */
132  size_t m_reseed_counter = 0;
133  };
134 
135 }
136 
137 #endif
Definition: bigint.h:619
Stateful_RNG(RandomNumberGenerator &rng, size_t reseed_interval)
Definition: stateful_rng.h:49
Stateful_RNG(Entropy_Sources &entropy_sources, size_t reseed_interval)
Definition: stateful_rng.h:59
Definition: alg_id.cpp:13
Stateful_RNG(RandomNumberGenerator &rng, Entropy_Sources &entropy_sources, size_t reseed_interval)
Definition: stateful_rng.h:35