Botan  2.8.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/exceptn.h>
10 #include <botan/internal/poly_dbl.h>
11 
12 namespace 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 */
27 void 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 */
54 void 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 */
80 void 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 */
105 std::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 }
std::string name() const override
Definition: cmac.cpp:105
size_t output_length() const override
Definition: cmac.h:23
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:210
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:174
MessageAuthenticationCode * clone() const override
Definition: cmac.cpp:113
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:108
Definition: alg_id.cpp:13
void clear() override
Definition: cmac.cpp:92
static secure_vector< uint8_t > poly_double(const secure_vector< uint8_t > &in)
Definition: cmac.cpp:17
CMAC(BlockCipher *cipher)
Definition: cmac.cpp:121
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:63
bool poly_double_supported_size(size_t n)
Definition: poly_dbl.h:22
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:183