Botan 3.6.1
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/internal/fmt.h>
12#include <botan/internal/poly_dbl.h>
13#include <botan/internal/stl_util.h>
14
15namespace Botan {
16
17/*
18* Update an CMAC Calculation
19*/
20void CMAC::add_data(std::span<const uint8_t> input) {
21 const size_t bs = output_length();
22
23 const size_t initial_fill = std::min(m_buffer.size() - m_position, input.size());
24 copy_mem(m_buffer.data() + m_position, input.data(), initial_fill);
25
26 if(m_position + input.size() > bs) {
27 xor_buf(m_state, m_buffer, bs);
28 m_cipher->encrypt(m_state);
29
30 BufferSlicer in(input);
31 in.skip(bs - m_position);
32 while(in.remaining() > bs) {
33 xor_buf(m_state, in.take(bs), bs);
34 m_cipher->encrypt(m_state);
35 }
36
37 const auto remaining = in.take(in.remaining());
38 copy_mem(m_buffer.data(), remaining.data(), remaining.size());
39 m_position = remaining.size();
40 } else {
41 m_position += input.size();
42 }
43}
44
45/*
46* Finalize an CMAC Calculation
47*/
48void CMAC::final_result(std::span<uint8_t> mac) {
49 xor_buf(m_state, m_buffer, m_position);
50
51 if(m_position == output_length()) {
52 xor_buf(m_state, m_B, output_length());
53 } else {
54 m_state[m_position] ^= 0x80;
55 xor_buf(m_state, m_P, output_length());
56 }
57
58 m_cipher->encrypt(m_state);
59
60 copy_mem(mac.data(), m_state.data(), output_length());
61
62 zeroise(m_state);
63 zeroise(m_buffer);
64 m_position = 0;
65}
66
68 return m_cipher->has_keying_material();
69}
70
71/*
72* CMAC Key Schedule
73*/
74void CMAC::key_schedule(std::span<const uint8_t> key) {
75 clear();
76 m_cipher->set_key(key);
77 m_cipher->encrypt(m_B);
78 poly_double_n(m_B.data(), m_B.size());
79 poly_double_n(m_P.data(), m_B.data(), m_P.size());
80}
81
82/*
83* Clear memory of sensitive data
84*/
86 m_cipher->clear();
87 zeroise(m_state);
88 zeroise(m_buffer);
89 zeroise(m_B);
90 zeroise(m_P);
91 m_position = 0;
92}
93
94/*
95* Return the name of this type
96*/
97std::string CMAC::name() const {
98 return fmt("CMAC({})", m_cipher->name());
99}
100
101/*
102* Return a new_object of this object
103*/
104std::unique_ptr<MessageAuthenticationCode> CMAC::new_object() const {
105 return std::make_unique<CMAC>(m_cipher->new_object());
106}
107
108/*
109* CMAC Constructor
110*/
111CMAC::CMAC(std::unique_ptr<BlockCipher> cipher) : m_cipher(std::move(cipher)), m_block_size(m_cipher->block_size()) {
112 if(poly_double_supported_size(m_block_size) == false) {
113 throw Invalid_Argument(fmt("CMAC cannot use the {} bit cipher {}", m_block_size * 8, m_cipher->name()));
114 }
115
116 m_state.resize(output_length());
117 m_buffer.resize(output_length());
118 m_B.resize(output_length());
119 m_P.resize(output_length());
120 m_position = 0;
121}
122
123} // namespace Botan
size_t output_length() const override
Definition cmac.h:23
CMAC(std::unique_ptr< BlockCipher > cipher)
Definition cmac.cpp:111
std::unique_ptr< MessageAuthenticationCode > new_object() const override
Definition cmac.cpp:104
void clear() override
Definition cmac.cpp:85
bool has_keying_material() const override
Definition cmac.cpp:67
std::string name() const override
Definition cmac.cpp:97
void zeroise(std::vector< T, Alloc > &vec)
Definition secmem.h:108
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
Definition mem_ops.h:341
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
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146