2 ******************************************************************************
3 * @file stm32f4xx_cryp_aes.c
4 * @author MCD Application Team
7 * @brief This file provides high level functions to encrypt and decrypt an
8 * input message using AES in ECB/CBC/CTR modes.
9 * It uses the stm32f4xx_cryp.c/.h drivers to access the STM32F4xx CRYP
14 * ===================================================================
15 * How to use this driver
16 * ===================================================================
17 * 1. Enable The CRYP controller clock using
18 * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function.
20 * 2. Encrypt and decrypt using AES in ECB Mode using CRYP_AES_ECB()
23 * 3. Encrypt and decrypt using AES in CBC Mode using CRYP_AES_CBC()
26 * 4. Encrypt and decrypt using AES in CTR Mode using CRYP_AES_CTR()
31 ******************************************************************************
34 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
35 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
36 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
37 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
38 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
39 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
41 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
42 ******************************************************************************
45 /* Includes ------------------------------------------------------------------*/
46 #include "stm32f4xx_cryp.h"
48 /** @addtogroup STM32F4xx_StdPeriph_Driver
53 * @brief CRYP driver modules
57 /* Private typedef -----------------------------------------------------------*/
58 /* Private define ------------------------------------------------------------*/
59 #define AESBUSY_TIMEOUT ((uint32_t) 0x00010000)
61 /* Private macro -------------------------------------------------------------*/
62 /* Private variables ---------------------------------------------------------*/
63 /* Private function prototypes -----------------------------------------------*/
64 /* Private functions ---------------------------------------------------------*/
66 /** @defgroup CRYP_Private_Functions
70 /** @defgroup CRYP_Group6 High Level AES functions
71 * @brief High Level AES functions
74 ===============================================================================
75 High Level AES functions
76 ===============================================================================
84 * @brief Encrypt and decrypt using AES in ECB Mode
85 * @param Mode: encryption or decryption Mode.
86 * This parameter can be one of the following values:
87 * @arg MODE_ENCRYPT: Encryption
88 * @arg MODE_DECRYPT: Decryption
89 * @param Key: Key used for AES algorithm.
90 * @param Keysize: length of the Key, must be a 128, 192 or 256.
91 * @param Input: pointer to the Input buffer.
92 * @param Ilength: length of the Input buffer, must be a multiple of 16.
93 * @param Output: pointer to the returned buffer.
94 * @retval An ErrorStatus enumeration value:
95 * - SUCCESS: Operation done
96 * - ERROR: Operation failed
98 ErrorStatus CRYP_AES_ECB(uint8_t Mode, uint8_t* Key, uint16_t Keysize,
99 uint8_t* Input, uint32_t Ilength, uint8_t* Output)
101 CRYP_InitTypeDef AES_CRYP_InitStructure;
102 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
103 __IO uint32_t counter = 0;
104 uint32_t busystatus = 0;
105 ErrorStatus status = SUCCESS;
106 uint32_t keyaddr = (uint32_t)Key;
107 uint32_t inputaddr = (uint32_t)Input;
108 uint32_t outputaddr = (uint32_t)Output;
111 /* Crypto structures initialisation*/
112 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
117 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
118 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
120 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
122 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
124 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
127 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
128 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
130 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
132 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
134 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
136 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
138 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
141 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
142 AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
144 AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
146 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
148 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
150 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
152 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
154 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
156 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
162 /*------------------ AES Decryption ------------------*/
163 if(Mode == MODE_DECRYPT) /* AES decryption */
165 /* Flush IN/OUT FIFOs */
168 /* Crypto Init for Key preparation for decryption process */
169 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
170 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
171 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
172 CRYP_Init(&AES_CRYP_InitStructure);
174 /* Key Initialisation */
175 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
177 /* Enable Crypto processor */
180 /* wait until the Busy flag is RESET */
183 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
185 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
187 if (busystatus != RESET)
193 /* Crypto Init for decryption process */
194 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
197 /*------------------ AES Encryption ------------------*/
198 else /* AES encryption */
201 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
203 /* Crypto Init for Encryption process */
204 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
207 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
208 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
209 CRYP_Init(&AES_CRYP_InitStructure);
211 /* Flush IN/OUT FIFOs */
214 /* Enable Crypto processor */
217 for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
220 /* Write the Input block in the IN FIFO */
221 CRYP_DataIn(*(uint32_t*)(inputaddr));
223 CRYP_DataIn(*(uint32_t*)(inputaddr));
225 CRYP_DataIn(*(uint32_t*)(inputaddr));
227 CRYP_DataIn(*(uint32_t*)(inputaddr));
230 /* Wait until the complete message has been processed */
234 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
236 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
238 if (busystatus != RESET)
245 /* Read the Output block from the Output FIFO */
246 *(uint32_t*)(outputaddr) = CRYP_DataOut();
248 *(uint32_t*)(outputaddr) = CRYP_DataOut();
250 *(uint32_t*)(outputaddr) = CRYP_DataOut();
252 *(uint32_t*)(outputaddr) = CRYP_DataOut();
264 * @brief Encrypt and decrypt using AES in CBC Mode
265 * @param Mode: encryption or decryption Mode.
266 * This parameter can be one of the following values:
267 * @arg MODE_ENCRYPT: Encryption
268 * @arg MODE_DECRYPT: Decryption
269 * @param InitVectors: Initialisation Vectors used for AES algorithm.
270 * @param Key: Key used for AES algorithm.
271 * @param Keysize: length of the Key, must be a 128, 192 or 256.
272 * @param Input: pointer to the Input buffer.
273 * @param Ilength: length of the Input buffer, must be a multiple of 16.
274 * @param Output: pointer to the returned buffer.
275 * @retval An ErrorStatus enumeration value:
276 * - SUCCESS: Operation done
277 * - ERROR: Operation failed
279 ErrorStatus CRYP_AES_CBC(uint8_t Mode, uint8_t InitVectors[16], uint8_t *Key,
280 uint16_t Keysize, uint8_t *Input, uint32_t Ilength,
283 CRYP_InitTypeDef AES_CRYP_InitStructure;
284 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
285 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
286 __IO uint32_t counter = 0;
287 uint32_t busystatus = 0;
288 ErrorStatus status = SUCCESS;
289 uint32_t keyaddr = (uint32_t)Key;
290 uint32_t inputaddr = (uint32_t)Input;
291 uint32_t outputaddr = (uint32_t)Output;
292 uint32_t ivaddr = (uint32_t)InitVectors;
295 /* Crypto structures initialisation*/
296 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
301 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
302 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
304 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
306 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
308 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
311 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
312 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
314 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
316 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
318 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
320 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
322 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
325 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
326 AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
328 AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
330 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
332 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
334 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
336 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
338 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
340 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
346 /* CRYP Initialization Vectors */
347 AES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
349 AES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
351 AES_CRYP_IVInitStructure.CRYP_IV1Left = __REV(*(uint32_t*)(ivaddr));
353 AES_CRYP_IVInitStructure.CRYP_IV1Right= __REV(*(uint32_t*)(ivaddr));
356 /*------------------ AES Decryption ------------------*/
357 if(Mode == MODE_DECRYPT) /* AES decryption */
359 /* Flush IN/OUT FIFOs */
362 /* Crypto Init for Key preparation for decryption process */
363 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
364 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
365 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
367 CRYP_Init(&AES_CRYP_InitStructure);
369 /* Key Initialisation */
370 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
372 /* Enable Crypto processor */
375 /* wait until the Busy flag is RESET */
378 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
380 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
382 if (busystatus != RESET)
388 /* Crypto Init for decryption process */
389 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
392 /*------------------ AES Encryption ------------------*/
393 else /* AES encryption */
395 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
397 /* Crypto Init for Encryption process */
398 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
400 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
401 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
402 CRYP_Init(&AES_CRYP_InitStructure);
404 /* CRYP Initialization Vectors */
405 CRYP_IVInit(&AES_CRYP_IVInitStructure);
407 /* Flush IN/OUT FIFOs */
410 /* Enable Crypto processor */
414 for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
417 /* Write the Input block in the IN FIFO */
418 CRYP_DataIn(*(uint32_t*)(inputaddr));
420 CRYP_DataIn(*(uint32_t*)(inputaddr));
422 CRYP_DataIn(*(uint32_t*)(inputaddr));
424 CRYP_DataIn(*(uint32_t*)(inputaddr));
426 /* Wait until the complete message has been processed */
430 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
432 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
434 if (busystatus != RESET)
441 /* Read the Output block from the Output FIFO */
442 *(uint32_t*)(outputaddr) = CRYP_DataOut();
444 *(uint32_t*)(outputaddr) = CRYP_DataOut();
446 *(uint32_t*)(outputaddr) = CRYP_DataOut();
448 *(uint32_t*)(outputaddr) = CRYP_DataOut();
460 * @brief Encrypt and decrypt using AES in CTR Mode
461 * @param Mode: encryption or decryption Mode.
462 * This parameter can be one of the following values:
463 * @arg MODE_ENCRYPT: Encryption
464 * @arg MODE_DECRYPT: Decryption
465 * @param InitVectors: Initialisation Vectors used for AES algorithm.
466 * @param Key: Key used for AES algorithm.
467 * @param Keysize: length of the Key, must be a 128, 192 or 256.
468 * @param Input: pointer to the Input buffer.
469 * @param Ilength: length of the Input buffer, must be a multiple of 16.
470 * @param Output: pointer to the returned buffer.
471 * @retval An ErrorStatus enumeration value:
472 * - SUCCESS: Operation done
473 * - ERROR: Operation failed
475 ErrorStatus CRYP_AES_CTR(uint8_t Mode, uint8_t InitVectors[16], uint8_t *Key,
476 uint16_t Keysize, uint8_t *Input, uint32_t Ilength,
479 CRYP_InitTypeDef AES_CRYP_InitStructure;
480 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
481 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
482 __IO uint32_t counter = 0;
483 uint32_t busystatus = 0;
484 ErrorStatus status = SUCCESS;
485 uint32_t keyaddr = (uint32_t)Key;
486 uint32_t inputaddr = (uint32_t)Input;
487 uint32_t outputaddr = (uint32_t)Output;
488 uint32_t ivaddr = (uint32_t)InitVectors;
491 /* Crypto structures initialisation*/
492 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
497 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
498 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
500 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
502 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
504 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
507 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
508 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
510 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
512 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
514 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
516 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
518 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
521 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
522 AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
524 AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
526 AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
528 AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
530 AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
532 AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
534 AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
536 AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
541 /* CRYP Initialization Vectors */
542 AES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
544 AES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
546 AES_CRYP_IVInitStructure.CRYP_IV1Left = __REV(*(uint32_t*)(ivaddr));
548 AES_CRYP_IVInitStructure.CRYP_IV1Right= __REV(*(uint32_t*)(ivaddr));
550 /* Key Initialisation */
551 CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
553 /*------------------ AES Decryption ------------------*/
554 if(Mode == MODE_DECRYPT) /* AES decryption */
556 /* Crypto Init for decryption process */
557 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
559 /*------------------ AES Encryption ------------------*/
560 else /* AES encryption */
562 /* Crypto Init for Encryption process */
563 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
565 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
566 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
567 CRYP_Init(&AES_CRYP_InitStructure);
569 /* CRYP Initialization Vectors */
570 CRYP_IVInit(&AES_CRYP_IVInitStructure);
572 /* Flush IN/OUT FIFOs */
575 /* Enable Crypto processor */
578 for(i=0; ((i<Ilength) && (status != ERROR)); i+=16)
581 /* Write the Input block in the IN FIFO */
582 CRYP_DataIn(*(uint32_t*)(inputaddr));
584 CRYP_DataIn(*(uint32_t*)(inputaddr));
586 CRYP_DataIn(*(uint32_t*)(inputaddr));
588 CRYP_DataIn(*(uint32_t*)(inputaddr));
590 /* Wait until the complete message has been processed */
594 busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
596 }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
598 if (busystatus != RESET)
605 /* Read the Output block from the Output FIFO */
606 *(uint32_t*)(outputaddr) = CRYP_DataOut();
608 *(uint32_t*)(outputaddr) = CRYP_DataOut();
610 *(uint32_t*)(outputaddr) = CRYP_DataOut();
612 *(uint32_t*)(outputaddr) = CRYP_DataOut();
637 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/