8#include <botan/hmac_drbg.h>
10#include <botan/internal/fmt.h>
17size_t hmac_drbg_security_level(
size_t mac_output_length) {
25 if(mac_output_length < 32) {
26 return (mac_output_length - 4) * 8;
32void check_limits(
size_t reseed_interval,
size_t max_number_of_bytes_per_request) {
35 if(reseed_interval == 0 || reseed_interval >
static_cast<size_t>(1) << 24) {
36 throw Invalid_Argument(
"Invalid value for reseed_interval");
39 if(max_number_of_bytes_per_request == 0 || max_number_of_bytes_per_request > 64 * 1024) {
40 throw Invalid_Argument(
"Invalid value for max_number_of_bytes_per_request");
48 size_t reseed_interval,
49 size_t max_number_of_bytes_per_request) :
51 m_mac(std::move(prf)),
52 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request),
53 m_security_level(hmac_drbg_security_level(m_mac->output_length())) {
64 size_t reseed_interval,
65 size_t max_number_of_bytes_per_request) :
66 Stateful_RNG(underlying_rng, entropy_sources, reseed_interval),
67 m_mac(std::move(prf)),
68 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request),
69 m_security_level(hmac_drbg_security_level(m_mac->output_length())) {
79 size_t reseed_interval,
80 size_t max_number_of_bytes_per_request) :
82 m_mac(std::move(prf)),
83 m_max_number_of_bytes_per_request(max_number_of_bytes_per_request),
84 m_security_level(hmac_drbg_security_level(m_mac->output_length())) {
94 m_mac(std::move(prf)),
95 m_max_number_of_bytes_per_request(64 * 1024),
96 m_security_level(hmac_drbg_security_level(m_mac->output_length())) {
104 m_max_number_of_bytes_per_request(64 * 1024),
105 m_security_level(hmac_drbg_security_level(m_mac->output_length())) {
109void HMAC_DRBG::clear_state() {
111 const size_t output_length = m_mac->output_length();
112 m_V.resize(output_length);
113 m_T.resize(output_length);
116 for(
size_t i = 0; i != m_V.size(); ++i) {
119 m_mac->set_key(std::vector<uint8_t>(m_V.size(), 0x00));
123 return fmt(
"HMAC_DRBG({})", m_mac->name());
130void HMAC_DRBG::generate_output(std::span<uint8_t> output, std::span<const uint8_t> input) {
137 while(!output.empty()) {
138 const size_t to_copy = std::min(output.size(), m_V.size());
141 copy_mem(output.data(), m_V.data(), to_copy);
143 output = output.subspan(to_copy);
153void HMAC_DRBG::update(std::span<const uint8_t> input) {
157 m_mac->update(input);
168 m_mac->update(input);
178 return m_security_level;
#define BOTAN_ASSERT_NOMSG(expr)
#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
int(* update)(CTX *, const void *, CC_LONG len)
std::string fmt(std::string_view format, const T &... args)
constexpr void copy_mem(T *out, const T *in, size_t n)