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