Botan  1.11.11
cmac.cpp
Go to the documentation of this file.
1 /*
2 * CMAC
3 * (C) 1999-2007,2014 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/cmac.h>
9 #include <botan/loadstor.h>
10 #include <botan/internal/xor_buf.h>
11 
12 namespace Botan {
13 
14 /*
15 * Perform CMAC's multiplication in GF(2^n)
16 */
18  {
19  const bool top_carry = (in[0] & 0x80);
20 
21  secure_vector<byte> out = in;
22 
23  byte carry = 0;
24  for(size_t i = out.size(); i != 0; --i)
25  {
26  byte temp = out[i-1];
27  out[i-1] = (temp << 1) | carry;
28  carry = (temp >> 7);
29  }
30 
31  if(top_carry)
32  {
33  switch(in.size())
34  {
35  case 8:
36  out[out.size()-1] ^= 0x1B;
37  break;
38  case 16:
39  out[out.size()-1] ^= 0x87;
40  break;
41  case 32:
42  out[out.size()-2] ^= 0x4;
43  out[out.size()-1] ^= 0x25;
44  break;
45  case 64:
46  out[out.size()-2] ^= 0x1;
47  out[out.size()-1] ^= 0x25;
48  break;
49  default:
50  throw std::runtime_error("Unsupported CMAC size " + std::to_string(in.size()));
51  }
52  }
53 
54  return out;
55  }
56 
57 /*
58 * Update an CMAC Calculation
59 */
60 void CMAC::add_data(const byte input[], size_t length)
61  {
62  buffer_insert(m_buffer, m_position, input, length);
63  if(m_position + length > output_length())
64  {
65  xor_buf(m_state, m_buffer, output_length());
66  m_cipher->encrypt(m_state);
67  input += (output_length() - m_position);
68  length -= (output_length() - m_position);
69  while(length > output_length())
70  {
71  xor_buf(m_state, input, output_length());
72  m_cipher->encrypt(m_state);
73  input += output_length();
74  length -= output_length();
75  }
76  copy_mem(&m_buffer[0], input, length);
77  m_position = 0;
78  }
79  m_position += length;
80  }
81 
82 /*
83 * Finalize an CMAC Calculation
84 */
85 void CMAC::final_result(byte mac[])
86  {
87  xor_buf(m_state, m_buffer, m_position);
88 
89  if(m_position == output_length())
90  {
91  xor_buf(m_state, m_B, output_length());
92  }
93  else
94  {
95  m_state[m_position] ^= 0x80;
96  xor_buf(m_state, m_P, output_length());
97  }
98 
99  m_cipher->encrypt(m_state);
100 
101  for(size_t i = 0; i != output_length(); ++i)
102  mac[i] = m_state[i];
103 
104  zeroise(m_state);
105  zeroise(m_buffer);
106  m_position = 0;
107  }
108 
109 /*
110 * CMAC Key Schedule
111 */
112 void CMAC::key_schedule(const byte key[], size_t length)
113  {
114  clear();
115  m_cipher->set_key(key, length);
116  m_cipher->encrypt(m_B);
117  m_B = poly_double(m_B);
118  m_P = poly_double(m_B);
119  }
120 
121 /*
122 * Clear memory of sensitive data
123 */
125  {
126  m_cipher->clear();
127  zeroise(m_state);
128  zeroise(m_buffer);
129  zeroise(m_B);
130  zeroise(m_P);
131  m_position = 0;
132  }
133 
134 /*
135 * Return the name of this type
136 */
137 std::string CMAC::name() const
138  {
139  return "CMAC(" + m_cipher->name() + ")";
140  }
141 
142 /*
143 * Return a clone of this object
144 */
146  {
147  return new CMAC(m_cipher->clone());
148  }
149 
150 /*
151 * CMAC Constructor
152 */
153 CMAC::CMAC(BlockCipher* cipher) : m_cipher(cipher)
154  {
155  if(m_cipher->block_size() != 8 && m_cipher->block_size() != 16 &&
156  m_cipher->block_size() != 32 && m_cipher->block_size() != 64)
157  {
158  throw Invalid_Argument("CMAC cannot use the " +
159  std::to_string(m_cipher->block_size() * 8) +
160  " bit cipher " + m_cipher->name());
161  }
162 
163  m_state.resize(output_length());
164  m_buffer.resize(output_length());
165  m_B.resize(output_length());
166  m_P.resize(output_length());
167  m_position = 0;
168  }
169 
170 }
void xor_buf(T out[], const T in[], size_t length)
Definition: xor_buf.h:23
std::unique_ptr< MessageAuthenticationCode > mac
Definition: fpe_fe1.cpp:89
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:46
void clear()
Definition: cmac.cpp:124
static secure_vector< byte > poly_double(const secure_vector< byte > &in)
Definition: cmac.cpp:17
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:92
uint8_t byte
Definition: types.h:30
size_t output_length() const
Definition: cmac.h:23
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:39
Definition: buf_comp.h:15
CMAC(BlockCipher *cipher)
Definition: cmac.cpp:153
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:103
MessageAuthenticationCode * clone() const
Definition: cmac.cpp:145
std::string name() const
Definition: cmac.cpp:137
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:166