1 /***************************************************************************//**
2 * @file
3 * @brief Advanced Encryption Standard (AES) accelerator peripheral API
4 * @author Energy Micro AS
5 * @version 3.0.0
6 *******************************************************************************
7 * @section License
8 * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
9 *******************************************************************************
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 *
21 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
22 * obligation to support this Software. Energy Micro AS is providing the
23 * Software "AS IS", with no express or implied warranties of any kind,
24 * including, but not limited to, any implied warranties of merchantability
25 * or fitness for any particular purpose or warranties against infringement
26 * of any proprietary rights of a third party.
27 *
28 * Energy Micro AS will not be liable for any consequential, incidental, or
29 * special damages, or any other relief, or for any claim by any third party,
30 * arising from your use of this Software.
31 *
32 ******************************************************************************/
33 #include "em_aes.h"
34 #include "em_assert.h"
35
36 #if defined(AES_COUNT) && (AES_COUNT > 0)
37 /***************************************************************************//**
38 * @addtogroup EM_Library
39 * @{
40 ******************************************************************************/
41
42 /***************************************************************************//**
43 * @addtogroup AES
44 * @brief Advanced Encryption Standard Accelerator (AES) Peripheral API for
45 * EFM32
46 * @details
47 * This API is intended for use on EFM32 target devices, and the following
48 * input/output notations should be noted:
49 *
50 * @li Input/output data (plaintext, ciphertext, key etc) are treated as
51 * byte arrays, starting with most significant byte. Ie, 32 bytes of
52 * plaintext (B0...B31) is located in memory in the same order, with B0 at
53 * the lower address and B31 at the higher address.
54 *
55 * @li Byte arrays must always be a multiple of AES block size, ie a multiple
56 * of 16. Padding, if required, is done at the end of the byte array.
57 *
58 * @li Byte arrays should be word (32 bit) aligned for performance
59 * considerations, since the array is accessed with 32 bit access type.
60 * The EFM32 supports unaligned accesses, but with a performance penalty.
61 *
62 * @li It is possible to specify the same output buffer as input buffer
63 * as long as they point to the same address. In that case the provided input
64 * buffer is replaced with the encrypted/decrypted output. Notice that the
65 * buffers must be exactly overlapping. If partly overlapping, the
66 * behaviour is undefined.
67 *
68 * It is up to the user to use a cipher mode according to its requirements
69 * in order to not break security. Please refer to specific cipher mode
70 * theory for details.
71 *
72 * References:
73 * @li Wikipedia - Cipher modes, http://en.wikipedia.org/wiki/Cipher_modes
74 *
75 * @li Recommendation for Block Cipher Modes of Operation,
76 * NIST Special Publication 800-38A, 2001 Edition,
77 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
78 * @{
79 ******************************************************************************/
80
81 /*******************************************************************************
82 ******************************* DEFINES ***********************************
83 ******************************************************************************/
84
85 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
86
87 #define AES_BLOCKSIZE 16
88
89 /** @endcond */
90
91 /*******************************************************************************
92 ************************** GLOBAL FUNCTIONS *******************************
93 ******************************************************************************/
94
95 /***************************************************************************//**
96 * @brief
97 * Cipher-block chaining (CBC) cipher mode encryption/decryption, 128 bit key.
98 *
99 * @details
100 * Encryption:
101 * @verbatim
102 * Plaintext Plaintext
103 * | |
104 * V V
105 * InitVector ->XOR +-------------->XOR
106 * | | |
107 * V | V
108 * +--------------+ | +--------------+
109 * Key ->| Block cipher | | Key ->| Block cipher |
110 * | encryption | | | encryption |
111 * +--------------+ | +--------------+
112 * |---------+ |
113 * V V
114 * Ciphertext Ciphertext
115 * @endverbatim
116 * Decryption:
117 * @verbatim
118 * Ciphertext Ciphertext
119 * |----------+ |
120 * V | V
121 * +--------------+ | +--------------+
122 * Key ->| Block cipher | | Key ->| Block cipher |
123 * | decryption | | | decryption |
124 * +--------------+ | +--------------+
125 * | | |
126 * V | V
127 * InitVector ->XOR +-------------->XOR
128 * | |
129 * V V
130 * Plaintext Plaintext
131 * @endverbatim
132 * Please refer to general comments on layout and byte ordering of parameters.
133 *
134 * @param[out] out
135 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
136 * may be set equal to @p in, in which case the input buffer is overwritten.
137 *
138 * @param[in] in
139 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
140 *
141 * @param[in] len
142 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
143 *
144 * @param[in] key
145 * When doing encryption, this is the 128 bit encryption key. When doing
146 * decryption, this is the 128 bit decryption key. The decryption key may
147 * be generated from the encryption key with AES_DecryptKey128().
148 * If this argument is null, the key will not be loaded, as it is assumed
149 * the key has been loaded into KEYHA previously.
150 *
151 * @param[in] iv
152 * 128 bit initalization vector to use.
153 *
154 * @param[in] encrypt
155 * Set to true to encrypt, false to decrypt.
156 ******************************************************************************/
AES_CBC128(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)157 void AES_CBC128(uint8_t *out,
158 const uint8_t *in,
159 unsigned int len,
160 const uint8_t *key,
161 const uint8_t *iv,
162 bool encrypt)
163 {
164 int i;
165 uint32_t *_out = (uint32_t *)out;
166 const uint32_t *_in = (const uint32_t *)in;
167 const uint32_t *_iv = (const uint32_t *)iv;
168 /* Need to buffer one block when decrypting in case 'out' replaces 'in' */
169 uint32_t prev[4];
170
171 EFM_ASSERT(!(len % AES_BLOCKSIZE));
172
173 /* Number of blocks to process */
174 len /= AES_BLOCKSIZE;
175
176 if (key)
177 {
178 const uint32_t *_key = (const uint32_t *)key;
179 /* Load key into high key for key buffer usage */
180 for (i = 3; i >= 0; i--)
181 {
182 AES->KEYHA = __REV(_key[i]);
183 }
184 }
185
186 if (encrypt)
187 {
188 /* Enable encryption with auto start using XOR */
189 AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_XORSTART;
190
191 /* Load initialization vector, since writing to DATA, it will */
192 /* not trigger encryption. */
193 for (i = 3; i >= 0; i--)
194 {
195 AES->DATA = __REV(_iv[i]);
196 }
197
198 /* Encrypt data */
199 while (len--)
200 {
201 /* Load data and trigger encryption */
202 for (i = 3; i >= 0; i--)
203 {
204 AES->XORDATA = __REV(_in[i]);
205 }
206 _in += 4;
207
208 /* Wait for completion */
209 while (AES->STATUS & AES_STATUS_RUNNING)
210 ;
211
212 /* Save encrypted data */
213 for (i = 3; i >= 0; i--)
214 {
215 _out[i] = __REV(AES->DATA);
216 }
217 _out += 4;
218 }
219 }
220 else
221 {
222 /* Select decryption mode */
223 AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
224
225 /* Copy init vector to previous buffer to avoid special handling */
226 for (i = 0; i < 4; i++)
227 {
228 prev[i] = _iv[i];
229 }
230
231 /* Decrypt data */
232 while (len--)
233 {
234 /* Load data and trigger decryption */
235 for (i = 3; i >= 0; i--)
236 {
237 AES->DATA = __REV(_in[i]);
238 }
239
240 /* Wait for completion */
241 while (AES->STATUS & AES_STATUS_RUNNING)
242 ;
243
244 /* In order to avoid additional buffer, we use HW directly for XOR and buffer */
245 /* (Writing to XORDATA will not trigger encoding, triggering enabled on DATA.) */
246 for (i = 3; i >= 0; i--)
247 {
248 AES->XORDATA = __REV(prev[i]);
249 prev[i] = _in[i];
250 }
251 _in += 4;
252
253 /* Then fetch decrypted data, we have to do it in a separate loop */
254 /* due to internal auto-shifting of words */
255 for (i = 3; i >= 0; i--)
256 {
257 _out[i] = __REV(AES->DATA);
258 }
259 _out += 4;
260 }
261 }
262 }
263
264
265 /***************************************************************************//**
266 * @brief
267 * Cipher-block chaining (CBC) cipher mode encryption/decryption, 256 bit key.
268 *
269 * @details
270 * Please see AES_CBC128() for CBC figure.
271 *
272 * Please refer to general comments on layout and byte ordering of parameters.
273 *
274 * @param[out] out
275 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
276 * may be set equal to @p in, in which case the input buffer is overwritten.
277 *
278 * @param[in] in
279 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
280 *
281 * @param[in] len
282 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
283 *
284 * @param[in] key
285 * When doing encryption, this is the 256 bit encryption key. When doing
286 * decryption, this is the 256 bit decryption key. The decryption key may
287 * be generated from the encryption key with AES_DecryptKey256().
288 *
289 * @param[in] iv
290 * 128 bit initalization vector to use.
291 *
292 * @param[in] encrypt
293 * Set to true to encrypt, false to decrypt.
294 ******************************************************************************/
AES_CBC256(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)295 void AES_CBC256(uint8_t *out,
296 const uint8_t *in,
297 unsigned int len,
298 const uint8_t *key,
299 const uint8_t *iv,
300 bool encrypt)
301 {
302 int i;
303 int j;
304 uint32_t *_out = (uint32_t *)out;
305 const uint32_t *_in = (const uint32_t *)in;
306 const uint32_t *_key = (const uint32_t *)key;
307 const uint32_t *_iv = (const uint32_t *)iv;
308 /* Need to buffer one block when decrypting in case output replaces input */
309 uint32_t prev[4];
310
311 EFM_ASSERT(!(len % AES_BLOCKSIZE));
312
313 /* Number of blocks to process */
314 len /= AES_BLOCKSIZE;
315
316 if (encrypt)
317 {
318 /* Enable encryption with auto start using XOR */
319 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_XORSTART;
320
321 /* Load initialization vector, since writing to DATA, it will */
322 /* not trigger encryption. */
323 for (i = 3; i >= 0; i--)
324 {
325 AES->DATA = __REV(_iv[i]);
326 }
327
328 /* Encrypt data */
329 while (len--)
330 {
331 /* Load key and data and trigger encryption */
332 for (i = 3, j = 7; i >= 0; i--, j--)
333 {
334 AES->KEYLA = __REV(_key[j]);
335 AES->KEYHA = __REV(_key[i]);
336 /* Write data last, since will trigger encryption on last iteration */
337 AES->XORDATA = __REV(_in[i]);
338 }
339 _in += 4;
340
341 /* Wait for completion */
342 while (AES->STATUS & AES_STATUS_RUNNING)
343 ;
344
345 /* Save encrypted data */
346 for (i = 3; i >= 0; i--)
347 {
348 _out[i] = __REV(AES->DATA);
349 }
350 _out += 4;
351 }
352 }
353 else
354 {
355 /* Select decryption mode */
356 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DECRYPT | AES_CTRL_DATASTART;
357
358 /* Copy init vector to previous buffer to avoid special handling */
359 for (i = 0; i < 4; i++)
360 {
361 prev[i] = _iv[i];
362 }
363
364 /* Decrypt data */
365 while (len--)
366 {
367 /* Load key and data and trigger decryption */
368 for (i = 3, j = 7; i >= 0; i--, j--)
369 {
370 AES->KEYLA = __REV(_key[j]);
371 AES->KEYHA = __REV(_key[i]);
372 /* Write data last, since will trigger encryption on last iteration */
373 AES->DATA = __REV(_in[i]);
374 }
375
376 /* Wait for completion */
377 while (AES->STATUS & AES_STATUS_RUNNING)
378 ;
379
380 /* In order to avoid additional buffer, we use HW directly for XOR and buffer */
381 for (i = 3; i >= 0; i--)
382 {
383 AES->XORDATA = __REV(prev[i]);
384 prev[i] = _in[i];
385 }
386 _in += 4;
387
388 /* Then fetch decrypted data, we have to do it in a separate loop */
389 /* due to internal auto-shifting of words */
390 for (i = 3; i >= 0; i--)
391 {
392 _out[i] = __REV(AES->DATA);
393 }
394 _out += 4;
395 }
396 }
397 }
398
399
400 /***************************************************************************//**
401 * @brief
402 * Cipher feedback (CFB) cipher mode encryption/decryption, 128 bit key.
403 *
404 * @details
405 * Encryption:
406 * @verbatim
407 * InitVector +----------------+
408 * | | |
409 * V | V
410 * +--------------+ | +--------------+
411 * Key ->| Block cipher | | Key ->| Block cipher |
412 * | encryption | | | encryption |
413 * +--------------+ | +--------------+
414 * | | |
415 * V | V
416 * Plaintext ->XOR | Plaintext ->XOR
417 * |---------+ |
418 * V V
419 * Ciphertext Ciphertext
420 * @endverbatim
421 * Decryption:
422 * @verbatim
423 * InitVector +----------------+
424 * | | |
425 * V | V
426 * +--------------+ | +--------------+
427 * Key ->| Block cipher | | Key ->| Block cipher |
428 * | encryption | | | encryption |
429 * +--------------+ | +--------------+
430 * | | |
431 * V | V
432 * XOR<- Ciphertext XOR<- Ciphertext
433 * | |
434 * V V
435 * Plaintext Plaintext
436 * @endverbatim
437 * Please refer to general comments on layout and byte ordering of parameters.
438 *
439 * @param[out] out
440 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
441 * may be set equal to @p in, in which case the input buffer is overwritten.
442 *
443 * @param[in] in
444 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
445 *
446 * @param[in] len
447 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
448 *
449 * @param[in] key
450 * 128 bit encryption key is used for both encryption and decryption modes.
451 *
452 * @param[in] iv
453 * 128 bit initalization vector to use.
454 *
455 * @param[in] encrypt
456 * Set to true to encrypt, false to decrypt.
457 ******************************************************************************/
AES_CFB128(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)458 void AES_CFB128(uint8_t *out,
459 const uint8_t *in,
460 unsigned int len,
461 const uint8_t *key,
462 const uint8_t *iv,
463 bool encrypt)
464 {
465 int i;
466 uint32_t *_out = (uint32_t *)out;
467 const uint32_t *_in = (const uint32_t *)in;
468 const uint32_t *_key = (const uint32_t *)key;
469 const uint32_t *_iv = (const uint32_t *)iv;
470 const uint32_t *data;
471 uint32_t tmp[4];
472
473 EFM_ASSERT(!(len % AES_BLOCKSIZE));
474
475 /* Select encryption mode */
476 AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
477
478 /* Load key into high key for key buffer usage */
479 for (i = 3; i >= 0; i--)
480 {
481 AES->KEYHA = __REV(_key[i]);
482 }
483
484 /* Encrypt/decrypt data */
485 data = _iv;
486 len /= AES_BLOCKSIZE;
487 while (len--)
488 {
489 /* Load data and trigger encryption */
490 for (i = 3; i >= 0; i--)
491 {
492 AES->DATA = __REV(data[i]);
493 }
494
495 /* Do some required processing before waiting for completion */
496 if (encrypt)
497 {
498 data = _out;
499 }
500 else
501 {
502 /* Must copy current ciphertext block since it may be overwritten */
503 for (i = 0; i < 4; i++)
504 {
505 tmp[i] = _in[i];
506 }
507 data = tmp;
508 }
509
510 /* Wait for completion */
511 while (AES->STATUS & AES_STATUS_RUNNING)
512 ;
513
514 /* Save encrypted/decrypted data */
515 for (i = 3; i >= 0; i--)
516 {
517 _out[i] = __REV(AES->DATA) ^ _in[i];
518 }
519 _out += 4;
520 _in += 4;
521 }
522 }
523
524
525 /***************************************************************************//**
526 * @brief
527 * Cipher feedback (CFB) cipher mode encryption/decryption, 256 bit key.
528 *
529 * @details
530 * Please see AES_CFB128() for CFB figure.
531 *
532 * Please refer to general comments on layout and byte ordering of parameters.
533 *
534 * @param[out] out
535 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
536 * may be set equal to @p in, in which case the input buffer is overwritten.
537 *
538 * @param[in] in
539 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
540 *
541 * @param[in] len
542 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
543 *
544 * @param[in] key
545 * 256 bit encryption key is used for both encryption and decryption modes.
546 *
547 * @param[in] iv
548 * 128 bit initalization vector to use.
549 *
550 * @param[in] encrypt
551 * Set to true to encrypt, false to decrypt.
552 ******************************************************************************/
AES_CFB256(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)553 void AES_CFB256(uint8_t *out,
554 const uint8_t *in,
555 unsigned int len,
556 const uint8_t *key,
557 const uint8_t *iv,
558 bool encrypt)
559 {
560 int i;
561 int j;
562 uint32_t *_out = (uint32_t *)out;
563 const uint32_t *_in = (const uint32_t *)in;
564 const uint32_t *_key = (const uint32_t *)key;
565 const uint32_t *_iv = (const uint32_t *)iv;
566 const uint32_t *data;
567 uint32_t tmp[4];
568
569 EFM_ASSERT(!(len % AES_BLOCKSIZE));
570
571 /* Select encryption mode */
572 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
573
574 /* Encrypt/decrypt data */
575 data = _iv;
576 len /= AES_BLOCKSIZE;
577 while (len--)
578 {
579 /* Load key and block to be encrypted/decrypted */
580 for (i = 3, j = 7; i >= 0; i--, j--)
581 {
582 AES->KEYLA = __REV(_key[j]);
583 AES->KEYHA = __REV(_key[i]);
584 /* Write data last, since will trigger encryption on last iteration */
585 AES->DATA = __REV(data[i]);
586 }
587
588 /* Do some required processing before waiting for completion */
589 if (encrypt)
590 {
591 data = _out;
592 }
593 else
594 {
595 /* Must copy current ciphertext block since it may be overwritten */
596 for (i = 0; i < 4; i++)
597 {
598 tmp[i] = _in[i];
599 }
600 data = tmp;
601 }
602
603 while (AES->STATUS & AES_STATUS_RUNNING)
604 ;
605
606 /* Save encrypted/decrypted data */
607 for (i = 3; i >= 0; i--)
608 {
609 _out[i] = __REV(AES->DATA) ^ _in[i];
610 }
611 _out += 4;
612 _in += 4;
613 }
614 }
615
616
617 /***************************************************************************//**
618 * @brief
619 * Counter (CTR) cipher mode encryption/decryption, 128 bit key.
620 *
621 * @details
622 * Encryption:
623 * @verbatim
624 * Counter Counter
625 * | |
626 * V V
627 * +--------------+ +--------------+
628 * Key ->| Block cipher | Key ->| Block cipher |
629 * | encryption | | encryption |
630 * +--------------+ +--------------+
631 * | |
632 * Plaintext ->XOR Plaintext ->XOR
633 * | |
634 * V V
635 * Ciphertext Ciphertext
636 * @endverbatim
637 * Decryption:
638 * @verbatim
639 * Counter Counter
640 * | |
641 * V V
642 * +--------------+ +--------------+
643 * Key ->| Block cipher | Key ->| Block cipher |
644 * | encryption | | encryption |
645 * +--------------+ +--------------+
646 * | |
647 * Ciphertext ->XOR Ciphertext ->XOR
648 * | |
649 * V V
650 * Plaintext Plaintext
651 * @endverbatim
652 * Please refer to general comments on layout and byte ordering of parameters.
653 *
654 * @param[out] out
655 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
656 * may be set equal to @p in, in which case the input buffer is overwritten.
657 *
658 * @param[in] in
659 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
660 *
661 * @param[in] len
662 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
663 *
664 * @param[in] key
665 * 128 bit encryption key.
666 * If this argument is null, the key will not be loaded, as it is assumed
667 * the key has been loaded into KEYHA previously.
668 *
669 * @param[in,out] ctr
670 * 128 bit initial counter value. The counter is updated after each AES
671 * block encoding through use of @p ctrFunc.
672 *
673 * @param[in] ctrFunc
674 * Function used to update counter value.
675 ******************************************************************************/
AES_CTR128(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,uint8_t * ctr,AES_CtrFuncPtr_TypeDef ctrFunc)676 void AES_CTR128(uint8_t *out,
677 const uint8_t *in,
678 unsigned int len,
679 const uint8_t *key,
680 uint8_t *ctr,
681 AES_CtrFuncPtr_TypeDef ctrFunc)
682 {
683 int i;
684 uint32_t *_out = (uint32_t *)out;
685 const uint32_t *_in = (const uint32_t *)in;
686 uint32_t *_ctr = (uint32_t *)ctr;
687
688 EFM_ASSERT(!(len % AES_BLOCKSIZE));
689 EFM_ASSERT(ctrFunc);
690
691 /* Select encryption mode, with auto trigger */
692 AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
693
694 if (key)
695 {
696 const uint32_t *_key = (const uint32_t *)key;
697 /* Load key into high key for key buffer usage */
698 for (i = 3; i >= 0; i--)
699 {
700 AES->KEYHA = __REV(_key[i]);
701 }
702 }
703
704 /* Encrypt/decrypt data */
705 len /= AES_BLOCKSIZE;
706 while (len--)
707 {
708 /* Load ctr to be encrypted/decrypted */
709 for (i = 3; i >= 0; i--)
710 {
711 AES->DATA = __REV(_ctr[i]);
712 }
713 /* Increment ctr for next use */
714 ctrFunc(ctr);
715
716 /* Wait for completion */
717 while (AES->STATUS & AES_STATUS_RUNNING)
718 ;
719
720 /* Save encrypted/decrypted data */
721 for (i = 3; i >= 0; i--)
722 {
723 _out[i] = __REV(AES->DATA) ^ _in[i];
724 }
725 _out += 4;
726 _in += 4;
727 }
728 }
729
730
731 /***************************************************************************//**
732 * @brief
733 * Counter (CTR) cipher mode encryption/decryption, 256 bit key.
734 *
735 * @details
736 * Please see AES_CTR128() for CTR figure.
737 *
738 * Please refer to general comments on layout and byte ordering of parameters.
739 *
740 * @param[out] out
741 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
742 * may be set equal to @p in, in which case the input buffer is overwritten.
743 *
744 * @param[in] in
745 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
746 *
747 * @param[in] len
748 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
749 *
750 * @param[in] key
751 * 256 bit encryption key.
752 *
753 * @param[in,out] ctr
754 * 128 bit initial counter value. The counter is updated after each AES
755 * block encoding through use of @p ctrFunc.
756 *
757 * @param[in] ctrFunc
758 * Function used to update counter value.
759 ******************************************************************************/
AES_CTR256(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,uint8_t * ctr,AES_CtrFuncPtr_TypeDef ctrFunc)760 void AES_CTR256(uint8_t *out,
761 const uint8_t *in,
762 unsigned int len,
763 const uint8_t *key,
764 uint8_t *ctr,
765 AES_CtrFuncPtr_TypeDef ctrFunc)
766 {
767 int i;
768 int j;
769 uint32_t *_out = (uint32_t *)out;
770 const uint32_t *_in = (const uint32_t *)in;
771 const uint32_t *_key = (const uint32_t *)key;
772 uint32_t *_ctr = (uint32_t *)ctr;
773
774 EFM_ASSERT(!(len % AES_BLOCKSIZE));
775 EFM_ASSERT(ctrFunc);
776
777 /* Select encryption mode, with auto trigger */
778 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
779
780 /* Encrypt/decrypt data */
781 len /= AES_BLOCKSIZE;
782 while (len--)
783 {
784 /* Load key and block to be encrypted/decrypted */
785 for (i = 3, j = 7; i >= 0; i--, j--)
786 {
787 AES->KEYLA = __REV(_key[j]);
788 AES->KEYHA = __REV(_key[i]);
789 /* Write data last, since will trigger encryption on last iteration */
790 AES->DATA = __REV(_ctr[i]);
791 }
792 /* Increment ctr for next use */
793 ctrFunc(ctr);
794
795 /* Wait for completion */
796 while (AES->STATUS & AES_STATUS_RUNNING)
797 ;
798
799 /* Save encrypted/decrypted data */
800 for (i = 3; i >= 0; i--)
801 {
802 _out[i] = __REV(AES->DATA) ^ _in[i];
803 }
804 _out += 4;
805 _in += 4;
806 }
807 }
808
809
810 /***************************************************************************//**
811 * @brief
812 * Update last 32 bits of 128 bit counter, by incrementing with 1.
813 *
814 * @details
815 * Notice that no special consideration is given to possible wrap around. If
816 * 32 least significant bits are 0xFFFFFFFF, they will be updated to 0x00000000,
817 * ignoring overflow.
818 *
819 * Please refer to general comments on layout and byte ordering of parameters.
820 *
821 * @param[in,out] ctr
822 * Buffer holding 128 bit counter to be updated.
823 ******************************************************************************/
AES_CTRUpdate32Bit(uint8_t * ctr)824 void AES_CTRUpdate32Bit(uint8_t *ctr)
825 {
826 uint32_t *_ctr = (uint32_t *)ctr;
827
828 _ctr[3] = __REV(__REV(_ctr[3]) + 1);
829 }
830
831
832 /***************************************************************************//**
833 * @brief
834 * Generate 128 bit decryption key from 128 bit encryption key. The decryption
835 * key is used for some cipher modes when decrypting.
836 *
837 * @details
838 * Please refer to general comments on layout and byte ordering of parameters.
839 *
840 * @param[out] out
841 * Buffer to place 128 bit decryption key. Must be at least 16 bytes long. It
842 * may be set equal to @p in, in which case the input buffer is overwritten.
843 *
844 * @param[in] in
845 * Buffer holding 128 bit encryption key. Must be at least 16 bytes long.
846 ******************************************************************************/
AES_DecryptKey128(uint8_t * out,const uint8_t * in)847 void AES_DecryptKey128(uint8_t *out, const uint8_t *in)
848 {
849 int i;
850 uint32_t *_out = (uint32_t *)out;
851 const uint32_t *_in = (const uint32_t *)in;
852
853 /* Load key */
854 for (i = 3; i >= 0; i--)
855 {
856 AES->KEYLA = __REV(_in[i]);
857 }
858
859 /* Do dummy encryption to generate decrypt key */
860 AES->CTRL = 0;
861 AES_IntClear(AES_IF_DONE);
862 AES->CMD = AES_CMD_START;
863
864 /* Wait for completion */
865 while (AES->STATUS & AES_STATUS_RUNNING)
866 ;
867
868 /* Save decryption key */
869 for (i = 3; i >= 0; i--)
870 {
871 _out[i] = __REV(AES->KEYLA);
872 }
873 }
874
875
876 /***************************************************************************//**
877 * @brief
878 * Generate 256 bit decryption key from 256 bit encryption key. The decryption
879 * key is used for some cipher modes when decrypting.
880 *
881 * @details
882 * Please refer to general comments on layout and byte ordering of parameters.
883 *
884 * @param[out] out
885 * Buffer to place 256 bit decryption key. Must be at least 32 bytes long. It
886 * may be set equal to @p in, in which case the input buffer is overwritten.
887 *
888 * @param[in] in
889 * Buffer holding 256 bit encryption key. Must be at least 32 bytes long.
890 ******************************************************************************/
AES_DecryptKey256(uint8_t * out,const uint8_t * in)891 void AES_DecryptKey256(uint8_t *out, const uint8_t *in)
892 {
893 int i;
894 int j;
895 uint32_t *_out = (uint32_t *)out;
896 const uint32_t *_in = (const uint32_t *)in;
897
898 /* Load key */
899 for (i = 3, j = 7; i >= 0; i--, j--)
900 {
901 AES->KEYLA = __REV(_in[j]);
902 AES->KEYHA = __REV(_in[i]);
903 }
904
905 /* Do dummy encryption to generate decrypt key */
906 AES->CTRL = AES_CTRL_AES256;
907 AES->CMD = AES_CMD_START;
908
909 /* Wait for completion */
910 while (AES->STATUS & AES_STATUS_RUNNING)
911 ;
912
913 /* Save decryption key */
914 for (i = 3, j = 7; i >= 0; i--, j--)
915 {
916 _out[j] = __REV(AES->KEYLA);
917 _out[i] = __REV(AES->KEYHA);
918 }
919 }
920
921
922 /***************************************************************************//**
923 * @brief
924 * Electronic Codebook (ECB) cipher mode encryption/decryption, 128 bit key.
925 *
926 * @details
927 * Encryption:
928 * @verbatim
929 * Plaintext Plaintext
930 * | |
931 * V V
932 * +--------------+ +--------------+
933 * Key ->| Block cipher | Key ->| Block cipher |
934 * | encryption | | encryption |
935 * +--------------+ +--------------+
936 * | |
937 * V V
938 * Ciphertext Ciphertext
939 * @endverbatim
940 * Decryption:
941 * @verbatim
942 * Ciphertext Ciphertext
943 * | |
944 * V V
945 * +--------------+ +--------------+
946 * Key ->| Block cipher | Key ->| Block cipher |
947 * | decryption | | decryption |
948 * +--------------+ +--------------+
949 * | |
950 * V V
951 * Plaintext Plaintext
952 * @endverbatim
953 * Please refer to general comments on layout and byte ordering of parameters.
954 *
955 * @param[out] out
956 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
957 * may be set equal to @p in, in which case the input buffer is overwritten.
958 *
959 * @param[in] in
960 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
961 *
962 * @param[in] len
963 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
964 *
965 * @param[in] key
966 * When doing encryption, this is the 128 bit encryption key. When doing
967 * decryption, this is the 128 bit decryption key. The decryption key may
968 * be generated from the encryption key with AES_DecryptKey128().
969 *
970 * @param[in] encrypt
971 * Set to true to encrypt, false to decrypt.
972 ******************************************************************************/
AES_ECB128(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,bool encrypt)973 void AES_ECB128(uint8_t *out,
974 const uint8_t *in,
975 unsigned int len,
976 const uint8_t *key,
977 bool encrypt)
978 {
979 int i;
980 uint32_t *_out = (uint32_t *)out;
981 const uint32_t *_in = (const uint32_t *)in;
982 const uint32_t *_key = (const uint32_t *)key;
983
984 EFM_ASSERT(!(len % AES_BLOCKSIZE));
985
986 /* Load key into high key for key buffer usage */
987 for (i = 3; i >= 0; i--)
988 {
989 AES->KEYHA = __REV(_key[i]);
990 }
991
992 if (encrypt)
993 {
994 /* Select encryption mode */
995 AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
996 }
997 else
998 {
999 /* Select decryption mode */
1000 AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
1001 }
1002
1003 /* Encrypt/decrypt data */
1004 len /= AES_BLOCKSIZE;
1005 while (len--)
1006 {
1007 /* Load block to be encrypted/decrypted */
1008 for (i = 3; i >= 0; i--)
1009 {
1010 AES->DATA = __REV(_in[i]);
1011 }
1012 _in += 4;
1013
1014 /* Wait for completion */
1015 while (AES->STATUS & AES_STATUS_RUNNING)
1016 ;
1017
1018 /* Save encrypted/decrypted data */
1019 for (i = 3; i >= 0; i--)
1020 {
1021 _out[i] = __REV(AES->DATA);
1022 }
1023 _out += 4;
1024 }
1025 }
1026
1027
1028 /***************************************************************************//**
1029 * @brief
1030 * Electronic Codebook (ECB) cipher mode encryption/decryption, 256 bit key.
1031 *
1032 * @details
1033 * Please see AES_ECB128() for ECB figure.
1034 *
1035 * Please refer to general comments on layout and byte ordering of parameters.
1036 *
1037 * @param[out] out
1038 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
1039 * may be set equal to @p in, in which case the input buffer is overwritten.
1040 *
1041 * @param[in] in
1042 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
1043 *
1044 * @param[in] len
1045 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
1046 *
1047 * @param[in] key
1048 * When doing encryption, this is the 256 bit encryption key. When doing
1049 * decryption, this is the 256 bit decryption key. The decryption key may
1050 * be generated from the encryption key with AES_DecryptKey256().
1051 *
1052 * @param[in] encrypt
1053 * Set to true to encrypt, false to decrypt.
1054 ******************************************************************************/
AES_ECB256(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,bool encrypt)1055 void AES_ECB256(uint8_t *out,
1056 const uint8_t *in,
1057 unsigned int len,
1058 const uint8_t *key,
1059 bool encrypt)
1060 {
1061 int i;
1062 int j;
1063 uint32_t *_out = (uint32_t *)out;
1064 const uint32_t *_in = (const uint32_t *)in;
1065 const uint32_t *_key = (const uint32_t *)key;
1066
1067 EFM_ASSERT(!(len % AES_BLOCKSIZE));
1068
1069 if (encrypt)
1070 {
1071 /* Select encryption mode */
1072 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
1073 }
1074 else
1075 {
1076 /* Select decryption mode */
1077 AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_AES256 | AES_CTRL_DATASTART;
1078 }
1079
1080 /* Encrypt/decrypt data */
1081 len /= AES_BLOCKSIZE;
1082 while (len--)
1083 {
1084 /* Load key and block to be encrypted/decrypted */
1085 for (i = 3, j = 7; i >= 0; i--, j--)
1086 {
1087 AES->KEYLA = __REV(_key[j]);
1088 AES->KEYHA = __REV(_key[i]);
1089 /* Write data last, since will trigger encryption on last iteration */
1090 AES->DATA = __REV(_in[i]);
1091 }
1092 _in += 4;
1093
1094 /* Wait for completion */
1095 while (AES->STATUS & AES_STATUS_RUNNING)
1096 ;
1097
1098 /* Save encrypted/decrypted data */
1099 for (i = 3; i >= 0; i--)
1100 {
1101 _out[i] = __REV(AES->DATA);
1102 }
1103 _out += 4;
1104 }
1105 }
1106
1107
1108 /***************************************************************************//**
1109 * @brief
1110 * Output feedback (OFB) cipher mode encryption/decryption, 128 bit key.
1111 *
1112 * @details
1113 * Encryption:
1114 * @verbatim
1115 * InitVector +----------------+
1116 * | | |
1117 * V | V
1118 * +--------------+ | +--------------+
1119 * Key ->| Block cipher | | Key ->| Block cipher |
1120 * | encryption | | | encryption |
1121 * +--------------+ | +--------------+
1122 * | | |
1123 * |---------+ |
1124 * V V
1125 * Plaintext ->XOR Plaintext ->XOR
1126 * | |
1127 * V V
1128 * Ciphertext Ciphertext
1129 * @endverbatim
1130 * Decryption:
1131 * @verbatim
1132 * InitVector +----------------+
1133 * | | |
1134 * V | V
1135 * +--------------+ | +--------------+
1136 * Key ->| Block cipher | | Key ->| Block cipher |
1137 * | encryption | | | encryption |
1138 * +--------------+ | +--------------+
1139 * | | |
1140 * |---------+ |
1141 * V V
1142 * Ciphertext ->XOR Ciphertext ->XOR
1143 * | |
1144 * V V
1145 * Plaintext Plaintext
1146 * @endverbatim
1147 * Please refer to general comments on layout and byte ordering of parameters.
1148 *
1149 * @param[out] out
1150 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
1151 * may be set equal to @p in, in which case the input buffer is overwritten.
1152 *
1153 * @param[in] in
1154 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
1155 *
1156 * @param[in] len
1157 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
1158 *
1159 * @param[in] key
1160 * 128 bit encryption key.
1161 *
1162 * @param[in] iv
1163 * 128 bit initalization vector to use.
1164 ******************************************************************************/
AES_OFB128(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv)1165 void AES_OFB128(uint8_t *out,
1166 const uint8_t *in,
1167 unsigned int len,
1168 const uint8_t *key,
1169 const uint8_t *iv)
1170 {
1171 int i;
1172 uint32_t *_out = (uint32_t *)out;
1173 const uint32_t *_in = (const uint32_t *)in;
1174 const uint32_t *_key = (const uint32_t *)key;
1175 const uint32_t *_iv = (const uint32_t *)iv;
1176
1177 EFM_ASSERT(!(len % AES_BLOCKSIZE));
1178
1179 /* Select encryption mode, trigger explicitly by command */
1180 AES->CTRL = AES_CTRL_KEYBUFEN;
1181
1182 /* Load key into high key for key buffer usage */
1183 /* Load initialization vector */
1184 for (i = 3; i >= 0; i--)
1185 {
1186 AES->KEYHA = __REV(_key[i]);
1187 AES->DATA = __REV(_iv[i]);
1188 }
1189
1190 /* Encrypt/decrypt data */
1191 len /= AES_BLOCKSIZE;
1192 while (len--)
1193 {
1194 AES->CMD = AES_CMD_START;
1195
1196 /* Wait for completion */
1197 while (AES->STATUS & AES_STATUS_RUNNING)
1198 ;
1199
1200 /* Save encrypted/decrypted data */
1201 for (i = 3; i >= 0; i--)
1202 {
1203 _out[i] = __REV(AES->DATA) ^ _in[i];
1204 }
1205 _out += 4;
1206 _in += 4;
1207 }
1208 }
1209
1210
1211 /***************************************************************************//**
1212 * @brief
1213 * Output feedback (OFB) cipher mode encryption/decryption, 256 bit key.
1214 *
1215 * @details
1216 * Please see AES_OFB128() for OFB figure.
1217 *
1218 * Please refer to general comments on layout and byte ordering of parameters.
1219 *
1220 * @param[out] out
1221 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
1222 * may be set equal to @p in, in which case the input buffer is overwritten.
1223 *
1224 * @param[in] in
1225 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
1226 *
1227 * @param[in] len
1228 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
1229 *
1230 * @param[in] key
1231 * 256 bit encryption key.
1232 *
1233 * @param[in] iv
1234 * 128 bit initalization vector to use.
1235 ******************************************************************************/
AES_OFB256(uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv)1236 void AES_OFB256(uint8_t *out,
1237 const uint8_t *in,
1238 unsigned int len,
1239 const uint8_t *key,
1240 const uint8_t *iv)
1241 {
1242 int i;
1243 int j;
1244 uint32_t *_out = (uint32_t *)out;
1245 const uint32_t *_in = (const uint32_t *)in;
1246 const uint32_t *_key = (const uint32_t *)key;
1247 const uint32_t *_iv = (const uint32_t *)iv;
1248
1249 EFM_ASSERT(!(len % AES_BLOCKSIZE));
1250
1251 /* Select encryption mode, trigger explicitly by command */
1252 AES->CTRL = AES_CTRL_AES256;
1253
1254 /* Load initialization vector */
1255 for (i = 3; i >= 0; i--)
1256 {
1257 AES->DATA = __REV(_iv[i]);
1258 }
1259
1260 /* Encrypt/decrypt data */
1261 len /= AES_BLOCKSIZE;
1262 while (len--)
1263 {
1264 /* Load key */
1265 for (i = 3, j = 7; i >= 0; i--, j--)
1266 {
1267 AES->KEYLA = __REV(_key[j]);
1268 AES->KEYHA = __REV(_key[i]);
1269 }
1270
1271 AES->CMD = AES_CMD_START;
1272
1273 /* Wait for completion */
1274 while (AES->STATUS & AES_STATUS_RUNNING)
1275 ;
1276
1277 /* Save encrypted/decrypted data */
1278 for (i = 3; i >= 0; i--)
1279 {
1280 _out[i] = __REV(AES->DATA) ^ _in[i];
1281 }
1282 _out += 4;
1283 _in += 4;
1284 }
1285 }
1286
1287
1288 /** @} (end addtogroup AES) */
1289 /** @} (end addtogroup EM_Library) */
1290
1291 #endif /* defined(AES_COUNT) && (AES_COUNT > 0) */
1292