9#include <botan/internal/hmac.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/ct_utils.h>
13#include <botan/internal/fmt.h>
20void HMAC::add_data(std::span<const uint8_t> input) {
22 m_hash->update(input);
28void HMAC::final_result(std::span<uint8_t> mac) {
31 m_hash->update(m_okey);
32 m_hash->update(mac.first(m_hash_output_length));
34 m_hash->update(m_ikey);
43 return m_hash_output_length;
47 return !m_okey.empty();
53void HMAC::key_schedule(std::span<const uint8_t> key) {
54 const uint8_t ipad = 0x36;
55 const uint8_t opad = 0x5C;
59 m_ikey.resize(m_hash_block_size);
60 m_okey.resize(m_hash_block_size);
82 if(key.size() > m_hash_block_size) {
84 m_hash->final(m_ikey.data());
85 }
else if(key.size() >= 20) {
88 copy_mem(std::span{m_ikey}.first(key.size()), key);
89 }
else if(!key.empty()) {
90 for(
size_t i = 0, i_mod_length = 0; i != m_hash_block_size; ++i) {
96 i_mod_length = needs_reduction.select(0, i_mod_length);
97 const uint8_t kb = key[i_mod_length];
100 m_ikey[i] =
static_cast<uint8_t
>(in_range.if_set_return(kb));
105 for(
size_t i = 0; i != m_hash_block_size; ++i) {
107 m_okey[i] = m_ikey[i] ^ ipad ^ opad;
110 m_hash->update(m_ikey);
126 return fmt(
"HMAC({})", m_hash->name());
133 return std::make_unique<HMAC>(m_hash->new_object());
140 m_hash(std::move(hash)),
142 m_hash_block_size(m_hash->hash_block_size()) {
143 BOTAN_ARG_CHECK(m_hash_block_size >= m_hash_output_length,
"HMAC is not compatible with this hash function");
#define BOTAN_ARG_CHECK(expr, msg)
static constexpr Mask< T > is_lte(T x, T y)
static constexpr Mask< T > is_lt(T x, T y)
bool has_keying_material() const override
size_t output_length() const override
std::string name() const override
std::unique_ptr< MessageAuthenticationCode > new_object() const override
Key_Length_Specification key_spec() const override
HMAC(std::unique_ptr< HashFunction > hash)
void assert_key_material_set() const
void zap(std::vector< T, Alloc > &vec)
std::string fmt(std::string_view format, const T &... args)
constexpr void copy_mem(T *out, const T *in, size_t n)
constexpr void clear_mem(T *ptr, size_t n)