Botan 3.5.0
Crypto and TLS for C&
kmac.cpp
Go to the documentation of this file.
1/*
2* KMAC
3* (C) 2023 Jack Lloyd
4* (C) 2023 Falko Strenzke
5* (C) 2023 René Meusel - Rohde & Schwarz Cybersecurity
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/internal/kmac.h>
11
12#include <botan/internal/cshake_xof.h>
13#include <botan/internal/fmt.h>
14#include <botan/internal/keccak_helpers.h>
15
16namespace Botan {
17
18KMAC::KMAC(std::unique_ptr<cSHAKE_XOF> cshake, size_t output_bit_length) :
19 m_output_bit_length(output_bit_length), m_message_started(false), m_cshake(std::move(cshake)) {
20 BOTAN_ARG_CHECK(m_output_bit_length % 8 == 0, "KMAC output length must be full bytes");
21 BOTAN_ARG_CHECK(m_output_bit_length > 0, "KMAC output length must be at least one byte");
22 BOTAN_ASSERT_NONNULL(m_cshake);
23}
24
25KMAC::~KMAC() = default;
26
28 zap(m_encoded_key);
29 m_message_started = false;
30 m_cshake->clear();
31}
32
33size_t KMAC::output_length() const {
34 return m_output_bit_length / 8;
35}
36
38 // KMAC supports key lengths from zero up to 2²⁰⁴⁰ (2^(2040)) bits:
39 // https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf#page=28
40 //
41 // However, we restrict the key length to 192 bytes in order to avoid allocation of overly
42 // large memory stretches when client code works with the maximal key length. We chose a
43 // boundary that contains the length of the default_salt of the one-step KDM with KMAC128
44 // of 164 bytes. (see NIST SP 800-56C Rev. 2, Section 4.1, Implementation-Dependent Parameters 3.).
45 return Key_Length_Specification(0, 192);
46}
47
49 return !m_encoded_key.empty();
50}
51
52std::string KMAC::provider() const {
53 return m_cshake->provider();
54}
55
56void KMAC::start_msg(std::span<const uint8_t> nonce) {
58 m_cshake->start(nonce);
59 m_cshake->update(m_encoded_key);
60 m_message_started = true;
61}
62
63void KMAC::add_data(std::span<const uint8_t> data) {
64 assert_key_material_set(!m_encoded_key.empty());
65 if(!m_message_started) {
66 start();
67 }
68 m_cshake->update(data);
69}
70
71void KMAC::final_result(std::span<uint8_t> output) {
73 std::array<uint8_t, keccak_max_int_encoding_size()> encoded_output_length_buffer;
74 m_cshake->update(keccak_int_right_encode(encoded_output_length_buffer, m_output_bit_length));
75 m_cshake->output(output.first(output_length()));
76 m_cshake->clear();
77 m_message_started = false;
78}
79
80void KMAC::key_schedule(std::span<const uint8_t> key) {
81 clear();
82 keccak_absorb_padded_strings_encoding(m_encoded_key, m_cshake->block_size(), key);
83}
84
85// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
86
87KMAC128::KMAC128(size_t output_bit_length) : KMAC(std::make_unique<cSHAKE_128_XOF>("KMAC"), output_bit_length) {}
88
89std::string KMAC128::name() const {
90 return fmt("KMAC-128({})", output_length() * 8);
91}
92
93std::unique_ptr<MessageAuthenticationCode> KMAC128::new_object() const {
94 return std::make_unique<KMAC128>(output_length() * 8);
95}
96
97KMAC256::KMAC256(size_t output_bit_length) : KMAC(std::make_unique<cSHAKE_256_XOF>("KMAC"), output_bit_length) {}
98
99std::string KMAC256::name() const {
100 return fmt("KMAC-256({})", output_length() * 8);
101}
102
103std::unique_ptr<MessageAuthenticationCode> KMAC256::new_object() const {
104 return std::make_unique<KMAC256>(output_length() * 8);
105}
106
107} // namespace Botan
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
std::string name() const override
Definition kmac.cpp:89
std::unique_ptr< MessageAuthenticationCode > new_object() const override
Definition kmac.cpp:93
KMAC128(size_t output_bit_length)
Definition kmac.cpp:87
std::string name() const override
Definition kmac.cpp:99
KMAC256(size_t output_bit_length)
Definition kmac.cpp:97
std::unique_ptr< MessageAuthenticationCode > new_object() const override
Definition kmac.cpp:103
KMAC(std::unique_ptr< cSHAKE_XOF > cshake, size_t output_bit_length)
Definition kmac.cpp:18
virtual ~KMAC()
bool has_keying_material() const final
Definition kmac.cpp:48
void clear() final
Definition kmac.cpp:27
size_t output_length() const final
Definition kmac.cpp:33
Key_Length_Specification key_spec() const final
Definition kmac.cpp:37
std::string provider() const final
Definition kmac.cpp:52
void assert_key_material_set() const
Definition sym_algo.h:139
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:117
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
size_t keccak_absorb_padded_strings_encoding(T &sink, size_t padding_mod, Ts... byte_strings)
std::span< const uint8_t > keccak_int_right_encode(std::span< uint8_t > out, size_t x)
constexpr size_t keccak_max_int_encoding_size()