Botan 2.19.3
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/cmac.h>
9#include <botan/exceptn.h>
10#include <botan/internal/poly_dbl.h>
11
12namespace Botan {
13
14/*
15* Perform CMAC's multiplication in GF(2^n)
16*/
18 {
19 secure_vector<uint8_t> out(in.size());
20 poly_double_n(out.data(), in.data(), out.size());
21 return out;
22 }
23
24/*
25* Update an CMAC Calculation
26*/
27void CMAC::add_data(const uint8_t input[], size_t length)
28 {
29 const size_t bs = output_length();
30
31 buffer_insert(m_buffer, m_position, input, length);
32 if(m_position + length > bs)
33 {
34 xor_buf(m_state, m_buffer, bs);
35 m_cipher->encrypt(m_state);
36 input += (bs - m_position);
37 length -= (bs - m_position);
38 while(length > bs)
39 {
40 xor_buf(m_state, input, bs);
41 m_cipher->encrypt(m_state);
42 input += bs;
43 length -= bs;
44 }
45 copy_mem(m_buffer.data(), input, length);
46 m_position = 0;
47 }
48 m_position += length;
49 }
50
51/*
52* Finalize an CMAC Calculation
53*/
54void CMAC::final_result(uint8_t mac[])
55 {
56 xor_buf(m_state, m_buffer, m_position);
57
58 if(m_position == output_length())
59 {
60 xor_buf(m_state, m_B, output_length());
61 }
62 else
63 {
64 m_state[m_position] ^= 0x80;
65 xor_buf(m_state, m_P, output_length());
66 }
67
68 m_cipher->encrypt(m_state);
69
70 copy_mem(mac, m_state.data(), output_length());
71
72 zeroise(m_state);
73 zeroise(m_buffer);
74 m_position = 0;
75 }
76
77/*
78* CMAC Key Schedule
79*/
80void CMAC::key_schedule(const uint8_t key[], size_t length)
81 {
82 clear();
83 m_cipher->set_key(key, length);
84 m_cipher->encrypt(m_B);
85 poly_double_n(m_B.data(), m_B.size());
86 poly_double_n(m_P.data(), m_B.data(), m_P.size());
87 }
88
89/*
90* Clear memory of sensitive data
91*/
93 {
94 m_cipher->clear();
95 zeroise(m_state);
96 zeroise(m_buffer);
97 zeroise(m_B);
98 zeroise(m_P);
99 m_position = 0;
100 }
101
102/*
103* Return the name of this type
104*/
105std::string CMAC::name() const
106 {
107 return "CMAC(" + m_cipher->name() + ")";
108 }
109
110/*
111* Return a clone of this object
112*/
114 {
115 return new CMAC(m_cipher->clone());
116 }
117
118/*
119* CMAC Constructor
120*/
122 m_cipher(cipher),
123 m_block_size(m_cipher->block_size())
124 {
125 if(poly_double_supported_size(m_block_size) == false)
126 {
127 throw Invalid_Argument("CMAC cannot use the " +
128 std::to_string(m_block_size * 8) +
129 " bit cipher " + m_cipher->name());
130 }
131
132 m_state.resize(output_length());
133 m_buffer.resize(output_length());
134 m_B.resize(output_length());
135 m_P.resize(output_length());
136 m_position = 0;
137 }
138
139}
size_t output_length() const override
Definition cmac.h:25
void clear() override
Definition cmac.cpp:92
MessageAuthenticationCode * clone() const override
Definition cmac.cpp:113
std::string name() const override
Definition cmac.cpp:105
CMAC(BlockCipher *cipher)
Definition cmac.cpp:121
static secure_vector< uint8_t > poly_double(const secure_vector< uint8_t > &in)
Definition cmac.cpp:17
void zeroise(std::vector< T, Alloc > &vec)
Definition secmem.h:114
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition mem_ops.h:228
void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:133
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition mem_ops.h:262
void poly_double_n(uint8_t out[], const uint8_t in[], size_t n)
Definition poly_dbl.cpp:73
bool poly_double_supported_size(size_t n)
Definition poly_dbl.h:22
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:65