2 ******************************************************************************
\r
3 * @file stm32l1xx_aes.c
\r
4 * @author MCD Application Team
\r
6 * @date 05-March-2012
\r
7 * @brief This file provides firmware functions to manage the following
\r
8 * functionalities of the AES peripheral:
\r
10 * + Read/Write operations
\r
11 * + DMA transfers management
\r
12 * + Interrupts and flags management
\r
15 ===============================================================================
\r
16 ##### AES Peripheral features #####
\r
17 ===============================================================================
\r
19 (#) The Advanced Encryption Standard hardware accelerator (AES) can be used
\r
20 to both encipher and decipher data using AES algorithm.
\r
21 (#) The AES supports 4 operation modes:
\r
22 (++) Encryption: It consumes 214 clock cycle when processing one 128-bit block
\r
23 (++) Decryption: It consumes 214 clock cycle when processing one 128-bit block
\r
24 (++) Key derivation for decryption: It consumes 80 clock cycle when processing one 128-bit block
\r
25 (++) Key Derivation and decryption: It consumes 288 clock cycle when processing one 128-bit blobk
\r
26 (#) Moreover 3 chaining modes are supported:
\r
27 (++) Electronic codebook (ECB): Each plain text is encrypted/decrypted separately
\r
28 (++) Cipher block chaining (CBC): Each block is XORed with the previous block
\r
29 (++) Counter mode (CTR): A 128-bit counter is encrypted and then XORed with the
\r
30 plain text to give the cipher text
\r
31 (#) The AES peripheral supports data swapping: 1-bit, 8-bit, 16-bit and 32-bit.
\r
32 (#) The AES peripheral supports write/read error handling with interrupt capability.
\r
33 (#) Automatic data flow control with support of direct memory access (DMA) using
\r
34 2 channels, one for incoming data (DMA2 Channel5), and one for outcoming data
\r
37 ##### How to use this driver #####
\r
38 ===============================================================================
\r
40 (#) AES AHB clock must be enabled to get write access to AES registers
\r
41 using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_AES, ENABLE).
\r
42 (#) Initialize the key using AES_KeyInit().
\r
43 (#) Configure the AES operation mode using AES_Init().
\r
44 (#) If required, enable interrupt source using AES_ITConfig() and
\r
45 enable the AES interrupt vector using NVIC_Init().
\r
46 (#) If required, when using the DMA mode.
\r
47 (##) Configure the DMA using DMA_Init().
\r
48 (##) Enable DMA requests using AES_DMAConfig().
\r
49 (#) Enable the AES peripheral using AES_Cmd().
\r
52 ******************************************************************************
\r
55 * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
\r
57 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
\r
58 * You may not use this file except in compliance with the License.
\r
59 * You may obtain a copy of the License at:
\r
61 * http://www.st.com/software_license_agreement_liberty_v2
\r
63 * Unless required by applicable law or agreed to in writing, software
\r
64 * distributed under the License is distributed on an "AS IS" BASIS,
\r
65 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
66 * See the License for the specific language governing permissions and
\r
67 * limitations under the License.
\r
69 ******************************************************************************
\r
72 /* Includes ------------------------------------------------------------------*/
\r
73 #include "stm32l1xx_aes.h"
\r
74 #include "stm32l1xx_rcc.h"
\r
76 /** @addtogroup STM32L1xx_StdPeriph_Driver
\r
81 * @brief AES driver modules
\r
85 /* Private typedef -----------------------------------------------------------*/
\r
86 /* Private define ------------------------------------------------------------*/
\r
87 #define CR_CLEAR_MASK ((uint32_t)0xFFFFFF81)
\r
89 /* Private macro -------------------------------------------------------------*/
\r
90 /* Private variables ---------------------------------------------------------*/
\r
91 /* Private function prototypes -----------------------------------------------*/
\r
92 /* Private functions ---------------------------------------------------------*/
\r
94 /** @defgroup AES_Private_Functions
\r
98 /** @defgroup AES_Group1 Initialization and configuration
\r
99 * @brief Initialization and configuration.
\r
102 ===============================================================================
\r
103 ##### Initialization and configuration #####
\r
104 ===============================================================================
\r
111 * @brief Deinitializes AES peripheral registers to their default reset values.
\r
115 void AES_DeInit(void)
\r
117 /* Enable AES reset state */
\r
118 RCC_AHBPeriphResetCmd(RCC_AHBPeriph_AES, ENABLE);
\r
119 /* Release AES from reset state */
\r
120 RCC_AHBPeriphResetCmd(RCC_AHBPeriph_AES, DISABLE);
\r
124 * @brief Initializes the AES peripheral according to the specified parameters
\r
125 * in the AES_InitStruct:
\r
126 * - AES_Operation: specifies the operation mode (encryption, decryption...).
\r
127 * - AES_Chaining: specifies the chaining mode (ECB, CBC or CTR).
\r
128 * - AES_DataType: specifies the data swapping type: 32-bit, 16-bit, 8-bit or 1-bit.
\r
129 * @note If AES is already enabled, use AES_Cmd(DISABLE) before setting the new
\r
130 * configuration (When AES is enabled, setting configuration is forbidden).
\r
131 * @param AES_InitStruct: pointer to an AES_InitTypeDef structure that contains
\r
132 * the configuration information for AES peripheral.
\r
135 void AES_Init(AES_InitTypeDef* AES_InitStruct)
\r
137 uint32_t tmpreg = 0;
\r
139 /* Check the parameters */
\r
140 assert_param(IS_AES_MODE(AES_InitStruct->AES_Operation));
\r
141 assert_param(IS_AES_CHAINING(AES_InitStruct->AES_Chaining));
\r
142 assert_param(IS_AES_DATATYPE(AES_InitStruct->AES_DataType));
\r
144 /* Get AES CR register value */
\r
147 /* Clear DATATYPE[1:0], MODE[1:0] and CHMOD[1:0] bits */
\r
148 tmpreg &= (uint32_t)CR_CLEAR_MASK;
\r
150 tmpreg |= (AES_InitStruct->AES_Operation | AES_InitStruct->AES_Chaining | AES_InitStruct->AES_DataType);
\r
152 AES->CR = (uint32_t) tmpreg;
\r
156 * @brief Initializes the AES Keys according to the specified parameters in the AES_KeyInitStruct.
\r
157 * @param AES_KeyInitStruct: pointer to an AES_KeyInitTypeDef structure that
\r
158 * contains the configuration information for the specified AES Keys.
\r
159 * @note This function must be called while the AES is disabled.
\r
160 * @note In encryption, key derivation and key derivation + decryption modes,
\r
161 * AES_KeyInitStruct must contain the encryption key.
\r
162 * In decryption mode, AES_KeyInitStruct must contain the decryption key.
\r
165 void AES_KeyInit(AES_KeyInitTypeDef* AES_KeyInitStruct)
\r
167 AES->KEYR0 = AES_KeyInitStruct->AES_Key0;
\r
168 AES->KEYR1 = AES_KeyInitStruct->AES_Key1;
\r
169 AES->KEYR2 = AES_KeyInitStruct->AES_Key2;
\r
170 AES->KEYR3 = AES_KeyInitStruct->AES_Key3;
\r
174 * @brief Initializes the AES Initialization Vector IV according to
\r
175 * the specified parameters in the AES_IVInitStruct.
\r
176 * @param AES_KeyInitStruct: pointer to an AES_IVInitTypeDef structure that
\r
177 * contains the configuration information for the specified AES IV.
\r
178 * @note When ECB chaining mode is selected, Initialization Vector IV has no
\r
180 * When CTR chaining mode is selected, AES_IV0 contains the CTR value.
\r
181 * AES_IV1, AES_IV2 and AES_IV3 contains nonce value.
\r
184 void AES_IVInit(AES_IVInitTypeDef* AES_IVInitStruct)
\r
186 AES->IVR0 = AES_IVInitStruct->AES_IV0;
\r
187 AES->IVR1 = AES_IVInitStruct->AES_IV1;
\r
188 AES->IVR2 = AES_IVInitStruct->AES_IV2;
\r
189 AES->IVR3 = AES_IVInitStruct->AES_IV3;
\r
193 * @brief Enable or disable the AES peripheral.
\r
194 * @param NewState: new state of the AES peripheral.
\r
195 * This parameter can be: ENABLE or DISABLE.
\r
196 * @note The key must be written while AES is disabled.
\r
199 void AES_Cmd(FunctionalState NewState)
\r
201 /* Check the parameter */
\r
202 assert_param(IS_FUNCTIONAL_STATE(NewState));
\r
204 if (NewState != DISABLE)
\r
206 /* Enable the AES peripheral */
\r
207 AES->CR |= (uint32_t) AES_CR_EN; /**< AES Enable */
\r
211 /* Disable the AES peripheral */
\r
212 AES->CR &= (uint32_t)(~AES_CR_EN); /**< AES Disable */
\r
220 /** @defgroup AES_Group2 Structures initialization functions
\r
221 * @brief Structures initialization.
\r
224 ===============================================================================
\r
225 ##### Structures initialization functions #####
\r
226 ===============================================================================
\r
233 * @brief Fills each AES_InitStruct member with its default value.
\r
234 * @param AES_InitStruct: pointer to an AES_InitTypeDef structure which will
\r
238 void AES_StructInit(AES_InitTypeDef* AES_InitStruct)
\r
240 AES_InitStruct->AES_Operation = AES_Operation_Encryp;
\r
241 AES_InitStruct->AES_Chaining = AES_Chaining_ECB;
\r
242 AES_InitStruct->AES_DataType = AES_DataType_32b;
\r
246 * @brief Fills each AES_KeyInitStruct member with its default value.
\r
247 * @param AES_KeyInitStruct: pointer to an AES_KeyInitStruct structure which
\r
248 * will be initialized.
\r
251 void AES_KeyStructInit(AES_KeyInitTypeDef* AES_KeyInitStruct)
\r
253 AES_KeyInitStruct->AES_Key0 = 0x00000000;
\r
254 AES_KeyInitStruct->AES_Key1 = 0x00000000;
\r
255 AES_KeyInitStruct->AES_Key2 = 0x00000000;
\r
256 AES_KeyInitStruct->AES_Key3 = 0x00000000;
\r
260 * @brief Fills each AES_IVInitStruct member with its default value.
\r
261 * @param AES_IVInitStruct: pointer to an AES_IVInitTypeDef structure which
\r
262 * will be initialized.
\r
265 void AES_IVStructInit(AES_IVInitTypeDef* AES_IVInitStruct)
\r
267 AES_IVInitStruct->AES_IV0 = 0x00000000;
\r
268 AES_IVInitStruct->AES_IV1 = 0x00000000;
\r
269 AES_IVInitStruct->AES_IV2 = 0x00000000;
\r
270 AES_IVInitStruct->AES_IV3 = 0x00000000;
\r
277 /** @defgroup AES_Group3 AES Read and Write
\r
278 * @brief AES Read and Write.
\r
281 ===============================================================================
\r
282 ##### AES Read and Write functions #####
\r
283 ===============================================================================
\r
290 * @brief Write data in DINR register to be processed by AES peripheral.
\r
291 * @note To process 128-bit data (4 * 32-bit), this function must be called
\r
292 * four times to write the 128-bit data in the 32-bit register DINR.
\r
293 * @note When an unexpected write to DOUTR register is detected, WRERR flag is
\r
295 * @param Data: The data to be processed.
\r
298 void AES_WriteSubData(uint32_t Data)
\r
305 * @brief Returns the data in DOUTR register processed by AES peripheral.
\r
306 * @note This function must be called four times to get the 128-bit data.
\r
307 * @note When an unexpected read of DINR register is detected, RDERR flag is
\r
309 * @retval The processed data.
\r
311 uint32_t AES_ReadSubData(void)
\r
318 * @brief Read the Key value.
\r
319 * @param AES_KeyInitStruct: pointer to an AES_KeyInitTypeDef structure which
\r
320 * will contain the key.
\r
321 * @note When the key derivation mode is selected, AES must be disabled
\r
322 * (AES_Cmd(DISABLE)) before reading the decryption key.
\r
323 * Reading the key while the AES is enabled will return unpredictable
\r
327 void AES_ReadKey(AES_KeyInitTypeDef* AES_KeyInitStruct)
\r
329 AES_KeyInitStruct->AES_Key0 = AES->KEYR0;
\r
330 AES_KeyInitStruct->AES_Key1 = AES->KEYR1;
\r
331 AES_KeyInitStruct->AES_Key2 = AES->KEYR2;
\r
332 AES_KeyInitStruct->AES_Key3 = AES->KEYR3;
\r
336 * @brief Read the Initialization Vector IV value.
\r
337 * @param AES_IVInitStruct: pointer to an AES_IVInitTypeDef structure which
\r
338 * will contain the Initialization Vector IV.
\r
339 * @note When the AES is enabled Reading the Initialization Vector IV value
\r
340 * will return 0. The AES must be disabled using AES_Cmd(DISABLE)
\r
341 * to get the right value.
\r
342 * @note When ECB chaining mode is selected, Initialization Vector IV has no
\r
344 * When CTR chaining mode is selected, AES_IV0 contains 32-bit Counter value.
\r
345 * AES_IV1, AES_IV2 and AES_IV3 contains nonce value.
\r
348 void AES_ReadIV(AES_IVInitTypeDef* AES_IVInitStruct)
\r
350 AES_IVInitStruct->AES_IV0 = AES->IVR0;
\r
351 AES_IVInitStruct->AES_IV1 = AES->IVR1;
\r
352 AES_IVInitStruct->AES_IV2 = AES->IVR2;
\r
353 AES_IVInitStruct->AES_IV3 = AES->IVR3;
\r
360 /** @defgroup AES_Group4 DMA transfers management functions
\r
361 * @brief DMA transfers management function.
\r
364 ===============================================================================
\r
365 ##### DMA transfers management functions #####
\r
366 ===============================================================================
\r
373 * @brief Configures the AES DMA interface.
\r
374 * @param AES_DMATransfer: Specifies the AES DMA transfer.
\r
375 * This parameter can be one of the following values:
\r
376 * @arg AES_DMATransfer_In: When selected, DMA manages the data input phase.
\r
377 * @arg AES_DMATransfer_Out: When selected, DMA manages the data output phase.
\r
378 * @arg AES_DMATransfer_InOut: When selected, DMA manages both the data input/output phases.
\r
379 * @param NewState Indicates the new state of the AES DMA interface.
\r
380 * This parameter can be: ENABLE or DISABLE.
\r
381 * @note The DMA has no action in key derivation mode.
\r
384 void AES_DMAConfig(uint32_t AES_DMATransfer, FunctionalState NewState)
\r
386 /* Check the parameter */
\r
387 assert_param(IS_AES_DMA_TRANSFER(AES_DMATransfer));
\r
389 if (NewState != DISABLE)
\r
391 /* Enable the DMA transfer */
\r
392 AES->CR |= (uint32_t) AES_DMATransfer;
\r
396 /* Disable the DMA transfer */
\r
397 AES->CR &= (uint32_t)(~AES_DMATransfer);
\r
405 /** @defgroup AES_Group5 Interrupts and flags management functions
\r
406 * @brief Interrupts and flags management functions.
\r
410 ===============================================================================
\r
411 ##### Interrupts and flags management functions #####
\r
412 ===============================================================================
\r
418 * @brief Enables or disables the specified AES interrupt.
\r
419 * @param AES_IT: Specifies the AES interrupt source to enable/disable.
\r
420 * This parameter can be any combinations of the following values:
\r
421 * @arg AES_IT_CC: Computation Complete Interrupt. If enabled, once CCF
\r
422 * flag is set an interrupt is generated.
\r
423 * @arg AES_IT_ERR: Error Interrupt. If enabled, once a read error
\r
424 * flags (RDERR) or write error flag (WRERR) is set,
\r
425 * an interrupt is generated.
\r
426 * @param NewState: The new state of the AES interrupt source.
\r
427 * This parameter can be: ENABLE or DISABLE.
\r
430 void AES_ITConfig(uint32_t AES_IT, FunctionalState NewState)
\r
432 /* Check the parameters */
\r
433 assert_param(IS_FUNCTIONAL_STATE(NewState));
\r
434 assert_param(IS_AES_IT(AES_IT));
\r
436 if (NewState != DISABLE)
\r
438 AES->CR |= (uint32_t) AES_IT; /**< AES_IT Enable */
\r
442 AES->CR &= (uint32_t)(~AES_IT); /**< AES_IT Disable */
\r
447 * @brief Checks whether the specified AES flag is set or not.
\r
448 * @param AES_FLAG specifies the flag to check.
\r
449 * This parameter can be one of the following values:
\r
450 * @arg AES_FLAG_CCF: Computation Complete Flag is set by hardware when
\r
451 * he computation phase is completed.
\r
452 * @arg AES_FLAG_RDERR: Read Error Flag is set when an unexpected read
\r
453 * operation of DOUTR register is detected.
\r
454 * @arg AES_FLAG_WRERR: Write Error Flag is set when an unexpected write
\r
455 * operation in DINR is detected.
\r
456 * @retval FlagStatus (SET or RESET)
\r
458 FlagStatus AES_GetFlagStatus(uint32_t AES_FLAG)
\r
460 FlagStatus bitstatus = RESET;
\r
462 /* Check parameters */
\r
463 assert_param(IS_AES_FLAG(AES_FLAG));
\r
465 if ((AES->SR & AES_FLAG) != (uint32_t)RESET)
\r
474 /* Return the AES_FLAG status */
\r
479 * @brief Clears the AES flags.
\r
480 * @param AES_FLAG: specifies the flag to clear.
\r
481 * This parameter can be:
\r
482 * @arg AES_FLAG_CCF: Computation Complete Flag is cleared by setting CCFC
\r
483 * bit in CR register.
\r
484 * @arg AES_FLAG_RDERR: Read Error is cleared by setting ERRC bit in
\r
486 * @arg AES_FLAG_WRERR: Write Error is cleared by setting ERRC bit in
\r
490 void AES_ClearFlag(uint32_t AES_FLAG)
\r
492 /* Check the parameters */
\r
493 assert_param(IS_AES_FLAG(AES_FLAG));
\r
495 /* Check if AES_FLAG is AES_FLAG_CCF */
\r
496 if (AES_FLAG == AES_FLAG_CCF)
\r
498 /* Clear CCF flag by setting CCFC bit */
\r
499 AES->CR |= (uint32_t) AES_CR_CCFC;
\r
501 else /* AES_FLAG is AES_FLAG_RDERR or AES_FLAG_WRERR */
\r
503 /* Clear RDERR and WRERR flags by setting ERRC bit */
\r
504 AES->CR |= (uint32_t) AES_CR_ERRC;
\r
509 * @brief Checks whether the specified AES interrupt has occurred or not.
\r
510 * @param AES_IT: Specifies the AES interrupt pending bit to check.
\r
511 * This parameter can be:
\r
512 * @arg AES_IT_CC: Computation Complete Interrupt.
\r
513 * @arg AES_IT_ERR: Error Interrupt.
\r
514 * @retval ITStatus The new state of AES_IT (SET or RESET).
\r
516 ITStatus AES_GetITStatus(uint32_t AES_IT)
\r
518 ITStatus itstatus = RESET;
\r
519 uint32_t cciebitstatus = RESET, ccfbitstatus = RESET;
\r
521 /* Check parameters */
\r
522 assert_param(IS_AES_GET_IT(AES_IT));
\r
524 cciebitstatus = AES->CR & AES_CR_CCIE;
\r
525 ccfbitstatus = AES->SR & AES_SR_CCF;
\r
527 /* Check if AES_IT is AES_IT_CC */
\r
528 if (AES_IT == AES_IT_CC)
\r
530 /* Check the status of the specified AES interrupt */
\r
531 if (((cciebitstatus) != (uint32_t)RESET) && ((ccfbitstatus) != (uint32_t)RESET))
\r
533 /* Interrupt occurred */
\r
538 /* Interrupt didn't occur */
\r
542 else /* AES_IT is AES_IT_ERR */
\r
544 /* Check the status of the specified AES interrupt */
\r
545 if ((AES->CR & AES_CR_ERRIE) != RESET)
\r
547 /* Check if WRERR or RDERR flags are set */
\r
548 if ((AES->SR & (uint32_t)(AES_SR_WRERR | AES_SR_RDERR)) != (uint16_t)RESET)
\r
550 /* Interrupt occurred */
\r
555 /* Interrupt didn't occur */
\r
561 /* Interrupt didn't occur */
\r
562 itstatus = (ITStatus) RESET;
\r
566 /* Return the AES_IT status */
\r
571 * @brief Clears the AES's interrupt pending bits.
\r
572 * @param AES_IT: specifies the interrupt pending bit to clear.
\r
573 * This parameter can be any combinations of the following values:
\r
574 * @arg AES_IT_CC: Computation Complete Interrupt.
\r
575 * @arg AES_IT_ERR: Error Interrupt.
\r
578 void AES_ClearITPendingBit(uint32_t AES_IT)
\r
580 /* Check the parameters */
\r
581 assert_param(IS_AES_IT(AES_IT));
\r
583 /* Clear the interrupt pending bit */
\r
584 AES->CR |= (uint32_t) (AES_IT >> (uint32_t) 0x00000002);
\r
599 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r