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