2 ******************************************************************************
3 * @file stm32f4xx_hal_cryp_ex.c
4 * @author MCD Application Team
7 * @brief Extended CRYP HAL module driver
8 * This file provides firmware functions to manage the following
9 * functionalities of CRYP extension peripheral:
10 * + Extended AES processing functions
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
17 The CRYP Extension HAL driver can be used as follows:
18 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
19 (##) Enable the CRYP interface clock using __CRYP_CLK_ENABLE()
20 (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT())
21 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
22 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
23 (+) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
24 (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA())
25 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
26 (+++) Configure and enable two DMA streams one for managing data transfer from
27 memory to peripheral (input stream) and another stream for managing data
28 transfer from peripheral to memory (output stream)
29 (+++) Associate the initilalized DMA handle to the CRYP DMA handle
31 (+++) Configure the priority and enable the NVIC for the transfer complete
32 interrupt on the two DMA Streams. The output stream should have higher
33 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
34 (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly:
35 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit
36 (##) The key size: 128, 192 and 256. This parameter is relevant only for AES
37 (##) The encryption/decryption key. Its size depends on the algorithm
38 used for encryption/decryption
39 (##) The initialization vector (counter). It is not used ECB mode.
40 (#)Three processing (encryption/decryption) functions are available:
41 (##) Polling mode: encryption and decryption APIs are blocking functions
42 i.e. they process the data and wait till the processing is finished
43 e.g. HAL_CRYPEx_AESGCM_Encrypt()
44 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
45 i.e. they process the data under interrupt
46 e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()
47 (##) DMA mode: encryption and decryption APIs are not blocking functions
48 i.e. the data transfer is ensured by DMA
49 e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA()
50 (#)When the processing function is called at first time after HAL_CRYP_Init()
51 the CRYP peripheral is initialized and processes the buffer in input.
52 At second call, the processing function performs an append of the already
54 When a new data block is to be processed, call HAL_CRYP_Init() then the
56 (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms
57 which provide authentication messages.
58 HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those
59 authentication messages.
60 Call those functions after the processing ones (polling, interrupt or DMA).
61 e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data
62 then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message
63 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
66 ******************************************************************************
69 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
71 * Redistribution and use in source and binary forms, with or without modification,
72 * are permitted provided that the following conditions are met:
73 * 1. Redistributions of source code must retain the above copyright notice,
74 * this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright notice,
76 * this list of conditions and the following disclaimer in the documentation
77 * and/or other materials provided with the distribution.
78 * 3. Neither the name of STMicroelectronics nor the names of its contributors
79 * may be used to endorse or promote products derived from this software
80 * without specific prior written permission.
82 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
83 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
85 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
86 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
88 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
89 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
90 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
91 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93 ******************************************************************************
96 /* Includes ------------------------------------------------------------------*/
97 #include "stm32f4xx_hal.h"
99 /** @addtogroup STM32F4xx_HAL_Driver
104 * @brief CRYP Extension HAL module driver.
108 #ifdef HAL_CRYP_MODULE_ENABLED
110 #if defined(STM32F437xx) || defined(STM32F439xx)
112 /* Private typedef -----------------------------------------------------------*/
113 /* Private define ------------------------------------------------------------*/
114 #define CRYPEx_TIMEOUT_VALUE 1
115 /* Private macro -------------------------------------------------------------*/
116 /* Private variables ---------------------------------------------------------*/
117 /* Private function prototypes -----------------------------------------------*/
118 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector, uint32_t IVSize);
119 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize);
120 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout);
121 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout);
122 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma);
123 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma);
124 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma);
125 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
127 /* Private functions ---------------------------------------------------------*/
129 /** @defgroup CRYPEx_Private_Functions
133 /** @defgroup CRYPEx_Group1 Extended AES processing functions
134 * @brief Extended processing functions.
137 ==============================================================================
138 ##### Extended AES processing functions #####
139 ==============================================================================
140 [..] This section provides functions allowing to:
141 (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes
142 (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes
143 (+) Finish the processing. This function is available only for GCM and CCM
144 [..] Three processing methods are available:
155 * @brief Initializes the CRYP peripheral in AES CCM encryption mode then
156 * encrypt pPlainData. The cypher data are available in pCypherData.
157 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
158 * the configuration information for CRYP module
159 * @param pPlainData: Pointer to the plaintext buffer
160 * @param Size: Length of the plaintext buffer, must be a multiple of 16
161 * @param pCypherData: Pointer to the cyphertext buffer
162 * @param Timeout: Timeout duration
165 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
167 uint32_t tickstart = 0;
168 uint32_t headersize = hcryp->Init.HeaderSize;
169 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
170 uint32_t loopcounter = 0;
171 uint32_t bufferidx = 0;
172 uint8_t blockb0[16] = {0};/* Block B0 */
173 uint8_t ctr[16] = {0}; /* Counter */
174 uint32_t b0addr = (uint32_t)blockb0;
179 /* Change the CRYP peripheral state */
180 hcryp->State = HAL_CRYP_STATE_BUSY;
182 /* Check if initialization phase has already been performed */
183 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
185 /************************ Formatting the header block *********************/
188 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
189 if(headersize < 65280)
191 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
192 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
197 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
198 hcryp->Init.pScratch[bufferidx++] = 0xFF;
199 hcryp->Init.pScratch[bufferidx++] = 0xFE;
200 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
201 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
202 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
203 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
206 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
207 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
209 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
211 /* Check if the header size is modulo 16 */
212 if ((headersize % 16) != 0)
214 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
215 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
217 hcryp->Init.pScratch[loopcounter] = 0;
219 /* Set the header size to modulo 16 */
220 headersize = ((headersize/16) + 1) * 16;
222 /* Set the pointer headeraddr to hcryp->Init.pScratch */
223 headeraddr = (uint32_t)hcryp->Init.pScratch;
225 /*********************** Formatting the block B0 **************************/
231 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
232 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
233 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
235 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
237 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
239 for ( ; loopcounter < 13; loopcounter++)
241 blockb0[loopcounter+1] = 0;
244 blockb0[14] = (Size >> 8);
245 blockb0[15] = (Size & 0xFF);
247 /************************* Formatting the initial counter *****************/
249 Bits 7 and 6 are reserved and shall be set to 0
250 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
252 Bits 0, 1, and 2 contain the same encoding of q as in B0
254 ctr[0] = blockb0[0] & 0x07;
255 /* byte 1 to NonceSize is the IV (Nonce) */
256 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
258 ctr[loopcounter] = blockb0[loopcounter];
260 /* Set the LSB to 1 */
264 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
266 /* Set the CRYP peripheral in AES CCM mode */
267 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
269 /* Set the Initialization Vector */
270 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, CRYP_KEYSIZE_128B);
272 /* Select init phase */
273 __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
275 b0addr = (uint32_t)blockb0;
276 /* Write the blockb0 block in the IN FIFO */
277 CRYP->DR = *(uint32_t*)(b0addr);
279 CRYP->DR = *(uint32_t*)(b0addr);
281 CRYP->DR = *(uint32_t*)(b0addr);
283 CRYP->DR = *(uint32_t*)(b0addr);
285 /* Enable the CRYP peripheral */
289 tickstart = HAL_GetTick();
291 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
293 /* Check for the Timeout */
294 if(Timeout != HAL_MAX_DELAY)
296 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
299 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
301 /* Process Unlocked */
308 /***************************** Header phase *******************************/
311 /* Select header phase */
312 __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
314 /* Enable the CRYP peripheral */
317 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
320 tickstart = HAL_GetTick();
322 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
325 /* Check for the Timeout */
326 if(Timeout != HAL_MAX_DELAY)
328 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
331 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
333 /* Process Unlocked */
341 /* Write the header block in the IN FIFO */
342 CRYP->DR = *(uint32_t*)(headeraddr);
344 CRYP->DR = *(uint32_t*)(headeraddr);
346 CRYP->DR = *(uint32_t*)(headeraddr);
348 CRYP->DR = *(uint32_t*)(headeraddr);
353 tickstart = HAL_GetTick();
355 while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
357 /* Check for the Timeout */
358 if(Timeout != HAL_MAX_DELAY)
360 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
363 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
365 /* Process Unlocked */
373 /* Save formatted counter into the scratch buffer pScratch */
374 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
376 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
379 hcryp->Init.pScratch[15] &= 0xfe;
381 /* Select payload phase once the header phase is performed */
382 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
385 __HAL_CRYP_FIFO_FLUSH();
387 /* Enable the CRYP peripheral */
391 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
394 /* Write Plain Data and Get Cypher Data */
395 if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK)
400 /* Change the CRYP peripheral state */
401 hcryp->State = HAL_CRYP_STATE_READY;
403 /* Process Unlocked */
406 /* Return function status */
411 * @brief Initializes the CRYP peripheral in AES GCM encryption mode then
412 * encrypt pPlainData. The cypher data are available in pCypherData.
413 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
414 * the configuration information for CRYP module
415 * @param pPlainData: Pointer to the plaintext buffer
416 * @param Size: Length of the plaintext buffer, must be a multiple of 16
417 * @param pCypherData: Pointer to the cyphertext buffer
418 * @param Timeout: Timeout duration
421 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
423 uint32_t tickstart = 0;
428 /* Change the CRYP peripheral state */
429 hcryp->State = HAL_CRYP_STATE_BUSY;
431 /* Check if initialization phase has already been performed */
432 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
435 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
437 /* Set the CRYP peripheral in AES GCM mode */
438 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
440 /* Set the Initialization Vector */
441 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
444 __HAL_CRYP_FIFO_FLUSH();
446 /* Enable the CRYP peripheral */
450 tickstart = HAL_GetTick();
452 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
454 /* Check for the Timeout */
455 if(Timeout != HAL_MAX_DELAY)
457 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
460 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
462 /* Process Unlocked */
470 /* Set the header phase */
471 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
476 /* Disable the CRYP peripheral */
477 __HAL_CRYP_DISABLE();
479 /* Select payload phase once the header phase is performed */
480 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
483 __HAL_CRYP_FIFO_FLUSH();
485 /* Enable the CRYP peripheral */
489 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
492 /* Write Plain Data and Get Cypher Data */
493 if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK)
498 /* Change the CRYP peripheral state */
499 hcryp->State = HAL_CRYP_STATE_READY;
501 /* Process Unlocked */
504 /* Return function status */
509 * @brief Initializes the CRYP peripheral in AES GCM decryption mode then
510 * decrypted pCypherData. The cypher data are available in pPlainData.
511 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
512 * the configuration information for CRYP module
513 * @param pCypherData: Pointer to the cyphertext buffer
514 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
515 * @param pPlainData: Pointer to the plaintext buffer
516 * @param Timeout: Timeout duration
519 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
521 uint32_t tickstart = 0;
526 /* Change the CRYP peripheral state */
527 hcryp->State = HAL_CRYP_STATE_BUSY;
529 /* Check if initialization phase has already been performed */
530 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
533 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
535 /* Set the CRYP peripheral in AES GCM decryption mode */
536 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
538 /* Set the Initialization Vector */
539 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
542 __HAL_CRYP_FIFO_FLUSH();
544 /* Enable the CRYP peripheral */
548 tickstart = HAL_GetTick();
550 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
552 /* Check for the Timeout */
553 if(Timeout != HAL_MAX_DELAY)
555 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
558 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
560 /* Process Unlocked */
568 /* Set the header phase */
569 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
573 /* Disable the CRYP peripheral */
574 __HAL_CRYP_DISABLE();
576 /* Select payload phase once the header phase is performed */
577 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
579 /* Enable the CRYP peripheral */
583 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
586 /* Write Plain Data and Get Cypher Data */
587 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
592 /* Change the CRYP peripheral state */
593 hcryp->State = HAL_CRYP_STATE_READY;
595 /* Process Unlocked */
598 /* Return function status */
603 * @brief Computes the authentication TAG.
604 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
605 * the configuration information for CRYP module
606 * @param Size: Total length of the plain/cyphertext buffer
607 * @param AuthTag: Pointer to the authentication buffer
608 * @param Timeout: Timeout duration
611 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint16_t Size, uint8_t *AuthTag, uint32_t Timeout)
613 uint32_t tickstart = 0;
614 uint32_t headerlength = hcryp->Init.HeaderSize * 8; /* Header length in bits */
615 uint32_t inputlength = Size * 8; /* input length in bits */
616 uint32_t tagaddr = (uint32_t)AuthTag;
621 /* Change the CRYP peripheral state */
622 hcryp->State = HAL_CRYP_STATE_BUSY;
624 /* Check if initialization phase has already been performed */
625 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
627 /* Change the CRYP phase */
628 hcryp->Phase = HAL_CRYP_PHASE_FINAL;
630 /* Disable CRYP to start the final phase */
631 __HAL_CRYP_DISABLE();
633 /* Select final phase */
634 __HAL_CRYP_SET_PHASE(CRYP_PHASE_FINAL);
636 /* Enable the CRYP peripheral */
639 /* Write the number of bits in header (64 bits) followed by the number of bits
641 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
644 CRYP->DR = __RBIT(headerlength);
646 CRYP->DR = __RBIT(inputlength);
648 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
651 CRYP->DR = __REV(headerlength);
653 CRYP->DR = __REV(inputlength);
655 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
658 CRYP->DR = __REV16(headerlength);
660 CRYP->DR = __REV16(inputlength);
662 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
665 CRYP->DR = (uint32_t)(headerlength);
667 CRYP->DR = (uint32_t)(inputlength);
670 tickstart = HAL_GetTick();
672 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_OFNE))
674 /* Check for the Timeout */
675 if(Timeout != HAL_MAX_DELAY)
677 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
680 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
682 /* Process Unlocked */
690 /* Read the Auth TAG in the IN FIFO */
691 *(uint32_t*)(tagaddr) = CRYP->DOUT;
693 *(uint32_t*)(tagaddr) = CRYP->DOUT;
695 *(uint32_t*)(tagaddr) = CRYP->DOUT;
697 *(uint32_t*)(tagaddr) = CRYP->DOUT;
700 /* Change the CRYP peripheral state */
701 hcryp->State = HAL_CRYP_STATE_READY;
703 /* Process Unlocked */
706 /* Return function status */
711 * @brief Computes the authentication TAG for AES CCM mode.
712 * @note This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt()
713 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
714 * the configuration information for CRYP module
715 * @param AuthTag: Pointer to the authentication buffer
716 * @param Timeout: Timeout duration
719 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout)
721 uint32_t tickstart = 0;
722 uint32_t tagaddr = (uint32_t)AuthTag;
723 uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch;
724 uint32_t temptag[4] = {0}; /* Temporary TAG (MAC) */
725 uint32_t loopcounter;
730 /* Change the CRYP peripheral state */
731 hcryp->State = HAL_CRYP_STATE_BUSY;
733 /* Check if initialization phase has already been performed */
734 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
736 /* Change the CRYP phase */
737 hcryp->Phase = HAL_CRYP_PHASE_FINAL;
739 /* Disable CRYP to start the final phase */
740 __HAL_CRYP_DISABLE();
742 /* Select final phase */
743 __HAL_CRYP_SET_PHASE(CRYP_PHASE_FINAL);
745 /* Enable the CRYP peripheral */
748 /* Write the counter block in the IN FIFO */
749 CRYP->DR = *(uint32_t*)ctraddr;
751 CRYP->DR = *(uint32_t*)ctraddr;
753 CRYP->DR = *(uint32_t*)ctraddr;
755 CRYP->DR = *(uint32_t*)ctraddr;
758 tickstart = HAL_GetTick();
760 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_OFNE))
762 /* Check for the Timeout */
763 if(Timeout != HAL_MAX_DELAY)
765 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
768 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
770 /* Process Unlocked */
778 /* Read the Auth TAG in the IN FIFO */
779 temptag[0] = CRYP->DOUT;
780 temptag[1] = CRYP->DOUT;
781 temptag[2] = CRYP->DOUT;
782 temptag[3] = CRYP->DOUT;
785 /* Copy temporary authentication TAG in user TAG buffer */
786 for(loopcounter = 0; loopcounter < hcryp->Init.TagSize ; loopcounter++)
788 /* Set the authentication TAG buffer */
789 *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
792 /* Change the CRYP peripheral state */
793 hcryp->State = HAL_CRYP_STATE_READY;
795 /* Process Unlocked */
798 /* Return function status */
803 * @brief Initializes the CRYP peripheral in AES CCM decryption mode then
804 * decrypted pCypherData. The cypher data are available in pPlainData.
805 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
806 * the configuration information for CRYP module
807 * @param pPlainData: Pointer to the plaintext buffer
808 * @param Size: Length of the plaintext buffer, must be a multiple of 16
809 * @param pCypherData: Pointer to the cyphertext buffer
810 * @param Timeout: Timeout duration
813 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
815 uint32_t tickstart = 0;
816 uint32_t headersize = hcryp->Init.HeaderSize;
817 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
818 uint32_t loopcounter = 0;
819 uint32_t bufferidx = 0;
820 uint8_t blockb0[16] = {0};/* Block B0 */
821 uint8_t ctr[16] = {0}; /* Counter */
822 uint32_t b0addr = (uint32_t)blockb0;
827 /* Change the CRYP peripheral state */
828 hcryp->State = HAL_CRYP_STATE_BUSY;
830 /* Check if initialization phase has already been performed */
831 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
833 /************************ Formatting the header block *********************/
836 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
837 if(headersize < 65280)
839 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
840 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
845 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
846 hcryp->Init.pScratch[bufferidx++] = 0xFF;
847 hcryp->Init.pScratch[bufferidx++] = 0xFE;
848 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
849 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
850 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
851 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
854 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
855 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
857 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
859 /* Check if the header size is modulo 16 */
860 if ((headersize % 16) != 0)
862 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
863 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
865 hcryp->Init.pScratch[loopcounter] = 0;
867 /* Set the header size to modulo 16 */
868 headersize = ((headersize/16) + 1) * 16;
870 /* Set the pointer headeraddr to hcryp->Init.pScratch */
871 headeraddr = (uint32_t)hcryp->Init.pScratch;
873 /*********************** Formatting the block B0 **************************/
879 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
880 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
881 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
883 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
885 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
887 for ( ; loopcounter < 13; loopcounter++)
889 blockb0[loopcounter+1] = 0;
892 blockb0[14] = (Size >> 8);
893 blockb0[15] = (Size & 0xFF);
895 /************************* Formatting the initial counter *****************/
897 Bits 7 and 6 are reserved and shall be set to 0
898 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
899 blocks are distinct from B0
900 Bits 0, 1, and 2 contain the same encoding of q as in B0
902 ctr[0] = blockb0[0] & 0x07;
903 /* byte 1 to NonceSize is the IV (Nonce) */
904 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
906 ctr[loopcounter] = blockb0[loopcounter];
908 /* Set the LSB to 1 */
912 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
914 /* Set the CRYP peripheral in AES CCM mode */
915 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
917 /* Set the Initialization Vector */
918 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, CRYP_KEYSIZE_128B);
920 /* Select init phase */
921 __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
923 b0addr = (uint32_t)blockb0;
924 /* Write the blockb0 block in the IN FIFO */
925 CRYP->DR = *(uint32_t*)(b0addr);
927 CRYP->DR = *(uint32_t*)(b0addr);
929 CRYP->DR = *(uint32_t*)(b0addr);
931 CRYP->DR = *(uint32_t*)(b0addr);
933 /* Enable the CRYP peripheral */
937 tickstart = HAL_GetTick();
939 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
941 /* Check for the Timeout */
942 if(Timeout != HAL_MAX_DELAY)
944 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
947 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
949 /* Process Unlocked */
956 /***************************** Header phase *******************************/
959 /* Select header phase */
960 __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
962 /* Enable Crypto processor */
965 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
968 tickstart = HAL_GetTick();
970 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
972 /* Check for the Timeout */
973 if(Timeout != HAL_MAX_DELAY)
975 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
978 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
980 /* Process Unlocked */
987 /* Write the header block in the IN FIFO */
988 CRYP->DR = *(uint32_t*)(headeraddr);
990 CRYP->DR = *(uint32_t*)(headeraddr);
992 CRYP->DR = *(uint32_t*)(headeraddr);
994 CRYP->DR = *(uint32_t*)(headeraddr);
999 tickstart = HAL_GetTick();
1001 while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1003 /* Check for the Timeout */
1004 if(Timeout != HAL_MAX_DELAY)
1006 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1009 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1011 /* Process Unlocked */
1012 __HAL_UNLOCK(hcryp);
1019 /* Save formatted counter into the scratch buffer pScratch */
1020 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
1022 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1025 hcryp->Init.pScratch[15] &= 0xfe;
1026 /* Select payload phase once the header phase is performed */
1027 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1030 __HAL_CRYP_FIFO_FLUSH();
1032 /* Enable the CRYP peripheral */
1033 __HAL_CRYP_ENABLE();
1036 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1039 /* Write Plain Data and Get Cypher Data */
1040 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
1045 /* Change the CRYP peripheral state */
1046 hcryp->State = HAL_CRYP_STATE_READY;
1048 /* Process Unlocked */
1049 __HAL_UNLOCK(hcryp);
1051 /* Return function status */
1056 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using IT.
1057 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1058 * the configuration information for CRYP module
1059 * @param pPlainData: Pointer to the plaintext buffer
1060 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1061 * @param pCypherData: Pointer to the cyphertext buffer
1062 * @retval HAL status
1064 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1066 uint32_t tickstart = 0;
1068 uint32_t outputaddr;
1070 if(hcryp->State == HAL_CRYP_STATE_READY)
1072 /* Process Locked */
1075 /* Get the buffer addresses and sizes */
1076 hcryp->CrypInCount = Size;
1077 hcryp->pCrypInBuffPtr = pPlainData;
1078 hcryp->pCrypOutBuffPtr = pCypherData;
1079 hcryp->CrypOutCount = Size;
1081 /* Change the CRYP peripheral state */
1082 hcryp->State = HAL_CRYP_STATE_BUSY;
1084 /* Check if initialization phase has already been performed */
1085 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1088 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1090 /* Set the CRYP peripheral in AES GCM mode */
1091 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
1093 /* Set the Initialization Vector */
1094 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
1097 __HAL_CRYP_FIFO_FLUSH();
1099 /* Enable CRYP to start the init phase */
1100 __HAL_CRYP_ENABLE();
1103 tickstart = HAL_GetTick();
1105 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1107 /* Check for the Timeout */
1109 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1112 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1114 /* Process Unlocked */
1115 __HAL_UNLOCK(hcryp);
1122 /* Set the header phase */
1123 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
1127 /* Disable the CRYP peripheral */
1128 __HAL_CRYP_DISABLE();
1130 /* Select payload phase once the header phase is performed */
1131 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1134 __HAL_CRYP_FIFO_FLUSH();
1137 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1142 /* Enable Interrupts */
1143 __HAL_CRYP_ENABLE_IT(CRYP_IT_INI | CRYP_IT_OUTI);
1144 /* Enable the CRYP peripheral */
1145 __HAL_CRYP_ENABLE();
1149 /* Process Locked */
1150 __HAL_UNLOCK(hcryp);
1151 /* Change the CRYP state and phase */
1152 hcryp->State = HAL_CRYP_STATE_READY;
1154 /* Return function status */
1157 else if (__HAL_CRYP_GET_IT(CRYP_IT_INI))
1159 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1160 /* Write the Input block in the IN FIFO */
1161 CRYP->DR = *(uint32_t*)(inputaddr);
1163 CRYP->DR = *(uint32_t*)(inputaddr);
1165 CRYP->DR = *(uint32_t*)(inputaddr);
1167 CRYP->DR = *(uint32_t*)(inputaddr);
1168 hcryp->pCrypInBuffPtr += 16;
1169 hcryp->CrypInCount -= 16;
1170 if(hcryp->CrypInCount == 0)
1172 __HAL_CRYP_DISABLE_IT(CRYP_IT_INI);
1173 /* Call the Input data transfer complete callback */
1174 HAL_CRYP_InCpltCallback(hcryp);
1177 else if (__HAL_CRYP_GET_IT(CRYP_IT_OUTI))
1179 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1180 /* Read the Output block from the Output FIFO */
1181 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1183 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1185 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1187 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1188 hcryp->pCrypOutBuffPtr += 16;
1189 hcryp->CrypOutCount -= 16;
1190 if(hcryp->CrypOutCount == 0)
1192 __HAL_CRYP_DISABLE_IT(CRYP_IT_OUTI);
1193 /* Process Unlocked */
1194 __HAL_UNLOCK(hcryp);
1195 /* Change the CRYP peripheral state */
1196 hcryp->State = HAL_CRYP_STATE_READY;
1197 /* Call Input transfer complete callback */
1198 HAL_CRYP_OutCpltCallback(hcryp);
1202 /* Return function status */
1207 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
1208 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1209 * the configuration information for CRYP module
1210 * @param pPlainData: Pointer to the plaintext buffer
1211 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1212 * @param pCypherData: Pointer to the cyphertext buffer
1213 * @retval HAL status
1215 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1217 uint32_t tickstart = 0;
1219 uint32_t outputaddr;
1221 uint32_t headersize = hcryp->Init.HeaderSize;
1222 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
1223 uint32_t loopcounter = 0;
1224 uint32_t bufferidx = 0;
1225 uint8_t blockb0[16] = {0};/* Block B0 */
1226 uint8_t ctr[16] = {0}; /* Counter */
1227 uint32_t b0addr = (uint32_t)blockb0;
1229 if(hcryp->State == HAL_CRYP_STATE_READY)
1231 /* Process Locked */
1234 hcryp->CrypInCount = Size;
1235 hcryp->pCrypInBuffPtr = pPlainData;
1236 hcryp->pCrypOutBuffPtr = pCypherData;
1237 hcryp->CrypOutCount = Size;
1239 /* Change the CRYP peripheral state */
1240 hcryp->State = HAL_CRYP_STATE_BUSY;
1242 /* Check if initialization phase has already been performed */
1243 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1245 /************************ Formatting the header block *******************/
1248 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1249 if(headersize < 65280)
1251 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1252 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1257 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1258 hcryp->Init.pScratch[bufferidx++] = 0xFF;
1259 hcryp->Init.pScratch[bufferidx++] = 0xFE;
1260 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
1261 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
1262 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
1263 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
1266 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1267 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1269 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
1271 /* Check if the header size is modulo 16 */
1272 if ((headersize % 16) != 0)
1274 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1275 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1277 hcryp->Init.pScratch[loopcounter] = 0;
1279 /* Set the header size to modulo 16 */
1280 headersize = ((headersize/16) + 1) * 16;
1282 /* Set the pointer headeraddr to hcryp->Init.pScratch */
1283 headeraddr = (uint32_t)hcryp->Init.pScratch;
1285 /*********************** Formatting the block B0 ************************/
1291 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
1292 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
1293 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
1295 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
1297 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
1299 for ( ; loopcounter < 13; loopcounter++)
1301 blockb0[loopcounter+1] = 0;
1304 blockb0[14] = (Size >> 8);
1305 blockb0[15] = (Size & 0xFF);
1307 /************************* Formatting the initial counter ***************/
1309 Bits 7 and 6 are reserved and shall be set to 0
1310 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
1311 blocks are distinct from B0
1312 Bits 0, 1, and 2 contain the same encoding of q as in B0
1314 ctr[0] = blockb0[0] & 0x07;
1315 /* byte 1 to NonceSize is the IV (Nonce) */
1316 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
1318 ctr[loopcounter] = blockb0[loopcounter];
1320 /* Set the LSB to 1 */
1324 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1326 /* Set the CRYP peripheral in AES CCM mode */
1327 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
1329 /* Set the Initialization Vector */
1330 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, hcryp->Init.KeySize);
1332 /* Select init phase */
1333 __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
1335 b0addr = (uint32_t)blockb0;
1336 /* Write the blockb0 block in the IN FIFO */
1337 CRYP->DR = *(uint32_t*)(b0addr);
1339 CRYP->DR = *(uint32_t*)(b0addr);
1341 CRYP->DR = *(uint32_t*)(b0addr);
1343 CRYP->DR = *(uint32_t*)(b0addr);
1345 /* Enable the CRYP peripheral */
1346 __HAL_CRYP_ENABLE();
1349 tickstart = HAL_GetTick();
1351 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1353 /* Check for the Timeout */
1354 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1357 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1359 /* Process Unlocked */
1360 __HAL_UNLOCK(hcryp);
1365 /***************************** Header phase *****************************/
1368 /* Select header phase */
1369 __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
1371 /* Enable Crypto processor */
1372 __HAL_CRYP_ENABLE();
1374 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1377 tickstart = HAL_GetTick();
1379 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
1381 /* Check for the Timeout */
1382 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1385 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1387 /* Process Unlocked */
1388 __HAL_UNLOCK(hcryp);
1393 /* Write the header block in the IN FIFO */
1394 CRYP->DR = *(uint32_t*)(headeraddr);
1396 CRYP->DR = *(uint32_t*)(headeraddr);
1398 CRYP->DR = *(uint32_t*)(headeraddr);
1400 CRYP->DR = *(uint32_t*)(headeraddr);
1405 tickstart = HAL_GetTick();
1407 while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1409 /* Check for the Timeout */
1410 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1413 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1415 /* Process Unlocked */
1416 __HAL_UNLOCK(hcryp);
1422 /* Save formatted counter into the scratch buffer pScratch */
1423 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
1425 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1428 hcryp->Init.pScratch[15] &= 0xfe;
1430 /* Select payload phase once the header phase is performed */
1431 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1434 __HAL_CRYP_FIFO_FLUSH();
1437 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1442 /* Enable Interrupts */
1443 __HAL_CRYP_ENABLE_IT(CRYP_IT_INI | CRYP_IT_OUTI);
1444 /* Enable the CRYP peripheral */
1445 __HAL_CRYP_ENABLE();
1449 /* Change the CRYP state and phase */
1450 hcryp->State = HAL_CRYP_STATE_READY;
1453 /* Return function status */
1456 else if (__HAL_CRYP_GET_IT(CRYP_IT_INI))
1458 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1459 /* Write the Input block in the IN FIFO */
1460 CRYP->DR = *(uint32_t*)(inputaddr);
1462 CRYP->DR = *(uint32_t*)(inputaddr);
1464 CRYP->DR = *(uint32_t*)(inputaddr);
1466 CRYP->DR = *(uint32_t*)(inputaddr);
1467 hcryp->pCrypInBuffPtr += 16;
1468 hcryp->CrypInCount -= 16;
1469 if(hcryp->CrypInCount == 0)
1471 __HAL_CRYP_DISABLE_IT(CRYP_IT_INI);
1472 /* Call Input transfer complete callback */
1473 HAL_CRYP_InCpltCallback(hcryp);
1476 else if (__HAL_CRYP_GET_IT(CRYP_IT_OUTI))
1478 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1479 /* Read the Output block from the Output FIFO */
1480 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1482 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1484 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1486 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1487 hcryp->pCrypOutBuffPtr += 16;
1488 hcryp->CrypOutCount -= 16;
1489 if(hcryp->CrypOutCount == 0)
1491 __HAL_CRYP_DISABLE_IT(CRYP_IT_OUTI);
1492 /* Process Unlocked */
1493 __HAL_UNLOCK(hcryp);
1494 /* Change the CRYP peripheral state */
1495 hcryp->State = HAL_CRYP_STATE_READY;
1496 /* Call Input transfer complete callback */
1497 HAL_CRYP_OutCpltCallback(hcryp);
1501 /* Return function status */
1506 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using IT.
1507 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1508 * the configuration information for CRYP module
1509 * @param pCypherData: Pointer to the cyphertext buffer
1510 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
1511 * @param pPlainData: Pointer to the plaintext buffer
1512 * @retval HAL status
1514 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
1516 uint32_t tickstart = 0;
1518 uint32_t outputaddr;
1520 if(hcryp->State == HAL_CRYP_STATE_READY)
1522 /* Process Locked */
1525 /* Get the buffer addresses and sizes */
1526 hcryp->CrypInCount = Size;
1527 hcryp->pCrypInBuffPtr = pCypherData;
1528 hcryp->pCrypOutBuffPtr = pPlainData;
1529 hcryp->CrypOutCount = Size;
1531 /* Change the CRYP peripheral state */
1532 hcryp->State = HAL_CRYP_STATE_BUSY;
1534 /* Check if initialization phase has already been performed */
1535 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1538 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1540 /* Set the CRYP peripheral in AES GCM decryption mode */
1541 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
1543 /* Set the Initialization Vector */
1544 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
1547 __HAL_CRYP_FIFO_FLUSH();
1549 /* Enable CRYP to start the init phase */
1550 __HAL_CRYP_ENABLE();
1553 tickstart = HAL_GetTick();
1555 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1557 /* Check for the Timeout */
1558 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1561 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1563 /* Process Unlocked */
1564 __HAL_UNLOCK(hcryp);
1570 /* Set the header phase */
1571 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
1575 /* Disable the CRYP peripheral */
1576 __HAL_CRYP_DISABLE();
1578 /* Select payload phase once the header phase is performed */
1579 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1582 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1587 /* Enable Interrupts */
1588 __HAL_CRYP_ENABLE_IT(CRYP_IT_INI | CRYP_IT_OUTI);
1589 /* Enable the CRYP peripheral */
1590 __HAL_CRYP_ENABLE();
1594 /* Process Locked */
1595 __HAL_UNLOCK(hcryp);
1596 /* Change the CRYP state and phase */
1597 hcryp->State = HAL_CRYP_STATE_READY;
1600 /* Return function status */
1603 else if (__HAL_CRYP_GET_IT(CRYP_IT_INI))
1605 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1606 /* Write the Input block in the IN FIFO */
1607 CRYP->DR = *(uint32_t*)(inputaddr);
1609 CRYP->DR = *(uint32_t*)(inputaddr);
1611 CRYP->DR = *(uint32_t*)(inputaddr);
1613 CRYP->DR = *(uint32_t*)(inputaddr);
1614 hcryp->pCrypInBuffPtr += 16;
1615 hcryp->CrypInCount -= 16;
1616 if(hcryp->CrypInCount == 0)
1618 __HAL_CRYP_DISABLE_IT(CRYP_IT_INI);
1619 /* Call the Input data transfer complete callback */
1620 HAL_CRYP_InCpltCallback(hcryp);
1623 else if (__HAL_CRYP_GET_IT(CRYP_IT_OUTI))
1625 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1626 /* Read the Output block from the Output FIFO */
1627 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1629 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1631 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1633 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1634 hcryp->pCrypOutBuffPtr += 16;
1635 hcryp->CrypOutCount -= 16;
1636 if(hcryp->CrypOutCount == 0)
1638 __HAL_CRYP_DISABLE_IT(CRYP_IT_OUTI);
1639 /* Process Unlocked */
1640 __HAL_UNLOCK(hcryp);
1641 /* Change the CRYP peripheral state */
1642 hcryp->State = HAL_CRYP_STATE_READY;
1643 /* Call Input transfer complete callback */
1644 HAL_CRYP_OutCpltCallback(hcryp);
1648 /* Return function status */
1653 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using interrupt
1654 * then decrypted pCypherData. The cypher data are available in pPlainData.
1655 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1656 * the configuration information for CRYP module
1657 * @param pCypherData: Pointer to the cyphertext buffer
1658 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1659 * @param pPlainData: Pointer to the plaintext buffer
1660 * @retval HAL status
1662 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
1665 uint32_t outputaddr;
1666 uint32_t tickstart = 0;
1667 uint32_t headersize = hcryp->Init.HeaderSize;
1668 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
1669 uint32_t loopcounter = 0;
1670 uint32_t bufferidx = 0;
1671 uint8_t blockb0[16] = {0};/* Block B0 */
1672 uint8_t ctr[16] = {0}; /* Counter */
1673 uint32_t b0addr = (uint32_t)blockb0;
1675 if(hcryp->State == HAL_CRYP_STATE_READY)
1677 /* Process Locked */
1680 hcryp->CrypInCount = Size;
1681 hcryp->pCrypInBuffPtr = pCypherData;
1682 hcryp->pCrypOutBuffPtr = pPlainData;
1683 hcryp->CrypOutCount = Size;
1685 /* Change the CRYP peripheral state */
1686 hcryp->State = HAL_CRYP_STATE_BUSY;
1688 /* Check if initialization phase has already been performed */
1689 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1691 /************************ Formatting the header block *******************/
1694 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1695 if(headersize < 65280)
1697 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1698 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1703 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1704 hcryp->Init.pScratch[bufferidx++] = 0xFF;
1705 hcryp->Init.pScratch[bufferidx++] = 0xFE;
1706 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
1707 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
1708 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
1709 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
1712 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1713 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
1715 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
1717 /* Check if the header size is modulo 16 */
1718 if ((headersize % 16) != 0)
1720 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1721 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
1723 hcryp->Init.pScratch[loopcounter] = 0;
1725 /* Set the header size to modulo 16 */
1726 headersize = ((headersize/16) + 1) * 16;
1728 /* Set the pointer headeraddr to hcryp->Init.pScratch */
1729 headeraddr = (uint32_t)hcryp->Init.pScratch;
1731 /*********************** Formatting the block B0 ************************/
1737 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
1738 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
1739 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
1741 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
1743 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
1745 for ( ; loopcounter < 13; loopcounter++)
1747 blockb0[loopcounter+1] = 0;
1750 blockb0[14] = (Size >> 8);
1751 blockb0[15] = (Size & 0xFF);
1753 /************************* Formatting the initial counter ***************/
1755 Bits 7 and 6 are reserved and shall be set to 0
1756 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
1757 blocks are distinct from B0
1758 Bits 0, 1, and 2 contain the same encoding of q as in B0
1760 ctr[0] = blockb0[0] & 0x07;
1761 /* byte 1 to NonceSize is the IV (Nonce) */
1762 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
1764 ctr[loopcounter] = blockb0[loopcounter];
1766 /* Set the LSB to 1 */
1770 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1772 /* Set the CRYP peripheral in AES CCM mode */
1773 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
1775 /* Set the Initialization Vector */
1776 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, hcryp->Init.KeySize);
1778 /* Select init phase */
1779 __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
1781 b0addr = (uint32_t)blockb0;
1782 /* Write the blockb0 block in the IN FIFO */
1783 CRYP->DR = *(uint32_t*)(b0addr);
1785 CRYP->DR = *(uint32_t*)(b0addr);
1787 CRYP->DR = *(uint32_t*)(b0addr);
1789 CRYP->DR = *(uint32_t*)(b0addr);
1791 /* Enable the CRYP peripheral */
1792 __HAL_CRYP_ENABLE();
1795 tickstart = HAL_GetTick();
1797 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1799 /* Check for the Timeout */
1800 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1803 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1805 /* Process Unlocked */
1806 __HAL_UNLOCK(hcryp);
1811 /***************************** Header phase *****************************/
1814 /* Select header phase */
1815 __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
1817 /* Enable Crypto processor */
1818 __HAL_CRYP_ENABLE();
1820 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
1823 tickstart = HAL_GetTick();
1825 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
1827 /* Check for the Timeout */
1828 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1831 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1833 /* Process Unlocked */
1834 __HAL_UNLOCK(hcryp);
1839 /* Write the header block in the IN FIFO */
1840 CRYP->DR = *(uint32_t*)(headeraddr);
1842 CRYP->DR = *(uint32_t*)(headeraddr);
1844 CRYP->DR = *(uint32_t*)(headeraddr);
1846 CRYP->DR = *(uint32_t*)(headeraddr);
1851 tickstart = HAL_GetTick();
1853 while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1855 /* Check for the Timeout */
1856 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1859 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1861 /* Process Unlocked */
1862 __HAL_UNLOCK(hcryp);
1868 /* Save formatted counter into the scratch buffer pScratch */
1869 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
1871 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1874 hcryp->Init.pScratch[15] &= 0xfe;
1875 /* Select payload phase once the header phase is performed */
1876 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
1879 __HAL_CRYP_FIFO_FLUSH();
1882 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1885 /* Enable Interrupts */
1886 __HAL_CRYP_ENABLE_IT(CRYP_IT_INI | CRYP_IT_OUTI);
1888 /* Enable the CRYP peripheral */
1889 __HAL_CRYP_ENABLE();
1891 /* Return function status */
1894 else if (__HAL_CRYP_GET_IT(CRYP_IT_INI))
1896 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1897 /* Write the Input block in the IN FIFO */
1898 CRYP->DR = *(uint32_t*)(inputaddr);
1900 CRYP->DR = *(uint32_t*)(inputaddr);
1902 CRYP->DR = *(uint32_t*)(inputaddr);
1904 CRYP->DR = *(uint32_t*)(inputaddr);
1905 hcryp->pCrypInBuffPtr += 16;
1906 hcryp->CrypInCount -= 16;
1907 if(hcryp->CrypInCount == 0)
1909 __HAL_CRYP_DISABLE_IT(CRYP_IT_INI);
1910 /* Call the Input data transfer complete callback */
1911 HAL_CRYP_InCpltCallback(hcryp);
1914 else if (__HAL_CRYP_GET_IT(CRYP_IT_OUTI))
1916 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1917 /* Read the Output block from the Output FIFO */
1918 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1920 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1922 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1924 *(uint32_t*)(outputaddr) = CRYP->DOUT;
1925 hcryp->pCrypOutBuffPtr += 16;
1926 hcryp->CrypOutCount -= 16;
1927 if(hcryp->CrypOutCount == 0)
1929 __HAL_CRYP_DISABLE_IT(CRYP_IT_OUTI);
1930 /* Process Unlocked */
1931 __HAL_UNLOCK(hcryp);
1932 /* Change the CRYP peripheral state */
1933 hcryp->State = HAL_CRYP_STATE_READY;
1934 /* Call Input transfer complete callback */
1935 HAL_CRYP_OutCpltCallback(hcryp);
1939 /* Return function status */
1944 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using DMA.
1945 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1946 * the configuration information for CRYP module
1947 * @param pPlainData: Pointer to the plaintext buffer
1948 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1949 * @param pCypherData: Pointer to the cyphertext buffer
1950 * @retval HAL status
1952 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1954 uint32_t tickstart = 0;
1956 uint32_t outputaddr;
1958 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
1960 /* Process Locked */
1963 inputaddr = (uint32_t)pPlainData;
1964 outputaddr = (uint32_t)pCypherData;
1966 /* Change the CRYP peripheral state */
1967 hcryp->State = HAL_CRYP_STATE_BUSY;
1969 /* Check if initialization phase has already been performed */
1970 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1973 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1975 /* Set the CRYP peripheral in AES GCM mode */
1976 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
1978 /* Set the Initialization Vector */
1979 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
1982 __HAL_CRYP_FIFO_FLUSH();
1984 /* Enable CRYP to start the init phase */
1985 __HAL_CRYP_ENABLE();
1988 tickstart = HAL_GetTick();
1990 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1992 /* Check for the Timeout */
1993 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1996 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1998 /* Process Unlocked */
1999 __HAL_UNLOCK(hcryp);
2005 __HAL_CRYP_FIFO_FLUSH();
2007 /* Set the header phase */
2008 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
2012 /* Disable the CRYP peripheral */
2013 __HAL_CRYP_DISABLE();
2015 /* Select payload phase once the header phase is performed */
2016 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
2019 __HAL_CRYP_FIFO_FLUSH();
2022 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2025 /* Set the input and output addresses and start DMA transfer */
2026 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2028 /* Unlock process */
2029 __HAL_UNLOCK(hcryp);
2031 /* Return function status */
2041 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
2042 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2043 * the configuration information for CRYP module
2044 * @param pPlainData: Pointer to the plaintext buffer
2045 * @param Size: Length of the plaintext buffer, must be a multiple of 16
2046 * @param pCypherData: Pointer to the cyphertext buffer
2047 * @retval HAL status
2049 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
2051 uint32_t tickstart = 0;
2053 uint32_t outputaddr;
2054 uint32_t headersize;
2055 uint32_t headeraddr;
2056 uint32_t loopcounter = 0;
2057 uint32_t bufferidx = 0;
2058 uint8_t blockb0[16] = {0};/* Block B0 */
2059 uint8_t ctr[16] = {0}; /* Counter */
2060 uint32_t b0addr = (uint32_t)blockb0;
2062 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2064 /* Process Locked */
2067 inputaddr = (uint32_t)pPlainData;
2068 outputaddr = (uint32_t)pCypherData;
2070 headersize = hcryp->Init.HeaderSize;
2071 headeraddr = (uint32_t)hcryp->Init.Header;
2073 hcryp->CrypInCount = Size;
2074 hcryp->pCrypInBuffPtr = pPlainData;
2075 hcryp->pCrypOutBuffPtr = pCypherData;
2076 hcryp->CrypOutCount = Size;
2078 /* Change the CRYP peripheral state */
2079 hcryp->State = HAL_CRYP_STATE_BUSY;
2081 /* Check if initialization phase has already been performed */
2082 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2084 /************************ Formatting the header block *******************/
2087 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2088 if(headersize < 65280)
2090 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
2091 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
2096 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2097 hcryp->Init.pScratch[bufferidx++] = 0xFF;
2098 hcryp->Init.pScratch[bufferidx++] = 0xFE;
2099 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
2100 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
2101 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
2102 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
2105 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2106 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
2108 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2110 /* Check if the header size is modulo 16 */
2111 if ((headersize % 16) != 0)
2113 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2114 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
2116 hcryp->Init.pScratch[loopcounter] = 0;
2118 /* Set the header size to modulo 16 */
2119 headersize = ((headersize/16) + 1) * 16;
2121 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2122 headeraddr = (uint32_t)hcryp->Init.pScratch;
2124 /*********************** Formatting the block B0 ************************/
2130 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2131 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2132 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2134 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
2136 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
2138 for ( ; loopcounter < 13; loopcounter++)
2140 blockb0[loopcounter+1] = 0;
2143 blockb0[14] = (Size >> 8);
2144 blockb0[15] = (Size & 0xFF);
2146 /************************* Formatting the initial counter ***************/
2148 Bits 7 and 6 are reserved and shall be set to 0
2149 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2150 blocks are distinct from B0
2151 Bits 0, 1, and 2 contain the same encoding of q as in B0
2153 ctr[0] = blockb0[0] & 0x07;
2154 /* byte 1 to NonceSize is the IV (Nonce) */
2155 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
2157 ctr[loopcounter] = blockb0[loopcounter];
2159 /* Set the LSB to 1 */
2163 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2165 /* Set the CRYP peripheral in AES CCM mode */
2166 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
2168 /* Set the Initialization Vector */
2169 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, CRYP_KEYSIZE_128B);
2171 /* Select init phase */
2172 __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
2174 b0addr = (uint32_t)blockb0;
2175 /* Write the blockb0 block in the IN FIFO */
2176 CRYP->DR = *(uint32_t*)(b0addr);
2178 CRYP->DR = *(uint32_t*)(b0addr);
2180 CRYP->DR = *(uint32_t*)(b0addr);
2182 CRYP->DR = *(uint32_t*)(b0addr);
2184 /* Enable the CRYP peripheral */
2185 __HAL_CRYP_ENABLE();
2188 tickstart = HAL_GetTick();
2190 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2192 /* Check for the Timeout */
2193 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2196 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2198 /* Process Unlocked */
2199 __HAL_UNLOCK(hcryp);
2204 /***************************** Header phase *****************************/
2207 /* Select header phase */
2208 __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
2210 /* Enable Crypto processor */
2211 __HAL_CRYP_ENABLE();
2213 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
2216 tickstart = HAL_GetTick();
2218 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
2220 /* Check for the Timeout */
2221 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2224 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2226 /* Process Unlocked */
2227 __HAL_UNLOCK(hcryp);
2232 /* Write the header block in the IN FIFO */
2233 CRYP->DR = *(uint32_t*)(headeraddr);
2235 CRYP->DR = *(uint32_t*)(headeraddr);
2237 CRYP->DR = *(uint32_t*)(headeraddr);
2239 CRYP->DR = *(uint32_t*)(headeraddr);
2244 tickstart = HAL_GetTick();
2246 while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2248 /* Check for the Timeout */
2249 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2252 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2254 /* Process Unlocked */
2255 __HAL_UNLOCK(hcryp);
2261 /* Save formatted counter into the scratch buffer pScratch */
2262 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
2264 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2267 hcryp->Init.pScratch[15] &= 0xfe;
2269 /* Select payload phase once the header phase is performed */
2270 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
2273 __HAL_CRYP_FIFO_FLUSH();
2276 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2279 /* Set the input and output addresses and start DMA transfer */
2280 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2282 /* Unlock process */
2283 __HAL_UNLOCK(hcryp);
2285 /* Return function status */
2295 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using DMA.
2296 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2297 * the configuration information for CRYP module
2298 * @param pCypherData: Pointer to the cyphertext buffer.
2299 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
2300 * @param pPlainData: Pointer to the plaintext buffer
2301 * @retval HAL status
2303 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2305 uint32_t tickstart = 0;
2307 uint32_t outputaddr;
2309 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2311 /* Process Locked */
2314 inputaddr = (uint32_t)pCypherData;
2315 outputaddr = (uint32_t)pPlainData;
2317 /* Change the CRYP peripheral state */
2318 hcryp->State = HAL_CRYP_STATE_BUSY;
2320 /* Check if initialization phase has already been performed */
2321 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2324 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2326 /* Set the CRYP peripheral in AES GCM decryption mode */
2327 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
2329 /* Set the Initialization Vector */
2330 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B);
2332 /* Enable CRYP to start the init phase */
2333 __HAL_CRYP_ENABLE();
2336 tickstart = HAL_GetTick();
2338 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2340 /* Check for the Timeout */
2341 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2344 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2346 /* Process Unlocked */
2347 __HAL_UNLOCK(hcryp);
2353 /* Set the header phase */
2354 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
2358 /* Disable the CRYP peripheral */
2359 __HAL_CRYP_DISABLE();
2361 /* Select payload phase once the header phase is performed */
2362 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
2365 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2368 /* Set the input and output addresses and start DMA transfer */
2369 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2371 /* Unlock process */
2372 __HAL_UNLOCK(hcryp);
2374 /* Return function status */
2384 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using DMA
2385 * then decrypted pCypherData. The cypher data are available in pPlainData.
2386 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2387 * the configuration information for CRYP module
2388 * @param pCypherData: Pointer to the cyphertext buffer
2389 * @param Size: Length of the plaintext buffer, must be a multiple of 16
2390 * @param pPlainData: Pointer to the plaintext buffer
2391 * @retval HAL status
2393 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2395 uint32_t tickstart = 0;
2397 uint32_t outputaddr;
2398 uint32_t headersize;
2399 uint32_t headeraddr;
2400 uint32_t loopcounter = 0;
2401 uint32_t bufferidx = 0;
2402 uint8_t blockb0[16] = {0};/* Block B0 */
2403 uint8_t ctr[16] = {0}; /* Counter */
2404 uint32_t b0addr = (uint32_t)blockb0;
2406 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2408 /* Process Locked */
2411 inputaddr = (uint32_t)pCypherData;
2412 outputaddr = (uint32_t)pPlainData;
2414 headersize = hcryp->Init.HeaderSize;
2415 headeraddr = (uint32_t)hcryp->Init.Header;
2417 hcryp->CrypInCount = Size;
2418 hcryp->pCrypInBuffPtr = pCypherData;
2419 hcryp->pCrypOutBuffPtr = pPlainData;
2420 hcryp->CrypOutCount = Size;
2422 /* Change the CRYP peripheral state */
2423 hcryp->State = HAL_CRYP_STATE_BUSY;
2425 /* Check if initialization phase has already been performed */
2426 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2428 /************************ Formatting the header block *******************/
2431 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2432 if(headersize < 65280)
2434 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
2435 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
2440 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2441 hcryp->Init.pScratch[bufferidx++] = 0xFF;
2442 hcryp->Init.pScratch[bufferidx++] = 0xFE;
2443 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000;
2444 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000;
2445 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00;
2446 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff;
2449 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2450 for(loopcounter = 0; loopcounter < headersize; loopcounter++)
2452 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2454 /* Check if the header size is modulo 16 */
2455 if ((headersize % 16) != 0)
2457 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2458 for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
2460 hcryp->Init.pScratch[loopcounter] = 0;
2462 /* Set the header size to modulo 16 */
2463 headersize = ((headersize/16) + 1) * 16;
2465 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2466 headeraddr = (uint32_t)hcryp->Init.pScratch;
2468 /*********************** Formatting the block B0 ************************/
2474 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2475 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2476 blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2478 for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
2480 blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
2482 for ( ; loopcounter < 13; loopcounter++)
2484 blockb0[loopcounter+1] = 0;
2487 blockb0[14] = (Size >> 8);
2488 blockb0[15] = (Size & 0xFF);
2490 /************************* Formatting the initial counter ***************/
2492 Bits 7 and 6 are reserved and shall be set to 0
2493 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2494 blocks are distinct from B0
2495 Bits 0, 1, and 2 contain the same encoding of q as in B0
2497 ctr[0] = blockb0[0] & 0x07;
2498 /* byte 1 to NonceSize is the IV (Nonce) */
2499 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
2501 ctr[loopcounter] = blockb0[loopcounter];
2503 /* Set the LSB to 1 */
2507 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2509 /* Set the CRYP peripheral in AES CCM mode */
2510 __HAL_CRYP_SET_MODE(CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
2512 /* Set the Initialization Vector */
2513 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr, CRYP_KEYSIZE_128B);
2515 /* Select init phase */
2516 __HAL_CRYP_SET_PHASE(CRYP_PHASE_INIT);
2518 b0addr = (uint32_t)blockb0;
2519 /* Write the blockb0 block in the IN FIFO */
2520 CRYP->DR = *(uint32_t*)(b0addr);
2522 CRYP->DR = *(uint32_t*)(b0addr);
2524 CRYP->DR = *(uint32_t*)(b0addr);
2526 CRYP->DR = *(uint32_t*)(b0addr);
2528 /* Enable the CRYP peripheral */
2529 __HAL_CRYP_ENABLE();
2532 tickstart = HAL_GetTick();
2534 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2536 /* Check for the Timeout */
2538 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2541 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2543 /* Process Unlocked */
2544 __HAL_UNLOCK(hcryp);
2550 /***************************** Header phase *****************************/
2553 /* Select header phase */
2554 __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
2556 /* Enable Crypto processor */
2557 __HAL_CRYP_ENABLE();
2559 for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
2562 tickstart = HAL_GetTick();
2564 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
2566 /* Check for the Timeout */
2567 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2570 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2572 /* Process Unlocked */
2573 __HAL_UNLOCK(hcryp);
2578 /* Write the header block in the IN FIFO */
2579 CRYP->DR = *(uint32_t*)(headeraddr);
2581 CRYP->DR = *(uint32_t*)(headeraddr);
2583 CRYP->DR = *(uint32_t*)(headeraddr);
2585 CRYP->DR = *(uint32_t*)(headeraddr);
2590 tickstart = HAL_GetTick();
2592 while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2594 /* Check for the Timeout */
2595 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2598 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2600 /* Process Unlocked */
2601 __HAL_UNLOCK(hcryp);
2607 /* Save formatted counter into the scratch buffer pScratch */
2608 for(loopcounter = 0; (loopcounter < 16); loopcounter++)
2610 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2613 hcryp->Init.pScratch[15] &= 0xfe;
2614 /* Select payload phase once the header phase is performed */
2615 __HAL_CRYP_SET_PHASE(CRYP_PHASE_PAYLOAD);
2618 __HAL_CRYP_FIFO_FLUSH();
2621 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2623 /* Set the input and output addresses and start DMA transfer */
2624 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2626 /* Unlock process */
2627 __HAL_UNLOCK(hcryp);
2629 /* Return function status */
2639 * @brief This function handles CRYP interrupt request.
2640 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2641 * the configuration information for CRYP module
2644 void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp)
2646 switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION)
2648 case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT:
2649 HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, HAL_NULL, 0, HAL_NULL);
2652 case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT:
2653 HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, HAL_NULL, 0, HAL_NULL);
2656 case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT:
2657 HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, HAL_NULL, 0, HAL_NULL);
2660 case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT:
2661 HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, HAL_NULL, 0, HAL_NULL);
2674 * @brief DMA CRYP Input Data process complete callback.
2675 * @param hdma: DMA handle
2678 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma)
2680 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2682 /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit
2683 in the DMACR register */
2684 CRYP->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
2686 /* Call input data transfer complete callback */
2687 HAL_CRYP_InCpltCallback(hcryp);
2691 * @brief DMA CRYP Output Data process complete callback.
2692 * @param hdma: DMA handle
2695 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma)
2697 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2699 /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit
2700 in the DMACR register */
2701 CRYP->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
2703 /* Enable the CRYP peripheral */
2704 __HAL_CRYP_DISABLE();
2706 /* Change the CRYP peripheral state */
2707 hcryp->State = HAL_CRYP_STATE_READY;
2709 /* Call output data transfer complete callback */
2710 HAL_CRYP_OutCpltCallback(hcryp);
2714 * @brief DMA CRYP communication error callback.
2715 * @param hdma: DMA handle
2718 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma)
2720 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2721 hcryp->State= HAL_CRYP_STATE_READY;
2722 HAL_CRYP_ErrorCallback(hcryp);
2726 * @brief Writes the Key in Key registers.
2727 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2728 * the configuration information for CRYP module
2729 * @param Key: Pointer to Key buffer
2730 * @param KeySize: Size of Key
2733 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize)
2735 uint32_t keyaddr = (uint32_t)Key;
2739 case CRYP_KEYSIZE_256B:
2740 /* Key Initialisation */
2741 CRYP->K0LR = __REV(*(uint32_t*)(keyaddr));
2743 CRYP->K0RR = __REV(*(uint32_t*)(keyaddr));
2745 CRYP->K1LR = __REV(*(uint32_t*)(keyaddr));
2747 CRYP->K1RR = __REV(*(uint32_t*)(keyaddr));
2749 CRYP->K2LR = __REV(*(uint32_t*)(keyaddr));
2751 CRYP->K2RR = __REV(*(uint32_t*)(keyaddr));
2753 CRYP->K3LR = __REV(*(uint32_t*)(keyaddr));
2755 CRYP->K3RR = __REV(*(uint32_t*)(keyaddr));
2757 case CRYP_KEYSIZE_192B:
2758 CRYP->K1LR = __REV(*(uint32_t*)(keyaddr));
2760 CRYP->K1RR = __REV(*(uint32_t*)(keyaddr));
2762 CRYP->K2LR = __REV(*(uint32_t*)(keyaddr));
2764 CRYP->K2RR = __REV(*(uint32_t*)(keyaddr));
2766 CRYP->K3LR = __REV(*(uint32_t*)(keyaddr));
2768 CRYP->K3RR = __REV(*(uint32_t*)(keyaddr));
2770 case CRYP_KEYSIZE_128B:
2771 CRYP->K2LR = __REV(*(uint32_t*)(keyaddr));
2773 CRYP->K2RR = __REV(*(uint32_t*)(keyaddr));
2775 CRYP->K3LR = __REV(*(uint32_t*)(keyaddr));
2777 CRYP->K3RR = __REV(*(uint32_t*)(keyaddr));
2785 * @brief Writes the InitVector/InitCounter in IV registers.
2786 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2787 * the configuration information for CRYP module
2788 * @param InitVector: Pointer to InitVector/InitCounter buffer
2789 * @param IVSize: Size of the InitVector/InitCounter
2792 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector, uint32_t IVSize)
2794 uint32_t ivaddr = (uint32_t)InitVector;
2798 case CRYP_KEYSIZE_128B:
2799 CRYP->IV0LR = __REV(*(uint32_t*)(ivaddr));
2801 CRYP->IV0RR = __REV(*(uint32_t*)(ivaddr));
2803 CRYP->IV1LR = __REV(*(uint32_t*)(ivaddr));
2805 CRYP->IV1RR = __REV(*(uint32_t*)(ivaddr));
2807 /* Whatever key size 192 or 256, Init vector is written in IV0LR and IV0RR */
2808 case CRYP_KEYSIZE_192B:
2809 CRYP->IV0LR = __REV(*(uint32_t*)(ivaddr));
2811 CRYP->IV0RR = __REV(*(uint32_t*)(ivaddr));
2813 case CRYP_KEYSIZE_256B:
2814 CRYP->IV0LR = __REV(*(uint32_t*)(ivaddr));
2816 CRYP->IV0RR = __REV(*(uint32_t*)(ivaddr));
2824 * @brief Process Data: Writes Input data in polling mode and read the Output data.
2825 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2826 * the configuration information for CRYP module
2827 * @param Input: Pointer to the Input buffer.
2828 * @param Ilength: Length of the Input buffer, must be a multiple of 16
2829 * @param Output: Pointer to the returned buffer
2830 * @param Timeout: Timeout value
2833 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout)
2835 uint32_t tickstart = 0;
2837 uint32_t inputaddr = (uint32_t)Input;
2838 uint32_t outputaddr = (uint32_t)Output;
2840 for(i=0; (i < Ilength); i+=16)
2842 /* Write the Input block in the IN FIFO */
2843 CRYP->DR = *(uint32_t*)(inputaddr);
2845 CRYP->DR = *(uint32_t*)(inputaddr);
2847 CRYP->DR = *(uint32_t*)(inputaddr);
2849 CRYP->DR = *(uint32_t*)(inputaddr);
2853 tickstart = HAL_GetTick();
2855 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_OFNE))
2857 /* Check for the Timeout */
2858 if(Timeout != HAL_MAX_DELAY)
2860 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2863 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2865 /* Process Unlocked */
2866 __HAL_UNLOCK(hcryp);
2872 /* Read the Output block from the OUT FIFO */
2873 *(uint32_t*)(outputaddr) = CRYP->DOUT;
2875 *(uint32_t*)(outputaddr) = CRYP->DOUT;
2877 *(uint32_t*)(outputaddr) = CRYP->DOUT;
2879 *(uint32_t*)(outputaddr) = CRYP->DOUT;
2882 /* Return function status */
2887 * @brief Sets the header phase
2888 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2889 * the configuration information for CRYP module
2890 * @param Input: Pointer to the Input buffer.
2891 * @param Ilength: Length of the Input buffer, must be a multiple of 16
2892 * @param Timeout: Timeout value
2895 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout)
2897 uint32_t tickstart = 0;
2898 uint32_t loopcounter = 0;
2899 uint32_t headeraddr = (uint32_t)Input;
2901 /***************************** Header phase *********************************/
2902 if(hcryp->Init.HeaderSize != 0)
2904 /* Select header phase */
2905 __HAL_CRYP_SET_PHASE(CRYP_PHASE_HEADER);
2906 /* Enable the CRYP peripheral */
2907 __HAL_CRYP_ENABLE();
2909 for(loopcounter = 0; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16)
2912 tickstart = HAL_GetTick();
2914 while(HAL_IS_BIT_CLR(CRYP->SR, CRYP_FLAG_IFEM))
2916 /* Check for the Timeout */
2917 if(Timeout != HAL_MAX_DELAY)
2919 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
2922 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2924 /* Process Unlocked */
2925 __HAL_UNLOCK(hcryp);
2931 /* Write the Input block in the IN FIFO */
2932 CRYP->DR = *(uint32_t*)(headeraddr);
2934 CRYP->DR = *(uint32_t*)(headeraddr);
2936 CRYP->DR = *(uint32_t*)(headeraddr);
2938 CRYP->DR = *(uint32_t*)(headeraddr);
2942 /* Wait until the complete message has been processed */
2945 tickstart = HAL_GetTick();
2947 while((CRYP->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2949 /* Check for the Timeout */
2950 if(Timeout != HAL_MAX_DELAY)
2952 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
2955 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2957 /* Process Unlocked */
2958 __HAL_UNLOCK(hcryp);
2965 /* Return function status */
2970 * @brief Sets the DMA configuration and start the DMA transfert.
2971 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2972 * the configuration information for CRYP module
2973 * @param inputaddr: Address of the Input buffer
2974 * @param Size: Size of the Input buffer, must be a multiple of 16
2975 * @param outputaddr: Address of the Output buffer
2978 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2980 /* Set the CRYP DMA transfer complete callback */
2981 hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt;
2982 /* Set the DMA error callback */
2983 hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
2985 /* Set the CRYP DMA transfer complete callback */
2986 hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt;
2987 /* Set the DMA error callback */
2988 hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
2990 /* Enable the CRYP peripheral */
2991 __HAL_CRYP_ENABLE();
2993 /* Enable the DMA In DMA Stream */
2994 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&CRYP->DR, Size/4);
2996 /* Enable In DMA request */
2997 CRYP->DMACR = CRYP_DMACR_DIEN;
2999 /* Enable the DMA Out DMA Stream */
3000 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&CRYP->DOUT, outputaddr, Size/4);
3002 /* Enable Out DMA request */
3003 CRYP->DMACR |= CRYP_DMACR_DOEN;
3009 #endif /* STM32F437xx || STM32F439xx */
3011 #endif /* HAL_CRYP_MODULE_ENABLED */
3020 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/