Botan 3.13.0
Crypto and TLS for C&
cmac.cpp
Go to the documentation of this file.
1/*
2* CMAC
3* (C) 1999-2007,2014 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/cmac.h>
9
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>
15
16namespace Botan {
17
18/*
19* Update an CMAC Calculation
20*/
21void CMAC::add_data(std::span<const uint8_t> input) {
23
24 const size_t bs = output_length();
25
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);
28
29 if(m_position + input.size() > bs) {
30 xor_buf(m_state, m_buffer, bs);
31 m_cipher->encrypt(m_state);
32
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);
38 }
39
40 const auto remaining = in.take(in.remaining());
41 copy_mem(m_buffer.data(), remaining.data(), remaining.size());
42 m_position = remaining.size();
43 } else {
44 m_position += input.size();
45 }
46}
47
48/*
49* Finalize an CMAC Calculation
50*/
51void CMAC::final_result(std::span<uint8_t> mac) {
52 xor_buf(m_state, m_buffer, m_position);
53
54 if(m_position == output_length()) {
55 xor_buf(m_state, m_B, output_length());
56 } else {
57 m_state[m_position] ^= 0x80;
58 xor_buf(m_state, m_P, output_length());
59 }
60
61 m_cipher->encrypt(m_state);
62
63 copy_mem(mac.data(), m_state.data(), output_length());
64
65 zeroise(m_state);
66 zeroise(m_buffer);
67 m_position = 0;
68}
69
70void CMAC::start_msg(std::span<const uint8_t> nonce) {
71 if(!nonce.empty()) {
72 throw Invalid_IV_Length(name(), nonce.size());
73 }
75
76 zeroise(m_state);
77 zeroise(m_buffer);
78 m_position = 0;
79}
80
82 return m_cipher->has_keying_material();
83}
84
85/*
86* CMAC Key Schedule
87*/
88void CMAC::key_schedule(std::span<const uint8_t> key) {
89 clear();
90 m_cipher->set_key(key);
91 m_cipher->encrypt(m_B);
92 poly_double_n(m_B.data(), m_B.size());
93 poly_double_n(m_P.data(), m_B.data(), m_P.size());
94}
95
96/*
97* Clear memory of sensitive data
98*/
100 m_cipher->clear();
101 zeroise(m_state);
102 zeroise(m_buffer);
103 zeroise(m_B);
104 zeroise(m_P);
105 m_position = 0;
106}
107
108/*
109* Return the name of this type
110*/
111std::string CMAC::name() const {
112 return fmt("CMAC({})", m_cipher->name());
113}
114
115/*
116* Return a new_object of this object
117*/
118std::unique_ptr<MessageAuthenticationCode> CMAC::new_object() const {
119 return std::make_unique<CMAC>(m_cipher->new_object());
120}
121
122/*
123* CMAC Constructor
124*/
125CMAC::CMAC(std::unique_ptr<BlockCipher> cipher) : m_cipher(std::move(cipher)), m_block_size(m_cipher->block_size()) {
126 if(!poly_double_supported_size(m_block_size)) {
127 throw Invalid_Argument(fmt("CMAC cannot use the {} bit cipher {}", m_block_size * 8, m_cipher->name()));
128 }
129
130 m_state.resize(output_length());
131 m_buffer.resize(output_length());
132 m_B.resize(output_length());
133 m_P.resize(output_length());
134 m_position = 0;
135}
136
137} // namespace Botan
size_t output_length() const override
Definition cmac.h:23
CMAC(std::unique_ptr< BlockCipher > cipher)
Definition cmac.cpp:125
std::unique_ptr< MessageAuthenticationCode > new_object() const override
Definition cmac.cpp:118
void clear() override
Definition cmac.cpp:99
bool has_keying_material() const override
Definition cmac.cpp:81
std::string name() const override
Definition cmac.cpp:111
void assert_key_material_set() const
Definition sym_algo.h:180
void zeroise(std::vector< T, Alloc > &vec)
Definition secmem.h:241
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
Definition mem_ops.h:403
void poly_double_n(uint8_t out[], const uint8_t in[], size_t n)
Definition poly_dbl.cpp:81
bool poly_double_supported_size(size_t n)
Definition poly_dbl.h:22