Botan  1.11.10
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  }
50  }
51 
52  return out;
53  }
54 
55 /*
56 * Update an CMAC Calculation
57 */
58 void CMAC::add_data(const byte input[], size_t length)
59  {
60  buffer_insert(m_buffer, m_position, input, length);
61  if(m_position + length > output_length())
62  {
63  xor_buf(m_state, m_buffer, output_length());
64  m_cipher->encrypt(m_state);
65  input += (output_length() - m_position);
66  length -= (output_length() - m_position);
67  while(length > output_length())
68  {
69  xor_buf(m_state, input, output_length());
70  m_cipher->encrypt(m_state);
71  input += output_length();
72  length -= output_length();
73  }
74  copy_mem(&m_buffer[0], input, length);
75  m_position = 0;
76  }
77  m_position += length;
78  }
79 
80 /*
81 * Finalize an CMAC Calculation
82 */
83 void CMAC::final_result(byte mac[])
84  {
85  xor_buf(m_state, m_buffer, m_position);
86 
87  if(m_position == output_length())
88  {
89  xor_buf(m_state, m_B, output_length());
90  }
91  else
92  {
93  m_state[m_position] ^= 0x80;
94  xor_buf(m_state, m_P, output_length());
95  }
96 
97  m_cipher->encrypt(m_state);
98 
99  for(size_t i = 0; i != output_length(); ++i)
100  mac[i] = m_state[i];
101 
102  zeroise(m_state);
103  zeroise(m_buffer);
104  m_position = 0;
105  }
106 
107 /*
108 * CMAC Key Schedule
109 */
110 void CMAC::key_schedule(const byte key[], size_t length)
111  {
112  clear();
113  m_cipher->set_key(key, length);
114  m_cipher->encrypt(m_B);
115  m_B = poly_double(m_B);
116  m_P = poly_double(m_B);
117  }
118 
119 /*
120 * Clear memory of sensitive data
121 */
123  {
124  m_cipher->clear();
125  zeroise(m_state);
126  zeroise(m_buffer);
127  zeroise(m_B);
128  zeroise(m_P);
129  m_position = 0;
130  }
131 
132 /*
133 * Return the name of this type
134 */
135 std::string CMAC::name() const
136  {
137  return "CMAC(" + m_cipher->name() + ")";
138  }
139 
140 /*
141 * Return a clone of this object
142 */
144  {
145  return new CMAC(m_cipher->clone());
146  }
147 
148 /*
149 * CMAC Constructor
150 */
151 CMAC::CMAC(BlockCipher* cipher) : m_cipher(cipher)
152  {
153  if(m_cipher->block_size() != 8 && m_cipher->block_size() != 16 &&
154  m_cipher->block_size() != 32 && m_cipher->block_size() != 64)
155  {
156  throw Invalid_Argument("CMAC cannot use the " +
157  std::to_string(m_cipher->block_size() * 8) +
158  " bit cipher " + m_cipher->name());
159  }
160 
161  m_state.resize(output_length());
162  m_buffer.resize(output_length());
163  m_B.resize(output_length());
164  m_P.resize(output_length());
165  m_position = 0;
166  }
167 
168 }
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:122
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:151
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:143
std::string name() const
Definition: cmac.cpp:135
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:166