ArduinoLibs
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
EAX.cpp
1 /*
2  * Copyright (C) 2015 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "EAX.h"
24 #include "Crypto.h"
25 #include <string.h>
26 
44  : blockCipher(0)
45 {
46  state.encPosn = 0;
47  state.authPosn = 0;
48  state.authMode = 0;
49 }
50 
51 EAXCommon::~EAXCommon()
52 {
53  clean(state);
54 }
55 
56 size_t EAXCommon::keySize() const
57 {
58  return blockCipher->keySize();
59 }
60 
61 size_t EAXCommon::ivSize() const
62 {
63  // Can use any size but 16 is recommended.
64  return 16;
65 }
66 
67 size_t EAXCommon::tagSize() const
68 {
69  // Tags can be up to 16 bytes in length.
70  return 16;
71 }
72 
73 bool EAXCommon::setKey(const uint8_t *key, size_t len)
74 {
75  return blockCipher->setKey(key, len);
76 }
77 
78 bool EAXCommon::setIV(const uint8_t *iv, size_t len)
79 {
80  // Must have at least 1 byte for the IV.
81  if (!len)
82  return false;
83 
84  // Hash the IV to create the initial nonce for CTR mode. Also creates B.
85  omacInitFirst(state.counter);
86  omacUpdate(state.counter, iv, len);
87  omacFinal(state.counter);
88 
89  // The tag is initially the nonce value. Will be XOR'ed with
90  // the hash of the authenticated and encrypted data later.
91  memcpy(state.tag, state.counter, 16);
92 
93  // Start the hashing context for the authenticated data.
94  omacInit(state.hash, 1);
95  state.encPosn = 16;
96  state.authMode = 1;
97 
98  // The EAX context is ready to go.
99  return true;
100 }
101 
102 void EAXCommon::encrypt(uint8_t *output, const uint8_t *input, size_t len)
103 {
104  if (state.authMode)
105  closeAuthData();
106  encryptCTR(output, input, len);
107  omacUpdate(state.hash, output, len);
108 }
109 
110 void EAXCommon::decrypt(uint8_t *output, const uint8_t *input, size_t len)
111 {
112  if (state.authMode)
113  closeAuthData();
114  omacUpdate(state.hash, input, len);
115  encryptCTR(output, input, len);
116 }
117 
118 void EAXCommon::addAuthData(const void *data, size_t len)
119 {
120  if (state.authMode)
121  omacUpdate(state.hash, (const uint8_t *)data, len);
122 }
123 
124 void EAXCommon::computeTag(void *tag, size_t len)
125 {
126  closeTag();
127  if (len > 16)
128  len = 16;
129  memcpy(tag, state.tag, len);
130 }
131 
132 bool EAXCommon::checkTag(const void *tag, size_t len)
133 {
134  // Can never match if the expected tag length is too long.
135  if (len > 16)
136  return false;
137 
138  // Compute the final tag and check it.
139  closeTag();
140  return secure_compare(state.tag, tag, len);
141 }
142 
144 {
145  clean(state);
146 }
147 
148 // Doubles a 128-bit value in the GF(2^128) field.
149 static void gfDouble(uint8_t value[16])
150 {
151  uint16_t temp = 0;
152  for (uint8_t index = 16; index > 0; ) {
153  --index;
154  temp |= (((uint16_t)(value[index])) << 1);
155  value[index] = (uint8_t)temp;
156  temp >>= 8;
157  }
158  value[15] ^= (uint8_t)((-temp) & 0x87);
159 }
160 
166 void EAXCommon::omacInitFirst(uint8_t omac[16])
167 {
168  // Start the OMAC context for the nonce. We assume that the
169  // data that follows will be at least 1 byte in length so that
170  // we can encrypt the zeroes now to derive the B value.
171  memset(omac, 0, 16);
172  blockCipher->encryptBlock(omac, omac);
173  state.authPosn = 0;
174 
175  // Generate the B value from the encrypted block of zeroes.
176  // We will need this later when finalising the OMAC hashes.
177  memcpy(state.b, omac, 16);
178  gfDouble(state.b);
179 }
180 
187 void EAXCommon::omacInit(uint8_t omac[16], uint8_t t)
188 {
189  memset(omac, 0, 15);
190  omac[15] = t;
191  state.authPosn = 16;
192 }
193 
201 void EAXCommon::omacUpdate(uint8_t omac[16], const uint8_t *data, size_t len)
202 {
203  while (len > 0) {
204  // Encrypt the current block if it is already full.
205  if (state.authPosn == 16) {
206  blockCipher->encryptBlock(omac, omac);
207  state.authPosn = 0;
208  }
209 
210  // XOR the incoming data with the current block.
211  uint8_t size = 16 - state.authPosn;
212  if (size > len)
213  size = (uint8_t)len;
214  for (uint8_t index = 0; index < size; ++index)
215  omac[(state.authPosn)++] ^= data[index];
216 
217  // Move onto the next block.
218  len -= size;
219  data += size;
220  }
221 }
222 
228 void EAXCommon::omacFinal(uint8_t omac[16])
229 {
230  // Apply padding if necessary.
231  if (state.authPosn != 16) {
232  // Need padding: XOR with P = 2 * B.
233  uint8_t p[16];
234  memcpy(p, state.b, 16);
235  gfDouble(p);
236  omac[state.authPosn] ^= 0x80;
237  for (uint8_t index = 0; index < 16; ++index)
238  omac[index] ^= p[index];
239  clean(p);
240  } else {
241  // No padding necessary: XOR with B.
242  for (uint8_t index = 0; index < 16; ++index)
243  omac[index] ^= state.b[index];
244  }
245 
246  // Encrypt the hash to get the final OMAC value.
247  blockCipher->encryptBlock(omac, omac);
248 }
249 
254 void EAXCommon::closeAuthData()
255 {
256  // Finalise the OMAC hash and XOR it with the final tag.
257  omacFinal(state.hash);
258  for (uint8_t index = 0; index < 16; ++index)
259  state.tag[index] ^= state.hash[index];
260  state.authMode = 0;
261 
262  // Initialise the hashing context for the ciphertext data.
263  omacInit(state.hash, 2);
264 }
265 
275 void EAXCommon::encryptCTR(uint8_t *output, const uint8_t *input, size_t len)
276 {
277  while (len > 0) {
278  // Do we need to start a new block?
279  if (state.encPosn == 16) {
280  // Encrypt the counter to create the next keystream block.
281  blockCipher->encryptBlock(state.stream, state.counter);
282  state.encPosn = 0;
283 
284  // Increment the counter, taking care not to reveal
285  // any timing information about the starting value.
286  // We iterate through the entire counter region even
287  // if we could stop earlier because a byte is non-zero.
288  uint16_t temp = 1;
289  uint8_t index = 16;
290  while (index > 0) {
291  --index;
292  temp += state.counter[index];
293  state.counter[index] = (uint8_t)temp;
294  temp >>= 8;
295  }
296  }
297 
298  // Encrypt/decrypt the current input block.
299  uint8_t size = 16 - state.encPosn;
300  if (size > len)
301  size = (uint8_t)len;
302  for (uint8_t index = 0; index < size; ++index)
303  output[index] = input[index] ^ state.stream[(state.encPosn)++];
304 
305  // Move onto the next block.
306  len -= size;
307  input += size;
308  output += size;
309  }
310 }
311 
312 void EAXCommon::closeTag()
313 {
314  // If we were only authenticating, then close off auth mode.
315  if (state.authMode)
316  closeAuthData();
317 
318  // Finalise the hash over the ciphertext and XOR with the final tag.
319  omacFinal(state.hash);
320  for (uint8_t index = 0; index < 16; ++index)
321  state.tag[index] ^= state.hash[index];
322 }
323 
bool setIV(const uint8_t *iv, size_t len)
Sets the initialization vector to use for future encryption and decryption operations.
Definition: EAX.cpp:78
void decrypt(uint8_t *output, const uint8_t *input, size_t len)
Decrypts an input buffer and writes the plaintext to an output buffer.
Definition: EAX.cpp:110
size_t tagSize() const
Returns the size of the authentication tag.
Definition: EAX.cpp:67
EAXCommon()
Constructs a new cipher in EAX mode.
Definition: EAX.cpp:43
bool checkTag(const void *tag, size_t len)
Finalizes the decryption process and checks the authentication tag.
Definition: EAX.cpp:132
virtual void encryptBlock(uint8_t *output, const uint8_t *input)=0
Encrypts a single block using this cipher.
void encrypt(uint8_t *output, const uint8_t *input, size_t len)
Encrypts an input buffer and writes the ciphertext to an output buffer.
Definition: EAX.cpp:102
void clear()
Clears all security-sensitive state from this cipher.
Definition: EAX.cpp:143
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: EAX.cpp:73
void computeTag(void *tag, size_t len)
Finalizes the encryption process and computes the authentication tag.
Definition: EAX.cpp:124
virtual bool setKey(const uint8_t *key, size_t len)=0
Sets the key to use for future encryption and decryption operations.
size_t ivSize() const
Size of the initialization vector for this cipher, in bytes.
Definition: EAX.cpp:61
void addAuthData(const void *data, size_t len)
Adds extra data that will be authenticated but not encrypted.
Definition: EAX.cpp:118
size_t keySize() const
Default size of the key for this cipher, in bytes.
Definition: EAX.cpp:56
virtual size_t keySize() const =0
Default size of the key for this block cipher, in bytes.