Botan  2.7.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 */
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  /**
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.
113  *
114  * @return max number of bytes per request (or zero)
115  */
116  virtual size_t max_number_of_bytes_per_request() const = 0;
117 
118  size_t reseed_interval() const { return m_reseed_interval; }
119 
120  void clear() override;
121 
122  protected:
123  void reseed_check();
124 
125  /**
126  * Called by a subclass to notify that a reseed has been
127  * successfully performed.
128  */
129  void reset_reseed_counter() { m_reseed_counter = 1; }
130 
131  private:
132  // A non-owned and possibly null pointer to shared RNG
133  RandomNumberGenerator* m_underlying_rng = nullptr;
134 
135  // A non-owned and possibly null pointer to a shared Entropy_Source
136  Entropy_Sources* m_entropy_sources = nullptr;
137 
138  const size_t m_reseed_interval;
139  uint32_t m_last_pid = 0;
140 
141  /*
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)
145  */
146  size_t m_reseed_counter = 0;
147  };
148 
149 }
150 
151 #endif
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
Definition: bigint.h:796
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