Botan  2.7.0
Crypto and TLS for C++11
hmac_drbg.h
Go to the documentation of this file.
1 /*
2 * HMAC_DRBG (SP800-90A)
3 * (C) 2014,2015,2016 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_HMAC_DRBG_H_
9 #define BOTAN_HMAC_DRBG_H_
10 
11 #include <botan/stateful_rng.h>
12 #include <botan/mac.h>
13 
14 namespace Botan {
15 
16 class Entropy_Sources;
17 
18 /**
19 * HMAC_DRBG from NIST SP800-90A
20 */
21 class BOTAN_PUBLIC_API(2,0) HMAC_DRBG final : public Stateful_RNG
22  {
23  public:
24  /**
25  * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
26  *
27  * Automatic reseeding is disabled completely, as it has no access to
28  * any source for seed material.
29  *
30  * If a fork is detected, the RNG will be unable to reseed itself
31  * in response. In this case, an exception will be thrown rather
32  * than generating duplicated output.
33  */
34  explicit HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf);
35 
36  /**
37  * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
38  *
39  * Automatic reseeding from @p underlying_rng will take place after
40  * @p reseed_interval many requests or after a fork was detected.
41  *
42  * @param prf MAC to use as a PRF
43  * @param underlying_rng is a reference to some RNG which will be used
44  * to perform the periodic reseeding
45  * @param reseed_interval specifies a limit of how many times
46  * the RNG will be called before automatic reseeding is performed
47  * @param max_number_of_bytes_per_request requests that are in size higher
48  * than max_number_of_bytes_per_request are treated as if multiple single
49  * requests of max_number_of_bytes_per_request size had been made.
50  * In theory SP 800-90A requires that we reject any request for a DRBG
51  * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
52  * the caller who wants an output larger than max_number_of_bytes_per_request,
53  * instead treat these requests as if multiple requests of
54  * max_number_of_bytes_per_request size had been made. NIST requires for
55  * HMAC_DRBG that every implementation set a value no more than 2**19 bits
56  * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
57  * example every 512 bit automatic reseeding occurs.
58  */
59  HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
60  RandomNumberGenerator& underlying_rng,
61  size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
62  size_t max_number_of_bytes_per_request = 64 * 1024);
63 
64  /**
65  * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
66  *
67  * Automatic reseeding from @p entropy_sources will take place after
68  * @p reseed_interval many requests or after a fork was detected.
69  *
70  * @param prf MAC to use as a PRF
71  * @param entropy_sources will be polled to perform reseeding periodically
72  * @param reseed_interval specifies a limit of how many times
73  * the RNG will be called before automatic reseeding is performed.
74  * @param max_number_of_bytes_per_request requests that are in size higher
75  * than max_number_of_bytes_per_request are treated as if multiple single
76  * requests of max_number_of_bytes_per_request size had been made.
77  * In theory SP 800-90A requires that we reject any request for a DRBG
78  * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
79  * the caller who wants an output larger than max_number_of_bytes_per_request,
80  * instead treat these requests as if multiple requests of
81  * max_number_of_bytes_per_request size had been made. NIST requires for
82  * HMAC_DRBG that every implementation set a value no more than 2**19 bits
83  * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
84  * example every 512 bit automatic reseeding occurs.
85  */
86  HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
87  Entropy_Sources& entropy_sources,
88  size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
89  size_t max_number_of_bytes_per_request = 64 * 1024);
90 
91  /**
92  * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
93  *
94  * Automatic reseeding from @p underlying_rng and @p entropy_sources
95  * will take place after @p reseed_interval many requests or after
96  * a fork was detected.
97  *
98  * @param prf MAC to use as a PRF
99  * @param underlying_rng is a reference to some RNG which will be used
100  * to perform the periodic reseeding
101  * @param entropy_sources will be polled to perform reseeding periodically
102  * @param reseed_interval specifies a limit of how many times
103  * the RNG will be called before automatic reseeding is performed.
104  * @param max_number_of_bytes_per_request requests that are in size higher
105  * than max_number_of_bytes_per_request are treated as if multiple single
106  * requests of max_number_of_bytes_per_request size had been made.
107  * In theory SP 800-90A requires that we reject any request for a DRBG
108  * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
109  * the caller who wants an output larger than max_number_of_bytes_per_request,
110  * instead treat these requests as if multiple requests of
111  * max_number_of_bytes_per_request size had been made. NIST requires for
112  * HMAC_DRBG that every implementation set a value no more than 2**19 bits
113  * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
114  * example every 512 bit automatic reseeding occurs.
115  */
116  HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
117  RandomNumberGenerator& underlying_rng,
118  Entropy_Sources& entropy_sources,
119  size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
120  size_t max_number_of_bytes_per_request = 64 * 1024);
121 
122  /**
123  * Constructor taking a string for the hash
124  */
125  explicit HMAC_DRBG(const std::string& hmac_hash) :
126  Stateful_RNG(),
127  m_mac(MessageAuthenticationCode::create_or_throw("HMAC(" + hmac_hash + ")")),
128  m_max_number_of_bytes_per_request(64 * 1024)
129  {
130  clear();
131  }
132 
133  std::string name() const override;
134 
135  void clear() override;
136 
137  void randomize(uint8_t output[], size_t output_len) override;
138 
139  void randomize_with_input(uint8_t output[], size_t output_len,
140  const uint8_t input[], size_t input_len) override;
141 
142  void add_entropy(const uint8_t input[], size_t input_len) override;
143 
144  size_t security_level() const override;
145 
146  size_t max_number_of_bytes_per_request() const override
147  { return m_max_number_of_bytes_per_request; }
148 
149  private:
150  void update(const uint8_t input[], size_t input_len);
151 
152  std::unique_ptr<MessageAuthenticationCode> m_mac;
154  const size_t m_max_number_of_bytes_per_request;
155  };
156 
157 }
158 
159 #endif
HMAC_DRBG(const std::string &hmac_hash)
Definition: hmac_drbg.h:125
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
size_t max_number_of_bytes_per_request() const override
Definition: hmac_drbg.h:146
Definition: alg_id.cpp:13
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88