Botan 1.10.17
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
11namespace 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*/
39void 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*/
64void 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*/
91void 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*/
116std::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*/
132CMAC::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 encrypt(const byte in[], byte out[]) const
static SecureVector< byte > poly_double(const MemoryRegion< byte > &in, byte polynomial)
Definition cmac.cpp:16
void clear()
Definition cmac.cpp:103
size_t output_length() const
Definition cmac.h:23
std::string name() const
Definition cmac.cpp:116
CMAC(BlockCipher *cipher)
Definition cmac.cpp:132
MessageAuthenticationCode * clone() const
Definition cmac.cpp:124
size_t size() const
Definition secmem.h:29
void copy(const T in[], size_t n)
Definition secmem.h:126
void zeroise(MemoryRegion< T > &vec)
Definition secmem.h:428
void xor_buf(byte out[], const byte in[], size_t length)
Definition xor_buf.h:21
std::invalid_argument Invalid_Argument
Definition exceptn.h:20