Botan 2.1.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 HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
14 RandomNumberGenerator& underlying_rng,
15 size_t reseed_interval,
16 size_t max_number_of_bytes_per_request) :
17 Stateful_RNG(underlying_rng, reseed_interval),
18 m_mac(std::move(prf)),
19 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
20 {
21 BOTAN_ASSERT_NONNULL(m_mac);
22
23 if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
24 {
25 throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
26 }
27
28 clear();
29 }
30
31 HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
32 RandomNumberGenerator& underlying_rng,
33 Entropy_Sources& entropy_sources,
34 size_t reseed_interval,
35 size_t max_number_of_bytes_per_request ) :
36 Stateful_RNG(underlying_rng, entropy_sources, reseed_interval),
37 m_mac(std::move(prf)),
38 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
39 {
40 BOTAN_ASSERT_NONNULL(m_mac);
41
42 if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
43 {
44 throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
45 }
46
47 clear();
48 }
49
50 HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
51 Entropy_Sources& entropy_sources,
52 size_t reseed_interval,
53 size_t max_number_of_bytes_per_request) :
54 Stateful_RNG(entropy_sources, reseed_interval),
55 m_mac(std::move(prf)),
56 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
57 {
58 BOTAN_ASSERT_NONNULL(m_mac);
59
60 if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
61 {
62 throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
63 }
64
65 clear();
66 }
67
68 HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf) :
69 Stateful_RNG(),
70 m_mac(std::move(prf)),
71 m_max_number_of_bytes_per_request(64*1024)
72 {
73 BOTAN_ASSERT_NONNULL(m_mac);
74 clear();
75 }
76
77 void HMAC_DRBG::clear()
78 {
79 Stateful_RNG::clear();
80
81 m_V.resize(m_mac->output_length());
82 for(size_t i = 0; i != m_V.size(); ++i)
83 m_V[i] = 0x01;
84 m_mac->set_key(std::vector<uint8_t>(m_mac->output_length(), 0x00));
85 }
86
87 std::string HMAC_DRBG::name() const
88 {
89 return "HMAC_DRBG(" + m_mac->name() + ")";
90 }
91
92 void HMAC_DRBG::randomize(uint8_t output[], size_t output_len)
93 {
94 randomize_with_input(output, output_len, nullptr, 0);
95 }
96
97 /*
98 * HMAC_DRBG generation
99 * See NIST SP800-90A section 10.1.2.5
100 */
101 void HMAC_DRBG::randomize_with_input(uint8_t output[], size_t output_len,
102 const uint8_t input[], size_t input_len)
103 {
104 while(output_len > 0)
105 {
106 size_t this_req = std::min(m_max_number_of_bytes_per_request, output_len);
107 output_len -= this_req;
108
109 reseed_check();
110
111 if(input_len > 0)
112 {
113 update(input, input_len);
114 }
115
116 while(this_req)
117 {
118 const size_t to_copy = std::min(this_req, m_V.size());
119 m_mac->update(m_V.data(), m_V.size());
120 m_mac->final(m_V.data());
121 copy_mem(output, m_V.data(), to_copy);
122
123 output += to_copy;
124 this_req -= to_copy;
125 }
126
127 update(input, input_len);
128 }
129
130 }
131
132 /*
133 * Reset V and the mac key with new values
134 * See NIST SP800-90A section 10.1.2.2
135 */
136 void HMAC_DRBG::update(const uint8_t input[], size_t input_len)
137 {
138 m_mac->update(m_V);
139 m_mac->update(0x00);
140 m_mac->update(input, input_len);
141 m_mac->set_key(m_mac->final());
142
143 m_mac->update(m_V.data(), m_V.size());
144 m_mac->final(m_V.data());
145
146 if(input_len > 0)
147 {
148 m_mac->update(m_V);
149 m_mac->update(0x01);
150 m_mac->update(input, input_len);
151 m_mac->set_key(m_mac->final());
152
153 m_mac->update(m_V.data(), m_V.size());
154 m_mac->final(m_V.data());
155 }
156 }
157
158 void HMAC_DRBG::add_entropy(const uint8_t input[], size_t input_len)
159 {
160 update(input, input_len);
161
162 if(8*input_len >= security_level())
163 {
164 m_reseed_counter = 1;
165 }
166 }
167
168 size_t HMAC_DRBG::security_level() const
169 {
170 // security strength of the hash function
171 // for pre-image resistance (see NIST SP 800-57)
172 // SHA-160: 128 bits, SHA-224, SHA-512/224: 192 bits,
173 // SHA-256, SHA-512/256, SHA-384, SHA-512: >= 256 bits
174 // NIST SP 800-90A only supports up to 256 bits though
175 if(m_mac->output_length() < 32)
176 {
177 return (m_mac->output_length() - 4) * 8;
178 }
179 else
180 {
181 return 32 * 8;
182 }
183 }
184 }
Botan::HMAC_DRBG::add_entropy
void add_entropy(const uint8_t input[], size_t input_len) override
Definition: hmac_drbg.cpp:158
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::Stateful_RNG
Definition: stateful_rng.h:25
m_mac
std::unique_ptr< MessageAuthenticationCode > m_mac
Definition: fpe_fe1.cpp:88
Botan::HMAC_DRBG::name
std::string name() const override
Definition: hmac_drbg.cpp:87
Botan::RandomNumberGenerator
Definition: rng.h:25
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:101
std
Definition: bigint.h:619
Botan::Stateful_RNG::clear
void clear() override
Definition: stateful_rng.cpp:13
Botan::HMAC_DRBG::HMAC_DRBG
HMAC_DRBG(std::unique_ptr< MessageAuthenticationCode > prf)
Definition: hmac_drbg.cpp:68
Botan::HMAC_DRBG::security_level
size_t security_level() const override
Definition: hmac_drbg.cpp:168
BOTAN_ASSERT_NONNULL
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:79
Botan::HMAC_DRBG::randomize
void randomize(uint8_t output[], size_t output_len) override
Definition: hmac_drbg.cpp:92
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Botan
Definition: alg_id.cpp:13
Botan::Stateful_RNG::reseed_check
void reseed_check()
Definition: stateful_rng.cpp:74
Botan::CT::min
T min(T a, T b)
Definition: ct_utils.h:180
Botan::Entropy_Sources
Definition: entropy_src.h:51
Botan::Stateful_RNG::m_reseed_counter
size_t m_reseed_counter
Definition: stateful_rng.h:132
Botan::HMAC_DRBG::clear
void clear() override
Definition: hmac_drbg.cpp:77