Coverage Report

Created: 2020-05-23 13:54

/src/botan/build/include/botan/stateful_rng.h
Line
Count
Source (jump to first uncovered line)
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
0
         {}
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
0
         {}
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
0
         {}
63
64
      /**
65
      * In this case, automatic reseeding is impossible
66
      */
67
7
      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
0
      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
0
      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
7
      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