9#include <botan/internal/sp800_56a.h>
11#include <botan/exceptn.h>
12#include <botan/internal/fmt.h>
18template <
class AuxiliaryFunction_t>
19void SP800_56A_kdf(AuxiliaryFunction_t& auxfunc,
22 const uint8_t secret[],
24 const uint8_t label[],
26 const uint64_t kRepsUpperBound = (1ULL << 32);
28 const size_t digest_len = auxfunc.output_length();
30 const size_t reps = key_len / digest_len + ((key_len % digest_len) ? 1 : 0);
32 if(reps >= kRepsUpperBound) {
34 throw Invalid_Argument(
"SP800-56A KDF requested output too large");
38 secure_vector<uint8_t> result;
39 for(
size_t i = 0; i < reps; i++) {
40 auxfunc.update_be(counter++);
41 auxfunc.update(secret, secret_len);
42 auxfunc.update(label, label_len);
43 auxfunc.final(result);
45 const size_t offset = digest_len * i;
46 const size_t len = std::min(result.size(), key_len - offset);
47 copy_mem(&key[offset], result.data(), len);
55 const uint8_t secret[],
59 const uint8_t label[],
60 size_t label_len)
const {
67 SP800_56A_kdf(*m_hash, key, key_len, secret, secret_len, label, label_len);
71 return fmt(
"SP800-56A({})", m_hash->name());
75 return std::make_unique<SP800_56A_Hash>(m_hash->new_object());
80 if(!m_mac->name().starts_with(
"HMAC(")) {
87 const uint8_t secret[],
91 const uint8_t label[],
92 size_t label_len)
const {
99 m_mac->set_key(salt, salt_len);
101 SP800_56A_kdf(*m_mac, key, key_len, secret, secret_len, label, label_len);
105 return fmt(
"SP800-56A({})", m_mac->name());
109 return std::make_unique<SP800_56A_HMAC>(m_mac->new_object());
SP800_56A_HMAC(std::unique_ptr< MessageAuthenticationCode > mac)
std::string name() const override
void kdf(uint8_t key[], size_t key_len, const uint8_t secret[], size_t secret_len, const uint8_t salt[], size_t salt_len, const uint8_t label[], size_t label_len) const override
std::unique_ptr< KDF > new_object() const override
void kdf(uint8_t key[], size_t key_len, const uint8_t secret[], size_t secret_len, const uint8_t salt[], size_t salt_len, const uint8_t label[], size_t label_len) const override
std::string name() const override
std::unique_ptr< KDF > new_object() const override
std::string fmt(std::string_view format, const T &... args)
constexpr void copy_mem(T *out, const T *in, size_t n)