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