Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

hmac_drbg.cpp
Go to the documentation of this file.
1 /*
2 * HMAC_DRBG
3 * (C) 2014,2015,2016 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/hmac_drbg.h>
9 #include <algorithm>
10
11 namespace Botan {
12
13 namespace {
14
15 void check_limits(size_t reseed_interval,
16 size_t max_number_of_bytes_per_request)
17 {
18 // SP800-90A permits up to 2^48, but it is not usable on 32 bit
19 // platforms, so we only allow up to 2^24, which is still reasonably high
20 if(reseed_interval == 0 || reseed_interval > static_cast<size_t>(1) << 24)
21 {
22 throw Invalid_Argument("Invalid value for reseed_interval");
23 }
24
25 if(max_number_of_bytes_per_request == 0 || max_number_of_bytes_per_request > 64 * 1024)
26 {
27 throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
28 }
29 }
30
31 }
32
33 HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
34 RandomNumberGenerator& underlying_rng,
35 size_t reseed_interval,
36 size_t max_number_of_bytes_per_request) :
37 Stateful_RNG(underlying_rng, reseed_interval),
38 m_mac(std::move(prf)),
39 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
40 {
41 BOTAN_ASSERT_NONNULL(m_mac);
42
43 check_limits(reseed_interval, max_number_of_bytes_per_request);
44
45 clear();
46 }
47
48 HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
49 RandomNumberGenerator& underlying_rng,
50 Entropy_Sources& entropy_sources,
51 size_t reseed_interval,
52 size_t max_number_of_bytes_per_request) :
53 Stateful_RNG(underlying_rng, entropy_sources, reseed_interval),
54 m_mac(std::move(prf)),
55 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
56 {
57 BOTAN_ASSERT_NONNULL(m_mac);
58
59 check_limits(reseed_interval, max_number_of_bytes_per_request);
60
61 clear();
62 }
63
64 HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
65 Entropy_Sources& entropy_sources,
66 size_t reseed_interval,
67 size_t max_number_of_bytes_per_request) :
68 Stateful_RNG(entropy_sources, reseed_interval),
69 m_mac(std::move(prf)),
70 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
71 {
72 BOTAN_ASSERT_NONNULL(m_mac);
73
74 check_limits(reseed_interval, max_number_of_bytes_per_request);
75
76 clear();
77 }
78
79 HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf) :
80 Stateful_RNG(),
81 m_mac(std::move(prf)),
82 m_max_number_of_bytes_per_request(64*1024)
83 {
84 BOTAN_ASSERT_NONNULL(m_mac);
85 clear();
86 }
87
88 void HMAC_DRBG::clear()
89 {
90 Stateful_RNG::clear();
91
92 const size_t output_length = m_mac->output_length();
93
94 m_V.resize(output_length);
95 for(size_t i = 0; i != m_V.size(); ++i)
96 m_V[i] = 0x01;
97 m_mac->set_key(std::vector<uint8_t>(output_length, 0x00));
98 }
99
100 std::string HMAC_DRBG::name() const
101 {
102 return "HMAC_DRBG(" + m_mac->name() + ")";
103 }
104
105 void HMAC_DRBG::randomize(uint8_t output[], size_t output_len)
106 {
107 randomize_with_input(output, output_len, nullptr, 0);
108 }
109
110 /*
111 * HMAC_DRBG generation
112 * See NIST SP800-90A section 10.1.2.5
113 */
114 void HMAC_DRBG::randomize_with_input(uint8_t output[], size_t output_len,
115 const uint8_t input[], size_t input_len)
116 {
117 while(output_len > 0)
118 {
119 size_t this_req = std::min(m_max_number_of_bytes_per_request, output_len);
120 output_len -= this_req;
121
122 reseed_check();
123
124 if(input_len > 0)
125 {
126 update(input, input_len);
127 }
128
129 while(this_req)
130 {
131 const size_t to_copy = std::min(this_req, m_V.size());
132 m_mac->update(m_V.data(), m_V.size());
133 m_mac->final(m_V.data());
134 copy_mem(output, m_V.data(), to_copy);
135
136 output += to_copy;
137 this_req -= to_copy;
138 }
139
140 update(input, input_len);
141 }
142
143 }
144
145 /*
146 * Reset V and the mac key with new values
147 * See NIST SP800-90A section 10.1.2.2
148 */
149 void HMAC_DRBG::update(const uint8_t input[], size_t input_len)
150 {
151 secure_vector<uint8_t> T(m_V.size());
152 m_mac->update(m_V);
153 m_mac->update(0x00);
154 m_mac->update(input, input_len);
155 m_mac->final(T.data());
156 m_mac->set_key(T);
157
158 m_mac->update(m_V.data(), m_V.size());
159 m_mac->final(m_V.data());
160
161 if(input_len > 0)
162 {
163 m_mac->update(m_V);
164 m_mac->update(0x01);
165 m_mac->update(input, input_len);
166 m_mac->final(T.data());
167 m_mac->set_key(T);
168
169 m_mac->update(m_V.data(), m_V.size());
170 m_mac->final(m_V.data());
171 }
172 }
173
174 void HMAC_DRBG::add_entropy(const uint8_t input[], size_t input_len)
175 {
176 update(input, input_len);
177
178 if(8*input_len >= security_level())
179 {
180 reset_reseed_counter();
181 }
182 }
183
184 size_t HMAC_DRBG::security_level() const
185 {
186 // security strength of the hash function
187 // for pre-image resistance (see NIST SP 800-57)
188 // SHA-160: 128 bits, SHA-224, SHA-512/224: 192 bits,
189 // SHA-256, SHA-512/256, SHA-384, SHA-512: >= 256 bits
190 // NIST SP 800-90A only supports up to 256 bits though
191
192 const size_t output_length = m_mac->output_length();
193
194 if(output_length < 32)
195 {
196 return (output_length - 4) * 8;
197 }
198 else
199 {
200 return 32 * 8;
201 }
202 }
203 }
Botan::HMAC_DRBG::add_entropy
void add_entropy(const uint8_t input[], size_t input_len) override
Definition: hmac_drbg.cpp:174
Botan::Stateful_RNG
Definition: stateful_rng.h:25
Botan::HMAC_DRBG::name
std::string name() const override
Definition: hmac_drbg.cpp:100
Botan::RandomNumberGenerator
Definition: rng.h:24
Botan::HMAC_DRBG::randomize_with_input
void randomize_with_input(uint8_t output[], size_t output_len, const uint8_t input[], size_t input_len) override
Definition: hmac_drbg.cpp:114
std
Definition: bigint.h:1135
Botan::Stateful_RNG::clear
void clear() override
Definition: stateful_rng.cpp:17
Botan::HMAC_DRBG::HMAC_DRBG
HMAC_DRBG(std::unique_ptr< MessageAuthenticationCode > prf)
Definition: hmac_drbg.cpp:79
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::HMAC_DRBG::security_level
size_t security_level() const override
Definition: hmac_drbg.cpp:184
BOTAN_ASSERT_NONNULL
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:107
Botan::HMAC_DRBG::randomize
void randomize(uint8_t output[], size_t output_len) override
Definition: hmac_drbg.cpp:105
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:132
Botan
Definition: alg_id.cpp:13
Botan::Stateful_RNG::reseed_check
void reseed_check()
Definition: stateful_rng.cpp:90
Botan::Stateful_RNG::reset_reseed_counter
void reset_reseed_counter()
Definition: stateful_rng.h:131
Botan::Entropy_Sources
Definition: entropy_src.h:56
T
fe T
Definition: ge.cpp:37
Botan::HMAC_DRBG::clear
void clear() override
Definition: hmac_drbg.cpp:88