Botan  2.11.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_PUBLIC_API(2,0) 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  */
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)
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  bool accepts_input() const override final { return true; }
79 
80  /**
81  * Mark state as requiring a reseed on next use
82  */
83  void force_reseed();
84 
85  void reseed_from_rng(RandomNumberGenerator& rng,
86  size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS) override final;
87 
88  /**
89  * Overrides default implementation and also includes the current
90  * process ID and the reseed counter.
91  */
92  void randomize_with_ts_input(uint8_t output[], size_t output_len) override final;
93 
94  /**
95  * Poll provided sources for up to poll_bits bits of entropy
96  * or until the timeout expires. Returns estimate of the number
97  * of bits collected.
98  */
99  size_t reseed(Entropy_Sources& srcs,
100  size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
101  std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override;
102 
103  /**
104  * @return intended security level of this DRBG
105  */
106  virtual size_t security_level() const = 0;
107 
108  /**
109  * Some DRBGs have a notion of the maximum number of bytes per
110  * request. Longer requests (to randomize) will be treated as
111  * multiple requests, and may initiate reseeding multiple times,
112  * depending on the values of max_number_of_bytes_per_request and
113  * reseed_interval(). This function returns zero if the RNG in
114  * question does not have such a notion.
115  *
116  * @return max number of bytes per request (or zero)
117  */
118  virtual size_t max_number_of_bytes_per_request() const = 0;
119 
120  size_t reseed_interval() const { return m_reseed_interval; }
121 
122  void clear() override;
123 
124  protected:
125  void reseed_check();
126 
127  /**
128  * Called by a subclass to notify that a reseed has been
129  * successfully performed.
130  */
131  void reset_reseed_counter() { m_reseed_counter = 1; }
132 
133  private:
134  // A non-owned and possibly null pointer to shared RNG
135  RandomNumberGenerator* m_underlying_rng = nullptr;
136 
137  // A non-owned and possibly null pointer to a shared Entropy_Source
138  Entropy_Sources* m_entropy_sources = nullptr;
139 
140  const size_t m_reseed_interval;
141  uint32_t m_last_pid = 0;
142 
143  /*
144  * Set to 1 after a successful seeding, then incremented. Reset
145  * to 0 by clear() or a fork. This logic is used even if
146  * automatic reseeding is disabled (via m_reseed_interval = 0)
147  */
148  size_t m_reseed_counter = 0;
149  };
150 
151 }
152 
153 #endif
bool RandomNumberGenerator & rng
Definition: numthry.h:176
int(* final)(unsigned char *, CTX *)
class BOTAN_PUBLIC_API(2, 11) Argon2 final class BOTAN_PUBLIC_API(2, 11) Argon2_Family final void size_t output_len
Definition: argon2.h:87
Definition: alg_id.cpp:13
class BOTAN_PUBLIC_API(2, 0) AlgorithmIdentifier final bool BOTAN_PUBLIC_API(2, 0) operator
Name Constraints.
Definition: asn1_obj.h:66
size_t const uint8_t input[]
Definition: base32.h:30
void BlockCipher const uint8_t size_t uint8_t output[]
Definition: package.h:29