1 /***************************************************************************//**
2 * @file
3 * @brief Cryptography 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 #include "em_device.h"
31
32 #if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
33
34 #include "em_crypto.h"
35 #include "sl_assert.h"
36 #include <stddef.h>
37 #include <string.h>
38
39 /***************************************************************************//**
40 * @addtogroup crypto
41 * @{
42 ******************************************************************************/
43
44 /*******************************************************************************
45 ******************************* DEFINES ***********************************
46 ******************************************************************************/
47
48 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
49
50 #define CRYPTO_INSTRUCTIONS_PER_REG (4UL)
51 #define CRYPTO_INSTRUCTIONS_MAX (12UL)
52 #define CRYPTO_INSTRUCTION_REGS (CRYPTO_INSTRUCTIONS_MAX / CRYPTO_INSTRUCTIONS_PER_REG)
53
54 #define CRYPTO_SHA1_BLOCK_SIZE_IN_BITS (512UL)
55 #define CRYPTO_SHA1_BLOCK_SIZE_IN_BYTES (CRYPTO_SHA1_BLOCK_SIZE_IN_BITS / 8UL)
56 #define CRYPTO_SHA1_BLOCK_SIZE_IN_32BIT_WORDS (CRYPTO_SHA1_BLOCK_SIZE_IN_BYTES / sizeof(uint32_t))
57 #define CRYPTO_SHA1_DIGEST_SIZE_IN_32BIT_WORDS (CRYPTO_SHA1_DIGEST_SIZE_IN_BYTES / sizeof(uint32_t))
58
59 #define CRYPTO_SHA256_BLOCK_SIZE_IN_BITS (512UL)
60 #define CRYPTO_SHA256_BLOCK_SIZE_IN_BYTES (CRYPTO_SHA256_BLOCK_SIZE_IN_BITS / 8UL)
61 #define CRYPTO_SHA256_BLOCK_SIZE_IN_32BIT_WORDS (CRYPTO_SHA256_BLOCK_SIZE_IN_BYTES / sizeof(uint32_t))
62
63 #define CRYPTO_SHA256_DIGEST_SIZE_IN_32BIT_WORDS (CRYPTO_SHA256_DIGEST_SIZE_IN_BYTES / sizeof(uint32_t))
64
65 #define PARTIAL_OPERAND_WIDTH_LOG2 (7UL) /* 2^7 = 128 */
66 #define PARTIAL_OPERAND_WIDTH (1UL << PARTIAL_OPERAND_WIDTH_LOG2)
67 #define PARTIAL_OPERAND_WIDTH_MASK (PARTIAL_OPERAND_WIDTH - 1UL)
68 #define PARTIAL_OPERAND_WIDTH_IN_BYTES (PARTIAL_OPERAND_WIDTH / 8UL)
69 #define PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS (PARTIAL_OPERAND_WIDTH_IN_BYTES / sizeof(uint32_t))
70
71 #define SWAP32(x) (__REV(x))
72
73 #define CRYPTO_AES_BLOCKSIZE (16UL)
74
75 /*******************************************************************************
76 *********************** STATIC FUNCTIONS **********************************
77 ******************************************************************************/
78
79 #ifdef USE_VARIABLE_SIZED_DATA_LOADS
80 __STATIC_INLINE void CRYPTO_DataWriteVariableSize(CRYPTO_DataReg_TypeDef dataReg,
81 const CRYPTO_Data_TypeDef val,
82 int valSize);
83 #endif // USE_VARIABLE_SIZED_DATA_LOADS
84
85 __STATIC_INLINE void cryptoBurstToCryptoAndZeroize(volatile uint32_t * reg,
86 const uint32_t * val);
87
88 __STATIC_INLINE void cryptoBurstFromCryptoAndZeroize(volatile uint32_t * reg,
89 uint32_t * val);
90
91 __STATIC_INLINE void cryptoBigintZeroize(uint32_t * words32bits,
92 unsigned num32bitWords);
93
94 __STATIC_INLINE void cryptoBigintIncrement(uint32_t * words32bits,
95 unsigned num32bitWords);
96
97 __STATIC_INLINE void CRYPTO_AES_ProcessLoop(CRYPTO_TypeDef *crypto,
98 unsigned int len,
99 CRYPTO_DataReg_TypeDef inReg,
100 const uint8_t * in,
101 CRYPTO_DataReg_TypeDef outReg,
102 uint8_t * out);
103
104 static void CRYPTO_AES_CBCx(CRYPTO_TypeDef *crypto,
105 uint8_t * out,
106 const uint8_t * in,
107 unsigned int len,
108 const uint8_t * key,
109 const uint8_t * iv,
110 bool encrypt,
111 CRYPTO_KeyWidth_TypeDef keyWidth);
112
113 static void CRYPTO_AES_PCBCx(CRYPTO_TypeDef *crypto,
114 uint8_t * out,
115 const uint8_t * in,
116 unsigned int len,
117 const uint8_t * key,
118 const uint8_t * iv,
119 bool encrypt,
120 CRYPTO_KeyWidth_TypeDef keyWidth);
121
122 static void CRYPTO_AES_CFBx(CRYPTO_TypeDef *crypto,
123 uint8_t * out,
124 const uint8_t * in,
125 unsigned int len,
126 const uint8_t * key,
127 const uint8_t * iv,
128 bool encrypt,
129 CRYPTO_KeyWidth_TypeDef keyWidth);
130
131 static void CRYPTO_AES_CTRx(CRYPTO_TypeDef *crypto,
132 uint8_t * out,
133 const uint8_t * in,
134 unsigned int len,
135 const uint8_t * key,
136 uint8_t * ctr,
137 CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc,
138 CRYPTO_KeyWidth_TypeDef keyWidth);
139
140 static void CRYPTO_AES_ECBx(CRYPTO_TypeDef *crypto,
141 uint8_t * out,
142 const uint8_t * in,
143 unsigned int len,
144 const uint8_t * key,
145 bool encrypt,
146 CRYPTO_KeyWidth_TypeDef keyWidth);
147
148 static void CRYPTO_AES_OFBx(CRYPTO_TypeDef *crypto,
149 uint8_t * out,
150 const uint8_t * in,
151 unsigned int len,
152 const uint8_t * key,
153 const uint8_t * iv,
154 CRYPTO_KeyWidth_TypeDef keyWidth);
155
156 #ifdef USE_VARIABLE_SIZED_DATA_LOADS
157 /***************************************************************************//**
158 * @brief
159 * Write variable sized 32 bit data array (max 128 bits) to a DATAX register.
160 *
161 * @details
162 * Write variable sized 32 bit array (max 128 bits / 4 words) to a DATAX
163 * register in the CRYPTO module.
164 *
165 * @param[in] dataReg The 128 bits DATA register.
166 * @param[in] val Value of the data to write to the DATA register.
167 * @param[in] valSize Size of @ref val in number of 32 bit words.
168 ******************************************************************************/
169 __STATIC_INLINE
CRYPTO_DataWriteVariableSize(CRYPTO_DataReg_TypeDef dataReg,const CRYPTO_Data_TypeDef val,int valSize)170 void CRYPTO_DataWriteVariableSize(CRYPTO_DataReg_TypeDef dataReg,
171 const CRYPTO_Data_TypeDef val,
172 int valSize)
173 {
174 int i;
175 volatile uint32_t * reg = (volatile uint32_t *) dataReg;
176
177 if (valSize < 4) {
178 /* Non optimal write of data. */
179 for (i = 0; i < valSize; i++) {
180 *reg = *val++;
181 }
182 for (; i < 4; i++) {
183 *reg = 0;
184 }
185 } else {
186 CRYPTO_BurstToCrypto(reg, &val[0]);
187 }
188 }
189 #endif
190
191 /** @endcond */
192
193 /*******************************************************************************
194 ************************** GLOBAL FUNCTIONS *******************************
195 ******************************************************************************/
CRYPTO_BurstToCrypto(volatile uint32_t * reg,const uint32_t * val)196 void CRYPTO_BurstToCrypto(volatile uint32_t * reg,
197 const uint32_t * val)
198 {
199 /* Load data from memory into local registers. */
200 register uint32_t v0 = val[0];
201 register uint32_t v1 = val[1];
202 register uint32_t v2 = val[2];
203 register uint32_t v3 = val[3];
204 /* Store data to CRYPTO */
205 *reg = v0;
206 *reg = v1;
207 *reg = v2;
208 *reg = v3;
209 }
210
CRYPTO_BurstFromCrypto(volatile uint32_t * reg,uint32_t * val)211 void CRYPTO_BurstFromCrypto(volatile uint32_t * reg, uint32_t * val)
212 {
213 /* Load data from CRYPTO into local registers. */
214 register uint32_t v0 = *reg;
215 register uint32_t v1 = *reg;
216 register uint32_t v2 = *reg;
217 register uint32_t v3 = *reg;
218 /* Store data to memory */
219 val[0] = v0;
220 val[1] = v1;
221 val[2] = v2;
222 val[3] = v3;
223 }
224
CRYPTO_DataWrite(CRYPTO_DataReg_TypeDef dataReg,const CRYPTO_Data_TypeDef val)225 void CRYPTO_DataWrite(CRYPTO_DataReg_TypeDef dataReg,
226 const CRYPTO_Data_TypeDef val)
227 {
228 CRYPTO_BurstToCrypto(dataReg, val);
229 }
230
CRYPTO_DataWriteUnaligned(volatile uint32_t * reg,const uint8_t * val)231 void CRYPTO_DataWriteUnaligned(volatile uint32_t * reg,
232 const uint8_t * val)
233 {
234 /* Check data is 32-bit aligned, if not move to temporary buffer before
235 writing.*/
236 if ((uintptr_t)val & 0x3) {
237 uint32_t temp[4];
238 memcpy(temp, val, sizeof(temp));
239 CRYPTO_DataWrite(reg, temp);
240 } else {
241 // Avoid casting val directly to uint32_t pointer as this can lead to the
242 // compiler making incorrect assumptions in the case where val is un-
243 // aligned.
244 const uint8_t * volatile tmp_val_ptr = val;
245 CRYPTO_DataWrite(reg, (const uint32_t*)tmp_val_ptr);
246 }
247 }
248
CRYPTO_DataRead(CRYPTO_DataReg_TypeDef dataReg,CRYPTO_Data_TypeDef val)249 void CRYPTO_DataRead(CRYPTO_DataReg_TypeDef dataReg,
250 CRYPTO_Data_TypeDef val)
251 {
252 CRYPTO_BurstFromCrypto(dataReg, val);
253 }
254
CRYPTO_DataReadUnaligned(volatile uint32_t * reg,uint8_t * val)255 void CRYPTO_DataReadUnaligned(volatile uint32_t * reg,
256 uint8_t * val)
257 {
258 /* Check data is 32bit aligned, if not, read into temporary buffer and
259 then move to user buffer. */
260 if ((uintptr_t)val & 0x3) {
261 uint32_t temp[4];
262 CRYPTO_DataRead(reg, temp);
263 memcpy(val, temp, sizeof(temp));
264 } else {
265 // Avoid casting val directly to uint32_t pointer as this can lead to the
266 // compiler making incorrect assumptions in the case where val is un-
267 // aligned.
268 uint8_t * volatile tmp_val_ptr = val;
269 CRYPTO_DataRead(reg, (uint32_t*)tmp_val_ptr);
270 }
271 }
272
CRYPTO_DDataWrite(CRYPTO_DDataReg_TypeDef ddataReg,const CRYPTO_DData_TypeDef val)273 void CRYPTO_DDataWrite(CRYPTO_DDataReg_TypeDef ddataReg,
274 const CRYPTO_DData_TypeDef val)
275 {
276 CRYPTO_BurstToCrypto(ddataReg, &val[0]);
277 CRYPTO_BurstToCrypto(ddataReg, &val[4]);
278 }
279
CRYPTO_DDataRead(CRYPTO_DDataReg_TypeDef ddataReg,CRYPTO_DData_TypeDef val)280 void CRYPTO_DDataRead(CRYPTO_DDataReg_TypeDef ddataReg,
281 CRYPTO_DData_TypeDef val)
282 {
283 CRYPTO_BurstFromCrypto(ddataReg, &val[0]);
284 CRYPTO_BurstFromCrypto(ddataReg, &val[4]);
285 }
286
CRYPTO_DDataReadUnaligned(CRYPTO_DDataReg_TypeDef ddataReg,uint8_t * val)287 void CRYPTO_DDataReadUnaligned(CRYPTO_DDataReg_TypeDef ddataReg,
288 uint8_t * val)
289 {
290 /* Check if the buffer pointer is 32-bit aligned, if not read the data into a
291 temporary 32-bit aligned buffer then copy the data to the output buffer.*/
292 if ((uintptr_t)val & 0x3) {
293 CRYPTO_DData_TypeDef temp;
294 CRYPTO_DDataRead(ddataReg, temp);
295 memcpy(val, temp, sizeof(temp));
296 } else {
297 // Avoid casting val directly to uint32_t pointer as this can lead to the
298 // compiler making incorrect assumptions in the case where val is un-
299 // aligned.
300 uint8_t * volatile tmp_val_ptr = val;
301 CRYPTO_DDataRead(ddataReg, (uint32_t*) tmp_val_ptr);
302 }
303 }
304
CRYPTO_QDataRead(CRYPTO_QDataReg_TypeDef qdataReg,CRYPTO_QData_TypeDef val)305 void CRYPTO_QDataRead(CRYPTO_QDataReg_TypeDef qdataReg,
306 CRYPTO_QData_TypeDef val)
307 {
308 CRYPTO_BurstFromCrypto(qdataReg, &val[0]);
309 CRYPTO_BurstFromCrypto(qdataReg, &val[4]);
310 CRYPTO_BurstFromCrypto(qdataReg, &val[8]);
311 CRYPTO_BurstFromCrypto(qdataReg, &val[12]);
312 }
313
CRYPTO_QDataWrite(CRYPTO_QDataReg_TypeDef qdataReg,const CRYPTO_QData_TypeDef val)314 void CRYPTO_QDataWrite(CRYPTO_QDataReg_TypeDef qdataReg,
315 const CRYPTO_QData_TypeDef val)
316 {
317 CRYPTO_BurstToCrypto(qdataReg, &val[0]);
318 CRYPTO_BurstToCrypto(qdataReg, &val[4]);
319 CRYPTO_BurstToCrypto(qdataReg, &val[8]);
320 CRYPTO_BurstToCrypto(qdataReg, &val[12]);
321 }
322
CRYPTO_QDataWriteUnaligned(CRYPTO_QDataReg_TypeDef qdataReg,const uint8_t * val)323 void CRYPTO_QDataWriteUnaligned(CRYPTO_QDataReg_TypeDef qdataReg,
324 const uint8_t * val)
325 {
326 /* Check data is 32-bit aligned,
327 if not move to temporary 32-bit aligned buffer before writing. */
328 if ((uintptr_t)val & 0x3) {
329 CRYPTO_QData_TypeDef temp;
330 memcpy(temp, val, sizeof(temp));
331 CRYPTO_QDataWrite(qdataReg, temp);
332 } else {
333 // Avoid casting val directly to uint32_t pointer as this can lead to the
334 // compiler making incorrect assumptions in the case where val is un-
335 // aligned.
336 const uint8_t * volatile tmp_val_ptr = val;
337 CRYPTO_QDataWrite(qdataReg, (const uint32_t*) tmp_val_ptr);
338 }
339 }
340
341 // Write sensitive value (typically key) to CRYPTO and zeroize local registers.
342 // Sensitive values in local registers may leak to stack or read directly by
343 // malicious software.
cryptoBurstToCryptoAndZeroize(volatile uint32_t * reg,const uint32_t * val)344 __STATIC_INLINE void cryptoBurstToCryptoAndZeroize(volatile uint32_t * reg,
345 const uint32_t * val)
346 {
347 /* Load data from memory into local registers. */
348 register volatile uint32_t v0 = val[0];
349 register volatile uint32_t v1 = val[1];
350 register volatile uint32_t v2 = val[2];
351 register volatile uint32_t v3 = val[3];
352 /* Store data to CRYPTO */
353 *reg = v0;
354 *reg = v1;
355 *reg = v2;
356 *reg = v3;
357 v0 = 0;
358 v1 = 0;
359 v2 = 0;
360 v3 = 0;
361 }
362
363 // Read sensitive value (typically key) from CRYPTO and zeroize local registers.
364 // Sensitive values in local registers may leak to stack or read directly by
365 // malicious software.
cryptoBurstFromCryptoAndZeroize(volatile uint32_t * reg,uint32_t * val)366 __STATIC_INLINE void cryptoBurstFromCryptoAndZeroize(volatile uint32_t * reg, uint32_t * val)
367 {
368 /* Load data from CRYPTO into local registers. */
369 register volatile uint32_t v0 = *reg;
370 register volatile uint32_t v1 = *reg;
371 register volatile uint32_t v2 = *reg;
372 register volatile uint32_t v3 = *reg;
373 /* Store data to memory */
374 val[0] = v0;
375 val[1] = v1;
376 val[2] = v2;
377 val[3] = v3;
378 v0 = 0;
379 v1 = 0;
380 v2 = 0;
381 v3 = 0;
382 }
383
CRYPTO_KeyBufWrite(CRYPTO_TypeDef * crypto,CRYPTO_KeyBuf_TypeDef val,CRYPTO_KeyWidth_TypeDef keyWidth)384 void CRYPTO_KeyBufWrite(CRYPTO_TypeDef *crypto,
385 CRYPTO_KeyBuf_TypeDef val,
386 CRYPTO_KeyWidth_TypeDef keyWidth)
387 {
388 if (keyWidth == cryptoKey256Bits) {
389 /* Set AES-256 mode */
390 BUS_RegBitWrite(&crypto->CTRL, _CRYPTO_CTRL_AES_SHIFT, _CRYPTO_CTRL_AES_AES256);
391 /* Load key in KEYBUF register (= DDATA4) */
392 cryptoBurstToCryptoAndZeroize(&crypto->DDATA4, &val[0]);
393 cryptoBurstToCryptoAndZeroize(&crypto->DDATA4, &val[4]);
394 } else {
395 /* Set AES-128 mode */
396 BUS_RegBitWrite(&crypto->CTRL, _CRYPTO_CTRL_AES_SHIFT, _CRYPTO_CTRL_AES_AES128);
397 cryptoBurstToCryptoAndZeroize(&crypto->KEYBUF, &val[0]);
398 }
399 }
400
CRYPTO_KeyBufWriteUnaligned(CRYPTO_TypeDef * crypto,const uint8_t * val,CRYPTO_KeyWidth_TypeDef keyWidth)401 void CRYPTO_KeyBufWriteUnaligned(CRYPTO_TypeDef *crypto,
402 const uint8_t * val,
403 CRYPTO_KeyWidth_TypeDef keyWidth)
404 {
405 /* Check if key val buffer is 32bit aligned, if not move to temporary
406 aligned buffer before writing.*/
407 if ((uintptr_t)val & 0x3) {
408 CRYPTO_KeyBuf_TypeDef temp;
409 if (keyWidth == cryptoKey128Bits) {
410 memcpy(temp, val, 16);
411 } else {
412 memcpy(temp, val, 32);
413 }
414 CRYPTO_KeyBufWrite(crypto, temp, keyWidth);
415 // Wipe out the plaintext key from the temp buffer on stack.
416 cryptoBigintZeroize(temp,
417 keyWidth == cryptoKey128Bits
418 ? CRYPTO_DATA_SIZE_IN_32BIT_WORDS
419 : CRYPTO_DDATA_SIZE_IN_32BIT_WORDS);
420 } else {
421 // Avoid casting val directly to uint32_t pointer as this can lead to the
422 // compiler making incorrect assumptions in the case where val is un-
423 // aligned.
424 const uint8_t * volatile tmp_val_ptr = val;
425 CRYPTO_KeyBufWrite(crypto, (uint32_t*)tmp_val_ptr, keyWidth);
426 }
427 }
428
CRYPTO_KeyBuf128Write(CRYPTO_TypeDef * crypto,const uint32_t * val)429 void CRYPTO_KeyBuf128Write(CRYPTO_TypeDef *crypto,
430 const uint32_t * val)
431 {
432 CRYPTO_BurstToCrypto(&crypto->KEYBUF, val);
433 }
434
CRYPTO_ModulusSet(CRYPTO_TypeDef * crypto,CRYPTO_ModulusId_TypeDef modulusId)435 void CRYPTO_ModulusSet(CRYPTO_TypeDef * crypto,
436 CRYPTO_ModulusId_TypeDef modulusId)
437 {
438 uint32_t temp = crypto->WAC & (~(_CRYPTO_WAC_MODULUS_MASK | _CRYPTO_WAC_MODOP_MASK));
439
440 switch (modulusId) {
441 case cryptoModulusBin256:
442 case cryptoModulusBin128:
443 case cryptoModulusGcmBin128:
444 case cryptoModulusEccB233:
445 case cryptoModulusEccB163:
446 #ifdef _CRYPTO_WAC_MODULUS_ECCBIN233N
447 case cryptoModulusEccB233Order:
448 case cryptoModulusEccB233KOrder:
449 case cryptoModulusEccB163Order:
450 case cryptoModulusEccB163KOrder:
451 #endif
452 crypto->WAC = temp | (uint32_t)modulusId | CRYPTO_WAC_MODOP_BINARY;
453 break;
454
455 case cryptoModulusEccP256:
456 case cryptoModulusEccP224:
457 case cryptoModulusEccP192:
458 #ifdef _CRYPTO_WAC_MODULUS_ECCPRIME256P
459 case cryptoModulusEccP256Order:
460 case cryptoModulusEccP224Order:
461 case cryptoModulusEccP192Order:
462 #endif
463 crypto->WAC = temp | (uint32_t)modulusId | CRYPTO_WAC_MODOP_REGULAR;
464 break;
465
466 default:
467 /* Unknown modulus identifier. */
468 EFM_ASSERT(false);
469 break;
470 }
471 }
472
473 /***************************************************************************//**
474 * @brief
475 * Read the key value currently used by the CRYPTO module.
476 *
477 * @details
478 * Read 128 bits or 256 bits from the KEY register in the CRYPTO module.
479 *
480 * @param[in] crypto
481 * A pointer to the CRYPTO peripheral register block.
482 *
483 * @param[in] val
484 * A value of the data to write to the KEYBUF register.
485 *
486 * @param[in] keyWidth
487 * Key width - 128 or 256 bits
488 ******************************************************************************/
CRYPTO_KeyRead(CRYPTO_TypeDef * crypto,CRYPTO_KeyBuf_TypeDef val,CRYPTO_KeyWidth_TypeDef keyWidth)489 void CRYPTO_KeyRead(CRYPTO_TypeDef * crypto,
490 CRYPTO_KeyBuf_TypeDef val,
491 CRYPTO_KeyWidth_TypeDef keyWidth)
492 {
493 EFM_ASSERT(&val[0] != NULL);
494
495 cryptoBurstFromCryptoAndZeroize(&crypto->KEY, &val[0]);
496 if (keyWidth == cryptoKey256Bits) {
497 cryptoBurstFromCryptoAndZeroize(&crypto->KEY, &val[4]);
498 }
499 }
500
501 /***************************************************************************//**
502 * @brief
503 * Read the key value currently used by the CRYPTO module.
504 *
505 * @details
506 * Read 128 bits or 256 bits from the KEY register in the CRYPTO module.
507 * The destination pointer does not have to be word-aligned, but an unaligned
508 * pointer might incur a performance penalty.
509 *
510 * @param[in] crypto
511 * A pointer to the CRYPTO peripheral register block.
512 *
513 * @param[in] val
514 * A pointer to a buffer which the key will be written to.
515 * Can be unaligned.
516 *
517 * @param[in] keyWidth
518 * Key width - 128 or 256 bits
519 ******************************************************************************/
CRYPTO_KeyReadUnaligned(CRYPTO_TypeDef * crypto,uint8_t * val,CRYPTO_KeyWidth_TypeDef keyWidth)520 void CRYPTO_KeyReadUnaligned(CRYPTO_TypeDef * crypto,
521 uint8_t * val,
522 CRYPTO_KeyWidth_TypeDef keyWidth)
523 {
524 if ((uint32_t)val & 0x3) {
525 CRYPTO_KeyBuf_TypeDef temp;
526 CRYPTO_KeyRead(crypto, temp, keyWidth);
527 if (keyWidth == cryptoKey128Bits) {
528 memcpy(val, temp, 16);
529 } else {
530 memcpy(val, temp, 32);
531 }
532 // Wipe out the plaintext key from the temp buffer on stack.
533 cryptoBigintZeroize(temp,
534 keyWidth == cryptoKey128Bits
535 ? CRYPTO_DATA_SIZE_IN_32BIT_WORDS
536 : CRYPTO_DDATA_SIZE_IN_32BIT_WORDS);
537 } else {
538 // Avoid casting val directly to uint32_t pointer as this can lead to the
539 // compiler making incorrect assumptions in the case where val is un-
540 // aligned.
541 uint8_t * volatile tmp_val_ptr = val;
542 CRYPTO_KeyRead(crypto, (uint32_t*)tmp_val_ptr, keyWidth);
543 }
544 }
545
546 /***************************************************************************//**
547 * @brief
548 * Perform a SHA-1 hash operation on a message.
549 *
550 * @details
551 * This function performs a SHA-1 hash operation on the message specified by
552 * msg with length msgLen and returns the message digest in msgDigest.
553 *
554 * @param[in] crypto
555 * A pointer to the CRYPTO peripheral register block.
556 *
557 * @param[in] msg
558 * Message to hash.
559 *
560 * @param[in] msgLen
561 * Length of message in bytes.
562 *
563 * @param[out] msgDigest
564 * A message digest.
565 ******************************************************************************/
CRYPTO_SHA_1(CRYPTO_TypeDef * crypto,const uint8_t * msg,uint64_t msgLen,CRYPTO_SHA1_Digest_TypeDef msgDigest)566 void CRYPTO_SHA_1(CRYPTO_TypeDef * crypto,
567 const uint8_t * msg,
568 uint64_t msgLen,
569 CRYPTO_SHA1_Digest_TypeDef msgDigest)
570 {
571 uint32_t temp;
572 uint32_t len;
573 int blockLen;
574 uint32_t shaBlock[CRYPTO_SHA1_BLOCK_SIZE_IN_32BIT_WORDS];
575 uint8_t * p8ShaBlock = (uint8_t *) shaBlock;
576
577 /* Initialize the CRYPTO module to do SHA-1. */
578 crypto->CTRL = CRYPTO_CTRL_SHA_SHA1;
579 crypto->SEQCTRL = 0;
580 crypto->SEQCTRLB = 0;
581
582 /* Set the result width of the MADD32 operation. */
583 CRYPTO_ResultWidthSet(crypto, cryptoResult256Bits);
584
585 /* Write the initialization value to DDATA1. */
586 crypto->DDATA1 = 0x67452301UL;
587 crypto->DDATA1 = 0xefcdab89UL;
588 crypto->DDATA1 = 0x98badcfeUL;
589 crypto->DDATA1 = 0x10325476UL;
590 crypto->DDATA1 = 0xc3d2e1f0UL;
591 crypto->DDATA1 = 0x00000000UL;
592 crypto->DDATA1 = 0x00000000UL;
593 crypto->DDATA1 = 0x00000000UL;
594
595 /* Copy data to DDATA0 and select DDATA0 and DDATA1 for SHA operation. */
596 CRYPTO_EXECUTE_2(crypto,
597 CRYPTO_CMD_INSTR_DDATA1TODDATA0,
598 CRYPTO_CMD_INSTR_SELDDATA0DDATA1);
599
600 len = (uint32_t)msgLen;
601
602 while (len >= CRYPTO_SHA1_BLOCK_SIZE_IN_BYTES) {
603 /* Write block to QDATA1. */
604 CRYPTO_InstructionSequenceWait(crypto);
605 CRYPTO_QDataWriteUnaligned(&crypto->QDATA1BIG, msg);
606
607 /* Execute SHA. */
608 CRYPTO_EXECUTE_3(crypto,
609 CRYPTO_CMD_INSTR_SHA,
610 CRYPTO_CMD_INSTR_MADD32,
611 CRYPTO_CMD_INSTR_DDATA0TODDATA1);
612
613 len -= CRYPTO_SHA1_BLOCK_SIZE_IN_BYTES;
614 msg += CRYPTO_SHA1_BLOCK_SIZE_IN_BYTES;
615 }
616
617 blockLen = 0;
618
619 /* Build the last (or second to last) block. */
620 for (; len > 0U; len--) {
621 p8ShaBlock[blockLen++] = *msg++;
622 }
623
624 /* Append the '1' bit. */
625 p8ShaBlock[blockLen++] = 0x80;
626
627 /* If the length is currently above 56 bytes, zeros are appended
628 * then compressed. Then, zeros are padded and length
629 * encoded like normal.
630 */
631 if (blockLen > 56) {
632 while (blockLen < 64) {
633 p8ShaBlock[blockLen++] = 0;
634 }
635
636 /* Write block to QDATA1BIG. */
637 CRYPTO_InstructionSequenceWait(crypto);
638 CRYPTO_QDataWrite(&crypto->QDATA1BIG, shaBlock);
639
640 /* Execute SH. */
641 CRYPTO_EXECUTE_3(crypto,
642 CRYPTO_CMD_INSTR_SHA,
643 CRYPTO_CMD_INSTR_MADD32,
644 CRYPTO_CMD_INSTR_DDATA0TODDATA1);
645 blockLen = 0;
646 }
647
648 /* Pad up to 56 bytes of zeros. */
649 while (blockLen < 56) {
650 p8ShaBlock[blockLen++] = 0;
651 }
652
653 /* Finally, encode the message length. */
654 {
655 uint64_t msgLenInBits = msgLen << 3U;
656 temp = (uint32_t)(msgLenInBits >> 32U);
657 *(uint32_t*)&p8ShaBlock[56] = SWAP32(temp);
658 temp = (uint32_t)msgLenInBits & 0xFFFFFFFFUL;
659 *(uint32_t*)&p8ShaBlock[60] = SWAP32(temp);
660 }
661
662 /* Write block to QDATA1BIG. */
663 CRYPTO_InstructionSequenceWait(crypto);
664 CRYPTO_QDataWrite(&crypto->QDATA1BIG, shaBlock);
665
666 /* Execute SHA. */
667 CRYPTO_EXECUTE_3(crypto,
668 CRYPTO_CMD_INSTR_SHA,
669 CRYPTO_CMD_INSTR_MADD32,
670 CRYPTO_CMD_INSTR_DDATA0TODDATA1);
671
672 /* Read the resulting message digest from DDATA0BIG. */
673 CRYPTO_InstructionSequenceWait(crypto);
674
675 /* Check if the buffer pointer is 32-bit aligned, if not read the data into a
676 temporary 32-bit aligned buffer then copy the data to the output buffer.*/
677 if ((uintptr_t)msgDigest & 0x3) {
678 CRYPTO_DData_TypeDef tempDData;
679 CRYPTO_DDataRead(&crypto->DDATA0BIG, tempDData);
680 memcpy(msgDigest, tempDData, sizeof(CRYPTO_SHA1_Digest_TypeDef));
681 } else {
682 ((uint32_t*)msgDigest)[0] = crypto->DDATA0BIG;
683 ((uint32_t*)msgDigest)[1] = crypto->DDATA0BIG;
684 ((uint32_t*)msgDigest)[2] = crypto->DDATA0BIG;
685 ((uint32_t*)msgDigest)[3] = crypto->DDATA0BIG;
686 ((uint32_t*)msgDigest)[4] = crypto->DDATA0BIG;
687 crypto->DDATA0BIG;
688 crypto->DDATA0BIG;
689 crypto->DDATA0BIG;
690 }
691 }
692
693 /***************************************************************************//**
694 * @brief
695 * Perform a SHA-256 hash operation on a message.
696 *
697 * @details
698 * This function performs a SHA-256 hash operation on the message specified
699 * by msg with length msgLen and returns the message digest in msgDigest.
700 *
701 * @param[in] crypto
702 * A pointer to the CRYPTO peripheral register block.
703 *
704 * @param[in] msg
705 * A message to hash.
706 *
707 * @param[in] msgLen
708 * The length of message in bytes.
709 *
710 * @param[out] msgDigest
711 * A message digest.
712 ******************************************************************************/
CRYPTO_SHA_256(CRYPTO_TypeDef * crypto,const uint8_t * msg,uint64_t msgLen,CRYPTO_SHA256_Digest_TypeDef msgDigest)713 void CRYPTO_SHA_256(CRYPTO_TypeDef * crypto,
714 const uint8_t * msg,
715 uint64_t msgLen,
716 CRYPTO_SHA256_Digest_TypeDef msgDigest)
717 {
718 uint32_t temp;
719 uint32_t len;
720 int blockLen;
721 uint32_t shaBlock[CRYPTO_SHA256_BLOCK_SIZE_IN_32BIT_WORDS];
722 uint8_t * p8ShaBlock = (uint8_t *) shaBlock;
723
724 /* Initial values */
725 shaBlock[0] = 0x6a09e667UL;
726 shaBlock[1] = 0xbb67ae85UL;
727 shaBlock[2] = 0x3c6ef372UL;
728 shaBlock[3] = 0xa54ff53aUL;
729 shaBlock[4] = 0x510e527fUL;
730 shaBlock[5] = 0x9b05688cUL;
731 shaBlock[6] = 0x1f83d9abUL;
732 shaBlock[7] = 0x5be0cd19UL;
733
734 /* Initialize the CRYPTO module to do SHA-256 (SHA-2). */
735 crypto->CTRL = CRYPTO_CTRL_SHA_SHA2;
736 crypto->SEQCTRL = 0;
737 crypto->SEQCTRLB = 0;
738
739 /* Set the result width of the MADD32 operation. */
740 CRYPTO_ResultWidthSet(crypto, cryptoResult256Bits);
741
742 /* Write the initialization value to DDATA1. */
743 CRYPTO_DDataWrite(&crypto->DDATA1, shaBlock);
744
745 /* Copy data ot DDATA0 and select DDATA0 and DDATA1 for SHA operation. */
746 CRYPTO_EXECUTE_2(crypto,
747 CRYPTO_CMD_INSTR_DDATA1TODDATA0,
748 CRYPTO_CMD_INSTR_SELDDATA0DDATA1);
749 len = (uint32_t)msgLen;
750
751 while (len >= CRYPTO_SHA256_BLOCK_SIZE_IN_BYTES) {
752 /* Write block to QDATA1BIG. */
753 CRYPTO_InstructionSequenceWait(crypto);
754 CRYPTO_QDataWriteUnaligned(&crypto->QDATA1BIG, msg);
755
756 /* Execute SHA. */
757 CRYPTO_EXECUTE_3(crypto,
758 CRYPTO_CMD_INSTR_SHA,
759 CRYPTO_CMD_INSTR_MADD32,
760 CRYPTO_CMD_INSTR_DDATA0TODDATA1);
761
762 len -= CRYPTO_SHA256_BLOCK_SIZE_IN_BYTES;
763 msg += CRYPTO_SHA256_BLOCK_SIZE_IN_BYTES;
764 }
765
766 blockLen = 0;
767
768 /* Build the last (or second to last) block. */
769 for (; len > 0U; len--) {
770 p8ShaBlock[blockLen++] = *msg++;
771 }
772
773 /* Append the '1' bit. */
774 p8ShaBlock[blockLen++] = 0x80;
775
776 /* If the length is currently above 56 bytes, zeros are appended
777 * then compressed. Then, zeros are padded and length
778 * encoded like normal.
779 */
780 if (blockLen > 56) {
781 while (blockLen < 64) {
782 p8ShaBlock[blockLen++] = 0;
783 }
784
785 /* Write block to QDATA1BIG. */
786 CRYPTO_InstructionSequenceWait(crypto);
787 CRYPTO_QDataWrite(&crypto->QDATA1BIG, shaBlock);
788
789 /* Execute SHA. */
790 CRYPTO_EXECUTE_3(crypto,
791 CRYPTO_CMD_INSTR_SHA,
792 CRYPTO_CMD_INSTR_MADD32,
793 CRYPTO_CMD_INSTR_DDATA0TODDATA1);
794 blockLen = 0;
795 }
796
797 /* Pad up to 56 bytes of zeros. */
798 while (blockLen < 56) {
799 p8ShaBlock[blockLen++] = 0;
800 }
801
802 /* Finally, encode the message length. */
803 {
804 uint64_t msgLenInBits = msgLen << 3;
805 temp = (uint32_t)(msgLenInBits >> 32);
806 *(uint32_t *)&p8ShaBlock[56] = SWAP32(temp);
807 temp = (uint32_t)msgLenInBits & 0xFFFFFFFFUL;
808 *(uint32_t *)&p8ShaBlock[60] = SWAP32(temp);
809 }
810
811 /* Write the final block to QDATA1BIG. */
812 CRYPTO_InstructionSequenceWait(crypto);
813 CRYPTO_QDataWrite(&crypto->QDATA1BIG, shaBlock);
814
815 /* Execute SHA. */
816 CRYPTO_EXECUTE_3(crypto,
817 CRYPTO_CMD_INSTR_SHA,
818 CRYPTO_CMD_INSTR_MADD32,
819 CRYPTO_CMD_INSTR_DDATA0TODDATA1);
820
821 /* Read the resulting message digest from DDATA0BIG. */
822 CRYPTO_InstructionSequenceWait(crypto);
823 CRYPTO_DDataReadUnaligned(&crypto->DDATA0BIG, msgDigest);
824 }
825
826 /***************************************************************************//**
827 * @brief
828 * Set the 32 bit word array to zero.
829 *
830 * @param[in] words32bits A pointer to the 32 bit word array.
831 * @param[in] num32bitWords A number of 32 bit words in array.
832 ******************************************************************************/
cryptoBigintZeroize(uint32_t * words32bits,unsigned num32bitWords)833 __STATIC_INLINE void cryptoBigintZeroize(uint32_t * words32bits,
834 unsigned num32bitWords)
835 {
836 volatile uint32_t *p = words32bits;
837 while (num32bitWords--) {
838 *p++ = 0;
839 }
840 }
841
842 /***************************************************************************//**
843 * @brief
844 * Increment value of 32bit word array by one.
845 *
846 * @param[in] words32bits Pointer to 32bit word array
847 * @param[in] num32bitWords Number of 32bit words in array
848 ******************************************************************************/
cryptoBigintIncrement(uint32_t * words32bits,unsigned num32bitWords)849 __STATIC_INLINE void cryptoBigintIncrement(uint32_t * words32bits,
850 unsigned num32bitWords)
851 {
852 unsigned i;
853 for (i = 0; i < num32bitWords; i++) {
854 if (++words32bits[i] != 0UL) {
855 break;
856 }
857 }
858 return;
859 }
860
861 /***************************************************************************//**
862 * @brief
863 * Multiply two big integers.
864 *
865 * @details
866 * This function uses the CRYPTO unit to multiply two big integer operands.
867 * If USE_VARIABLE_SIZED_DATA_LOADS is defined, the sizes of the operands
868 * may be any multiple of 32 bits. If USE_VARIABLE_SIZED_DATA_LOADS is _not_
869 * defined, the sizes of the operands must be a multiple of 128 bits.
870 *
871 * @param[in] crypto CRYPTO module
872 * @param[in] A An operand A
873 * @param[in] aSize The size of the operand A in bits
874 * @param[in] B An operand B
875 * @param[in] bSize The size of the operand B in bits
876 * @param[out] R The result of multiplication
877 * @param[in] rSize The size of the result buffer R in bits
878 ******************************************************************************/
CRYPTO_Mul(CRYPTO_TypeDef * crypto,uint32_t * A,int aSize,uint32_t * B,int bSize,uint32_t * R,int rSize)879 void CRYPTO_Mul(CRYPTO_TypeDef * crypto,
880 uint32_t * A, int aSize,
881 uint32_t * B, int bSize,
882 uint32_t * R, int rSize)
883 {
884 unsigned i, j;
885
886 /**************** Initializations ******************/
887
888 #ifdef USE_VARIABLE_SIZED_DATA_LOADS
889 unsigned numWordsLastOperandA = ((unsigned)aSize & PARTIAL_OPERAND_WIDTH_MASK) >> 5;
890 unsigned numPartialOperandsA = numWordsLastOperandA
891 ? ((unsigned)aSize >> PARTIAL_OPERAND_WIDTH_LOG2) + 1
892 : (unsigned)aSize >> PARTIAL_OPERAND_WIDTH_LOG2;
893 unsigned numWordsLastOperandB = ((unsigned)bSize & PARTIAL_OPERAND_WIDTH_MASK) >> 5;
894 unsigned numPartialOperandsB = numWordsLastOperandB
895 ? ((unsigned)bSize >> PARTIAL_OPERAND_WIDTH_LOG2) + 1
896 : (unsigned)bSize >> PARTIAL_OPERAND_WIDTH_LOG2;
897 unsigned numWordsLastOperandR = ((unsigned)rSize & PARTIAL_OPERAND_WIDTH_MASK) >> 5;
898 unsigned numPartialOperandsR = numWordsLastOperandR
899 ? ((unsigned)rSize >> PARTIAL_OPERAND_WIDTH_LOG2) + 1
900 : (unsigned)rSize >> PARTIAL_OPERAND_WIDTH_LOG2;
901 EFM_ASSERT(numPartialOperandsA + numPartialOperandsB <= numPartialOperandsR);
902 #else
903 unsigned numPartialOperandsA = (unsigned)aSize >> PARTIAL_OPERAND_WIDTH_LOG2;
904 unsigned numPartialOperandsB = (unsigned)bSize >> PARTIAL_OPERAND_WIDTH_LOG2;
905 EFM_ASSERT(((unsigned)aSize & PARTIAL_OPERAND_WIDTH_MASK) == 0UL);
906 EFM_ASSERT(((unsigned)bSize & PARTIAL_OPERAND_WIDTH_MASK) == 0UL);
907 #endif
908 EFM_ASSERT(aSize + bSize <= rSize);
909
910 /* Set R to zero. */
911 cryptoBigintZeroize(R, (unsigned)rSize >> 5);
912
913 /* Set the multiplication width. */
914 crypto->WAC = CRYPTO_WAC_MULWIDTH_MUL128 | CRYPTO_WAC_RESULTWIDTH_256BIT;
915
916 /* Set up DMA request signaling for MCU to run in parallel with
917 the CRYPTO instruction sequence execution and prepare data loading which
918 can take place immediately when CRYPTO is ready inside the instruction
919 sequence. */
920 crypto->CTRL =
921 CRYPTO_CTRL_DMA0RSEL_DATA0 | CRYPTO_CTRL_DMA0MODE_FULL
922 | CRYPTO_CTRL_DMA1RSEL_DATA1 | CRYPTO_CTRL_DMA1MODE_FULL;
923
924 CRYPTO_EXECUTE_4(crypto,
925 CRYPTO_CMD_INSTR_CCLR, /* Carry = 0 */
926 CRYPTO_CMD_INSTR_CLR, /* DDATA0 = 0 */
927 /* clear result accumulation register */
928 CRYPTO_CMD_INSTR_DDATA0TODDATA2,
929 CRYPTO_CMD_INSTR_SELDDATA1DDATA3);
930 /*
931 register map:
932 DDATA0: working register
933 DDATA1: B(j)
934 DDATA2: R(i+j+1) and R(i+j), combined with DMA entry for B(j)
935 DDATA3: A(i)
936 */
937
938 CRYPTO_SEQ_LOAD_10(crypto,
939 /* Temporarily load the partial operand B(j) to DATA0. */
940 /* R(i+j+1) is still in DATA1 */
941 CRYPTO_CMD_INSTR_DMA0TODATA,
942 /* Move B(j) to DDATA1. */
943 CRYPTO_CMD_INSTR_DDATA2TODDATA1,
944
945 /* Restore the previous partial result (now R(i+j)). */
946 CRYPTO_CMD_INSTR_DATA1TODATA0,
947
948 /* Load the next partial result R(i+j+1). */
949 CRYPTO_CMD_INSTR_DMA1TODATA,
950
951 /* Execute the partial multiplication A(i)inDDATA1 * B(j)inDDATA3.*/
952 CRYPTO_CMD_INSTR_MULO,
953
954 /* Add the result to the previous partial result. */
955 /* AND take the previous carry value into account */
956 /* at the right place (bit 128, ADDIC instruction. */
957 CRYPTO_CMD_INSTR_SELDDATA0DDATA2,
958 CRYPTO_CMD_INSTR_ADDIC,
959
960 /* Save the new partial result (lower half). */
961 CRYPTO_CMD_INSTR_DDATA0TODDATA2,
962 CRYPTO_CMD_INSTR_DATATODMA0,
963 /* Reset the operand selector for next.*/
964 CRYPTO_CMD_INSTR_SELDDATA2DDATA3
965 );
966
967 /**************** End Initializations ******************/
968
969 for (i = 0; i < numPartialOperandsA; i++) {
970 /* Load the partial operand #1 A>>(i*PARTIAL_OPERAND_WIDTH) to DDATA1. */
971 #ifdef USE_VARIABLE_SIZED_DATA_LOADS
972 if ( (numWordsLastOperandA != 0) && (i == numPartialOperandsA - 1) ) {
973 CRYPTO_DataWriteVariableSize(&crypto->DATA2,
974 &A[i * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS],
975 numWordsLastOperandA);
976 } else {
977 CRYPTO_DataWrite(&crypto->DATA2, &A[i * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
978 }
979 #else
980 CRYPTO_DataWrite(&crypto->DATA2, &A[i * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
981 #endif
982
983 /* Load the partial result in R>>(i*PARTIAL_OPERAND_WIDTH) to DATA1. */
984 #ifdef USE_VARIABLE_SIZED_DATA_LOADS
985 if ( (numWordsLastOperandR != 0) && (i == numPartialOperandsR - 1) ) {
986 CRYPTO_DataWriteVariableSize(&crypto->DATA1,
987 &R[i * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS],
988 numWordsLastOperandR);
989 } else {
990 CRYPTO_DataWrite(&crypto->DATA1, &R[i * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
991 }
992 #else
993 CRYPTO_DataWrite(&crypto->DATA1, &R[i * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
994 #endif
995
996 /* Clear carry. */
997 crypto->CMD = CRYPTO_CMD_INSTR_CCLR;
998
999 /* Set up the number of sequence iterations and block size. */
1000 crypto->SEQCTRL = CRYPTO_SEQCTRL_BLOCKSIZE_16BYTES
1001 | (PARTIAL_OPERAND_WIDTH_IN_BYTES * numPartialOperandsB);
1002
1003 /* Execute the MULtiply instruction sequence. */
1004 CRYPTO_InstructionSequenceExecute(crypto);
1005
1006 for (j = 0; j < numPartialOperandsB; j++) {
1007 /* Load the partial operand 2 B>>(j*`PARTIAL_OPERAND_WIDTH) to DDATA2
1008 (via DATA0). */
1009 while ((crypto->STATUS & CRYPTO_STATUS_DMAACTIVE) == 0) {
1010 }
1011
1012 #ifdef USE_VARIABLE_SIZED_DATA_LOADS
1013 if ( (numWordsLastOperandB != 0) && (j == numPartialOperandsB - 1) ) {
1014 CRYPTO_DataWriteVariableSize(&crypto->DATA0,
1015 &B[j * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS],
1016 numWordsLastOperandB);
1017 } else {
1018 CRYPTO_DataWrite(&crypto->DATA0,
1019 &B[j * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
1020 }
1021 #else
1022 CRYPTO_DataWrite(&crypto->DATA0,
1023 &B[j * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
1024 #endif
1025
1026 /* Load the most significant partial result
1027 R>>((i+j+1)*`PARTIAL_OPERAND_WIDTH) into DATA1. */
1028 #ifdef USE_VARIABLE_SIZED_DATA_LOADS
1029 if ( (numWordsLastOperandR != 0) && ( (i + j + 1U) == numPartialOperandsR - 1U) ) {
1030 CRYPTO_DataWriteVariableSize(&crypto->DATA1,
1031 &R[(i + j + 1U) * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS],
1032 numWordsLastOperandR);
1033 } else {
1034 CRYPTO_DataWrite(&crypto->DATA1,
1035 &R[(i + j + 1U) * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
1036 }
1037 #else
1038 CRYPTO_DataWrite(&crypto->DATA1,
1039 &R[(i + j + 1U) * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
1040 #endif
1041 while ((crypto->STATUS & CRYPTO_STATUS_DMAACTIVE) == 0) {
1042 }
1043 /* Store the least significant partial result. */
1044 CRYPTO_DataRead(&crypto->DATA0,
1045 &R[(i + j) * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
1046 } /* for (j=0; j<numPartialOperandsB; j++) */
1047
1048 /* Handle carry at the end of the inner loop. */
1049 if (CRYPTO_CarryIsSet(crypto)) {
1050 cryptoBigintIncrement(&R[(i + numPartialOperandsB + 1U)
1051 * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS],
1052 (numPartialOperandsA - i - 1U)
1053 * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS);
1054 }
1055
1056 CRYPTO_DataRead(&crypto->DATA1,
1057 &R[(i + numPartialOperandsB)
1058 * PARTIAL_OPERAND_WIDTH_IN_32BIT_WORDS]);
1059 } /* for (i=0; i<numPartialOperandsA; i++) */
1060 }
1061
1062 /***************************************************************************//**
1063 * @brief
1064 * AES Cipher-block chaining (CBC) cipher mode encryption/decryption, 128 bit key.
1065 *
1066 * @details
1067 * Encryption:
1068 * @verbatim
1069 * Plaintext Plaintext
1070 * | |
1071 * V V
1072 * InitVector ->XOR +-------------->XOR
1073 * | | |
1074 * V | V
1075 * +--------------+ | +--------------+
1076 * Key ->| Block cipher | | Key ->| Block cipher |
1077 * | encryption | | | encryption |
1078 * +--------------+ | +--------------+
1079 * |---------+ |
1080 * V V
1081 * Ciphertext Ciphertext
1082 * @endverbatim
1083 * Decryption:
1084 * @verbatim
1085 * Ciphertext Ciphertext
1086 * |----------+ |
1087 * V | V
1088 * +--------------+ | +--------------+
1089 * Key ->| Block cipher | | Key ->| Block cipher |
1090 * | decryption | | | decryption |
1091 * +--------------+ | +--------------+
1092 * | | |
1093 * V | V
1094 * InitVector ->XOR +-------------->XOR
1095 * | |
1096 * V V
1097 * Plaintext Plaintext
1098 * @endverbatim
1099 * See general comments on layout and byte ordering of parameters.
1100 *
1101 * @param[in] crypto
1102 * A pointer to the CRYPTO peripheral register block.
1103 *
1104 * @param[out] out
1105 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1106 * may be set equal to @p in, in which case the input buffer is overwritten.
1107 *
1108 * @param[in] in
1109 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1110 *
1111 * @param[in] len
1112 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1113 *
1114 * @param[in] key
1115 * When encrypting, this is the 128 bit encryption key. When
1116 * decrypting, this is the 128 bit decryption key. The decryption key may
1117 * be generated from the encryption key with CRYPTO_AES_DecryptKey128().
1118 * If this argument is null, the key will not be loaded, as it is assumed
1119 * the key has been loaded into KEYHA previously.
1120 *
1121 * @param[in] iv
1122 * 128 bit initialization vector to use.
1123 *
1124 * @param[in] encrypt
1125 * Set to true to encrypt, false to decrypt.
1126 ******************************************************************************/
CRYPTO_AES_CBC128(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)1127 void CRYPTO_AES_CBC128(CRYPTO_TypeDef * crypto,
1128 uint8_t * out,
1129 const uint8_t * in,
1130 unsigned int len,
1131 const uint8_t * key,
1132 const uint8_t * iv,
1133 bool encrypt)
1134 {
1135 crypto->CTRL = CRYPTO_CTRL_AES_AES128;
1136 CRYPTO_AES_CBCx(crypto, out, in, len, key, iv, encrypt, cryptoKey128Bits);
1137 }
1138
1139 /***************************************************************************//**
1140 * @brief
1141 * AES Cipher-block chaining (CBC) cipher mode encryption/decryption, 256 bit
1142 * key.
1143 *
1144 * @details
1145 * See CRYPTO_AES_CBC128() for the CBC figure.
1146 *
1147 * See general comments on layout and byte ordering of parameters.
1148 *
1149 * @param[in] crypto
1150 * A pointer to the CRYPTO peripheral register block.
1151 *
1152 * @param[out] out
1153 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1154 * may be set equal to @p in, in which case the input buffer is overwritten.
1155 *
1156 * @param[in] in
1157 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1158 *
1159 * @param[in] len
1160 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1161 *
1162 * @param[in] key
1163 * When encrypting, this is the 256 bit encryption key. When
1164 * decrypting, this is the 256 bit decryption key. The decryption key may
1165 * be generated from the encryption key with CRYPTO_AES_DecryptKey256().
1166 *
1167 * @param[in] iv
1168 * 128 bit initialization vector to use.
1169 *
1170 * @param[in] encrypt
1171 * Set to true to encrypt, false to decrypt.
1172 ******************************************************************************/
CRYPTO_AES_CBC256(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)1173 void CRYPTO_AES_CBC256(CRYPTO_TypeDef * crypto,
1174 uint8_t * out,
1175 const uint8_t * in,
1176 unsigned int len,
1177 const uint8_t * key,
1178 const uint8_t * iv,
1179 bool encrypt)
1180 {
1181 crypto->CTRL = CRYPTO_CTRL_AES_AES256;
1182 CRYPTO_AES_CBCx(crypto, out, in, len, key, iv, encrypt, cryptoKey256Bits);
1183 }
1184
1185 /***************************************************************************//**
1186 * @brief
1187 * AES Propagating Cipher-block chaining (PCBC) cipher mode encryption/decryption, 128 bit key.
1188 *
1189 * @details
1190 * Encryption:
1191 * @verbatim
1192 * Plaintext Plaintext
1193 * |--------------+ |
1194 * V V V
1195 * InitVector ->XOR +-->XOR-------->XOR
1196 * | | |
1197 * V | V
1198 * +--------------+ | +--------------+
1199 * Key ->| Block cipher | | Key ->| Block cipher |
1200 * | encryption | | | encryption |
1201 * +--------------+ | +--------------+
1202 * |---------+ |
1203 * V V
1204 * Ciphertext Ciphertext
1205 * @endverbatim
1206 * Decryption:
1207 * @verbatim
1208 * Ciphertext Ciphertext
1209 * |----------+ |
1210 * V | V
1211 * +--------------+ | +--------------+
1212 * Key ->| Block cipher | | Key ->| Block cipher |
1213 * | decryption | | | decryption |
1214 * +--------------+ | +--------------+
1215 * | | |
1216 * V V V
1217 * InitVector ->XOR +--->XOR------------>XOR
1218 * |---+ |
1219 * V V
1220 * Plaintext Plaintext
1221 * @endverbatim
1222 * See general comments on layout and byte ordering of parameters.
1223 *
1224 * @param[in] crypto
1225 * A pointer to the CRYPTO peripheral register block.
1226 *
1227 * @param[out] out
1228 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1229 * may be set equal to @p in, in which case the input buffer is overwritten.
1230 *
1231 * @param[in] in
1232 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1233 *
1234 * @param[in] len
1235 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1236 *
1237 * @param[in] key
1238 * When encrypting, this is the 128 bit encryption key. When
1239 * decrypting, this is the 128 bit decryption key. The decryption key may
1240 * be generated from the encryption key with CRYPTO_AES_DecryptKey128().
1241 * If this argument is null, the key will not be loaded, as it is assumed
1242 * the key has been loaded into KEYHA previously.
1243 *
1244 * @param[in] iv
1245 * 128 bit initialization vector to use.
1246 *
1247 * @param[in] encrypt
1248 * Set to true to encrypt, false to decrypt.
1249 ******************************************************************************/
CRYPTO_AES_PCBC128(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)1250 void CRYPTO_AES_PCBC128(CRYPTO_TypeDef * crypto,
1251 uint8_t * out,
1252 const uint8_t * in,
1253 unsigned int len,
1254 const uint8_t * key,
1255 const uint8_t * iv,
1256 bool encrypt)
1257 {
1258 crypto->CTRL = CRYPTO_CTRL_AES_AES128;
1259 CRYPTO_AES_PCBCx(crypto, out, in, len, key, iv, encrypt, cryptoKey128Bits);
1260 }
1261
1262 /***************************************************************************//**
1263 * @brief
1264 * AES Propagating Cipher-block chaining (PCBC) cipher mode encryption/decryption, 256 bit
1265 * key.
1266 *
1267 * @details
1268 * See CRYPTO_AES_PCBC128() for the PCBC figure.
1269 *
1270 * See general comments on layout and byte ordering of parameters.
1271 *
1272 * @param[in] crypto
1273 * A pointer to the CRYPTO peripheral register block.
1274 *
1275 * @param[out] out
1276 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1277 * may be set equal to @p in, in which case the input buffer is overwritten.
1278 *
1279 * @param[in] in
1280 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1281 *
1282 * @param[in] len
1283 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1284 *
1285 * @param[in] key
1286 * When encrypting, this is the 256 bit encryption key. When
1287 * decrypting, this is the 256 bit decryption key. The decryption key may
1288 * be generated from the encryption key with CRYPTO_AES_DecryptKey256().
1289 *
1290 * @param[in] iv
1291 * 128 bit initialization vector to use.
1292 *
1293 * @param[in] encrypt
1294 * Set to true to encrypt, false to decrypt.
1295 ******************************************************************************/
CRYPTO_AES_PCBC256(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)1296 void CRYPTO_AES_PCBC256(CRYPTO_TypeDef * crypto,
1297 uint8_t * out,
1298 const uint8_t * in,
1299 unsigned int len,
1300 const uint8_t * key,
1301 const uint8_t * iv,
1302 bool encrypt)
1303 {
1304 crypto->CTRL = CRYPTO_CTRL_AES_AES256;
1305 CRYPTO_AES_PCBCx(crypto, out, in, len, key, iv, encrypt, cryptoKey256Bits);
1306 }
1307
1308 /***************************************************************************//**
1309 * @brief
1310 * AES Cipher feedback (CFB) cipher mode encryption/decryption, 128 bit key.
1311 *
1312 * @details
1313 * Encryption:
1314 * @verbatim
1315 * InitVector +----------------+
1316 * | | |
1317 * V | V
1318 * +--------------+ | +--------------+
1319 * Key ->| Block cipher | | Key ->| Block cipher |
1320 * | encryption | | | encryption |
1321 * +--------------+ | +--------------+
1322 * | | |
1323 * V | V
1324 * Plaintext ->XOR | Plaintext ->XOR
1325 * |---------+ |
1326 * V V
1327 * Ciphertext Ciphertext
1328 * @endverbatim
1329 * Decryption:
1330 * @verbatim
1331 * InitVector +----------------+
1332 * | | |
1333 * V | V
1334 * +--------------+ | +--------------+
1335 * Key ->| Block cipher | | Key ->| Block cipher |
1336 * | encryption | | | encryption |
1337 * +--------------+ | +--------------+
1338 * | | |
1339 * V | V
1340 * XOR<- Ciphertext XOR<- Ciphertext
1341 * | |
1342 * V V
1343 * Plaintext Plaintext
1344 * @endverbatim
1345 * See general comments on layout and byte ordering of parameters.
1346 *
1347 * @param[in] crypto
1348 * A pointer to the CRYPTO peripheral register block.
1349 *
1350 * @param[out] out
1351 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1352 * may be set equal to @p in, in which case the input buffer is overwritten.
1353 *
1354 * @param[in] in
1355 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1356 *
1357 * @param[in] len
1358 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1359 *
1360 * @param[in] key
1361 * 128 bit encryption key is used for both encryption and decryption modes.
1362 *
1363 * @param[in] iv
1364 * 128 bit initialization vector to use.
1365 *
1366 * @param[in] encrypt
1367 * Set to true to encrypt, false to decrypt.
1368 ******************************************************************************/
CRYPTO_AES_CFB128(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)1369 void CRYPTO_AES_CFB128(CRYPTO_TypeDef * crypto,
1370 uint8_t * out,
1371 const uint8_t * in,
1372 unsigned int len,
1373 const uint8_t * key,
1374 const uint8_t * iv,
1375 bool encrypt)
1376 {
1377 crypto->CTRL = CRYPTO_CTRL_AES_AES128;
1378 CRYPTO_AES_CFBx(crypto, out, in, len, key, iv, encrypt, cryptoKey128Bits);
1379 }
1380
1381 /***************************************************************************//**
1382 * @brief
1383 * AES Cipher feedback (CFB) cipher mode encryption/decryption, 256 bit key.
1384 *
1385 * @details
1386 * See CRYPTO_AES_CFB128() for the CFB figure.
1387 *
1388 * See general comments on layout and byte ordering of parameters.
1389 *
1390 * @param[in] crypto
1391 * A pointer to the CRYPTO peripheral register block.
1392 *
1393 * @param[out] out
1394 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1395 * may be set equal to @p in, in which case the input buffer is overwritten.
1396 *
1397 * @param[in] in
1398 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1399 *
1400 * @param[in] len
1401 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1402 *
1403 * @param[in] key
1404 * 256 bit encryption key is used for both encryption and decryption modes.
1405 *
1406 * @param[in] iv
1407 * 128 bit initialization vector to use.
1408 *
1409 * @param[in] encrypt
1410 * Set to true to encrypt, false to decrypt.
1411 ******************************************************************************/
CRYPTO_AES_CFB256(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt)1412 void CRYPTO_AES_CFB256(CRYPTO_TypeDef * crypto,
1413 uint8_t * out,
1414 const uint8_t * in,
1415 unsigned int len,
1416 const uint8_t * key,
1417 const uint8_t * iv,
1418 bool encrypt)
1419 {
1420 crypto->CTRL = CRYPTO_CTRL_AES_AES256;
1421 CRYPTO_AES_CFBx(crypto, out, in, len, key, iv, encrypt, cryptoKey256Bits);
1422 }
1423
1424 /***************************************************************************//**
1425 * @brief
1426 * AES Counter (CTR) cipher mode encryption/decryption, 128 bit key.
1427 *
1428 * @details
1429 * Encryption:
1430 * @verbatim
1431 * Counter Counter
1432 * | |
1433 * V V
1434 * +--------------+ +--------------+
1435 * Key ->| Block cipher | Key ->| Block cipher |
1436 * | encryption | | encryption |
1437 * +--------------+ +--------------+
1438 * | |
1439 * Plaintext ->XOR Plaintext ->XOR
1440 * | |
1441 * V V
1442 * Ciphertext Ciphertext
1443 * @endverbatim
1444 * Decryption:
1445 * @verbatim
1446 * Counter Counter
1447 * | |
1448 * V V
1449 * +--------------+ +--------------+
1450 * Key ->| Block cipher | Key ->| Block cipher |
1451 * | encryption | | encryption |
1452 * +--------------+ +--------------+
1453 * | |
1454 * Ciphertext ->XOR Ciphertext ->XOR
1455 * | |
1456 * V V
1457 * Plaintext Plaintext
1458 * @endverbatim
1459 * See general comments on layout and byte ordering of parameters.
1460 *
1461 * @param[in] crypto
1462 * A pointer to CRYPTO peripheral register block.
1463 *
1464 * @param[out] out
1465 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1466 * may be set equal to @p in, in which case the input buffer is overwritten.
1467 *
1468 * @param[in] in
1469 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1470 *
1471 * @param[in] len
1472 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1473 *
1474 * @param[in] key
1475 * 128 bit encryption key.
1476 * If this argument is null, the key will not be loaded, as it is assumed
1477 * the key has been loaded into KEYHA previously.
1478 *
1479 * @param[in,out] ctr
1480 * 128 bit initial counter value. The counter is updated after each AES
1481 * block encoding through use of @p ctrFunc.
1482 *
1483 * @param[in] ctrFunc
1484 * A function used to update the counter value. Not supported by CRYPTO.
1485 * This parameter is included for backwards compatibility with
1486 * the EFM32 em_aes.h API.
1487 ******************************************************************************/
CRYPTO_AES_CTR128(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,uint8_t * ctr,CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc)1488 void CRYPTO_AES_CTR128(CRYPTO_TypeDef * crypto,
1489 uint8_t * out,
1490 const uint8_t * in,
1491 unsigned int len,
1492 const uint8_t * key,
1493 uint8_t * ctr,
1494 CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc)
1495 {
1496 crypto->CTRL = CRYPTO_CTRL_AES_AES128;
1497 CRYPTO_AES_CTRx(crypto, out, in, len, key, ctr, ctrFunc, cryptoKey128Bits);
1498 }
1499
1500 /***************************************************************************//**
1501 * @brief
1502 * AES Counter (CTR) cipher mode encryption/decryption, 256 bit key.
1503 *
1504 * @details
1505 * See CRYPTO_AES_CTR128() for CTR figure.
1506 *
1507 * See general comments on layout and byte ordering of parameters.
1508 *
1509 * @param[in] crypto
1510 * A pointer to the CRYPTO peripheral register block.
1511 *
1512 * @param[out] out
1513 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1514 * may be set equal to @p in, in which case the input buffer is overwritten.
1515 *
1516 * @param[in] in
1517 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1518 *
1519 * @param[in] len
1520 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1521 *
1522 * @param[in] key
1523 * 256 bit encryption key.
1524 *
1525 * @param[in,out] ctr
1526 * 128 bit initial counter value. The counter is updated after each AES
1527 * block encoding through use of @p ctrFunc.
1528 *
1529 * @param[in] ctrFunc
1530 * A function used to update counter value. Not supported by CRYPTO.
1531 * This parameter is included in order for backwards compatibility with
1532 * the EFM32 em_aes.h API.
1533 ******************************************************************************/
CRYPTO_AES_CTR256(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,uint8_t * ctr,CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc)1534 void CRYPTO_AES_CTR256(CRYPTO_TypeDef * crypto,
1535 uint8_t * out,
1536 const uint8_t * in,
1537 unsigned int len,
1538 const uint8_t * key,
1539 uint8_t * ctr,
1540 CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc)
1541 {
1542 crypto->CTRL = CRYPTO_CTRL_AES_AES256;
1543 CRYPTO_AES_CTRx(crypto, out, in, len, key, ctr, ctrFunc, cryptoKey256Bits);
1544 }
1545
1546 /***************************************************************************//**
1547 * @brief
1548 * Update the last 32 bits of 128 bit counter by incrementing with 1.
1549 *
1550 * @details
1551 * Notice that no special consideration is given to the possible wrap around. If
1552 * 32 least significant bits are 0xFFFFFFFF, they will be updated to 0x00000000,
1553 * ignoring overflow.
1554 *
1555 * See general comments on layout and byte ordering of parameters.
1556 *
1557 * @param[in,out] ctr
1558 * A buffer holding 128 bit counter to be updated.
1559 ******************************************************************************/
CRYPTO_AES_CTRUpdate32Bit(uint8_t * ctr)1560 void CRYPTO_AES_CTRUpdate32Bit(uint8_t * ctr)
1561 {
1562 uint32_t * _ctr = (uint32_t *) ctr;
1563
1564 _ctr[3] = __REV(__REV(_ctr[3]) + 1U);
1565 }
1566
1567 /***************************************************************************//**
1568 * @brief
1569 * Generate 128 bit AES decryption key from 128 bit encryption key. The
1570 * decryption key is used for some cipher modes when decrypting.
1571 *
1572 * @details
1573 * See general comments on layout and byte ordering of parameters.
1574 *
1575 * @param[in] crypto
1576 * A pointer to the CRYPTO peripheral register block.
1577 *
1578 * @param[out] out
1579 * A buffer to place 128 bit decryption key. Must be at least 16 bytes long. It
1580 * may be set equal to @p in, in which case the input buffer is overwritten.
1581 *
1582 * @param[in] in
1583 * A buffer holding 128 bit encryption key. Must be at least 16 bytes long.
1584 ******************************************************************************/
CRYPTO_AES_DecryptKey128(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in)1585 void CRYPTO_AES_DecryptKey128(CRYPTO_TypeDef * crypto,
1586 uint8_t * out,
1587 const uint8_t * in)
1588 {
1589 /* Setup CRYPTO in AES-128 mode. */
1590 crypto->CTRL = CRYPTO_CTRL_AES_AES128;
1591
1592 /* Load key */
1593 CRYPTO_DataWriteUnaligned(&crypto->KEYBUF, in);
1594
1595 /* Do dummy encryption to generate decrypt key */
1596 crypto->CMD = CRYPTO_CMD_INSTR_AESENC;
1597
1598 /* Wait for the instruction to finish. */
1599 CRYPTO_InstructionSequenceWait(crypto);
1600
1601 /* Save decryption key */
1602 CRYPTO_DataReadUnaligned(&crypto->KEY, out);
1603 }
1604
1605 /***************************************************************************//**
1606 * @brief
1607 * Generate 256 bit AES decryption key from 256 bit encryption key. The
1608 * decryption key is used for some cipher modes when decrypting.
1609 *
1610 * @details
1611 * See general comments on layout and byte ordering of parameters.
1612 *
1613 * @param[in] crypto
1614 * A pointer to the CRYPTO peripheral register block.
1615 *
1616 * @param[out] out
1617 * A buffer to place 256 bit decryption key. Must be at least 32 bytes long. It
1618 * may be set equal to @p in, in which case the input buffer is overwritten.
1619 *
1620 * @param[in] in
1621 * A buffer holding 256 bit encryption key. Must be at least 32 bytes long.
1622 ******************************************************************************/
CRYPTO_AES_DecryptKey256(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in)1623 void CRYPTO_AES_DecryptKey256(CRYPTO_TypeDef * crypto,
1624 uint8_t * out,
1625 const uint8_t * in)
1626 {
1627 /* Set up CRYPTO in AES-256 mode. */
1628 crypto->CTRL = CRYPTO_CTRL_AES_AES256;
1629
1630 /* Load the key. */
1631 CRYPTO_DataWriteUnaligned(&crypto->KEYBUF, in);
1632 CRYPTO_DataWriteUnaligned(&crypto->KEYBUF, &in[16]);
1633
1634 /* Do dummy encryption to generate a decrypt key. */
1635 crypto->CMD = CRYPTO_CMD_INSTR_AESENC;
1636
1637 /* Wait for the instruction to finish. */
1638 CRYPTO_InstructionSequenceWait(crypto);
1639
1640 /* Save the decryption key. */
1641 CRYPTO_DataReadUnaligned(&crypto->KEY, out);
1642 CRYPTO_DataReadUnaligned(&crypto->KEY, &out[16]);
1643 }
1644
1645 /***************************************************************************//**
1646 * @brief
1647 * AES Electronic Codebook (ECB) cipher mode encryption/decryption,
1648 * 128 bit key.
1649 *
1650 * @details
1651 * Encryption:
1652 * @verbatim
1653 * Plaintext Plaintext
1654 * | |
1655 * V V
1656 * +--------------+ +--------------+
1657 * Key ->| Block cipher | Key ->| Block cipher |
1658 * | encryption | | encryption |
1659 * +--------------+ +--------------+
1660 * | |
1661 * V V
1662 * Ciphertext Ciphertext
1663 * @endverbatim
1664 * Decryption:
1665 * @verbatim
1666 * Ciphertext Ciphertext
1667 * | |
1668 * V V
1669 * +--------------+ +--------------+
1670 * Key ->| Block cipher | Key ->| Block cipher |
1671 * | decryption | | decryption |
1672 * +--------------+ +--------------+
1673 * | |
1674 * V V
1675 * Plaintext Plaintext
1676 * @endverbatim
1677 * See general comments on layout and byte ordering of parameters.
1678 *
1679 * @param[in] crypto
1680 * A pointer to the CRYPTO peripheral register block.
1681 *
1682 * @param[out] out
1683 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1684 * may be set equal to @p in, in which case the input buffer is overwritten.
1685 *
1686 * @param[in] in
1687 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1688 *
1689 * @param[in] len
1690 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1691 *
1692 * @param[in] key
1693 * When encrypting, this is the 128 bit encryption key. When
1694 * decrypting, this is the 128 bit decryption key. The decryption key may
1695 * be generated from the encryption key with CRYPTO_AES_DecryptKey128().
1696 *
1697 * @param[in] encrypt
1698 * Set to true to encrypt, false to decrypt.
1699 ******************************************************************************/
CRYPTO_AES_ECB128(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,bool encrypt)1700 void CRYPTO_AES_ECB128(CRYPTO_TypeDef * crypto,
1701 uint8_t * out,
1702 const uint8_t * in,
1703 unsigned int len,
1704 const uint8_t * key,
1705 bool encrypt)
1706 {
1707 crypto->CTRL = CRYPTO_CTRL_AES_AES128;
1708 CRYPTO_AES_ECBx(crypto, out, in, len, key, encrypt, cryptoKey128Bits);
1709 }
1710
1711 /***************************************************************************//**
1712 * @brief
1713 * AES Electronic Codebook (ECB) cipher mode encryption/decryption,
1714 * 256 bit key.
1715 *
1716 * @details
1717 * See CRYPTO_AES_ECB128() for ECB figure.
1718 *
1719 * See general comments on layout and byte ordering of parameters.
1720 *
1721 * @param[in] crypto
1722 * A pointer to the CRYPTO peripheral register block.
1723 *
1724 * @param[out] out
1725 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1726 * may be set equal to @p in, in which case the input buffer is overwritten.
1727 *
1728 * @param[in] in
1729 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1730 *
1731 * @param[in] len
1732 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1733 *
1734 * @param[in] key
1735 * When encrypting, this is the 256 bit encryption key. When
1736 * decrypting, this is the 256 bit decryption key. The decryption key may
1737 * be generated from the encryption key with CRYPTO_AES_DecryptKey256().
1738 *
1739 * @param[in] encrypt
1740 * Set to true to encrypt, false to decrypt.
1741 ******************************************************************************/
CRYPTO_AES_ECB256(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,bool encrypt)1742 void CRYPTO_AES_ECB256(CRYPTO_TypeDef * crypto,
1743 uint8_t * out,
1744 const uint8_t * in,
1745 unsigned int len,
1746 const uint8_t * key,
1747 bool encrypt)
1748 {
1749 crypto->CTRL = CRYPTO_CTRL_AES_AES256;
1750 CRYPTO_AES_ECBx(crypto, out, in, len, key, encrypt, cryptoKey256Bits);
1751 }
1752
1753 /***************************************************************************//**
1754 * @brief
1755 * AES Output feedback (OFB) cipher mode encryption/decryption, 128 bit key.
1756 *
1757 * @details
1758 * Encryption:
1759 * @verbatim
1760 * InitVector +----------------+
1761 * | | |
1762 * V | V
1763 * +--------------+ | +--------------+
1764 * Key ->| Block cipher | | Key ->| Block cipher |
1765 * | encryption | | | encryption |
1766 * +--------------+ | +--------------+
1767 * | | |
1768 * |---------+ |
1769 * V V
1770 * Plaintext ->XOR Plaintext ->XOR
1771 * | |
1772 * V V
1773 * Ciphertext Ciphertext
1774 * @endverbatim
1775 * Decryption:
1776 * @verbatim
1777 * InitVector +----------------+
1778 * | | |
1779 * V | V
1780 * +--------------+ | +--------------+
1781 * Key ->| Block cipher | | Key ->| Block cipher |
1782 * | encryption | | | encryption |
1783 * +--------------+ | +--------------+
1784 * | | |
1785 * |---------+ |
1786 * V V
1787 * Ciphertext ->XOR Ciphertext ->XOR
1788 * | |
1789 * V V
1790 * Plaintext Plaintext
1791 * @endverbatim
1792 * See general comments on layout and byte ordering of parameters.
1793 *
1794 * @param[in] crypto
1795 * A pointer to the CRYPTO peripheral register block.
1796 *
1797 * @param[out] out
1798 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1799 * may be set equal to @p in, in which case the input buffer is overwritten.
1800 *
1801 * @param[in] in
1802 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1803 *
1804 * @param[in] len
1805 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1806 *
1807 * @param[in] key
1808 * 128 bit encryption key.
1809 *
1810 * @param[in] iv
1811 * 128 bit initialization vector to use.
1812 ******************************************************************************/
CRYPTO_AES_OFB128(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv)1813 void CRYPTO_AES_OFB128(CRYPTO_TypeDef * crypto,
1814 uint8_t * out,
1815 const uint8_t * in,
1816 unsigned int len,
1817 const uint8_t * key,
1818 const uint8_t * iv)
1819 {
1820 crypto->CTRL = CRYPTO_CTRL_AES_AES128;
1821 CRYPTO_AES_OFBx(crypto, out, in, len, key, iv, cryptoKey128Bits);
1822 }
1823
1824 /***************************************************************************//**
1825 * @brief
1826 * AES Output feedback (OFB) cipher mode encryption/decryption, 256 bit key.
1827 *
1828 * @details
1829 * See CRYPTO_AES_OFB128() for OFB figure.
1830 *
1831 * See general comments on layout and byte ordering of parameters.
1832 *
1833 * @param[in] crypto
1834 * A pointer to CRYPTO peripheral register block.
1835 *
1836 * @param[out] out
1837 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1838 * may be set equal to @p in, in which case the input buffer is overwritten.
1839 *
1840 * @param[in] in
1841 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1842 *
1843 * @param[in] len
1844 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1845 *
1846 * @param[in] key
1847 * 256 bit encryption key.
1848 *
1849 * @param[in] iv
1850 * 128 bit initialization vector to use.
1851 ******************************************************************************/
CRYPTO_AES_OFB256(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv)1852 void CRYPTO_AES_OFB256(CRYPTO_TypeDef * crypto,
1853 uint8_t * out,
1854 const uint8_t * in,
1855 unsigned int len,
1856 const uint8_t * key,
1857 const uint8_t * iv)
1858 {
1859 crypto->CTRL = CRYPTO_CTRL_AES_AES256;
1860 CRYPTO_AES_OFBx(crypto, out, in, len, key, iv, cryptoKey256Bits);
1861 }
1862
1863 /*******************************************************************************
1864 ************************** LOCAL FUNCTIONS *******************************
1865 ******************************************************************************/
1866
1867 /***************************************************************************//**
1868 * @brief
1869 * Cipher-block chaining (CBC) cipher mode encryption/decryption, 128/256 bit key.
1870 *
1871 * @details
1872 * See CRYPTO_AES_CBC128() for CBC figure.
1873 *
1874 * See general comments on layout and byte ordering of parameters.
1875 *
1876 * @param[in] crypto
1877 * A pointer to the CRYPTO peripheral register block.
1878 *
1879 * @param[out] out
1880 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1881 * may be set equal to @p in, in which case the input buffer is overwritten.
1882 *
1883 * @param[in] in
1884 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1885 *
1886 * @param[in] len
1887 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1888 *
1889 * @param[in] key
1890 * When encrypting, this is the 256 bit encryption key. When
1891 * decrypting, this is the 256 bit decryption key. The decryption key may
1892 * be generated from the encryption key with CRYPTO_AES_DecryptKey256().
1893 *
1894 * @param[in] iv
1895 * 128 bit initialization vector to use.
1896 *
1897 * @param[in] encrypt
1898 * Set to true to encrypt, false to decrypt.
1899 *
1900 * @param[in] keyWidth
1901 * Set to cryptoKey128Bits or cryptoKey256Bits.
1902 ******************************************************************************/
CRYPTO_AES_CBCx(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt,CRYPTO_KeyWidth_TypeDef keyWidth)1903 static void CRYPTO_AES_CBCx(CRYPTO_TypeDef * crypto,
1904 uint8_t * out,
1905 const uint8_t * in,
1906 unsigned int len,
1907 const uint8_t * key,
1908 const uint8_t * iv,
1909 bool encrypt,
1910 CRYPTO_KeyWidth_TypeDef keyWidth)
1911 {
1912 EFM_ASSERT((len % CRYPTO_AES_BLOCKSIZE) == 0U);
1913
1914 /* Initialize control registers. */
1915 crypto->WAC = 0;
1916
1917 CRYPTO_KeyBufWriteUnaligned(crypto, key, keyWidth);
1918
1919 if (encrypt) {
1920 CRYPTO_DataWriteUnaligned(&crypto->DATA0, iv);
1921
1922 CRYPTO_SEQ_LOAD_2(crypto,
1923 CRYPTO_CMD_INSTR_DATA1TODATA0XOR,
1924 CRYPTO_CMD_INSTR_AESENC);
1925 } else {
1926 CRYPTO_DataWriteUnaligned(&crypto->DATA2, iv);
1927
1928 CRYPTO_SEQ_LOAD_4(crypto,
1929 CRYPTO_CMD_INSTR_DATA1TODATA0,
1930 CRYPTO_CMD_INSTR_AESDEC,
1931 CRYPTO_CMD_INSTR_DATA2TODATA0XOR,
1932 CRYPTO_CMD_INSTR_DATA1TODATA2);
1933 }
1934
1935 CRYPTO_AES_ProcessLoop(crypto, len,
1936 &crypto->DATA1, in,
1937 &crypto->DATA0, out);
1938 }
1939
1940 /***************************************************************************//**
1941 * @brief
1942 * Propagating cipher-block chaining (PCBC) cipher mode encryption/decryption, 128/256 bit key.
1943 *
1944 * @details
1945 * See CRYPTO_AES_PCBC128() for PCBC figure.
1946 *
1947 * See general comments on layout and byte ordering of parameters.
1948 *
1949 * @param[in] crypto
1950 * A pointer to the CRYPTO peripheral register block.
1951 *
1952 * @param[out] out
1953 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
1954 * may be set equal to @p in, in which case the input buffer is overwritten.
1955 *
1956 * @param[in] in
1957 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
1958 *
1959 * @param[in] len
1960 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
1961 *
1962 * @param[in] key
1963 * When encrypting, this is the 256 bit encryption key. When
1964 * decrypting, this is the 256 bit decryption key. The decryption key may
1965 * be generated from the encryption key with CRYPTO_AES_DecryptKey256().
1966 *
1967 * @param[in] iv
1968 * 128 bit initialization vector to use.
1969 *
1970 * @param[in] encrypt
1971 * Set to true to encrypt, false to decrypt.
1972 *
1973 * @param[in] keyWidth
1974 * Set to cryptoKey128Bits or cryptoKey256Bits.
1975 ******************************************************************************/
CRYPTO_AES_PCBCx(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt,CRYPTO_KeyWidth_TypeDef keyWidth)1976 static void CRYPTO_AES_PCBCx(CRYPTO_TypeDef * crypto,
1977 uint8_t * out,
1978 const uint8_t * in,
1979 unsigned int len,
1980 const uint8_t * key,
1981 const uint8_t * iv,
1982 bool encrypt,
1983 CRYPTO_KeyWidth_TypeDef keyWidth)
1984 {
1985 EFM_ASSERT((len % CRYPTO_AES_BLOCKSIZE) == 0U);
1986
1987 /* Initialize control registers. */
1988 crypto->WAC = 0;
1989
1990 CRYPTO_KeyBufWriteUnaligned(crypto, key, keyWidth);
1991 CRYPTO_DataWriteUnaligned(&crypto->DATA0, iv);
1992
1993 if (encrypt) {
1994 CRYPTO_SEQ_LOAD_4(crypto,
1995 CRYPTO_CMD_INSTR_DATA1TODATA0XOR,
1996 CRYPTO_CMD_INSTR_AESENC,
1997 CRYPTO_CMD_INSTR_DATA0TODATA2,
1998 CRYPTO_CMD_INSTR_DATA1TODATA0XOR);
1999 } else {
2000 CRYPTO_SEQ_LOAD_6(crypto,
2001 CRYPTO_CMD_INSTR_DATA0TODATA3,
2002 CRYPTO_CMD_INSTR_DATA1TODATA0,
2003 CRYPTO_CMD_INSTR_AESDEC,
2004 CRYPTO_CMD_INSTR_DATA3TODATA0XOR,
2005 CRYPTO_CMD_INSTR_DATA0TODATA2,
2006 CRYPTO_CMD_INSTR_DATA1TODATA0XOR);
2007 }
2008
2009 CRYPTO_AES_ProcessLoop(crypto, len,
2010 &crypto->DATA1, in,
2011 &crypto->DATA2, out);
2012 }
2013
2014 /***************************************************************************//**
2015 * @brief
2016 * Cipher feedback (CFB) cipher mode encryption/decryption, 128/256 bit key.
2017 *
2018 * @details
2019 * See CRYPTO_AES_CFB128() for CFB figure.
2020 *
2021 * See general comments on layout and byte ordering of parameters.
2022 *
2023 * @param[in] crypto
2024 * A pointer to the CRYPTO peripheral register block.
2025 *
2026 * @param[out] out
2027 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
2028 * may be set equal to @p in, in which case the input buffer is overwritten.
2029 *
2030 * @param[in] in
2031 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
2032 *
2033 * @param[in] len
2034 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
2035 *
2036 * @param[in] key
2037 * 256 bit encryption key is used for both encryption and decryption modes.
2038 *
2039 * @param[in] iv
2040 * 128 bit initialization vector to use.
2041 *
2042 * @param[in] encrypt
2043 * Set to true to encrypt, false to decrypt.
2044 *
2045 * @param[in] keyWidth
2046 * Set to cryptoKey128Bits or cryptoKey256Bits.
2047 ******************************************************************************/
CRYPTO_AES_CFBx(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,bool encrypt,CRYPTO_KeyWidth_TypeDef keyWidth)2048 static void CRYPTO_AES_CFBx(CRYPTO_TypeDef * crypto,
2049 uint8_t * out,
2050 const uint8_t * in,
2051 unsigned int len,
2052 const uint8_t * key,
2053 const uint8_t * iv,
2054 bool encrypt,
2055 CRYPTO_KeyWidth_TypeDef keyWidth)
2056 {
2057 EFM_ASSERT((len % CRYPTO_AES_BLOCKSIZE) == 0U);
2058
2059 /* Initialize control registers. */
2060 crypto->WAC = 0;
2061
2062 /* Load the key. */
2063 CRYPTO_KeyBufWriteUnaligned(crypto, key, keyWidth);
2064
2065 /* Load instructions to the CRYPTO sequencer. */
2066 if (encrypt) {
2067 /* Load IV */
2068 CRYPTO_DataWriteUnaligned(&crypto->DATA0, iv);
2069
2070 CRYPTO_SEQ_LOAD_2(crypto,
2071 CRYPTO_CMD_INSTR_AESENC,
2072 CRYPTO_CMD_INSTR_DATA1TODATA0XOR);
2073 } else {
2074 /* Load IV */
2075 CRYPTO_DataWriteUnaligned(&crypto->DATA2, iv);
2076
2077 CRYPTO_SEQ_LOAD_4(crypto,
2078 CRYPTO_CMD_INSTR_DATA2TODATA0,
2079 CRYPTO_CMD_INSTR_AESENC,
2080 CRYPTO_CMD_INSTR_DATA1TODATA0XOR,
2081 CRYPTO_CMD_INSTR_DATA1TODATA2);
2082 }
2083
2084 CRYPTO_AES_ProcessLoop(crypto, len,
2085 &crypto->DATA1, in,
2086 &crypto->DATA0, out);
2087 }
2088
2089 /***************************************************************************//**
2090 * @brief
2091 * Counter (CTR) cipher mode encryption/decryption, 128/256 bit key.
2092 *
2093 * @details
2094 * See CRYPTO_AES_CTR128() for CTR figure.
2095 *
2096 * See general comments on layout and byte ordering of parameters.
2097 *
2098 * @param[in] crypto
2099 * A pointer to the CRYPTO peripheral register block.
2100 *
2101 * @param[out] out
2102 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
2103 * may be set equal to @p in, in which case the input buffer is overwritten.
2104 *
2105 * @param[in] in
2106 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
2107 *
2108 * @param[in] len
2109 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
2110 *
2111 * @param[in] key
2112 * 256 bit encryption key.
2113 *
2114 * @param[in,out] ctr
2115 * 128 bit initial counter value. The counter is updated after each AES
2116 * block encoding through use of @p ctrFunc.
2117 *
2118 * @param[in] ctrFunc
2119 * A function used to update counter value. Not supported by CRYPTO.
2120 * This parameter is included for backwards compatibility with
2121 * the EFM32 em_aes.h API.
2122 *
2123 * @param[in] keyWidth
2124 * Set to cryptoKey128Bits or cryptoKey256Bits.
2125 ******************************************************************************/
CRYPTO_AES_CTRx(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,uint8_t * ctr,CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc,CRYPTO_KeyWidth_TypeDef keyWidth)2126 static void CRYPTO_AES_CTRx(CRYPTO_TypeDef * crypto,
2127 uint8_t * out,
2128 const uint8_t * in,
2129 unsigned int len,
2130 const uint8_t * key,
2131 uint8_t * ctr,
2132 CRYPTO_AES_CtrFuncPtr_TypeDef ctrFunc,
2133 CRYPTO_KeyWidth_TypeDef keyWidth)
2134 {
2135 (void) ctrFunc;
2136
2137 EFM_ASSERT((len % CRYPTO_AES_BLOCKSIZE) == 0U);
2138
2139 /* Initialize control registers. */
2140 crypto->CTRL |= CRYPTO_CTRL_INCWIDTH_INCWIDTH4;
2141 crypto->WAC = 0;
2142
2143 CRYPTO_KeyBufWriteUnaligned(crypto, key, keyWidth);
2144
2145 CRYPTO_DataWriteUnaligned(&crypto->DATA1, ctr);
2146
2147 CRYPTO_SEQ_LOAD_4(crypto,
2148 CRYPTO_CMD_INSTR_DATA1TODATA0,
2149 CRYPTO_CMD_INSTR_AESENC,
2150 CRYPTO_CMD_INSTR_DATA1INC,
2151 CRYPTO_CMD_INSTR_DATA2TODATA0XOR);
2152
2153 CRYPTO_AES_ProcessLoop(crypto, len,
2154 &crypto->DATA2, in,
2155 &crypto->DATA0, out);
2156
2157 CRYPTO_DataReadUnaligned(&crypto->DATA1, ctr);
2158 }
2159
2160 /***************************************************************************//**
2161 * @brief
2162 * Electronic Codebook (ECB) cipher mode encryption/decryption, 128/256 bit key.
2163 *
2164 * @details
2165 * See CRYPTO_AES_ECB128() for ECB figure.
2166 *
2167 * See general comments on layout and byte ordering of parameters.
2168 *
2169 * @param[in] crypto
2170 * A pointer to the CRYPTO peripheral register block.
2171 *
2172 * @param[out] out
2173 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
2174 * may be set equal to @p in, in which case the input buffer is overwritten.
2175 *
2176 * @param[in] in
2177 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
2178 *
2179 * @param[in] len
2180 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
2181 *
2182 * @param[in] key
2183 * When encrypting, this is the 256 bit encryption key. When
2184 * decrypting, this is the 256 bit decryption key. The decryption key may
2185 * be generated from the encryption key with CRYPTO_AES_DecryptKey256().
2186 *
2187 * @param[in] encrypt
2188 * Set to true to encrypt, false to decrypt.
2189 *
2190 * @param[in] keyWidth
2191 * Set to cryptoKey128Bits or cryptoKey256Bits.
2192 ******************************************************************************/
CRYPTO_AES_ECBx(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,bool encrypt,CRYPTO_KeyWidth_TypeDef keyWidth)2193 static void CRYPTO_AES_ECBx(CRYPTO_TypeDef * crypto,
2194 uint8_t * out,
2195 const uint8_t * in,
2196 unsigned int len,
2197 const uint8_t * key,
2198 bool encrypt,
2199 CRYPTO_KeyWidth_TypeDef keyWidth)
2200 {
2201 EFM_ASSERT((len % CRYPTO_AES_BLOCKSIZE) == 0U);
2202
2203 crypto->WAC = 0;
2204
2205 CRYPTO_KeyBufWriteUnaligned(crypto, key, keyWidth);
2206
2207 if (encrypt) {
2208 CRYPTO_SEQ_LOAD_2(crypto,
2209 CRYPTO_CMD_INSTR_AESENC,
2210 CRYPTO_CMD_INSTR_DATA0TODATA1);
2211 } else {
2212 CRYPTO_SEQ_LOAD_2(crypto,
2213 CRYPTO_CMD_INSTR_AESDEC,
2214 CRYPTO_CMD_INSTR_DATA0TODATA1);
2215 }
2216
2217 CRYPTO_AES_ProcessLoop(crypto, len,
2218 &crypto->DATA0, in,
2219 &crypto->DATA1, out);
2220 }
2221
2222 /***************************************************************************//**
2223 * @brief
2224 * Output feedback (OFB) cipher mode encryption/decryption, 128/256 bit key.
2225 *
2226 * @details
2227 * See CRYPTO_AES_OFB128() for OFB figure.
2228 *
2229 * See general comments on layout and byte ordering of parameters.
2230 *
2231 * @param[in] crypto
2232 * A pointer to CRYPTO peripheral register block.
2233 *
2234 * @param[out] out
2235 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
2236 * may be set equal to @p in, in which case the input buffer is overwritten.
2237 *
2238 * @param[in] in
2239 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
2240 *
2241 * @param[in] len
2242 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
2243 *
2244 * @param[in] key
2245 * 256 bit encryption key.
2246 *
2247 * @param[in] iv
2248 * 128 bit initialization vector to use.
2249 *
2250 * @param[in] keyWidth
2251 * Set to cryptoKey128Bits or cryptoKey256Bits.
2252 ******************************************************************************/
CRYPTO_AES_OFBx(CRYPTO_TypeDef * crypto,uint8_t * out,const uint8_t * in,unsigned int len,const uint8_t * key,const uint8_t * iv,CRYPTO_KeyWidth_TypeDef keyWidth)2253 static void CRYPTO_AES_OFBx(CRYPTO_TypeDef * crypto,
2254 uint8_t * out,
2255 const uint8_t * in,
2256 unsigned int len,
2257 const uint8_t * key,
2258 const uint8_t * iv,
2259 CRYPTO_KeyWidth_TypeDef keyWidth)
2260 {
2261 EFM_ASSERT((len % CRYPTO_AES_BLOCKSIZE) == 0U);
2262
2263 crypto->WAC = 0;
2264
2265 CRYPTO_KeyBufWriteUnaligned(crypto, key, keyWidth);
2266
2267 CRYPTO_DataWriteUnaligned(&crypto->DATA2, iv);
2268
2269 CRYPTO_SEQ_LOAD_6(crypto,
2270 CRYPTO_CMD_INSTR_DATA0TODATA1,
2271 CRYPTO_CMD_INSTR_DATA2TODATA0,
2272 CRYPTO_CMD_INSTR_AESENC,
2273 CRYPTO_CMD_INSTR_DATA0TODATA2,
2274 CRYPTO_CMD_INSTR_DATA1TODATA0XOR,
2275 CRYPTO_CMD_INSTR_DATA0TODATA1);
2276
2277 CRYPTO_AES_ProcessLoop(crypto, len,
2278 &crypto->DATA0, in,
2279 &crypto->DATA1, out);
2280 }
2281
2282 /***************************************************************************//**
2283 * @brief
2284 * Perform generic AES loop.
2285 *
2286 * @details
2287 * Function loads given register with provided input data. Triggers CRYPTO to
2288 * perform sequence of instructions and read specified output register to
2289 * output buffer.
2290 *
2291 * @param[in] crypto
2292 * A pointer to the CRYPTO peripheral register block.
2293 *
2294 * @param[in] len
2295 * A number of bytes to encrypt/decrypt. Must be a multiple of 16.
2296 *
2297 * @param[in] inReg
2298 * An input register - one of DATA0,DATA1,DATA2,DATA3
2299 *
2300 * @param[in] in
2301 * A buffer holding data to encrypt/decrypt. Must be at least @p len long.
2302 *
2303 * @param[in] outReg
2304 * An output register - one of DATA0,DATA1,DATA2,DATA3
2305 *
2306 * @param[out] out
2307 * A buffer to place encrypted/decrypted data. Must be at least @p len long. It
2308 * may be set equal to @p in, in which case the input buffer is overwritten.
2309 ******************************************************************************/
CRYPTO_AES_ProcessLoop(CRYPTO_TypeDef * crypto,unsigned int len,CRYPTO_DataReg_TypeDef inReg,const uint8_t * in,CRYPTO_DataReg_TypeDef outReg,uint8_t * out)2310 __STATIC_INLINE void CRYPTO_AES_ProcessLoop(CRYPTO_TypeDef * crypto,
2311 unsigned int len,
2312 CRYPTO_DataReg_TypeDef inReg,
2313 const uint8_t * in,
2314 CRYPTO_DataReg_TypeDef outReg,
2315 uint8_t * out)
2316 {
2317 len /= CRYPTO_AES_BLOCKSIZE;
2318 crypto->SEQCTRL = 16UL << _CRYPTO_SEQCTRL_LENGTHA_SHIFT;
2319
2320 if (((uintptr_t)in & 0x3) || ((uintptr_t)out & 0x3)) {
2321 while (len > 0UL) {
2322 len--;
2323 /* Load data and trigger encryption. */
2324 CRYPTO_DataWriteUnaligned(inReg, in);
2325 CRYPTO_InstructionSequenceExecute(crypto);
2326
2327 /* Wait for the sequence to finish. */
2328 CRYPTO_InstructionSequenceWait(crypto);
2329 /* Save encrypted/decrypted data. */
2330 CRYPTO_DataReadUnaligned(outReg, out);
2331
2332 out += 16;
2333 in += 16;
2334 }
2335 } else {
2336 /* Optimized version, 15% faster for -O3. */
2337 if (len > 0UL) {
2338 /* Load first data and trigger encryption. */
2339 CRYPTO_DataWrite(inReg, (uint32_t *)in);
2340 CRYPTO_InstructionSequenceExecute(crypto);
2341
2342 /* Do loop administration while CRYPTO engine is working. */
2343 in += 16;
2344 len--;
2345
2346 while (len > 0UL) {
2347 /* Wait for the sequence to finish. */
2348 CRYPTO_InstructionSequenceWait(crypto);
2349 /* Save encrypted/decrypted data. */
2350 CRYPTO_DataRead(outReg, (uint32_t *)out);
2351
2352 /* Load next data and retrigger encryption asap. */
2353 CRYPTO_DataWrite(inReg, (uint32_t *)in);
2354 CRYPTO_InstructionSequenceExecute(crypto);
2355
2356 /* Do loop administration while CRYPTO engine is working. */
2357 out += 16;
2358 in += 16;
2359 len--;
2360 }
2361
2362 /* Wait for the sequence to finish. */
2363 CRYPTO_InstructionSequenceWait(crypto);
2364 /* Save last encrypted/decrypted data. */
2365 CRYPTO_DataRead(outReg, (uint32_t *)out);
2366 }
2367 }
2368 }
2369
2370 /** @} (end addtogroup crypto) */
2371
2372 #endif /* defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0) */
2373