ArduinoLibs
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
AES256.cpp
1 /*
2  * Copyright (C) 2015,2018 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 "AES.h"
24 #include "Crypto.h"
25 #include <string.h>
26 
41 {
42  rounds = 14;
43  schedule = sched;
44 }
45 
46 AES256::~AES256()
47 {
48  clean(sched);
49 }
50 
55 size_t AES256::keySize() const
56 {
57  return 32;
58 }
59 
60 bool AES256::setKey(const uint8_t *key, size_t len)
61 {
62  if (len != 32)
63  return false;
64 
65  // Copy the key itself into the first 32 bytes of the schedule.
66  uint8_t *schedule = sched;
67  memcpy(schedule, key, 32);
68 
69  // Expand the key schedule until we have 240 bytes of expanded key.
70  uint8_t iteration = 1;
71  uint8_t n = 32;
72  uint8_t w = 8;
73  while (n < 240) {
74  if (w == 8) {
75  // Every 32 bytes (8 words) we need to apply the key schedule core.
76  keyScheduleCore(schedule + 32, schedule + 28, iteration);
77  schedule[32] ^= schedule[0];
78  schedule[33] ^= schedule[1];
79  schedule[34] ^= schedule[2];
80  schedule[35] ^= schedule[3];
81  ++iteration;
82  w = 0;
83  } else if (w == 4) {
84  // At the 16 byte mark we need to apply the S-box.
85  applySbox(schedule + 32, schedule + 28);
86  schedule[32] ^= schedule[0];
87  schedule[33] ^= schedule[1];
88  schedule[34] ^= schedule[2];
89  schedule[35] ^= schedule[3];
90  } else {
91  // Otherwise just XOR the word with the one 32 bytes previous.
92  schedule[32] = schedule[28] ^ schedule[0];
93  schedule[33] = schedule[29] ^ schedule[1];
94  schedule[34] = schedule[30] ^ schedule[2];
95  schedule[35] = schedule[31] ^ schedule[3];
96  }
97 
98  // Advance to the next word in the schedule.
99  schedule += 4;
100  n += 4;
101  ++w;
102  }
103 
104  return true;
105 }
106 
132 // Helper macros.
133 #define LEFT 0
134 #define RIGHT 16
135 #define ENCRYPT(phase) \
136  do { \
137  AESCommon::subBytesAndShiftRows(state2, state1); \
138  AESCommon::mixColumn(state1, state2); \
139  AESCommon::mixColumn(state1 + 4, state2 + 4); \
140  AESCommon::mixColumn(state1 + 8, state2 + 8); \
141  AESCommon::mixColumn(state1 + 12, state2 + 12); \
142  for (posn = 0; posn < 16; ++posn) \
143  state1[posn] ^= schedule[posn + (phase)]; \
144  } while (0)
145 #define DECRYPT(phase) \
146  do { \
147  for (posn = 0; posn < 16; ++posn) \
148  state2[posn] ^= schedule[posn + (phase)]; \
149  AESCommon::inverseMixColumn(state1, state2); \
150  AESCommon::inverseMixColumn(state1 + 4, state2 + 4); \
151  AESCommon::inverseMixColumn(state1 + 8, state2 + 8); \
152  AESCommon::inverseMixColumn(state1 + 12, state2 + 12); \
153  AESCommon::inverseShiftRowsAndSubBytes(state2, state1); \
154  } while (0)
155 #define KCORE(n) \
156  do { \
157  AESCommon::keyScheduleCore(temp, schedule + 28, (n)); \
158  schedule[0] ^= temp[0]; \
159  schedule[1] ^= temp[1]; \
160  schedule[2] ^= temp[2]; \
161  schedule[3] ^= temp[3]; \
162  } while (0)
163 #define KXOR(a, b) \
164  do { \
165  schedule[(a) * 4] ^= schedule[(b) * 4]; \
166  schedule[(a) * 4 + 1] ^= schedule[(b) * 4 + 1]; \
167  schedule[(a) * 4 + 2] ^= schedule[(b) * 4 + 2]; \
168  schedule[(a) * 4 + 3] ^= schedule[(b) * 4 + 3]; \
169  } while (0)
170 #define KSBOX() \
171  do { \
172  AESCommon::applySbox(temp, schedule + 12); \
173  schedule[16] ^= temp[0]; \
174  schedule[17] ^= temp[1]; \
175  schedule[18] ^= temp[2]; \
176  schedule[19] ^= temp[3]; \
177  } while (0)
178 
188 {
189 }
190 
191 AESTiny256::~AESTiny256()
192 {
193  clean(schedule);
194 }
195 
200 size_t AESTiny256::blockSize() const
201 {
202  return 16;
203 }
204 
209 size_t AESTiny256::keySize() const
210 {
211  return 32;
212 }
213 
214 bool AESTiny256::setKey(const uint8_t *key, size_t len)
215 {
216  if (len == 32) {
217  // Make a copy of the key - it will be expanded in encryptBlock().
218  memcpy(schedule, key, 32);
219  return true;
220  }
221  return false;
222 }
223 
224 void AESTiny256::encryptBlock(uint8_t *output, const uint8_t *input)
225 {
226  uint8_t schedule[32];
227  uint8_t posn;
228  uint8_t round;
229  uint8_t state1[16];
230  uint8_t state2[16];
231  uint8_t temp[4];
232 
233  // Start with the key in the schedule buffer.
234  memcpy(schedule, this->schedule, 32);
235 
236  // Copy the input into the state and perform the first round.
237  for (posn = 0; posn < 16; ++posn)
238  state1[posn] = input[posn] ^ schedule[posn];
239  ENCRYPT(RIGHT);
240 
241  // Perform the next 12 rounds of the cipher two at a time.
242  for (round = 1; round <= 6; ++round) {
243  // Expand the next 32 bytes of the key schedule.
244  KCORE(round);
245  KXOR(1, 0);
246  KXOR(2, 1);
247  KXOR(3, 2);
248  KSBOX();
249  KXOR(5, 4);
250  KXOR(6, 5);
251  KXOR(7, 6);
252 
253  // Encrypt using the left and right halves of the key schedule.
254  ENCRYPT(LEFT);
255  ENCRYPT(RIGHT);
256  }
257 
258  // Expand the final 16 bytes of the key schedule.
259  KCORE(7);
260  KXOR(1, 0);
261  KXOR(2, 1);
262  KXOR(3, 2);
263 
264  // Perform the final round.
265  AESCommon::subBytesAndShiftRows(state2, state1);
266  for (posn = 0; posn < 16; ++posn)
267  output[posn] = state2[posn] ^ schedule[posn];
268 }
269 
270 void AESTiny256::decryptBlock(uint8_t *output, const uint8_t *input)
271 {
272  // Decryption is not supported by AESTiny256.
273 }
274 
276 {
277  clean(schedule);
278 }
279 
307 {
308 }
309 
310 AESSmall256::~AESSmall256()
311 {
312  clean(reverse);
313 }
314 
315 bool AESSmall256::setKey(const uint8_t *key, size_t len)
316 {
317  uint8_t *schedule;
318  uint8_t round;
319  uint8_t temp[4];
320 
321  // Set the encryption key first.
322  if (!AESTiny256::setKey(key, len))
323  return false;
324 
325  // Expand the key schedule up to the last round which gives
326  // us the round keys to use for the final two rounds. We can
327  // then work backwards from there in decryptBlock().
328  schedule = reverse;
329  memcpy(schedule, key, 32);
330  for (round = 1; round <= 6; ++round) {
331  KCORE(round);
332  KXOR(1, 0);
333  KXOR(2, 1);
334  KXOR(3, 2);
335  KSBOX();
336  KXOR(5, 4);
337  KXOR(6, 5);
338  KXOR(7, 6);
339  }
340  KCORE(7);
341  KXOR(1, 0);
342  KXOR(2, 1);
343  KXOR(3, 2);
344 
345  // Key is ready to go.
346  return true;
347 }
348 
349 void AESSmall256::decryptBlock(uint8_t *output, const uint8_t *input)
350 {
351  uint8_t schedule[32];
352  uint8_t round;
353  uint8_t posn;
354  uint8_t state1[16];
355  uint8_t state2[16];
356  uint8_t temp[4];
357 
358  // Start with the end of the decryption schedule.
359  memcpy(schedule, reverse, 32);
360 
361  // Copy the input into the state and reverse the final round.
362  for (posn = 0; posn < 16; ++posn)
363  state1[posn] = input[posn] ^ schedule[posn];
364  AESCommon::inverseShiftRowsAndSubBytes(state2, state1);
365  KXOR(3, 2);
366  KXOR(2, 1);
367  KXOR(1, 0);
368  KCORE(7);
369 
370  // Perform the next 12 rounds of the decryption process two at a time.
371  for (round = 6; round >= 1; --round) {
372  // Decrypt using the right and left halves of the key schedule.
373  DECRYPT(RIGHT);
374  DECRYPT(LEFT);
375 
376  // Expand the next 32 bytes of the key schedule in reverse.
377  KXOR(7, 6);
378  KXOR(6, 5);
379  KXOR(5, 4);
380  KSBOX();
381  KXOR(3, 2);
382  KXOR(2, 1);
383  KXOR(1, 0);
384  KCORE(round);
385  }
386 
387  // Reverse the initial round and create the output words.
388  DECRYPT(RIGHT);
389  for (posn = 0; posn < 16; ++posn)
390  output[posn] = state2[posn] ^ schedule[posn];
391 }
392 
394 {
395  clean(reverse);
397 }
void clear()
Clears all security-sensitive state from this block cipher.
Definition: AES256.cpp:275
size_t keySize() const
Size of a 256-bit AES key in bytes.
Definition: AES256.cpp:209
AESSmall256()
Constructs an AES 256-bit block cipher with no initial key.
Definition: AES256.cpp:306
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
Definition: AES256.cpp:270
void encryptBlock(uint8_t *output, const uint8_t *input)
Encrypts a single block using this cipher.
Definition: AES256.cpp:224
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
Definition: AES256.cpp:349
AES256()
Constructs an AES 256-bit block cipher with no initial key.
Definition: AES256.cpp:40
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES256.cpp:60
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES256.cpp:214
void clear()
Clears all security-sensitive state from this block cipher.
Definition: AES256.cpp:393
AESTiny256()
Constructs an AES 256-bit block cipher with no initial key.
Definition: AES256.cpp:187
size_t keySize() const
Size of a 256-bit AES key in bytes.
Definition: AES256.cpp:55
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: AES256.cpp:315
size_t blockSize() const
Size of an AES block in bytes.
Definition: AES256.cpp:200