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