Move telemetry displayport init and cms device registering
[betaflight.git] / lib / main / STM32F4 / Drivers / STM32F4xx_StdPeriph_Driver / src / stm32f4xx_cryp_aes.c
bloba99808f8f97b11c39e2ad5b75356d4b2b25f7af5
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_cryp_aes.c
4 * @author MCD Application Team
5 * @version V1.7.1
6 * @date 20-May-2016
7 * @brief This file provides high level functions to encrypt and decrypt an
8 * input message using AES in ECB/CBC/CTR/GCM/CCM modes.
9 * It uses the stm32f4xx_cryp.c/.h drivers to access the STM32F4xx CRYP
10 * peripheral.
11 * AES-ECB/CBC/CTR/GCM/CCM modes are available on STM32F437x Devices.
12 * For STM32F41xx Devices, only AES-ECB/CBC/CTR modes are available.
14 @verbatim
15 ===================================================================
16 ##### How to use this driver #####
17 ===================================================================
18 [..]
19 (#) Enable The CRYP controller clock using
20 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function.
22 (#) Encrypt and decrypt using AES in ECB Mode using CRYP_AES_ECB() function.
24 (#) Encrypt and decrypt using AES in CBC Mode using CRYP_AES_CBC() function.
26 (#) Encrypt and decrypt using AES in CTR Mode using CRYP_AES_CTR() function.
28 (#) Encrypt and decrypt using AES in GCM Mode using CRYP_AES_GCM() function.
30 (#) Encrypt and decrypt using AES in CCM Mode using CRYP_AES_CCM() function.
32 @endverbatim
34 ******************************************************************************
35 * @attention
37 * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
39 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
40 * You may not use this file except in compliance with the License.
41 * You may obtain a copy of the License at:
43 * http://www.st.com/software_license_agreement_liberty_v2
45 * Unless required by applicable law or agreed to in writing, software
46 * distributed under the License is distributed on an "AS IS" BASIS,
47 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48 * See the License for the specific language governing permissions and
49 * limitations under the License.
51 ******************************************************************************
54 /* Includes ------------------------------------------------------------------*/
55 #include "stm32f4xx_cryp.h"
57 /** @addtogroup STM32F4xx_StdPeriph_Driver
58 * @{
61 /** @defgroup CRYP
62 * @brief CRYP driver modules
63 * @{
66 /* Private typedef -----------------------------------------------------------*/
67 /* Private define ------------------------------------------------------------*/
68 #define AESBUSY_TIMEOUT ((uint32_t) 0x00010000)
70 /* Private macro -------------------------------------------------------------*/
71 /* Private variables ---------------------------------------------------------*/
72 /* Private function prototypes -----------------------------------------------*/
73 /* Private functions ---------------------------------------------------------*/
75 /** @defgroup CRYP_Private_Functions
76 * @{
77 */
79 /** @defgroup CRYP_Group6 High Level AES functions
80 * @brief High Level AES functions
82 @verbatim
83 ===============================================================================
84 ##### High Level AES functions #####
85 ===============================================================================
87 @endverbatim
88 * @{
91 /**
92 * @brief Encrypt and decrypt using AES in ECB Mode
93 * @param Mode: encryption or decryption Mode.
94 * This parameter can be one of the following values:
95 * @arg MODE_ENCRYPT: Encryption
96 * @arg MODE_DECRYPT: Decryption
97 * @param Key: Key used for AES algorithm.
98 * @param Keysize: length of the Key, must be a 128, 192 or 256.
99 * @param Input: pointer to the Input buffer.
100 * @param Ilength: length of the Input buffer, must be a multiple of 16.
101 * @param Output: pointer to the returned buffer.
102 * @retval An ErrorStatus enumeration value:
103 * - SUCCESS: Operation done
104 * - ERROR: Operation failed
106 ErrorStatus CRYP_AES_ECB(uint8_t Mode, uint8_t* Key, uint16_t Keysize,
107 uint8_t* Input, uint32_t Ilength, uint8_t* Output)
109 CRYP_InitTypeDef AES_CRYP_InitStructure;
110 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
111 __IO uint32_t counter = 0;
112 uint32_t busystatus = 0;
113 ErrorStatus status = SUCCESS;
114 uint32_t keyaddr = (uint32_t)Key;
115 uint32_t inputaddr = (uint32_t)Input;
116 uint32_t outputaddr = (uint32_t)Output;
117 uint32_t i = 0;
119 /* Crypto structures initialisation*/
120 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
122 switch(Keysize)
124 case 128:
125 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
126 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
127 keyaddr+=4;
128 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
129 keyaddr+=4;
130 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
131 keyaddr+=4;
132 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
133 break;
134 case 192:
135 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
136 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
137 keyaddr+=4;
138 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
139 keyaddr+=4;
140 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
141 keyaddr+=4;
142 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
143 keyaddr+=4;
144 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
145 keyaddr+=4;
146 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
147 break;
148 case 256:
149 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
150 AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
151 keyaddr+=4;
152 AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
153 keyaddr+=4;
154 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
155 keyaddr+=4;
156 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
157 keyaddr+=4;
158 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
159 keyaddr+=4;
160 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
161 keyaddr+=4;
162 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
163 keyaddr+=4;
164 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
165 break;
166 default:
167 break;
170 /*------------------ AES Decryption ------------------*/
171 if(Mode == MODE_DECRYPT) /* AES decryption */
173 /* Flush IN/OUT FIFOs */
174 CRYP_FIFOFlush();
176 /* Crypto Init for Key preparation for decryption process */
177 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
178 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
179 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
180 CRYP_Init(&AES_CRYP_InitStructure);
182 /* Key Initialisation */
183 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
185 /* Enable Crypto processor */
186 CRYP_Cmd(ENABLE);
188 /* wait until the Busy flag is RESET */
191 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
192 counter++;
193 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
195 if (busystatus != RESET)
197 status = ERROR;
199 else
201 /* Crypto Init for decryption process */
202 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
205 /*------------------ AES Encryption ------------------*/
206 else /* AES encryption */
209 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
211 /* Crypto Init for Encryption process */
212 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
215 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
216 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
217 CRYP_Init(&AES_CRYP_InitStructure);
219 /* Flush IN/OUT FIFOs */
220 CRYP_FIFOFlush();
222 /* Enable Crypto processor */
223 CRYP_Cmd(ENABLE);
225 if(CRYP_GetCmdStatus() == DISABLE)
227 /* The CRYP peripheral clock is not enabled or the device doesn't embed
228 the CRYP peripheral (please check the device sales type. */
229 return(ERROR);
232 for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
235 /* Write the Input block in the IN FIFO */
236 CRYP_DataIn(*(uint32_t*)(inputaddr));
237 inputaddr+=4;
238 CRYP_DataIn(*(uint32_t*)(inputaddr));
239 inputaddr+=4;
240 CRYP_DataIn(*(uint32_t*)(inputaddr));
241 inputaddr+=4;
242 CRYP_DataIn(*(uint32_t*)(inputaddr));
243 inputaddr+=4;
245 /* Wait until the complete message has been processed */
246 counter = 0;
249 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
250 counter++;
251 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
253 if (busystatus != RESET)
255 status = ERROR;
257 else
260 /* Read the Output block from the Output FIFO */
261 *(uint32_t*)(outputaddr) = CRYP_DataOut();
262 outputaddr+=4;
263 *(uint32_t*)(outputaddr) = CRYP_DataOut();
264 outputaddr+=4;
265 *(uint32_t*)(outputaddr) = CRYP_DataOut();
266 outputaddr+=4;
267 *(uint32_t*)(outputaddr) = CRYP_DataOut();
268 outputaddr+=4;
272 /* Disable Crypto */
273 CRYP_Cmd(DISABLE);
275 return status;
279 * @brief Encrypt and decrypt using AES in CBC Mode
280 * @param Mode: encryption or decryption Mode.
281 * This parameter can be one of the following values:
282 * @arg MODE_ENCRYPT: Encryption
283 * @arg MODE_DECRYPT: Decryption
284 * @param InitVectors: Initialisation Vectors used for AES algorithm.
285 * @param Key: Key used for AES algorithm.
286 * @param Keysize: length of the Key, must be a 128, 192 or 256.
287 * @param Input: pointer to the Input buffer.
288 * @param Ilength: length of the Input buffer, must be a multiple of 16.
289 * @param Output: pointer to the returned buffer.
290 * @retval An ErrorStatus enumeration value:
291 * - SUCCESS: Operation done
292 * - ERROR: Operation failed
294 ErrorStatus CRYP_AES_CBC(uint8_t Mode, uint8_t InitVectors[16], uint8_t *Key,
295 uint16_t Keysize, uint8_t *Input, uint32_t Ilength,
296 uint8_t *Output)
298 CRYP_InitTypeDef AES_CRYP_InitStructure;
299 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
300 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
301 __IO uint32_t counter = 0;
302 uint32_t busystatus = 0;
303 ErrorStatus status = SUCCESS;
304 uint32_t keyaddr = (uint32_t)Key;
305 uint32_t inputaddr = (uint32_t)Input;
306 uint32_t outputaddr = (uint32_t)Output;
307 uint32_t ivaddr = (uint32_t)InitVectors;
308 uint32_t i = 0;
310 /* Crypto structures initialisation*/
311 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
313 switch(Keysize)
315 case 128:
316 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
317 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
318 keyaddr+=4;
319 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
320 keyaddr+=4;
321 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
322 keyaddr+=4;
323 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
324 break;
325 case 192:
326 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
327 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
328 keyaddr+=4;
329 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
330 keyaddr+=4;
331 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
332 keyaddr+=4;
333 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
334 keyaddr+=4;
335 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
336 keyaddr+=4;
337 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
338 break;
339 case 256:
340 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
341 AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
342 keyaddr+=4;
343 AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
344 keyaddr+=4;
345 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
346 keyaddr+=4;
347 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
348 keyaddr+=4;
349 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
350 keyaddr+=4;
351 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
352 keyaddr+=4;
353 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
354 keyaddr+=4;
355 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
356 break;
357 default:
358 break;
361 /* CRYP Initialization Vectors */
362 AES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
363 ivaddr+=4;
364 AES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
365 ivaddr+=4;
366 AES_CRYP_IVInitStructure.CRYP_IV1Left = __REV(*(uint32_t*)(ivaddr));
367 ivaddr+=4;
368 AES_CRYP_IVInitStructure.CRYP_IV1Right= __REV(*(uint32_t*)(ivaddr));
371 /*------------------ AES Decryption ------------------*/
372 if(Mode == MODE_DECRYPT) /* AES decryption */
374 /* Flush IN/OUT FIFOs */
375 CRYP_FIFOFlush();
377 /* Crypto Init for Key preparation for decryption process */
378 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
379 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
380 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
382 CRYP_Init(&AES_CRYP_InitStructure);
384 /* Key Initialisation */
385 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
387 /* Enable Crypto processor */
388 CRYP_Cmd(ENABLE);
390 /* wait until the Busy flag is RESET */
393 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
394 counter++;
395 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
397 if (busystatus != RESET)
399 status = ERROR;
401 else
403 /* Crypto Init for decryption process */
404 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
407 /*------------------ AES Encryption ------------------*/
408 else /* AES encryption */
410 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
412 /* Crypto Init for Encryption process */
413 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
415 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
416 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
417 CRYP_Init(&AES_CRYP_InitStructure);
419 /* CRYP Initialization Vectors */
420 CRYP_IVInit(&AES_CRYP_IVInitStructure);
422 /* Flush IN/OUT FIFOs */
423 CRYP_FIFOFlush();
425 /* Enable Crypto processor */
426 CRYP_Cmd(ENABLE);
428 if(CRYP_GetCmdStatus() == DISABLE)
430 /* The CRYP peripheral clock is not enabled or the device doesn't embed
431 the CRYP peripheral (please check the device sales type. */
432 return(ERROR);
435 for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
438 /* Write the Input block in the IN FIFO */
439 CRYP_DataIn(*(uint32_t*)(inputaddr));
440 inputaddr+=4;
441 CRYP_DataIn(*(uint32_t*)(inputaddr));
442 inputaddr+=4;
443 CRYP_DataIn(*(uint32_t*)(inputaddr));
444 inputaddr+=4;
445 CRYP_DataIn(*(uint32_t*)(inputaddr));
446 inputaddr+=4;
447 /* Wait until the complete message has been processed */
448 counter = 0;
451 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
452 counter++;
453 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
455 if (busystatus != RESET)
457 status = ERROR;
459 else
462 /* Read the Output block from the Output FIFO */
463 *(uint32_t*)(outputaddr) = CRYP_DataOut();
464 outputaddr+=4;
465 *(uint32_t*)(outputaddr) = CRYP_DataOut();
466 outputaddr+=4;
467 *(uint32_t*)(outputaddr) = CRYP_DataOut();
468 outputaddr+=4;
469 *(uint32_t*)(outputaddr) = CRYP_DataOut();
470 outputaddr+=4;
474 /* Disable Crypto */
475 CRYP_Cmd(DISABLE);
477 return status;
481 * @brief Encrypt and decrypt using AES in CTR Mode
482 * @param Mode: encryption or decryption Mode.
483 * This parameter can be one of the following values:
484 * @arg MODE_ENCRYPT: Encryption
485 * @arg MODE_DECRYPT: Decryption
486 * @param InitVectors: Initialisation Vectors used for AES algorithm.
487 * @param Key: Key used for AES algorithm.
488 * @param Keysize: length of the Key, must be a 128, 192 or 256.
489 * @param Input: pointer to the Input buffer.
490 * @param Ilength: length of the Input buffer, must be a multiple of 16.
491 * @param Output: pointer to the returned buffer.
492 * @retval An ErrorStatus enumeration value:
493 * - SUCCESS: Operation done
494 * - ERROR: Operation failed
496 ErrorStatus CRYP_AES_CTR(uint8_t Mode, uint8_t InitVectors[16], uint8_t *Key,
497 uint16_t Keysize, uint8_t *Input, uint32_t Ilength,
498 uint8_t *Output)
500 CRYP_InitTypeDef AES_CRYP_InitStructure;
501 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
502 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
503 __IO uint32_t counter = 0;
504 uint32_t busystatus = 0;
505 ErrorStatus status = SUCCESS;
506 uint32_t keyaddr = (uint32_t)Key;
507 uint32_t inputaddr = (uint32_t)Input;
508 uint32_t outputaddr = (uint32_t)Output;
509 uint32_t ivaddr = (uint32_t)InitVectors;
510 uint32_t i = 0;
512 /* Crypto structures initialisation*/
513 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
515 switch(Keysize)
517 case 128:
518 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
519 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
520 keyaddr+=4;
521 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
522 keyaddr+=4;
523 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
524 keyaddr+=4;
525 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
526 break;
527 case 192:
528 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
529 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
530 keyaddr+=4;
531 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
532 keyaddr+=4;
533 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
534 keyaddr+=4;
535 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
536 keyaddr+=4;
537 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
538 keyaddr+=4;
539 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
540 break;
541 case 256:
542 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
543 AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
544 keyaddr+=4;
545 AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
546 keyaddr+=4;
547 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
548 keyaddr+=4;
549 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
550 keyaddr+=4;
551 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
552 keyaddr+=4;
553 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
554 keyaddr+=4;
555 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
556 keyaddr+=4;
557 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
558 break;
559 default:
560 break;
562 /* CRYP Initialization Vectors */
563 AES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
564 ivaddr+=4;
565 AES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
566 ivaddr+=4;
567 AES_CRYP_IVInitStructure.CRYP_IV1Left = __REV(*(uint32_t*)(ivaddr));
568 ivaddr+=4;
569 AES_CRYP_IVInitStructure.CRYP_IV1Right= __REV(*(uint32_t*)(ivaddr));
571 /* Key Initialisation */
572 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
574 /*------------------ AES Decryption ------------------*/
575 if(Mode == MODE_DECRYPT) /* AES decryption */
577 /* Crypto Init for decryption process */
578 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
580 /*------------------ AES Encryption ------------------*/
581 else /* AES encryption */
583 /* Crypto Init for Encryption process */
584 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
586 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
587 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
588 CRYP_Init(&AES_CRYP_InitStructure);
590 /* CRYP Initialization Vectors */
591 CRYP_IVInit(&AES_CRYP_IVInitStructure);
593 /* Flush IN/OUT FIFOs */
594 CRYP_FIFOFlush();
596 /* Enable Crypto processor */
597 CRYP_Cmd(ENABLE);
599 if(CRYP_GetCmdStatus() == DISABLE)
601 /* The CRYP peripheral clock is not enabled or the device doesn't embed
602 the CRYP peripheral (please check the device sales type. */
603 return(ERROR);
606 for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
609 /* Write the Input block in the IN FIFO */
610 CRYP_DataIn(*(uint32_t*)(inputaddr));
611 inputaddr+=4;
612 CRYP_DataIn(*(uint32_t*)(inputaddr));
613 inputaddr+=4;
614 CRYP_DataIn(*(uint32_t*)(inputaddr));
615 inputaddr+=4;
616 CRYP_DataIn(*(uint32_t*)(inputaddr));
617 inputaddr+=4;
618 /* Wait until the complete message has been processed */
619 counter = 0;
622 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
623 counter++;
624 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
626 if (busystatus != RESET)
628 status = ERROR;
630 else
633 /* Read the Output block from the Output FIFO */
634 *(uint32_t*)(outputaddr) = CRYP_DataOut();
635 outputaddr+=4;
636 *(uint32_t*)(outputaddr) = CRYP_DataOut();
637 outputaddr+=4;
638 *(uint32_t*)(outputaddr) = CRYP_DataOut();
639 outputaddr+=4;
640 *(uint32_t*)(outputaddr) = CRYP_DataOut();
641 outputaddr+=4;
644 /* Disable Crypto */
645 CRYP_Cmd(DISABLE);
647 return status;
651 * @brief Encrypt and decrypt using AES in GCM Mode. The GCM and CCM modes
652 * are available only on STM32F437x Devices.
653 * @param Mode: encryption or decryption Mode.
654 * This parameter can be one of the following values:
655 * @arg MODE_ENCRYPT: Encryption
656 * @arg MODE_DECRYPT: Decryption
657 * @param InitVectors: Initialisation Vectors used for AES algorithm.
658 * @param Key: Key used for AES algorithm.
659 * @param Keysize: length of the Key, must be a 128, 192 or 256.
660 * @param Input: pointer to the Input buffer.
661 * @param Ilength: length of the Input buffer in bytes, must be a multiple of 16.
662 * @param Header: pointer to the header buffer.
663 * @param Hlength: length of the header buffer in bytes, must be a multiple of 16.
664 * @param Output: pointer to the returned buffer.
665 * @param AuthTAG: pointer to the authentication TAG buffer.
666 * @retval An ErrorStatus enumeration value:
667 * - SUCCESS: Operation done
668 * - ERROR: Operation failed
670 ErrorStatus CRYP_AES_GCM(uint8_t Mode, uint8_t InitVectors[16],
671 uint8_t *Key, uint16_t Keysize,
672 uint8_t *Input, uint32_t ILength,
673 uint8_t *Header, uint32_t HLength,
674 uint8_t *Output, uint8_t *AuthTAG)
676 CRYP_InitTypeDef AES_CRYP_InitStructure;
677 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
678 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
679 __IO uint32_t counter = 0;
680 uint32_t busystatus = 0;
681 ErrorStatus status = SUCCESS;
682 uint32_t keyaddr = (uint32_t)Key;
683 uint32_t inputaddr = (uint32_t)Input;
684 uint32_t outputaddr = (uint32_t)Output;
685 uint32_t ivaddr = (uint32_t)InitVectors;
686 uint32_t headeraddr = (uint32_t)Header;
687 uint32_t tagaddr = (uint32_t)AuthTAG;
688 uint64_t headerlength = HLength * 8;/* header length in bits */
689 uint64_t inputlength = ILength * 8;/* input length in bits */
690 uint32_t loopcounter = 0;
692 /* Crypto structures initialisation*/
693 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
695 switch(Keysize)
697 case 128:
698 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
699 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
700 keyaddr+=4;
701 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
702 keyaddr+=4;
703 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
704 keyaddr+=4;
705 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
706 break;
707 case 192:
708 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
709 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
710 keyaddr+=4;
711 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
712 keyaddr+=4;
713 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
714 keyaddr+=4;
715 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
716 keyaddr+=4;
717 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
718 keyaddr+=4;
719 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
720 break;
721 case 256:
722 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
723 AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
724 keyaddr+=4;
725 AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
726 keyaddr+=4;
727 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
728 keyaddr+=4;
729 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
730 keyaddr+=4;
731 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
732 keyaddr+=4;
733 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
734 keyaddr+=4;
735 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
736 keyaddr+=4;
737 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
738 break;
739 default:
740 break;
743 /* CRYP Initialization Vectors */
744 AES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
745 ivaddr+=4;
746 AES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
747 ivaddr+=4;
748 AES_CRYP_IVInitStructure.CRYP_IV1Left = __REV(*(uint32_t*)(ivaddr));
749 ivaddr+=4;
750 AES_CRYP_IVInitStructure.CRYP_IV1Right= __REV(*(uint32_t*)(ivaddr));
752 /*------------------ AES Encryption ------------------*/
753 if(Mode == MODE_ENCRYPT) /* AES encryption */
755 /* Flush IN/OUT FIFOs */
756 CRYP_FIFOFlush();
758 /* Key Initialisation */
759 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
761 /* CRYP Initialization Vectors */
762 CRYP_IVInit(&AES_CRYP_IVInitStructure);
764 /* Crypto Init for Key preparation for decryption process */
765 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
766 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_GCM;
767 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
768 CRYP_Init(&AES_CRYP_InitStructure);
770 /***************************** Init phase *********************************/
771 /* Select init phase */
772 CRYP_PhaseConfig(CRYP_Phase_Init);
774 /* Enable Crypto processor */
775 CRYP_Cmd(ENABLE);
777 /* Wait for CRYPEN bit to be 0 */
778 while(CRYP_GetCmdStatus() == ENABLE)
782 /***************************** header phase *******************************/
783 if(HLength != 0)
785 /* Select header phase */
786 CRYP_PhaseConfig(CRYP_Phase_Header);
788 /* Enable Crypto processor */
789 CRYP_Cmd(ENABLE);
791 if(CRYP_GetCmdStatus() == DISABLE)
793 /* The CRYP peripheral clock is not enabled or the device doesn't embed
794 the CRYP peripheral (please check the device sales type. */
795 return(ERROR);
798 for(loopcounter = 0; (loopcounter < HLength); loopcounter+=16)
800 /* Wait until the IFEM flag is reset */
801 while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
805 /* Write the Input block in the IN FIFO */
806 CRYP_DataIn(*(uint32_t*)(headeraddr));
807 headeraddr+=4;
808 CRYP_DataIn(*(uint32_t*)(headeraddr));
809 headeraddr+=4;
810 CRYP_DataIn(*(uint32_t*)(headeraddr));
811 headeraddr+=4;
812 CRYP_DataIn(*(uint32_t*)(headeraddr));
813 headeraddr+=4;
816 /* Wait until the complete message has been processed */
817 counter = 0;
820 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
821 counter++;
822 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
824 if (busystatus != RESET)
826 status = ERROR;
830 /**************************** payload phase *******************************/
831 if(ILength != 0)
833 /* Select payload phase */
834 CRYP_PhaseConfig(CRYP_Phase_Payload);
836 /* Enable Crypto processor */
837 CRYP_Cmd(ENABLE);
839 if(CRYP_GetCmdStatus() == DISABLE)
841 /* The CRYP peripheral clock is not enabled or the device doesn't embed
842 the CRYP peripheral (please check the device sales type. */
843 return(ERROR);
846 for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
848 /* Wait until the IFEM flag is reset */
849 while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
852 /* Write the Input block in the IN FIFO */
853 CRYP_DataIn(*(uint32_t*)(inputaddr));
854 inputaddr+=4;
855 CRYP_DataIn(*(uint32_t*)(inputaddr));
856 inputaddr+=4;
857 CRYP_DataIn(*(uint32_t*)(inputaddr));
858 inputaddr+=4;
859 CRYP_DataIn(*(uint32_t*)(inputaddr));
860 inputaddr+=4;
862 /* Wait until the complete message has been processed */
863 counter = 0;
866 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
867 counter++;
868 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
870 if (busystatus != RESET)
872 status = ERROR;
874 else
876 /* Wait until the OFNE flag is reset */
877 while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
881 /* Read the Output block from the Output FIFO */
882 *(uint32_t*)(outputaddr) = CRYP_DataOut();
883 outputaddr+=4;
884 *(uint32_t*)(outputaddr) = CRYP_DataOut();
885 outputaddr+=4;
886 *(uint32_t*)(outputaddr) = CRYP_DataOut();
887 outputaddr+=4;
888 *(uint32_t*)(outputaddr) = CRYP_DataOut();
889 outputaddr+=4;
894 /***************************** final phase ********************************/
895 /* Select final phase */
896 CRYP_PhaseConfig(CRYP_Phase_Final);
898 /* Enable Crypto processor */
899 CRYP_Cmd(ENABLE);
901 if(CRYP_GetCmdStatus() == DISABLE)
903 /* The CRYP peripheral clock is not enabled or the device doesn't embed
904 the CRYP peripheral (please check the device sales type. */
905 return(ERROR);
908 /* Write number of bits concatenated with header in the IN FIFO */
909 CRYP_DataIn(__REV(headerlength>>32));
910 CRYP_DataIn(__REV(headerlength));
911 CRYP_DataIn(__REV(inputlength>>32));
912 CRYP_DataIn(__REV(inputlength));
913 /* Wait until the OFNE flag is reset */
914 while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
918 tagaddr = (uint32_t)AuthTAG;
919 /* Read the Auth TAG in the IN FIFO */
920 *(uint32_t*)(tagaddr) = CRYP_DataOut();
921 tagaddr+=4;
922 *(uint32_t*)(tagaddr) = CRYP_DataOut();
923 tagaddr+=4;
924 *(uint32_t*)(tagaddr) = CRYP_DataOut();
925 tagaddr+=4;
926 *(uint32_t*)(tagaddr) = CRYP_DataOut();
927 tagaddr+=4;
929 /*------------------ AES Decryption ------------------*/
930 else /* AES decryption */
932 /* Flush IN/OUT FIFOs */
933 CRYP_FIFOFlush();
935 /* Key Initialisation */
936 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
938 /* CRYP Initialization Vectors */
939 CRYP_IVInit(&AES_CRYP_IVInitStructure);
941 /* Crypto Init for Key preparation for decryption process */
942 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
943 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_GCM;
944 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
945 CRYP_Init(&AES_CRYP_InitStructure);
947 /***************************** Init phase *********************************/
948 /* Select init phase */
949 CRYP_PhaseConfig(CRYP_Phase_Init);
951 /* Enable Crypto processor */
952 CRYP_Cmd(ENABLE);
954 /* Wait for CRYPEN bit to be 0 */
955 while(CRYP_GetCmdStatus() == ENABLE)
959 /***************************** header phase *******************************/
960 if(HLength != 0)
962 /* Select header phase */
963 CRYP_PhaseConfig(CRYP_Phase_Header);
965 /* Enable Crypto processor */
966 CRYP_Cmd(ENABLE);
968 if(CRYP_GetCmdStatus() == DISABLE)
970 /* The CRYP peripheral clock is not enabled or the device doesn't embed
971 the CRYP peripheral (please check the device sales type. */
972 return(ERROR);
975 for(loopcounter = 0; (loopcounter < HLength); loopcounter+=16)
977 /* Wait until the IFEM flag is reset */
978 while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
982 /* Write the Input block in the IN FIFO */
983 CRYP_DataIn(*(uint32_t*)(headeraddr));
984 headeraddr+=4;
985 CRYP_DataIn(*(uint32_t*)(headeraddr));
986 headeraddr+=4;
987 CRYP_DataIn(*(uint32_t*)(headeraddr));
988 headeraddr+=4;
989 CRYP_DataIn(*(uint32_t*)(headeraddr));
990 headeraddr+=4;
993 /* Wait until the complete message has been processed */
994 counter = 0;
997 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
998 counter++;
999 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1001 if (busystatus != RESET)
1003 status = ERROR;
1007 /**************************** payload phase *******************************/
1008 if(ILength != 0)
1010 /* Select payload phase */
1011 CRYP_PhaseConfig(CRYP_Phase_Payload);
1013 /* Enable Crypto processor */
1014 CRYP_Cmd(ENABLE);
1016 if(CRYP_GetCmdStatus() == DISABLE)
1018 /* The CRYP peripheral clock is not enabled or the device doesn't embed
1019 the CRYP peripheral (please check the device sales type. */
1020 return(ERROR);
1023 for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1025 /* Wait until the IFEM flag is reset */
1026 while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1029 /* Write the Input block in the IN FIFO */
1030 CRYP_DataIn(*(uint32_t*)(inputaddr));
1031 inputaddr+=4;
1032 CRYP_DataIn(*(uint32_t*)(inputaddr));
1033 inputaddr+=4;
1034 CRYP_DataIn(*(uint32_t*)(inputaddr));
1035 inputaddr+=4;
1036 CRYP_DataIn(*(uint32_t*)(inputaddr));
1037 inputaddr+=4;
1039 /* Wait until the complete message has been processed */
1040 counter = 0;
1043 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1044 counter++;
1045 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1047 if (busystatus != RESET)
1049 status = ERROR;
1051 else
1053 /* Wait until the OFNE flag is reset */
1054 while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1058 /* Read the Output block from the Output FIFO */
1059 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1060 outputaddr+=4;
1061 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1062 outputaddr+=4;
1063 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1064 outputaddr+=4;
1065 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1066 outputaddr+=4;
1071 /***************************** final phase ********************************/
1072 /* Select final phase */
1073 CRYP_PhaseConfig(CRYP_Phase_Final);
1075 /* Enable Crypto processor */
1076 CRYP_Cmd(ENABLE);
1078 if(CRYP_GetCmdStatus() == DISABLE)
1080 /* The CRYP peripheral clock is not enabled or the device doesn't embed
1081 the CRYP peripheral (please check the device sales type. */
1082 return(ERROR);
1085 /* Write number of bits concatenated with header in the IN FIFO */
1086 CRYP_DataIn(__REV(headerlength>>32));
1087 CRYP_DataIn(__REV(headerlength));
1088 CRYP_DataIn(__REV(inputlength>>32));
1089 CRYP_DataIn(__REV(inputlength));
1090 /* Wait until the OFNE flag is reset */
1091 while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1095 tagaddr = (uint32_t)AuthTAG;
1096 /* Read the Auth TAG in the IN FIFO */
1097 *(uint32_t*)(tagaddr) = CRYP_DataOut();
1098 tagaddr+=4;
1099 *(uint32_t*)(tagaddr) = CRYP_DataOut();
1100 tagaddr+=4;
1101 *(uint32_t*)(tagaddr) = CRYP_DataOut();
1102 tagaddr+=4;
1103 *(uint32_t*)(tagaddr) = CRYP_DataOut();
1104 tagaddr+=4;
1106 /* Disable Crypto */
1107 CRYP_Cmd(DISABLE);
1109 return status;
1113 * @brief Encrypt and decrypt using AES in CCM Mode. The GCM and CCM modes
1114 * are available only on STM32F437x Devices.
1115 * @param Mode: encryption or decryption Mode.
1116 * This parameter can be one of the following values:
1117 * @arg MODE_ENCRYPT: Encryption
1118 * @arg MODE_DECRYPT: Decryption
1119 * @param Nonce: the nonce used for AES algorithm. It shall be unique for each processing.
1120 * @param Key: Key used for AES algorithm.
1121 * @param Keysize: length of the Key, must be a 128, 192 or 256.
1122 * @param Input: pointer to the Input buffer.
1123 * @param Ilength: length of the Input buffer in bytes, must be a multiple of 16.
1124 * @param Header: pointer to the header buffer.
1125 * @param Hlength: length of the header buffer in bytes.
1126 * @param HBuffer: pointer to temporary buffer used to append the header
1127 * HBuffer size must be equal to Hlength + 21
1128 * @param Output: pointer to the returned buffer.
1129 * @param AuthTAG: pointer to the authentication TAG buffer.
1130 * @param TAGSize: the size of the TAG (called also MAC).
1131 * @retval An ErrorStatus enumeration value:
1132 * - SUCCESS: Operation done
1133 * - ERROR: Operation failed
1135 ErrorStatus CRYP_AES_CCM(uint8_t Mode,
1136 uint8_t* Nonce, uint32_t NonceSize,
1137 uint8_t *Key, uint16_t Keysize,
1138 uint8_t *Input, uint32_t ILength,
1139 uint8_t *Header, uint32_t HLength, uint8_t *HBuffer,
1140 uint8_t *Output,
1141 uint8_t *AuthTAG, uint32_t TAGSize)
1143 CRYP_InitTypeDef AES_CRYP_InitStructure;
1144 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
1145 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
1146 __IO uint32_t counter = 0;
1147 uint32_t busystatus = 0;
1148 ErrorStatus status = SUCCESS;
1149 uint32_t keyaddr = (uint32_t)Key;
1150 uint32_t inputaddr = (uint32_t)Input;
1151 uint32_t outputaddr = (uint32_t)Output;
1152 uint32_t headeraddr = (uint32_t)Header;
1153 uint32_t tagaddr = (uint32_t)AuthTAG;
1154 uint32_t headersize = HLength;
1155 uint32_t loopcounter = 0;
1156 uint32_t bufferidx = 0;
1157 uint8_t blockb0[16] = {0};/* Block B0 */
1158 uint8_t ctr[16] = {0}; /* Counter */
1159 uint32_t temptag[4] = {0}; /* temporary TAG (MAC) */
1160 uint32_t ctraddr = (uint32_t)ctr;
1161 uint32_t b0addr = (uint32_t)blockb0;
1163 /************************ Formatting the header block ***********************/
1164 if(headersize != 0)
1166 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1167 if(headersize < 65280)
1169 HBuffer[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1170 HBuffer[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1171 headersize += 2;
1173 else
1175 /* header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1176 HBuffer[bufferidx++] = 0xFF;
1177 HBuffer[bufferidx++] = 0xFE;
1178 HBuffer[bufferidx++] = headersize & 0xff000000;
1179 HBuffer[bufferidx++] = headersize & 0x00ff0000;
1180 HBuffer[bufferidx++] = headersize & 0x0000ff00;
1181 HBuffer[bufferidx++] = headersize & 0x000000ff;
1182 headersize += 6;
1184 /* Copy the header buffer in internal buffer "HBuffer" */
1185 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1187 HBuffer[bufferidx++] = Header[loopcounter];
1189 /* Check if the header size is modulo 16 */
1190 if ((headersize % 16) != 0)
1192 /* Padd the header buffer with 0s till the HBuffer length is modulo 16 */
1193 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1195 HBuffer[loopcounter] = 0;
1197 /* Set the header size to modulo 16 */
1198 headersize = ((headersize/16) + 1) * 16;
1200 /* set the pointer headeraddr to HBuffer */
1201 headeraddr = (uint32_t)HBuffer;
1203 /************************* Formatting the block B0 **************************/
1204 if(headersize != 0)
1206 blockb0[0] = 0x40;
1208 /* Flags byte */
1209 blockb0[0] |= 0u | (((( (uint8_t) TAGSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - NonceSize) - 1) & 0x07);
1211 for (loopcounter = 0; loopcounter < NonceSize; loopcounter++)
1213 blockb0[loopcounter+1] = Nonce[loopcounter];
1215 for ( ; loopcounter < 13; loopcounter++)
1217 blockb0[loopcounter+1] = 0;
1220 blockb0[14] = ((ILength >> 8) & 0xFF);
1221 blockb0[15] = (ILength & 0xFF);
1223 /************************* Formatting the initial counter *******************/
1224 /* Byte 0:
1225 Bits 7 and 6 are reserved and shall be set to 0
1226 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
1227 are distinct from B0
1228 Bits 0, 1, and 2 contain the same encoding of q as in B0
1230 ctr[0] = blockb0[0] & 0x07;
1231 /* byte 1 to NonceSize is the IV (Nonce) */
1232 for(loopcounter = 1; loopcounter < NonceSize + 1; loopcounter++)
1234 ctr[loopcounter] = blockb0[loopcounter];
1236 /* Set the LSB to 1 */
1237 ctr[15] |= 0x01;
1239 /* Crypto structures initialisation*/
1240 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
1242 switch(Keysize)
1244 case 128:
1245 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
1246 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1247 keyaddr+=4;
1248 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1249 keyaddr+=4;
1250 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1251 keyaddr+=4;
1252 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1253 break;
1254 case 192:
1255 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
1256 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
1257 keyaddr+=4;
1258 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
1259 keyaddr+=4;
1260 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1261 keyaddr+=4;
1262 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1263 keyaddr+=4;
1264 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1265 keyaddr+=4;
1266 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1267 break;
1268 case 256:
1269 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
1270 AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
1271 keyaddr+=4;
1272 AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
1273 keyaddr+=4;
1274 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
1275 keyaddr+=4;
1276 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
1277 keyaddr+=4;
1278 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
1279 keyaddr+=4;
1280 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
1281 keyaddr+=4;
1282 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
1283 keyaddr+=4;
1284 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
1285 break;
1286 default:
1287 break;
1290 /* CRYP Initialization Vectors */
1291 AES_CRYP_IVInitStructure.CRYP_IV0Left = (__REV(*(uint32_t*)(ctraddr)));
1292 ctraddr+=4;
1293 AES_CRYP_IVInitStructure.CRYP_IV0Right= (__REV(*(uint32_t*)(ctraddr)));
1294 ctraddr+=4;
1295 AES_CRYP_IVInitStructure.CRYP_IV1Left = (__REV(*(uint32_t*)(ctraddr)));
1296 ctraddr+=4;
1297 AES_CRYP_IVInitStructure.CRYP_IV1Right= (__REV(*(uint32_t*)(ctraddr)));
1299 /*------------------ AES Encryption ------------------*/
1300 if(Mode == MODE_ENCRYPT) /* AES encryption */
1302 /* Flush IN/OUT FIFOs */
1303 CRYP_FIFOFlush();
1305 /* Key Initialisation */
1306 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
1308 /* CRYP Initialization Vectors */
1309 CRYP_IVInit(&AES_CRYP_IVInitStructure);
1311 /* Crypto Init for Key preparation for decryption process */
1312 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
1313 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CCM;
1314 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
1315 CRYP_Init(&AES_CRYP_InitStructure);
1317 /***************************** Init phase *********************************/
1318 /* Select init phase */
1319 CRYP_PhaseConfig(CRYP_Phase_Init);
1321 b0addr = (uint32_t)blockb0;
1322 /* Write the blockb0 block in the IN FIFO */
1323 CRYP_DataIn((*(uint32_t*)(b0addr)));
1324 b0addr+=4;
1325 CRYP_DataIn((*(uint32_t*)(b0addr)));
1326 b0addr+=4;
1327 CRYP_DataIn((*(uint32_t*)(b0addr)));
1328 b0addr+=4;
1329 CRYP_DataIn((*(uint32_t*)(b0addr)));
1331 /* Enable Crypto processor */
1332 CRYP_Cmd(ENABLE);
1334 /* Wait for CRYPEN bit to be 0 */
1335 while(CRYP_GetCmdStatus() == ENABLE)
1338 /***************************** header phase *******************************/
1339 if(headersize != 0)
1341 /* Select header phase */
1342 CRYP_PhaseConfig(CRYP_Phase_Header);
1344 /* Enable Crypto processor */
1345 CRYP_Cmd(ENABLE);
1347 if(CRYP_GetCmdStatus() == DISABLE)
1349 /* The CRYP peripheral clock is not enabled or the device doesn't embed
1350 the CRYP peripheral (please check the device sales type. */
1351 return(ERROR);
1354 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1356 /* Wait until the IFEM flag is reset */
1357 while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1361 /* Write the Input block in the IN FIFO */
1362 CRYP_DataIn(*(uint32_t*)(headeraddr));
1363 headeraddr+=4;
1364 CRYP_DataIn(*(uint32_t*)(headeraddr));
1365 headeraddr+=4;
1366 CRYP_DataIn(*(uint32_t*)(headeraddr));
1367 headeraddr+=4;
1368 CRYP_DataIn(*(uint32_t*)(headeraddr));
1369 headeraddr+=4;
1372 /* Wait until the complete message has been processed */
1373 counter = 0;
1376 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1377 counter++;
1378 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1380 if (busystatus != RESET)
1382 status = ERROR;
1386 /**************************** payload phase *******************************/
1387 if(ILength != 0)
1389 /* Select payload phase */
1390 CRYP_PhaseConfig(CRYP_Phase_Payload);
1392 /* Enable Crypto processor */
1393 CRYP_Cmd(ENABLE);
1395 if(CRYP_GetCmdStatus() == DISABLE)
1397 /* The CRYP peripheral clock is not enabled or the device doesn't embed
1398 the CRYP peripheral (please check the device sales type. */
1399 return(ERROR);
1402 for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1404 /* Wait until the IFEM flag is reset */
1405 while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1409 /* Write the Input block in the IN FIFO */
1410 CRYP_DataIn(*(uint32_t*)(inputaddr));
1411 inputaddr+=4;
1412 CRYP_DataIn(*(uint32_t*)(inputaddr));
1413 inputaddr+=4;
1414 CRYP_DataIn(*(uint32_t*)(inputaddr));
1415 inputaddr+=4;
1416 CRYP_DataIn(*(uint32_t*)(inputaddr));
1417 inputaddr+=4;
1419 /* Wait until the complete message has been processed */
1420 counter = 0;
1423 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1424 counter++;
1425 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1427 if (busystatus != RESET)
1429 status = ERROR;
1431 else
1433 /* Wait until the OFNE flag is reset */
1434 while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1438 /* Read the Output block from the Output FIFO */
1439 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1440 outputaddr+=4;
1441 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1442 outputaddr+=4;
1443 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1444 outputaddr+=4;
1445 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1446 outputaddr+=4;
1451 /***************************** final phase ********************************/
1452 /* Select final phase */
1453 CRYP_PhaseConfig(CRYP_Phase_Final);
1455 /* Enable Crypto processor */
1456 CRYP_Cmd(ENABLE);
1458 if(CRYP_GetCmdStatus() == DISABLE)
1460 /* The CRYP peripheral clock is not enabled or the device doesn't embed
1461 the CRYP peripheral (please check the device sales type. */
1462 return(ERROR);
1465 ctraddr = (uint32_t)ctr;
1466 /* Write the counter block in the IN FIFO */
1467 CRYP_DataIn(*(uint32_t*)(ctraddr));
1468 ctraddr+=4;
1469 CRYP_DataIn(*(uint32_t*)(ctraddr));
1470 ctraddr+=4;
1471 CRYP_DataIn(*(uint32_t*)(ctraddr));
1472 ctraddr+=4;
1473 /* Reset bit 0 (after 8-bit swap) is equivalent to reset bit 24 (before 8-bit swap) */
1474 CRYP_DataIn(*(uint32_t*)(ctraddr) & 0xfeffffff);
1476 /* Wait until the OFNE flag is reset */
1477 while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1481 /* Read the Auth TAG in the IN FIFO */
1482 temptag[0] = CRYP_DataOut();
1483 temptag[1] = CRYP_DataOut();
1484 temptag[2] = CRYP_DataOut();
1485 temptag[3] = CRYP_DataOut();
1487 /*------------------ AES Decryption ------------------*/
1488 else /* AES decryption */
1490 /* Flush IN/OUT FIFOs */
1491 CRYP_FIFOFlush();
1493 /* Key Initialisation */
1494 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
1496 /* CRYP Initialization Vectors */
1497 CRYP_IVInit(&AES_CRYP_IVInitStructure);
1499 /* Crypto Init for Key preparation for decryption process */
1500 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
1501 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CCM;
1502 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
1503 CRYP_Init(&AES_CRYP_InitStructure);
1505 /***************************** Init phase *********************************/
1506 /* Select init phase */
1507 CRYP_PhaseConfig(CRYP_Phase_Init);
1509 b0addr = (uint32_t)blockb0;
1510 /* Write the blockb0 block in the IN FIFO */
1511 CRYP_DataIn((*(uint32_t*)(b0addr)));
1512 b0addr+=4;
1513 CRYP_DataIn((*(uint32_t*)(b0addr)));
1514 b0addr+=4;
1515 CRYP_DataIn((*(uint32_t*)(b0addr)));
1516 b0addr+=4;
1517 CRYP_DataIn((*(uint32_t*)(b0addr)));
1519 /* Enable Crypto processor */
1520 CRYP_Cmd(ENABLE);
1522 /* Wait for CRYPEN bit to be 0 */
1523 while(CRYP_GetCmdStatus() == ENABLE)
1527 /***************************** header phase *******************************/
1528 if(headersize != 0)
1530 /* Select header phase */
1531 CRYP_PhaseConfig(CRYP_Phase_Header);
1533 /* Enable Crypto processor */
1534 CRYP_Cmd(ENABLE);
1536 if(CRYP_GetCmdStatus() == DISABLE)
1538 /* The CRYP peripheral clock is not enabled or the device doesn't embed
1539 the CRYP peripheral (please check the device sales type. */
1540 return(ERROR);
1543 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1545 /* Wait until the IFEM flag is reset */
1546 while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1550 /* Write the Input block in the IN FIFO */
1551 CRYP_DataIn(*(uint32_t*)(headeraddr));
1552 headeraddr+=4;
1553 CRYP_DataIn(*(uint32_t*)(headeraddr));
1554 headeraddr+=4;
1555 CRYP_DataIn(*(uint32_t*)(headeraddr));
1556 headeraddr+=4;
1557 CRYP_DataIn(*(uint32_t*)(headeraddr));
1558 headeraddr+=4;
1561 /* Wait until the complete message has been processed */
1562 counter = 0;
1565 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1566 counter++;
1567 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1569 if (busystatus != RESET)
1571 status = ERROR;
1575 /**************************** payload phase *******************************/
1576 if(ILength != 0)
1578 /* Select payload phase */
1579 CRYP_PhaseConfig(CRYP_Phase_Payload);
1581 /* Enable Crypto processor */
1582 CRYP_Cmd(ENABLE);
1584 if(CRYP_GetCmdStatus() == DISABLE)
1586 /* The CRYP peripheral clock is not enabled or the device doesn't embed
1587 the CRYP peripheral (please check the device sales type. */
1588 return(ERROR);
1591 for(loopcounter = 0; ((loopcounter < ILength) && (status != ERROR)); loopcounter+=16)
1593 /* Wait until the IFEM flag is reset */
1594 while(CRYP_GetFlagStatus(CRYP_FLAG_IFEM) == RESET)
1598 /* Write the Input block in the IN FIFO */
1599 CRYP_DataIn(*(uint32_t*)(inputaddr));
1600 inputaddr+=4;
1601 CRYP_DataIn(*(uint32_t*)(inputaddr));
1602 inputaddr+=4;
1603 CRYP_DataIn(*(uint32_t*)(inputaddr));
1604 inputaddr+=4;
1605 CRYP_DataIn(*(uint32_t*)(inputaddr));
1606 inputaddr+=4;
1608 /* Wait until the complete message has been processed */
1609 counter = 0;
1612 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
1613 counter++;
1614 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
1616 if (busystatus != RESET)
1618 status = ERROR;
1620 else
1622 /* Wait until the OFNE flag is reset */
1623 while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1627 /* Read the Output block from the Output FIFO */
1628 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1629 outputaddr+=4;
1630 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1631 outputaddr+=4;
1632 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1633 outputaddr+=4;
1634 *(uint32_t*)(outputaddr) = CRYP_DataOut();
1635 outputaddr+=4;
1640 /***************************** final phase ********************************/
1641 /* Select final phase */
1642 CRYP_PhaseConfig(CRYP_Phase_Final);
1644 /* Enable Crypto processor */
1645 CRYP_Cmd(ENABLE);
1647 if(CRYP_GetCmdStatus() == DISABLE)
1649 /* The CRYP peripheral clock is not enabled or the device doesn't embed
1650 the CRYP peripheral (please check the device sales type. */
1651 return(ERROR);
1654 ctraddr = (uint32_t)ctr;
1655 /* Write the counter block in the IN FIFO */
1656 CRYP_DataIn(*(uint32_t*)(ctraddr));
1657 ctraddr+=4;
1658 CRYP_DataIn(*(uint32_t*)(ctraddr));
1659 ctraddr+=4;
1660 CRYP_DataIn(*(uint32_t*)(ctraddr));
1661 ctraddr+=4;
1662 /* Reset bit 0 (after 8-bit swap) is equivalent to reset bit 24 (before 8-bit swap) */
1663 CRYP_DataIn(*(uint32_t*)(ctraddr) & 0xfeffffff);
1665 /* Wait until the OFNE flag is reset */
1666 while(CRYP_GetFlagStatus(CRYP_FLAG_OFNE) == RESET)
1670 /* Read the Authentification TAG (MAC) in the IN FIFO */
1671 temptag[0] = CRYP_DataOut();
1672 temptag[1] = CRYP_DataOut();
1673 temptag[2] = CRYP_DataOut();
1674 temptag[3] = CRYP_DataOut();
1677 /* Copy temporary authentication TAG in user TAG buffer */
1678 for(loopcounter = 0; (loopcounter < TAGSize); loopcounter++)
1680 /* Set the authentication TAG buffer */
1681 *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
1684 /* Disable Crypto */
1685 CRYP_Cmd(DISABLE);
1687 return status;
1691 * @}
1695 * @}
1699 * @}
1703 * @}
1706 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/