Botan  1.10.9
cmac.cpp
Go to the documentation of this file.
1 /*
2 * CMAC
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/cmac.h>
9 #include <botan/internal/xor_buf.h>
10 
11 namespace Botan {
12 
13 /*
14 * Perform CMAC's multiplication in GF(2^n)
15 */
17  byte polynomial)
18  {
19  const byte poly_xor = (in[0] & 0x80) ? polynomial : 0;
20 
21  SecureVector<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  out[out.size()-1] ^= poly_xor;
32 
33  return out;
34  }
35 
36 /*
37 * Update an CMAC Calculation
38 */
39 void CMAC::add_data(const byte input[], size_t length)
40  {
41  buffer.copy(position, input, length);
42  if(position + length > output_length())
43  {
44  xor_buf(state, buffer, output_length());
45  e->encrypt(state);
46  input += (output_length() - position);
47  length -= (output_length() - position);
48  while(length > output_length())
49  {
50  xor_buf(state, input, output_length());
51  e->encrypt(state);
52  input += output_length();
53  length -= output_length();
54  }
55  buffer.copy(input, length);
56  position = 0;
57  }
58  position += length;
59  }
60 
61 /*
62 * Finalize an CMAC Calculation
63 */
64 void CMAC::final_result(byte mac[])
65  {
66  xor_buf(state, buffer, position);
67 
68  if(position == output_length())
69  {
70  xor_buf(state, B, output_length());
71  }
72  else
73  {
74  state[position] ^= 0x80;
75  xor_buf(state, P, output_length());
76  }
77 
78  e->encrypt(state);
79 
80  for(size_t i = 0; i != output_length(); ++i)
81  mac[i] = state[i];
82 
83  zeroise(state);
84  zeroise(buffer);
85  position = 0;
86  }
87 
88 /*
89 * CMAC Key Schedule
90 */
91 void CMAC::key_schedule(const byte key[], size_t length)
92  {
93  clear();
94  e->set_key(key, length);
95  e->encrypt(B);
96  B = poly_double(B, polynomial);
97  P = poly_double(B, polynomial);
98  }
99 
100 /*
101 * Clear memory of sensitive data
102 */
104  {
105  e->clear();
106  zeroise(state);
107  zeroise(buffer);
108  zeroise(B);
109  zeroise(P);
110  position = 0;
111  }
112 
113 /*
114 * Return the name of this type
115 */
116 std::string CMAC::name() const
117  {
118  return "CMAC(" + e->name() + ")";
119  }
120 
121 /*
122 * Return a clone of this object
123 */
125  {
126  return new CMAC(e->clone());
127  }
128 
129 /*
130 * CMAC Constructor
131 */
132 CMAC::CMAC(BlockCipher* e_in) : e(e_in)
133  {
134  if(e->block_size() == 16)
135  polynomial = 0x87;
136  else if(e->block_size() == 8)
137  polynomial = 0x1B;
138  else
139  throw Invalid_Argument("CMAC cannot use the cipher " + e->name());
140 
141  state.resize(output_length());
142  buffer.resize(output_length());
143  B.resize(output_length());
144  P.resize(output_length());
145  position = 0;
146  }
147 
148 /*
149 * CMAC Destructor
150 */
152  {
153  delete e;
154  }
155 
156 }
void resize(size_t n)
Definition: secmem.h:211
virtual void clear()=0
virtual BlockCipher * clone() const =0
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
void copy(const T in[], size_t n)
Definition: secmem.h:120
void clear()
Definition: cmac.cpp:103
unsigned char byte
Definition: types.h:22
void set_key(const SymmetricKey &key)
Definition: sym_algo.h:60
MessageAuthenticationCode * mac
Definition: fpe_fe1.cpp:94
size_t output_length() const
Definition: cmac.h:23
size_t size() const
Definition: secmem.h:29
virtual std::string name() const =0
CMAC(BlockCipher *cipher)
Definition: cmac.cpp:132
void encrypt(const byte in[], byte out[]) const
Definition: block_cipher.h:47
MessageAuthenticationCode * clone() const
Definition: cmac.cpp:124
std::string name() const
Definition: cmac.cpp:116
void xor_buf(byte out[], const byte in[], size_t length)
Definition: xor_buf.h:21
void zeroise(MemoryRegion< T > &vec)
Definition: secmem.h:415
static SecureVector< byte > poly_double(const MemoryRegion< byte > &in, byte polynomial)
Definition: cmac.cpp:16
virtual size_t block_size() const =0