Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
10 namespace Botan {
11
12 /*
13 * Perform CMAC's multiplication in GF(2^n)
14 */
15 secure_vector<uint8_t> CMAC::poly_double(const secure_vector<uint8_t>& in)
16 {
17 const bool top_carry = static_cast<bool>((in[0] & 0x80) != 0);
18
19 secure_vector<uint8_t> out = in;
20
21 uint8_t carry = 0;
22 for(size_t i = out.size(); i != 0; --i)
23 {
24 uint8_t temp = out[i-1];
25 out[i-1] = (temp << 1) | carry;
26 carry = (temp >> 7);
27 }
28
29 if(top_carry)
30 {
31 switch(in.size())
32 {
33 case 8:
34 out[out.size()-1] ^= 0x1B;
35 break;
36 case 16:
37 out[out.size()-1] ^= 0x87;
38 break;
39 case 32:
40 out[out.size()-2] ^= 0x4;
41 out[out.size()-1] ^= 0x25;
42 break;
43 case 64:
44 out[out.size()-2] ^= 0x1;
45 out[out.size()-1] ^= 0x25;
46 break;
47 default:
48 throw Exception("Unsupported CMAC size " + std::to_string(in.size()));
49 }
50 }
51
52 return out;
53 }
54
55 /*
56 * Update an CMAC Calculation
57 */
58 void CMAC::add_data(const uint8_t 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.data(), 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(uint8_t 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 uint8_t 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 */
122 void CMAC::clear()
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 */
143 MessageAuthenticationCode* CMAC::clone() const
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 }
Botan::xor_buf
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::CMAC::name
std::string name() const override
Definition: cmac.cpp:135
Botan::Exception
Definition: exceptn.h:21
Botan::CMAC::output_length
size_t output_length() const override
Definition: cmac.h:23
Botan::MessageAuthenticationCode
Definition: mac.h:20
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::CMAC::clone
MessageAuthenticationCode * clone() const override
Definition: cmac.cpp:143
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Botan
Definition: alg_id.cpp:13
Botan::CMAC::clear
void clear() override
Definition: cmac.cpp:122
Botan::CMAC::poly_double
static secure_vector< uint8_t > poly_double(const secure_vector< uint8_t > &in)
Definition: cmac.cpp:15
Botan::CMAC::CMAC
CMAC(BlockCipher *cipher)
Definition: cmac.cpp:151
Botan::buffer_insert
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:133
Botan::BlockCipher
Definition: block_cipher.h:19
Botan::zeroise
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:211