8#include <botan/hmac_drbg.h>
15size_t hmac_drbg_security_level(
size_t mac_output_length)
24 if(mac_output_length < 32)
26 return (mac_output_length - 4) * 8;
34void check_limits(
size_t reseed_interval,
35 size_t max_number_of_bytes_per_request)
39 if(reseed_interval == 0 || reseed_interval >
static_cast<size_t>(1) << 24)
41 throw Invalid_Argument(
"Invalid value for reseed_interval");
44 if(max_number_of_bytes_per_request == 0 || max_number_of_bytes_per_request > 64 * 1024)
46 throw Invalid_Argument(
"Invalid value for max_number_of_bytes_per_request");
54 size_t reseed_interval,
55 size_t max_number_of_bytes_per_request) :
57 m_mac(
std::move(prf)),
58 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request),
59 m_security_level(hmac_drbg_security_level(m_mac->output_length()))
71 size_t reseed_interval,
72 size_t max_number_of_bytes_per_request) :
73 Stateful_RNG(underlying_rng, entropy_sources, reseed_interval),
74 m_mac(
std::move(prf)),
75 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request),
76 m_security_level(hmac_drbg_security_level(m_mac->output_length()))
87 size_t reseed_interval,
88 size_t max_number_of_bytes_per_request) :
90 m_mac(
std::move(prf)),
91 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request),
92 m_security_level(hmac_drbg_security_level(m_mac->output_length()))
103 m_mac(
std::move(prf)),
104 m_max_number_of_bytes_per_request(64*1024),
105 m_security_level(hmac_drbg_security_level(m_mac->output_length()))
114 m_max_number_of_bytes_per_request(64 * 1024),
115 m_security_level(hmac_drbg_security_level(m_mac->output_length()))
120void HMAC_DRBG::clear_state()
124 const size_t output_length = m_mac->output_length();
125 m_V.resize(output_length);
128 for(
size_t i = 0; i != m_V.size(); ++i)
130 m_mac->set_key(std::vector<uint8_t>(m_V.size(), 0x00));
135 return "HMAC_DRBG(" + m_mac->name() +
")";
142void HMAC_DRBG::generate_output(uint8_t output[],
size_t output_len,
143 const uint8_t input[],
size_t input_len)
150 while(output_len > 0)
152 const size_t to_copy = std::min(output_len, m_V.size());
153 m_mac->update(m_V.data(), m_V.size());
154 m_mac->final(m_V.data());
155 copy_mem(output, m_V.data(), to_copy);
158 output_len -= to_copy;
168void HMAC_DRBG::update(
const uint8_t input[],
size_t input_len)
170 secure_vector<uint8_t>
T(m_V.size());
173 m_mac->update(input, input_len);
174 m_mac->final(
T.data());
177 m_mac->update(m_V.data(), m_V.size());
178 m_mac->final(m_V.data());
184 m_mac->update(input, input_len);
185 m_mac->final(
T.data());
188 m_mac->update(m_V.data(), m_V.size());
189 m_mac->final(m_V.data());
195 return m_security_level;
#define BOTAN_ASSERT_NONNULL(ptr)
std::string name() const override
size_t security_level() const override
size_t max_number_of_bytes_per_request() const override
HMAC_DRBG(std::unique_ptr< MessageAuthenticationCode > prf)
size_t reseed_interval() const
void clear() override final
int(* update)(CTX *, const void *, CC_LONG len)
void copy_mem(T *out, const T *in, size_t n)