8#include <botan/internal/cmac.h>
10#include <botan/exceptn.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/buffer_slicer.h>
13#include <botan/internal/fmt.h>
14#include <botan/internal/poly_dbl.h>
21void CMAC::add_data(std::span<const uint8_t> input) {
26 const size_t initial_fill = std::min(m_buffer.size() - m_position, input.size());
27 copy_mem(m_buffer.data() + m_position, input.data(), initial_fill);
29 if(m_position + input.size() > bs) {
31 m_cipher->encrypt(m_state);
33 BufferSlicer in(input);
34 in.skip(bs - m_position);
35 while(in.remaining() > bs) {
36 xor_buf(m_state, in.take(bs), bs);
37 m_cipher->encrypt(m_state);
40 const auto remaining = in.take(in.remaining());
41 copy_mem(m_buffer.data(), remaining.data(), remaining.size());
42 m_position = remaining.size();
44 m_position += input.size();
51void CMAC::final_result(std::span<uint8_t> mac) {
52 xor_buf(m_state, m_buffer, m_position);
57 m_state[m_position] ^= 0x80;
61 m_cipher->encrypt(m_state);
70void CMAC::start_msg(std::span<const uint8_t> nonce) {
72 throw Invalid_IV_Length(
name(), nonce.size());
82 return m_cipher->has_keying_material();
88void CMAC::key_schedule(std::span<const uint8_t> key) {
90 m_cipher->set_key(key);
91 m_cipher->encrypt(m_B);
112 return fmt(
"CMAC({})", m_cipher->name());
119 return std::make_unique<CMAC>(m_cipher->new_object());
125CMAC::CMAC(std::unique_ptr<BlockCipher> cipher) : m_cipher(std::move(cipher)), m_block_size(m_cipher->block_size()) {
127 throw Invalid_Argument(
fmt(
"CMAC cannot use the {} bit cipher {}", m_block_size * 8, m_cipher->name()));
size_t output_length() const override
CMAC(std::unique_ptr< BlockCipher > cipher)
std::unique_ptr< MessageAuthenticationCode > new_object() const override
bool has_keying_material() const override
std::string name() const override
void assert_key_material_set() const
void zeroise(std::vector< T, Alloc > &vec)
std::string fmt(std::string_view format, const T &... args)
constexpr void copy_mem(T *out, const T *in, size_t n)
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
void poly_double_n(uint8_t out[], const uint8_t in[], size_t n)
bool poly_double_supported_size(size_t n)