Coverage Report

Created: 2023-09-25 06:34

/src/botan/src/lib/mac/kmac/kmac.cpp
Line
Count
Source (jump to first uncovered line)
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
16
namespace Botan {
17
18
KMAC::KMAC(std::unique_ptr<cSHAKE_XOF> cshake, size_t output_bit_length) :
19
0
      m_output_bit_length(output_bit_length), m_message_started(false), m_cshake(std::move(cshake)) {
20
0
   BOTAN_ARG_CHECK(m_output_bit_length % 8 == 0, "KMAC output length must be full bytes");
21
0
   BOTAN_ARG_CHECK(m_output_bit_length > 0, "KMAC output length must be at least one byte");
22
0
   BOTAN_ASSERT_NONNULL(m_cshake);
23
0
}
24
25
0
KMAC::~KMAC() = default;
26
27
0
void KMAC::clear() {
28
0
   zap(m_encoded_key);
29
0
   m_message_started = false;
30
0
   m_cshake->clear();
31
0
}
32
33
0
size_t KMAC::output_length() const {
34
0
   return m_output_bit_length / 8;
35
0
}
36
37
0
Key_Length_Specification KMAC::key_spec() const {
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 64 bytes in order to avoid allocation of overly
42
   // large memory stretches when client code works with the maximal key length.
43
0
   return Key_Length_Specification(0, 64);
44
0
}
45
46
0
bool KMAC::has_keying_material() const {
47
0
   return !m_encoded_key.empty();
48
0
}
49
50
0
std::string KMAC::provider() const {
51
0
   return m_cshake->provider();
52
0
}
53
54
0
void KMAC::start_msg(const uint8_t nonce[], size_t nonce_len) {
55
0
   assert_key_material_set();
56
0
   m_cshake->start({nonce, nonce_len}, {});
57
0
   m_cshake->update(m_encoded_key);
58
0
   m_message_started = true;
59
0
}
60
61
0
void KMAC::add_data(std::span<const uint8_t> data) {
62
0
   assert_key_material_set(!m_encoded_key.empty());
63
0
   if(!m_message_started) {
64
0
      start();
65
0
   }
66
0
   m_cshake->update(data);
67
0
}
68
69
0
void KMAC::final_result(std::span<uint8_t> output) {
70
0
   assert_key_material_set();
71
0
   std::array<uint8_t, keccak_max_int_encoding_size()> encoded_output_length_buffer;
72
0
   m_cshake->update(keccak_int_right_encode(encoded_output_length_buffer, m_output_bit_length));
73
0
   m_cshake->output(output.first(output_length()));
74
0
   m_cshake->clear();
75
0
   m_message_started = false;
76
0
}
77
78
0
void KMAC::key_schedule(std::span<const uint8_t> key) {
79
0
   clear();
80
0
   keccak_absorb_padded_strings_encoding(m_encoded_key, m_cshake->block_size(), key);
81
0
}
82
83
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
84
85
0
KMAC128::KMAC128(size_t output_bit_length) : KMAC(std::make_unique<cSHAKE_128_XOF>("KMAC"), output_bit_length) {}
86
87
0
std::string KMAC128::name() const {
88
0
   return fmt("KMAC-128({})", output_length() * 8);
89
0
}
90
91
0
std::unique_ptr<MessageAuthenticationCode> KMAC128::new_object() const {
92
0
   return std::make_unique<KMAC128>(output_length() * 8);
93
0
}
94
95
0
KMAC256::KMAC256(size_t output_bit_length) : KMAC(std::make_unique<cSHAKE_256_XOF>("KMAC"), output_bit_length) {}
96
97
0
std::string KMAC256::name() const {
98
0
   return fmt("KMAC-256({})", output_length() * 8);
99
0
}
100
101
0
std::unique_ptr<MessageAuthenticationCode> KMAC256::new_object() const {
102
0
   return std::make_unique<KMAC256>(output_length() * 8);
103
0
}
104
105
}  // namespace Botan