12#include <botan/internal/sp800_56c_one_step.h>
14#include <botan/exceptn.h>
15#include <botan/mem_ops.h>
16#include <botan/internal/bit_ops.h>
17#include <botan/internal/buffer_stuffer.h>
18#include <botan/internal/fmt.h>
19#include <botan/internal/kmac.h>
27concept hash_or_mac_type = std::is_same_v<T, HashFunction> || std::is_same_v<T, MessageAuthenticationCode>;
32template <hash_or_mac_type HashOrMacType>
33void kdm_internal(std::span<uint8_t> output_buffer,
34 std::span<const uint8_t> z,
35 std::span<const uint8_t> fixed_info,
36 HashOrMacType& hash_or_mac,
37 const std::function<
void(HashOrMacType&)>& init_h_callback) {
44 if(output_buffer.empty()) {
48 const size_t output_len = output_buffer.size();
49 const size_t h_output_len = hash_or_mac.output_length();
69 for(
size_t i = 1; i <= reps; i++) {
74 init_h_callback(hash_or_mac);
77 hash_or_mac.update_be(counter);
78 hash_or_mac.update(z);
79 hash_or_mac.update(fixed_info);
82 if(k.remaining_capacity() >= h_output_len) {
83 hash_or_mac.final(k.next(h_output_len));
86 const auto k_i = hash_or_mac.final();
87 k.append(std::span{k_i}.first(k.remaining_capacity()));
96void SP800_56C_One_Step_Hash::perform_kdf(std::span<uint8_t> key,
97 std::span<const uint8_t> secret,
98 std::span<const uint8_t> salt,
99 std::span<const uint8_t> label)
const {
100 BOTAN_ARG_CHECK(salt.empty(),
"SP800-56C KDF with hash does not support using a salt parameter");
101 kdm_internal<HashFunction>(key, secret, label, *m_hash, [](
HashFunction&) { });
105 return fmt(
"SP800-56A({})", m_hash->name());
109 return std::make_unique<SP800_56C_One_Step_Hash>(m_hash->new_object());
113 m_mac(std::move(mac)) {
115 if(!m_mac->name().starts_with(
"HMAC(")) {
116 throw Algorithm_Not_Found(
"Only HMAC can be used with SP800_56A_HMAC");
120void SP800_56C_One_Step_HMAC::perform_kdf(std::span<uint8_t> key,
121 std::span<const uint8_t> secret,
122 std::span<const uint8_t> salt,
123 std::span<const uint8_t> label)
const {
138 return fmt(
"SP800-56A({})", m_mac->name());
142 return std::make_unique<SP800_56C_One_Step_HMAC>(m_mac->new_object());
146void SP800_56A_One_Step_KMAC_Abstract::perform_kdf(std::span<uint8_t> key,
147 std::span<const uint8_t> secret,
148 std::span<const uint8_t> salt,
149 std::span<const uint8_t> label)
const {
169 kdf_mac.
start(std::array<uint8_t, 3>{
'K',
'D',
'F'});
173std::unique_ptr<MessageAuthenticationCode> SP800_56C_One_Step_KMAC128::create_kmac_instance(
174 size_t output_byte_len)
const {
175 return std::make_unique<KMAC128>(output_byte_len * 8);
178std::unique_ptr<MessageAuthenticationCode> SP800_56C_One_Step_KMAC256::create_kmac_instance(
179 size_t output_byte_len)
const {
180 return std::make_unique<KMAC256>(output_byte_len * 8);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ARG_CHECK(expr, msg)
Helper class to ease in-place marshalling of concatenated fixed-length values.
void start(std::span< const uint8_t > nonce)
virtual std::unique_ptr< MessageAuthenticationCode > create_kmac_instance(size_t output_byte_len) const =0
virtual size_t default_salt_length() const =0
See SP800-56C Section 4.1 - Implementation-Dependent Parameters 3.
SP800_56C_One_Step_HMAC(std::unique_ptr< MessageAuthenticationCode > mac)
std::string name() const override
std::unique_ptr< KDF > new_object() const override
std::string name() const override
std::unique_ptr< KDF > new_object() const override
void set_key(const OctetString &key)
std::string fmt(std::string_view format, const T &... args)
BOTAN_FORCE_INLINE constexpr T ceil_division(T a, T b)