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/fmt.h> 
   18#include <botan/internal/kmac.h> 
   26concept hash_or_mac_type = std::is_same_v<T, HashFunction> || std::is_same_v<T, MessageAuthenticationCode>;
 
   31template <hash_or_mac_type HashOrMacType>
 
   32void kdm_internal(std::span<uint8_t> output_buffer,
 
   33                  std::span<const uint8_t> z,
 
   34                  std::span<const uint8_t> fixed_info,
 
   35                  HashOrMacType& hash_or_mac,
 
   36                  const std::function<
void(HashOrMacType&)>& init_h_callback) {
 
   37   size_t l = output_buffer.size() * 8;
 
   42   size_t reps = 
ceil_division(l, hash_or_mac.output_length() * 8);
 
   64   for(
size_t i = 1; i <= reps; i++) {
 
   69      init_h_callback(hash_or_mac);
 
   72      hash_or_mac.update_be(counter);
 
   73      hash_or_mac.update(z);
 
   74      hash_or_mac.update(fixed_info);
 
   75      auto k_i = hash_or_mac.final();
 
   78      result.insert(result.end(), k_i.begin(), k_i.end());
 
   82   copy_mem(output_buffer, std::span(result).subspan(0, output_buffer.size()));
 
   87void SP800_56C_One_Step_Hash::perform_kdf(std::span<uint8_t> key,
 
   88                                          std::span<const uint8_t> secret,
 
   89                                          std::span<const uint8_t> salt,
 
   90                                          std::span<const uint8_t> label)
 const {
 
   91   BOTAN_ARG_CHECK(salt.empty(), 
"SP800-56C KDF with hash does not support using a salt parameter");
 
   92   kdm_internal<HashFunction>(key, secret, label, *m_hash, [](
HashFunction&) {  });
 
   96   return fmt(
"SP800-56A({})", m_hash->name());
 
 
  100   return std::make_unique<SP800_56C_One_Step_Hash>(m_hash->new_object());
 
 
  104      m_mac(std::move(mac)) {
 
  106   if(!m_mac->name().starts_with(
"HMAC(")) {
 
  107      throw Algorithm_Not_Found(
"Only HMAC can be used with SP800_56A_HMAC");
 
 
  111void SP800_56C_One_Step_HMAC::perform_kdf(std::span<uint8_t> key,
 
  112                                          std::span<const uint8_t> secret,
 
  113                                          std::span<const uint8_t> salt,
 
  114                                          std::span<const uint8_t> label)
 const {
 
  129   return fmt(
"SP800-56A({})", m_mac->name());
 
 
  133   return std::make_unique<SP800_56C_One_Step_HMAC>(m_mac->new_object());
 
 
  137void SP800_56A_One_Step_KMAC_Abstract::perform_kdf(std::span<uint8_t> key,
 
  138                                                   std::span<const uint8_t> secret,
 
  139                                                   std::span<const uint8_t> salt,
 
  140                                                   std::span<const uint8_t> label)
 const {
 
  160      kdf_mac.
start(std::array<uint8_t, 3>{
'K', 
'D', 
'F'});
 
  164std::unique_ptr<MessageAuthenticationCode> SP800_56C_One_Step_KMAC128::create_kmac_instance(
 
  165   size_t output_byte_len)
 const {
 
  166   return std::make_unique<KMAC128>(output_byte_len * 8);
 
  169std::unique_ptr<MessageAuthenticationCode> SP800_56C_One_Step_KMAC256::create_kmac_instance(
 
  170   size_t output_byte_len)
 const {
 
  171   return std::make_unique<KMAC256>(output_byte_len * 8);
 
#define BOTAN_ARG_CHECK(expr, msg)
 
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)
 
constexpr void copy_mem(T *out, const T *in, size_t n)
 
std::string fmt(std::string_view format, const T &... args)
 
BOTAN_FORCE_INLINE constexpr T ceil_division(T a, T b)
 
std::vector< T, secure_allocator< T > > secure_vector