2 ******************************************************************************
3 * @file stm32f7xx_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 __HAL_RCC_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 initialized 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 -@- For CCM Encrypt/Decrypt API's, only DataType = 8-bit is supported by this version.
64 -@- The HAL_CRYPEx_AESGCM_xxxx() implementation is limited to 32bits inputs data length
65 (Plain/Cyphertext, Header) compared with GCM standards specifications (800-38D).
66 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
69 ******************************************************************************
72 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
74 * Redistribution and use in source and binary forms, with or without modification,
75 * are permitted provided that the following conditions are met:
76 * 1. Redistributions of source code must retain the above copyright notice,
77 * this list of conditions and the following disclaimer.
78 * 2. Redistributions in binary form must reproduce the above copyright notice,
79 * this list of conditions and the following disclaimer in the documentation
80 * and/or other materials provided with the distribution.
81 * 3. Neither the name of STMicroelectronics nor the names of its contributors
82 * may be used to endorse or promote products derived from this software
83 * without specific prior written permission.
85 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
86 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
87 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
89 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
90 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
91 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
92 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
93 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
94 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96 ******************************************************************************
99 /* Includes ------------------------------------------------------------------*/
100 #include "stm32f7xx_hal.h"
102 /** @addtogroup STM32F7xx_HAL_Driver
105 #if defined (STM32F756xx) || defined (STM32F777xx) || defined (STM32F779xx)
106 /** @defgroup CRYPEx CRYPEx
107 * @brief CRYP Extension HAL module driver.
112 #ifdef HAL_CRYP_MODULE_ENABLED
114 /* Private typedef -----------------------------------------------------------*/
115 /* Private define ------------------------------------------------------------*/
116 /** @addtogroup CRYPEx_Private_define
119 #define CRYPEx_TIMEOUT_VALUE 1
124 /* Private macro -------------------------------------------------------------*/
125 /* Private variables ---------------------------------------------------------*/
126 /* Private function prototypes -----------------------------------------------*/
127 /** @defgroup CRYPEx_Private_Functions_prototypes CRYP Private Functions Prototypes
130 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef
*hcryp
, uint8_t *InitVector
);
131 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef
*hcryp
, uint8_t *Key
, uint32_t KeySize
);
132 static HAL_StatusTypeDef
CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef
*hcryp
, uint8_t *Input
, uint16_t Ilength
, uint8_t *Output
, uint32_t Timeout
);
133 static HAL_StatusTypeDef
CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef
*hcryp
, uint8_t* Input
, uint16_t Ilength
, uint32_t Timeout
);
134 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef
*hdma
);
135 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef
*hdma
);
136 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef
*hdma
);
137 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef
*hcryp
, uint32_t inputaddr
, uint16_t Size
, uint32_t outputaddr
);
142 /* Private functions ---------------------------------------------------------*/
143 /** @addtogroup CRYPEx_Private_Functions
148 * @brief DMA CRYP Input Data process complete callback.
149 * @param hdma: DMA handle
152 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef
*hdma
)
154 CRYP_HandleTypeDef
* hcryp
= ( CRYP_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
156 /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit
157 in the DMACR register */
158 hcryp
->Instance
->DMACR
&= (uint32_t)(~CRYP_DMACR_DIEN
);
160 /* Call input data transfer complete callback */
161 HAL_CRYP_InCpltCallback(hcryp
);
165 * @brief DMA CRYP Output Data process complete callback.
166 * @param hdma: DMA handle
169 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef
*hdma
)
171 CRYP_HandleTypeDef
* hcryp
= ( CRYP_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
173 /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit
174 in the DMACR register */
175 hcryp
->Instance
->DMACR
&= (uint32_t)(~CRYP_DMACR_DOEN
);
177 /* Enable the CRYP peripheral */
178 __HAL_CRYP_DISABLE(hcryp
);
180 /* Change the CRYP peripheral state */
181 hcryp
->State
= HAL_CRYP_STATE_READY
;
183 /* Call output data transfer complete callback */
184 HAL_CRYP_OutCpltCallback(hcryp
);
188 * @brief DMA CRYP communication error callback.
189 * @param hdma: DMA handle
192 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef
*hdma
)
194 CRYP_HandleTypeDef
* hcryp
= ( CRYP_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
195 hcryp
->State
= HAL_CRYP_STATE_READY
;
196 HAL_CRYP_ErrorCallback(hcryp
);
200 * @brief Writes the Key in Key registers.
201 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
202 * the configuration information for CRYP module
203 * @param Key: Pointer to Key buffer
204 * @param KeySize: Size of Key
207 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef
*hcryp
, uint8_t *Key
, uint32_t KeySize
)
209 uint32_t keyaddr
= (uint32_t)Key
;
213 case CRYP_KEYSIZE_256B
:
214 /* Key Initialisation */
215 hcryp
->Instance
->K0LR
= __REV(*(uint32_t*)(keyaddr
));
217 hcryp
->Instance
->K0RR
= __REV(*(uint32_t*)(keyaddr
));
219 hcryp
->Instance
->K1LR
= __REV(*(uint32_t*)(keyaddr
));
221 hcryp
->Instance
->K1RR
= __REV(*(uint32_t*)(keyaddr
));
223 hcryp
->Instance
->K2LR
= __REV(*(uint32_t*)(keyaddr
));
225 hcryp
->Instance
->K2RR
= __REV(*(uint32_t*)(keyaddr
));
227 hcryp
->Instance
->K3LR
= __REV(*(uint32_t*)(keyaddr
));
229 hcryp
->Instance
->K3RR
= __REV(*(uint32_t*)(keyaddr
));
231 case CRYP_KEYSIZE_192B
:
232 hcryp
->Instance
->K1LR
= __REV(*(uint32_t*)(keyaddr
));
234 hcryp
->Instance
->K1RR
= __REV(*(uint32_t*)(keyaddr
));
236 hcryp
->Instance
->K2LR
= __REV(*(uint32_t*)(keyaddr
));
238 hcryp
->Instance
->K2RR
= __REV(*(uint32_t*)(keyaddr
));
240 hcryp
->Instance
->K3LR
= __REV(*(uint32_t*)(keyaddr
));
242 hcryp
->Instance
->K3RR
= __REV(*(uint32_t*)(keyaddr
));
244 case CRYP_KEYSIZE_128B
:
245 hcryp
->Instance
->K2LR
= __REV(*(uint32_t*)(keyaddr
));
247 hcryp
->Instance
->K2RR
= __REV(*(uint32_t*)(keyaddr
));
249 hcryp
->Instance
->K3LR
= __REV(*(uint32_t*)(keyaddr
));
251 hcryp
->Instance
->K3RR
= __REV(*(uint32_t*)(keyaddr
));
259 * @brief Writes the InitVector/InitCounter in IV registers.
260 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
261 * the configuration information for CRYP module
262 * @param InitVector: Pointer to InitVector/InitCounter buffer
265 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef
*hcryp
, uint8_t *InitVector
)
267 uint32_t ivaddr
= (uint32_t)InitVector
;
269 hcryp
->Instance
->IV0LR
= __REV(*(uint32_t*)(ivaddr
));
271 hcryp
->Instance
->IV0RR
= __REV(*(uint32_t*)(ivaddr
));
273 hcryp
->Instance
->IV1LR
= __REV(*(uint32_t*)(ivaddr
));
275 hcryp
->Instance
->IV1RR
= __REV(*(uint32_t*)(ivaddr
));
279 * @brief Process Data: Writes Input data in polling mode and read the Output data.
280 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
281 * the configuration information for CRYP module
282 * @param Input: Pointer to the Input buffer.
283 * @param Ilength: Length of the Input buffer, must be a multiple of 16
284 * @param Output: Pointer to the returned buffer
285 * @param Timeout: Timeout value
288 static HAL_StatusTypeDef
CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef
*hcryp
, uint8_t *Input
, uint16_t Ilength
, uint8_t *Output
, uint32_t Timeout
)
290 uint32_t tickstart
= 0;
292 uint32_t inputaddr
= (uint32_t)Input
;
293 uint32_t outputaddr
= (uint32_t)Output
;
295 for(i
=0; (i
< Ilength
); i
+=16)
297 /* Write the Input block in the IN FIFO */
298 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
300 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
302 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
304 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
308 tickstart
= HAL_GetTick();
310 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_OFNE
))
312 /* Check for the Timeout */
313 if(Timeout
!= HAL_MAX_DELAY
)
315 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
318 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
320 /* Process Unlocked */
327 /* Read the Output block from the OUT FIFO */
328 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
330 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
332 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
334 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
337 /* Return function status */
342 * @brief Sets the header phase
343 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
344 * the configuration information for CRYP module
345 * @param Input: Pointer to the Input buffer.
346 * @param Ilength: Length of the Input buffer, must be a multiple of 16
347 * @param Timeout: Timeout value
350 static HAL_StatusTypeDef
CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef
*hcryp
, uint8_t* Input
, uint16_t Ilength
, uint32_t Timeout
)
352 uint32_t tickstart
= 0;
353 uint32_t loopcounter
= 0;
354 uint32_t headeraddr
= (uint32_t)Input
;
356 /***************************** Header phase *********************************/
357 if(hcryp
->Init
.HeaderSize
!= 0)
359 /* Select header phase */
360 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_HEADER
);
361 /* Enable the CRYP peripheral */
362 __HAL_CRYP_ENABLE(hcryp
);
364 for(loopcounter
= 0; (loopcounter
< hcryp
->Init
.HeaderSize
); loopcounter
+=16)
367 tickstart
= HAL_GetTick();
369 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_IFEM
))
371 /* Check for the Timeout */
372 if(Timeout
!= HAL_MAX_DELAY
)
374 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
377 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
379 /* Process Unlocked */
386 /* Write the Input block in the IN FIFO */
387 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
389 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
391 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
393 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
397 /* Wait until the complete message has been processed */
400 tickstart
= HAL_GetTick();
402 while((hcryp
->Instance
->SR
& CRYP_FLAG_BUSY
) == CRYP_FLAG_BUSY
)
404 /* Check for the Timeout */
405 if(Timeout
!= HAL_MAX_DELAY
)
407 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
410 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
412 /* Process Unlocked */
420 /* Return function status */
425 * @brief Sets the DMA configuration and start the DMA transfer.
426 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
427 * the configuration information for CRYP module
428 * @param inputaddr: Address of the Input buffer
429 * @param Size: Size of the Input buffer, must be a multiple of 16
430 * @param outputaddr: Address of the Output buffer
433 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef
*hcryp
, uint32_t inputaddr
, uint16_t Size
, uint32_t outputaddr
)
435 /* Set the CRYP DMA transfer complete callback */
436 hcryp
->hdmain
->XferCpltCallback
= CRYPEx_GCMCCM_DMAInCplt
;
437 /* Set the DMA error callback */
438 hcryp
->hdmain
->XferErrorCallback
= CRYPEx_GCMCCM_DMAError
;
440 /* Set the CRYP DMA transfer complete callback */
441 hcryp
->hdmaout
->XferCpltCallback
= CRYPEx_GCMCCM_DMAOutCplt
;
442 /* Set the DMA error callback */
443 hcryp
->hdmaout
->XferErrorCallback
= CRYPEx_GCMCCM_DMAError
;
445 /* Enable the CRYP peripheral */
446 __HAL_CRYP_ENABLE(hcryp
);
448 /* Enable the DMA In DMA Stream */
449 HAL_DMA_Start_IT(hcryp
->hdmain
, inputaddr
, (uint32_t)&hcryp
->Instance
->DR
, Size
/4);
451 /* Enable In DMA request */
452 hcryp
->Instance
->DMACR
= CRYP_DMACR_DIEN
;
454 /* Enable the DMA Out DMA Stream */
455 HAL_DMA_Start_IT(hcryp
->hdmaout
, (uint32_t)&hcryp
->Instance
->DOUT
, outputaddr
, Size
/4);
457 /* Enable Out DMA request */
458 hcryp
->Instance
->DMACR
|= CRYP_DMACR_DOEN
;
465 /* Exported functions---------------------------------------------------------*/
466 /** @addtogroup CRYPEx_Exported_Functions
470 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
471 * @brief Extended processing functions.
474 ==============================================================================
475 ##### Extended AES processing functions #####
476 ==============================================================================
477 [..] This section provides functions allowing to:
478 (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes
479 (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes
480 (+) Finish the processing. This function is available only for GCM and CCM
481 [..] Three processing methods are available:
492 * @brief Initializes the CRYP peripheral in AES CCM encryption mode then
493 * encrypt pPlainData. The cypher data are available in pCypherData.
494 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
495 * the configuration information for CRYP module
496 * @param pPlainData: Pointer to the plaintext buffer
497 * @param Size: Length of the plaintext buffer, must be a multiple of 16
498 * @param pCypherData: Pointer to the cyphertext buffer
499 * @param Timeout: Timeout duration
502 HAL_StatusTypeDef
HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef
*hcryp
, uint8_t *pPlainData
, uint16_t Size
, uint8_t *pCypherData
, uint32_t Timeout
)
504 uint32_t tickstart
= 0;
505 uint32_t headersize
= hcryp
->Init
.HeaderSize
;
506 uint32_t headeraddr
= (uint32_t)hcryp
->Init
.Header
;
507 uint32_t loopcounter
= 0;
508 uint32_t bufferidx
= 0;
509 uint8_t blockb0
[16] = {0};/* Block B0 */
510 uint8_t ctr
[16] = {0}; /* Counter */
511 uint32_t b0addr
= (uint32_t)blockb0
;
516 /* Change the CRYP peripheral state */
517 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
519 /* Check if initialization phase has already been performed */
520 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
522 /************************ Formatting the header block *********************/
525 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
526 if(headersize
< 65280)
528 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
>> 8) & 0xFF);
529 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
) & 0xFF);
534 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
535 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFF;
536 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFE;
537 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0xff000000U
;
538 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x00ff0000U
;
539 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x0000ff00U
;
540 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x000000ffU
;
543 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
544 for(loopcounter
= 0; loopcounter
< headersize
; loopcounter
++)
546 hcryp
->Init
.pScratch
[bufferidx
++] = hcryp
->Init
.Header
[loopcounter
];
548 /* Check if the header size is modulo 16 */
549 if ((headersize
% 16) != 0)
551 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
552 for(loopcounter
= headersize
; loopcounter
<= ((headersize
/16) + 1) * 16; loopcounter
++)
554 hcryp
->Init
.pScratch
[loopcounter
] = 0;
556 /* Set the header size to modulo 16 */
557 headersize
= ((headersize
/16) + 1) * 16;
559 /* Set the pointer headeraddr to hcryp->Init.pScratch */
560 headeraddr
= (uint32_t)hcryp
->Init
.pScratch
;
562 /*********************** Formatting the block B0 **************************/
568 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
569 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp
->Init
.TagSize
- (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
570 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp
->Init
.IVSize
) - (uint8_t)1) & (uint8_t)0x07);
572 for (loopcounter
= 0; loopcounter
< hcryp
->Init
.IVSize
; loopcounter
++)
574 blockb0
[loopcounter
+1] = hcryp
->Init
.pInitVect
[loopcounter
];
576 for ( ; loopcounter
< 13; loopcounter
++)
578 blockb0
[loopcounter
+1] = 0;
581 blockb0
[14] = (Size
>> 8);
582 blockb0
[15] = (Size
& 0xFF);
584 /************************* Formatting the initial counter *****************/
586 Bits 7 and 6 are reserved and shall be set to 0
587 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
589 Bits 0, 1, and 2 contain the same encoding of q as in B0
591 ctr
[0] = blockb0
[0] & 0x07;
592 /* byte 1 to NonceSize is the IV (Nonce) */
593 for(loopcounter
= 1; loopcounter
< hcryp
->Init
.IVSize
+ 1; loopcounter
++)
595 ctr
[loopcounter
] = blockb0
[loopcounter
];
597 /* Set the LSB to 1 */
601 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
603 /* Set the CRYP peripheral in AES CCM mode */
604 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT
);
606 /* Set the Initialization Vector */
607 CRYPEx_GCMCCM_SetInitVector(hcryp
, ctr
);
609 /* Select init phase */
610 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_INIT
);
612 b0addr
= (uint32_t)blockb0
;
613 /* Write the blockb0 block in the IN FIFO */
614 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
616 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
618 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
620 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
622 /* Enable the CRYP peripheral */
623 __HAL_CRYP_ENABLE(hcryp
);
626 tickstart
= HAL_GetTick();
628 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
630 /* Check for the Timeout */
631 if(Timeout
!= HAL_MAX_DELAY
)
633 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
636 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
638 /* Process Unlocked */
645 /***************************** Header phase *******************************/
648 /* Select header phase */
649 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_HEADER
);
651 /* Enable the CRYP peripheral */
652 __HAL_CRYP_ENABLE(hcryp
);
654 for(loopcounter
= 0; (loopcounter
< headersize
); loopcounter
+=16)
657 tickstart
= HAL_GetTick();
659 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_IFEM
))
662 /* Check for the Timeout */
663 if(Timeout
!= HAL_MAX_DELAY
)
665 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
668 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
670 /* Process Unlocked */
678 /* Write the header block in the IN FIFO */
679 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
681 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
683 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
685 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
690 tickstart
= HAL_GetTick();
692 while((hcryp
->Instance
->SR
& CRYP_FLAG_BUSY
) == CRYP_FLAG_BUSY
)
694 /* Check for the Timeout */
695 if(Timeout
!= HAL_MAX_DELAY
)
697 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
700 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
702 /* Process Unlocked */
710 /* Save formatted counter into the scratch buffer pScratch */
711 for(loopcounter
= 0; (loopcounter
< 16); loopcounter
++)
713 hcryp
->Init
.pScratch
[loopcounter
] = ctr
[loopcounter
];
716 hcryp
->Init
.pScratch
[15] &= 0xfe;
718 /* Select payload phase once the header phase is performed */
719 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
722 __HAL_CRYP_FIFO_FLUSH(hcryp
);
724 /* Enable the CRYP peripheral */
725 __HAL_CRYP_ENABLE(hcryp
);
728 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
731 /* Write Plain Data and Get Cypher Data */
732 if(CRYPEx_GCMCCM_ProcessData(hcryp
,pPlainData
, Size
, pCypherData
, Timeout
) != HAL_OK
)
737 /* Change the CRYP peripheral state */
738 hcryp
->State
= HAL_CRYP_STATE_READY
;
740 /* Process Unlocked */
743 /* Return function status */
748 * @brief Initializes the CRYP peripheral in AES GCM encryption mode then
749 * encrypt pPlainData. The cypher data are available in pCypherData.
750 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
751 * the configuration information for CRYP module
752 * @param pPlainData: Pointer to the plaintext buffer
753 * @param Size: Length of the plaintext buffer, must be a multiple of 16
754 * @param pCypherData: Pointer to the cyphertext buffer
755 * @param Timeout: Timeout duration
758 HAL_StatusTypeDef
HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef
*hcryp
, uint8_t *pPlainData
, uint16_t Size
, uint8_t *pCypherData
, uint32_t Timeout
)
760 uint32_t tickstart
= 0;
765 /* Change the CRYP peripheral state */
766 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
768 /* Check if initialization phase has already been performed */
769 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
772 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
774 /* Set the CRYP peripheral in AES GCM mode */
775 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT
);
777 /* Set the Initialization Vector */
778 CRYPEx_GCMCCM_SetInitVector(hcryp
, hcryp
->Init
.pInitVect
);
781 __HAL_CRYP_FIFO_FLUSH(hcryp
);
783 /* Enable the CRYP peripheral */
784 __HAL_CRYP_ENABLE(hcryp
);
787 tickstart
= HAL_GetTick();
789 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
791 /* Check for the Timeout */
792 if(Timeout
!= HAL_MAX_DELAY
)
794 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
797 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
799 /* Process Unlocked */
807 /* Set the header phase */
808 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp
, hcryp
->Init
.Header
, hcryp
->Init
.HeaderSize
, Timeout
) != HAL_OK
)
813 /* Disable the CRYP peripheral */
814 __HAL_CRYP_DISABLE(hcryp
);
816 /* Select payload phase once the header phase is performed */
817 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
820 __HAL_CRYP_FIFO_FLUSH(hcryp
);
822 /* Enable the CRYP peripheral */
823 __HAL_CRYP_ENABLE(hcryp
);
826 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
829 /* Write Plain Data and Get Cypher Data */
830 if(CRYPEx_GCMCCM_ProcessData(hcryp
, pPlainData
, Size
, pCypherData
, Timeout
) != HAL_OK
)
835 /* Change the CRYP peripheral state */
836 hcryp
->State
= HAL_CRYP_STATE_READY
;
838 /* Process Unlocked */
841 /* Return function status */
846 * @brief Initializes the CRYP peripheral in AES GCM decryption mode then
847 * decrypted pCypherData. The cypher data are available in pPlainData.
848 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
849 * the configuration information for CRYP module
850 * @param pCypherData: Pointer to the cyphertext buffer
851 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
852 * @param pPlainData: Pointer to the plaintext buffer
853 * @param Timeout: Timeout duration
856 HAL_StatusTypeDef
HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef
*hcryp
, uint8_t *pCypherData
, uint16_t Size
, uint8_t *pPlainData
, uint32_t Timeout
)
858 uint32_t tickstart
= 0;
863 /* Change the CRYP peripheral state */
864 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
866 /* Check if initialization phase has already been performed */
867 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
870 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
872 /* Set the CRYP peripheral in AES GCM decryption mode */
873 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT
);
875 /* Set the Initialization Vector */
876 CRYPEx_GCMCCM_SetInitVector(hcryp
, hcryp
->Init
.pInitVect
);
879 __HAL_CRYP_FIFO_FLUSH(hcryp
);
881 /* Enable the CRYP peripheral */
882 __HAL_CRYP_ENABLE(hcryp
);
885 tickstart
= HAL_GetTick();
887 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
889 /* Check for the Timeout */
890 if(Timeout
!= HAL_MAX_DELAY
)
892 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
895 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
897 /* Process Unlocked */
905 /* Set the header phase */
906 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp
, hcryp
->Init
.Header
, hcryp
->Init
.HeaderSize
, Timeout
) != HAL_OK
)
910 /* Disable the CRYP peripheral */
911 __HAL_CRYP_DISABLE(hcryp
);
913 /* Select payload phase once the header phase is performed */
914 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
916 /* Enable the CRYP peripheral */
917 __HAL_CRYP_ENABLE(hcryp
);
920 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
923 /* Write Plain Data and Get Cypher Data */
924 if(CRYPEx_GCMCCM_ProcessData(hcryp
, pCypherData
, Size
, pPlainData
, Timeout
) != HAL_OK
)
929 /* Change the CRYP peripheral state */
930 hcryp
->State
= HAL_CRYP_STATE_READY
;
932 /* Process Unlocked */
935 /* Return function status */
940 * @brief Computes the authentication TAG.
941 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
942 * the configuration information for CRYP module
943 * @param Size: Total length of the plain/cyphertext buffer
944 * @param AuthTag: Pointer to the authentication buffer
945 * @param Timeout: Timeout duration
948 HAL_StatusTypeDef
HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef
*hcryp
, uint32_t Size
, uint8_t *AuthTag
, uint32_t Timeout
)
950 uint32_t tickstart
= 0;
951 uint64_t headerlength
= hcryp
->Init
.HeaderSize
* 8; /* Header length in bits */
952 uint64_t inputlength
= Size
* 8; /* input length in bits */
953 uint32_t tagaddr
= (uint32_t)AuthTag
;
958 /* Change the CRYP peripheral state */
959 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
961 /* Check if initialization phase has already been performed */
962 if(hcryp
->Phase
== HAL_CRYP_PHASE_PROCESS
)
964 /* Change the CRYP phase */
965 hcryp
->Phase
= HAL_CRYP_PHASE_FINAL
;
967 /* Disable CRYP to start the final phase */
968 __HAL_CRYP_DISABLE(hcryp
);
970 /* Select final phase */
971 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_FINAL
);
973 /* Enable the CRYP peripheral */
974 __HAL_CRYP_ENABLE(hcryp
);
976 /* Write the number of bits in header (64 bits) followed by the number of bits
978 if(hcryp
->Init
.DataType
== CRYP_DATATYPE_1B
)
980 hcryp
->Instance
->DR
= __RBIT(headerlength
>> 32);
981 hcryp
->Instance
->DR
= __RBIT(headerlength
);
982 hcryp
->Instance
->DR
= __RBIT(inputlength
>> 32);
983 hcryp
->Instance
->DR
= __RBIT(inputlength
);
985 else if(hcryp
->Init
.DataType
== CRYP_DATATYPE_8B
)
987 hcryp
->Instance
->DR
= __REV(headerlength
>> 32);
988 hcryp
->Instance
->DR
= __REV(headerlength
);
989 hcryp
->Instance
->DR
= __REV(inputlength
>> 32);
990 hcryp
->Instance
->DR
= __REV(inputlength
);
992 else if(hcryp
->Init
.DataType
== CRYP_DATATYPE_16B
)
994 hcryp
->Instance
->DR
= __ROR((uint32_t)(headerlength
>> 32), 16);
995 hcryp
->Instance
->DR
= __ROR((uint32_t)headerlength
, 16);
996 hcryp
->Instance
->DR
= __ROR((uint32_t)(inputlength
>> 32), 16);
997 hcryp
->Instance
->DR
= __ROR((uint32_t)inputlength
, 16);
999 else if(hcryp
->Init
.DataType
== CRYP_DATATYPE_32B
)
1001 hcryp
->Instance
->DR
= (uint32_t)(headerlength
>> 32);
1002 hcryp
->Instance
->DR
= (uint32_t)(headerlength
);
1003 hcryp
->Instance
->DR
= (uint32_t)(inputlength
>> 32);
1004 hcryp
->Instance
->DR
= (uint32_t)(inputlength
);
1007 tickstart
= HAL_GetTick();
1009 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_OFNE
))
1011 /* Check for the Timeout */
1012 if(Timeout
!= HAL_MAX_DELAY
)
1014 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1017 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1019 /* Process Unlocked */
1020 __HAL_UNLOCK(hcryp
);
1027 /* Read the Auth TAG in the IN FIFO */
1028 *(uint32_t*)(tagaddr
) = hcryp
->Instance
->DOUT
;
1030 *(uint32_t*)(tagaddr
) = hcryp
->Instance
->DOUT
;
1032 *(uint32_t*)(tagaddr
) = hcryp
->Instance
->DOUT
;
1034 *(uint32_t*)(tagaddr
) = hcryp
->Instance
->DOUT
;
1037 /* Change the CRYP peripheral state */
1038 hcryp
->State
= HAL_CRYP_STATE_READY
;
1040 /* Process Unlocked */
1041 __HAL_UNLOCK(hcryp
);
1043 /* Return function status */
1048 * @brief Computes the authentication TAG for AES CCM mode.
1049 * @note This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt()
1050 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1051 * the configuration information for CRYP module
1052 * @param AuthTag: Pointer to the authentication buffer
1053 * @param Timeout: Timeout duration
1054 * @retval HAL status
1056 HAL_StatusTypeDef
HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef
*hcryp
, uint8_t *AuthTag
, uint32_t Timeout
)
1058 uint32_t tickstart
= 0;
1059 uint32_t tagaddr
= (uint32_t)AuthTag
;
1060 uint32_t ctraddr
= (uint32_t)hcryp
->Init
.pScratch
;
1061 uint32_t temptag
[4] = {0}; /* Temporary TAG (MAC) */
1062 uint32_t loopcounter
;
1064 /* Process Locked */
1067 /* Change the CRYP peripheral state */
1068 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1070 /* Check if initialization phase has already been performed */
1071 if(hcryp
->Phase
== HAL_CRYP_PHASE_PROCESS
)
1073 /* Change the CRYP phase */
1074 hcryp
->Phase
= HAL_CRYP_PHASE_FINAL
;
1076 /* Disable CRYP to start the final phase */
1077 __HAL_CRYP_DISABLE(hcryp
);
1079 /* Select final phase */
1080 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_FINAL
);
1082 /* Enable the CRYP peripheral */
1083 __HAL_CRYP_ENABLE(hcryp
);
1085 /* Write the counter block in the IN FIFO */
1086 hcryp
->Instance
->DR
= *(uint32_t*)ctraddr
;
1088 hcryp
->Instance
->DR
= *(uint32_t*)ctraddr
;
1090 hcryp
->Instance
->DR
= *(uint32_t*)ctraddr
;
1092 hcryp
->Instance
->DR
= *(uint32_t*)ctraddr
;
1095 tickstart
= HAL_GetTick();
1097 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_OFNE
))
1099 /* Check for the Timeout */
1100 if(Timeout
!= HAL_MAX_DELAY
)
1102 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1105 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1107 /* Process Unlocked */
1108 __HAL_UNLOCK(hcryp
);
1115 /* Read the Auth TAG in the IN FIFO */
1116 temptag
[0] = hcryp
->Instance
->DOUT
;
1117 temptag
[1] = hcryp
->Instance
->DOUT
;
1118 temptag
[2] = hcryp
->Instance
->DOUT
;
1119 temptag
[3] = hcryp
->Instance
->DOUT
;
1122 /* Copy temporary authentication TAG in user TAG buffer */
1123 for(loopcounter
= 0; loopcounter
< hcryp
->Init
.TagSize
; loopcounter
++)
1125 /* Set the authentication TAG buffer */
1126 *((uint8_t*)tagaddr
+loopcounter
) = *((uint8_t*)temptag
+loopcounter
);
1129 /* Change the CRYP peripheral state */
1130 hcryp
->State
= HAL_CRYP_STATE_READY
;
1132 /* Process Unlocked */
1133 __HAL_UNLOCK(hcryp
);
1135 /* Return function status */
1140 * @brief Initializes the CRYP peripheral in AES CCM decryption mode then
1141 * decrypted pCypherData. The cypher data are available in pPlainData.
1142 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1143 * the configuration information for CRYP module
1144 * @param pPlainData: Pointer to the plaintext buffer
1145 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1146 * @param pCypherData: Pointer to the cyphertext buffer
1147 * @param Timeout: Timeout duration
1148 * @retval HAL status
1150 HAL_StatusTypeDef
HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef
*hcryp
, uint8_t *pCypherData
, uint16_t Size
, uint8_t *pPlainData
, uint32_t Timeout
)
1152 uint32_t tickstart
= 0;
1153 uint32_t headersize
= hcryp
->Init
.HeaderSize
;
1154 uint32_t headeraddr
= (uint32_t)hcryp
->Init
.Header
;
1155 uint32_t loopcounter
= 0;
1156 uint32_t bufferidx
= 0;
1157 uint8_t blockb0
[16] = {0};/* Block B0 */
1158 uint8_t ctr
[16] = {0}; /* Counter */
1159 uint32_t b0addr
= (uint32_t)blockb0
;
1161 /* Process Locked */
1164 /* Change the CRYP peripheral state */
1165 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1167 /* Check if initialization phase has already been performed */
1168 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
1170 /************************ Formatting the header block *********************/
1173 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1174 if(headersize
< 65280)
1176 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
>> 8) & 0xFFU
);
1177 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
) & 0xFFU
);
1182 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1183 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFFU
;
1184 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFEU
;
1185 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0xff000000U
;
1186 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x00ff0000U
;
1187 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x0000ff00U
;
1188 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x000000ffU
;
1191 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1192 for(loopcounter
= 0; loopcounter
< headersize
; loopcounter
++)
1194 hcryp
->Init
.pScratch
[bufferidx
++] = hcryp
->Init
.Header
[loopcounter
];
1196 /* Check if the header size is modulo 16 */
1197 if ((headersize
% 16) != 0)
1199 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1200 for(loopcounter
= headersize
; loopcounter
<= ((headersize
/16) + 1) * 16; loopcounter
++)
1202 hcryp
->Init
.pScratch
[loopcounter
] = 0;
1204 /* Set the header size to modulo 16 */
1205 headersize
= ((headersize
/16) + 1) * 16;
1207 /* Set the pointer headeraddr to hcryp->Init.pScratch */
1208 headeraddr
= (uint32_t)hcryp
->Init
.pScratch
;
1210 /*********************** Formatting the block B0 **************************/
1216 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
1217 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp
->Init
.TagSize
- (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
1218 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp
->Init
.IVSize
) - (uint8_t)1) & (uint8_t)0x07);
1220 for (loopcounter
= 0; loopcounter
< hcryp
->Init
.IVSize
; loopcounter
++)
1222 blockb0
[loopcounter
+1] = hcryp
->Init
.pInitVect
[loopcounter
];
1224 for ( ; loopcounter
< 13; loopcounter
++)
1226 blockb0
[loopcounter
+1] = 0;
1229 blockb0
[14] = (Size
>> 8);
1230 blockb0
[15] = (Size
& 0xFF);
1232 /************************* Formatting the initial counter *****************/
1234 Bits 7 and 6 are reserved and shall be set to 0
1235 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
1236 blocks are distinct from B0
1237 Bits 0, 1, and 2 contain the same encoding of q as in B0
1239 ctr
[0] = blockb0
[0] & 0x07;
1240 /* byte 1 to NonceSize is the IV (Nonce) */
1241 for(loopcounter
= 1; loopcounter
< hcryp
->Init
.IVSize
+ 1; loopcounter
++)
1243 ctr
[loopcounter
] = blockb0
[loopcounter
];
1245 /* Set the LSB to 1 */
1249 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
1251 /* Set the CRYP peripheral in AES CCM mode */
1252 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT
);
1254 /* Set the Initialization Vector */
1255 CRYPEx_GCMCCM_SetInitVector(hcryp
, ctr
);
1257 /* Select init phase */
1258 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_INIT
);
1260 b0addr
= (uint32_t)blockb0
;
1261 /* Write the blockb0 block in the IN FIFO */
1262 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
1264 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
1266 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
1268 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
1270 /* Enable the CRYP peripheral */
1271 __HAL_CRYP_ENABLE(hcryp
);
1274 tickstart
= HAL_GetTick();
1276 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
1278 /* Check for the Timeout */
1279 if(Timeout
!= HAL_MAX_DELAY
)
1281 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1284 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1286 /* Process Unlocked */
1287 __HAL_UNLOCK(hcryp
);
1293 /***************************** Header phase *******************************/
1296 /* Select header phase */
1297 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_HEADER
);
1299 /* Enable Crypto processor */
1300 __HAL_CRYP_ENABLE(hcryp
);
1302 for(loopcounter
= 0; (loopcounter
< headersize
); loopcounter
+=16)
1305 tickstart
= HAL_GetTick();
1307 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_IFEM
))
1309 /* Check for the Timeout */
1310 if(Timeout
!= HAL_MAX_DELAY
)
1312 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1315 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1317 /* Process Unlocked */
1318 __HAL_UNLOCK(hcryp
);
1324 /* Write the header block in the IN FIFO */
1325 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
1327 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
1329 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
1331 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
1336 tickstart
= HAL_GetTick();
1338 while((hcryp
->Instance
->SR
& CRYP_FLAG_BUSY
) == CRYP_FLAG_BUSY
)
1340 /* Check for the Timeout */
1341 if(Timeout
!= HAL_MAX_DELAY
)
1343 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1346 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1348 /* Process Unlocked */
1349 __HAL_UNLOCK(hcryp
);
1356 /* Save formatted counter into the scratch buffer pScratch */
1357 for(loopcounter
= 0; (loopcounter
< 16); loopcounter
++)
1359 hcryp
->Init
.pScratch
[loopcounter
] = ctr
[loopcounter
];
1362 hcryp
->Init
.pScratch
[15] &= 0xfe;
1363 /* Select payload phase once the header phase is performed */
1364 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
1367 __HAL_CRYP_FIFO_FLUSH(hcryp
);
1369 /* Enable the CRYP peripheral */
1370 __HAL_CRYP_ENABLE(hcryp
);
1373 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
1376 /* Write Plain Data and Get Cypher Data */
1377 if(CRYPEx_GCMCCM_ProcessData(hcryp
, pCypherData
, Size
, pPlainData
, Timeout
) != HAL_OK
)
1382 /* Change the CRYP peripheral state */
1383 hcryp
->State
= HAL_CRYP_STATE_READY
;
1385 /* Process Unlocked */
1386 __HAL_UNLOCK(hcryp
);
1388 /* Return function status */
1393 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using IT.
1394 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1395 * the configuration information for CRYP module
1396 * @param pPlainData: Pointer to the plaintext buffer
1397 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1398 * @param pCypherData: Pointer to the cyphertext buffer
1399 * @retval HAL status
1401 HAL_StatusTypeDef
HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef
*hcryp
, uint8_t *pPlainData
, uint16_t Size
, uint8_t *pCypherData
)
1403 uint32_t tickstart
= 0;
1405 uint32_t outputaddr
;
1407 if(hcryp
->State
== HAL_CRYP_STATE_READY
)
1409 /* Process Locked */
1412 /* Get the buffer addresses and sizes */
1413 hcryp
->CrypInCount
= Size
;
1414 hcryp
->pCrypInBuffPtr
= pPlainData
;
1415 hcryp
->pCrypOutBuffPtr
= pCypherData
;
1416 hcryp
->CrypOutCount
= Size
;
1418 /* Change the CRYP peripheral state */
1419 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1421 /* Check if initialization phase has already been performed */
1422 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
1425 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
1427 /* Set the CRYP peripheral in AES GCM mode */
1428 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT
);
1430 /* Set the Initialization Vector */
1431 CRYPEx_GCMCCM_SetInitVector(hcryp
, hcryp
->Init
.pInitVect
);
1434 __HAL_CRYP_FIFO_FLUSH(hcryp
);
1436 /* Enable CRYP to start the init phase */
1437 __HAL_CRYP_ENABLE(hcryp
);
1440 tickstart
= HAL_GetTick();
1442 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
1444 /* Check for the Timeout */
1446 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
1449 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1451 /* Process Unlocked */
1452 __HAL_UNLOCK(hcryp
);
1459 /* Set the header phase */
1460 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp
, hcryp
->Init
.Header
, hcryp
->Init
.HeaderSize
, 1) != HAL_OK
)
1464 /* Disable the CRYP peripheral */
1465 __HAL_CRYP_DISABLE(hcryp
);
1467 /* Select payload phase once the header phase is performed */
1468 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
1471 __HAL_CRYP_FIFO_FLUSH(hcryp
);
1474 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
1479 /* Enable Interrupts */
1480 __HAL_CRYP_ENABLE_IT(hcryp
, CRYP_IT_INI
| CRYP_IT_OUTI
);
1481 /* Enable the CRYP peripheral */
1482 __HAL_CRYP_ENABLE(hcryp
);
1486 /* Process Locked */
1487 __HAL_UNLOCK(hcryp
);
1488 /* Change the CRYP state and phase */
1489 hcryp
->State
= HAL_CRYP_STATE_READY
;
1491 /* Return function status */
1494 else if (__HAL_CRYP_GET_IT(hcryp
, CRYP_IT_INI
))
1496 inputaddr
= (uint32_t)hcryp
->pCrypInBuffPtr
;
1497 /* Write the Input block in the IN FIFO */
1498 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1500 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1502 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1504 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1505 hcryp
->pCrypInBuffPtr
+= 16;
1506 hcryp
->CrypInCount
-= 16;
1507 if(hcryp
->CrypInCount
== 0)
1509 __HAL_CRYP_DISABLE_IT(hcryp
, CRYP_IT_INI
);
1510 /* Call the Input data transfer complete callback */
1511 HAL_CRYP_InCpltCallback(hcryp
);
1514 else if (__HAL_CRYP_GET_IT(hcryp
, CRYP_IT_OUTI
))
1516 outputaddr
= (uint32_t)hcryp
->pCrypOutBuffPtr
;
1517 /* Read the Output block from the Output FIFO */
1518 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1520 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1522 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1524 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1525 hcryp
->pCrypOutBuffPtr
+= 16;
1526 hcryp
->CrypOutCount
-= 16;
1527 if(hcryp
->CrypOutCount
== 0)
1529 __HAL_CRYP_DISABLE_IT(hcryp
, CRYP_IT_OUTI
);
1530 /* Process Unlocked */
1531 __HAL_UNLOCK(hcryp
);
1532 /* Change the CRYP peripheral state */
1533 hcryp
->State
= HAL_CRYP_STATE_READY
;
1534 /* Call Input transfer complete callback */
1535 HAL_CRYP_OutCpltCallback(hcryp
);
1539 /* Return function status */
1544 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
1545 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1546 * the configuration information for CRYP module
1547 * @param pPlainData: Pointer to the plaintext buffer
1548 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1549 * @param pCypherData: Pointer to the cyphertext buffer
1550 * @retval HAL status
1552 HAL_StatusTypeDef
HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef
*hcryp
, uint8_t *pPlainData
, uint16_t Size
, uint8_t *pCypherData
)
1554 uint32_t tickstart
= 0;
1556 uint32_t outputaddr
;
1558 uint32_t headersize
= hcryp
->Init
.HeaderSize
;
1559 uint32_t headeraddr
= (uint32_t)hcryp
->Init
.Header
;
1560 uint32_t loopcounter
= 0;
1561 uint32_t bufferidx
= 0;
1562 uint8_t blockb0
[16] = {0};/* Block B0 */
1563 uint8_t ctr
[16] = {0}; /* Counter */
1564 uint32_t b0addr
= (uint32_t)blockb0
;
1566 if(hcryp
->State
== HAL_CRYP_STATE_READY
)
1568 /* Process Locked */
1571 hcryp
->CrypInCount
= Size
;
1572 hcryp
->pCrypInBuffPtr
= pPlainData
;
1573 hcryp
->pCrypOutBuffPtr
= pCypherData
;
1574 hcryp
->CrypOutCount
= Size
;
1576 /* Change the CRYP peripheral state */
1577 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1579 /* Check if initialization phase has already been performed */
1580 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
1582 /************************ Formatting the header block *******************/
1585 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1586 if(headersize
< 65280)
1588 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
>> 8) & 0xFFU
);
1589 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
) & 0xFFU
);
1594 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1595 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFFU
;
1596 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFEU
;
1597 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0xff000000U
;
1598 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x00ff0000U
;
1599 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x0000ff00U
;
1600 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x000000ffU
;
1603 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1604 for(loopcounter
= 0; loopcounter
< headersize
; loopcounter
++)
1606 hcryp
->Init
.pScratch
[bufferidx
++] = hcryp
->Init
.Header
[loopcounter
];
1608 /* Check if the header size is modulo 16 */
1609 if ((headersize
% 16) != 0)
1611 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1612 for(loopcounter
= headersize
; loopcounter
<= ((headersize
/16) + 1) * 16; loopcounter
++)
1614 hcryp
->Init
.pScratch
[loopcounter
] = 0;
1616 /* Set the header size to modulo 16 */
1617 headersize
= ((headersize
/16) + 1) * 16;
1619 /* Set the pointer headeraddr to hcryp->Init.pScratch */
1620 headeraddr
= (uint32_t)hcryp
->Init
.pScratch
;
1622 /*********************** Formatting the block B0 ************************/
1628 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
1629 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp
->Init
.TagSize
- (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
1630 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp
->Init
.IVSize
) - (uint8_t)1) & (uint8_t)0x07);
1632 for (loopcounter
= 0; loopcounter
< hcryp
->Init
.IVSize
; loopcounter
++)
1634 blockb0
[loopcounter
+1] = hcryp
->Init
.pInitVect
[loopcounter
];
1636 for ( ; loopcounter
< 13; loopcounter
++)
1638 blockb0
[loopcounter
+1] = 0;
1641 blockb0
[14] = (Size
>> 8);
1642 blockb0
[15] = (Size
& 0xFF);
1644 /************************* Formatting the initial counter ***************/
1646 Bits 7 and 6 are reserved and shall be set to 0
1647 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
1648 blocks are distinct from B0
1649 Bits 0, 1, and 2 contain the same encoding of q as in B0
1651 ctr
[0] = blockb0
[0] & 0x07;
1652 /* byte 1 to NonceSize is the IV (Nonce) */
1653 for(loopcounter
= 1; loopcounter
< hcryp
->Init
.IVSize
+ 1; loopcounter
++)
1655 ctr
[loopcounter
] = blockb0
[loopcounter
];
1657 /* Set the LSB to 1 */
1661 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
1663 /* Set the CRYP peripheral in AES CCM mode */
1664 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT
);
1666 /* Set the Initialization Vector */
1667 CRYPEx_GCMCCM_SetInitVector(hcryp
, ctr
);
1669 /* Select init phase */
1670 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_INIT
);
1672 b0addr
= (uint32_t)blockb0
;
1673 /* Write the blockb0 block in the IN FIFO */
1674 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
1676 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
1678 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
1680 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
1682 /* Enable the CRYP peripheral */
1683 __HAL_CRYP_ENABLE(hcryp
);
1686 tickstart
= HAL_GetTick();
1688 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
1690 /* Check for the Timeout */
1691 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
1694 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1696 /* Process Unlocked */
1697 __HAL_UNLOCK(hcryp
);
1702 /***************************** Header phase *****************************/
1705 /* Select header phase */
1706 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_HEADER
);
1708 /* Enable Crypto processor */
1709 __HAL_CRYP_ENABLE(hcryp
);
1711 for(loopcounter
= 0; (loopcounter
< headersize
); loopcounter
+=16)
1714 tickstart
= HAL_GetTick();
1716 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_IFEM
))
1718 /* Check for the Timeout */
1719 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
1722 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1724 /* Process Unlocked */
1725 __HAL_UNLOCK(hcryp
);
1730 /* Write the header block in the IN FIFO */
1731 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
1733 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
1735 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
1737 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
1742 tickstart
= HAL_GetTick();
1744 while((hcryp
->Instance
->SR
& CRYP_FLAG_BUSY
) == CRYP_FLAG_BUSY
)
1746 /* Check for the Timeout */
1747 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
1750 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1752 /* Process Unlocked */
1753 __HAL_UNLOCK(hcryp
);
1759 /* Save formatted counter into the scratch buffer pScratch */
1760 for(loopcounter
= 0; (loopcounter
< 16); loopcounter
++)
1762 hcryp
->Init
.pScratch
[loopcounter
] = ctr
[loopcounter
];
1765 hcryp
->Init
.pScratch
[15] &= 0xfe;
1767 /* Select payload phase once the header phase is performed */
1768 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
1771 __HAL_CRYP_FIFO_FLUSH(hcryp
);
1774 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
1779 /* Enable Interrupts */
1780 __HAL_CRYP_ENABLE_IT(hcryp
, CRYP_IT_INI
| CRYP_IT_OUTI
);
1781 /* Enable the CRYP peripheral */
1782 __HAL_CRYP_ENABLE(hcryp
);
1786 /* Change the CRYP state and phase */
1787 hcryp
->State
= HAL_CRYP_STATE_READY
;
1790 /* Return function status */
1793 else if (__HAL_CRYP_GET_IT(hcryp
, CRYP_IT_INI
))
1795 inputaddr
= (uint32_t)hcryp
->pCrypInBuffPtr
;
1796 /* Write the Input block in the IN FIFO */
1797 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1799 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1801 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1803 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1804 hcryp
->pCrypInBuffPtr
+= 16;
1805 hcryp
->CrypInCount
-= 16;
1806 if(hcryp
->CrypInCount
== 0)
1808 __HAL_CRYP_DISABLE_IT(hcryp
, CRYP_IT_INI
);
1809 /* Call Input transfer complete callback */
1810 HAL_CRYP_InCpltCallback(hcryp
);
1813 else if (__HAL_CRYP_GET_IT(hcryp
, CRYP_IT_OUTI
))
1815 outputaddr
= (uint32_t)hcryp
->pCrypOutBuffPtr
;
1816 /* Read the Output block from the Output FIFO */
1817 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1819 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1821 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1823 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1824 hcryp
->pCrypOutBuffPtr
+= 16;
1825 hcryp
->CrypOutCount
-= 16;
1826 if(hcryp
->CrypOutCount
== 0)
1828 __HAL_CRYP_DISABLE_IT(hcryp
, CRYP_IT_OUTI
);
1829 /* Process Unlocked */
1830 __HAL_UNLOCK(hcryp
);
1831 /* Change the CRYP peripheral state */
1832 hcryp
->State
= HAL_CRYP_STATE_READY
;
1833 /* Call Input transfer complete callback */
1834 HAL_CRYP_OutCpltCallback(hcryp
);
1838 /* Return function status */
1843 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using IT.
1844 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1845 * the configuration information for CRYP module
1846 * @param pCypherData: Pointer to the cyphertext buffer
1847 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
1848 * @param pPlainData: Pointer to the plaintext buffer
1849 * @retval HAL status
1851 HAL_StatusTypeDef
HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef
*hcryp
, uint8_t *pCypherData
, uint16_t Size
, uint8_t *pPlainData
)
1853 uint32_t tickstart
= 0;
1855 uint32_t outputaddr
;
1857 if(hcryp
->State
== HAL_CRYP_STATE_READY
)
1859 /* Process Locked */
1862 /* Get the buffer addresses and sizes */
1863 hcryp
->CrypInCount
= Size
;
1864 hcryp
->pCrypInBuffPtr
= pCypherData
;
1865 hcryp
->pCrypOutBuffPtr
= pPlainData
;
1866 hcryp
->CrypOutCount
= Size
;
1868 /* Change the CRYP peripheral state */
1869 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1871 /* Check if initialization phase has already been performed */
1872 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
1875 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
1877 /* Set the CRYP peripheral in AES GCM decryption mode */
1878 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT
);
1880 /* Set the Initialization Vector */
1881 CRYPEx_GCMCCM_SetInitVector(hcryp
, hcryp
->Init
.pInitVect
);
1884 __HAL_CRYP_FIFO_FLUSH(hcryp
);
1886 /* Enable CRYP to start the init phase */
1887 __HAL_CRYP_ENABLE(hcryp
);
1890 tickstart
= HAL_GetTick();
1892 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
1894 /* Check for the Timeout */
1895 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
1898 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
1900 /* Process Unlocked */
1901 __HAL_UNLOCK(hcryp
);
1907 /* Set the header phase */
1908 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp
, hcryp
->Init
.Header
, hcryp
->Init
.HeaderSize
, 1) != HAL_OK
)
1912 /* Disable the CRYP peripheral */
1913 __HAL_CRYP_DISABLE(hcryp
);
1915 /* Select payload phase once the header phase is performed */
1916 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
1919 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
1924 /* Enable Interrupts */
1925 __HAL_CRYP_ENABLE_IT(hcryp
, CRYP_IT_INI
| CRYP_IT_OUTI
);
1926 /* Enable the CRYP peripheral */
1927 __HAL_CRYP_ENABLE(hcryp
);
1931 /* Process Locked */
1932 __HAL_UNLOCK(hcryp
);
1933 /* Change the CRYP state and phase */
1934 hcryp
->State
= HAL_CRYP_STATE_READY
;
1937 /* Return function status */
1940 else if (__HAL_CRYP_GET_IT(hcryp
, CRYP_IT_INI
))
1942 inputaddr
= (uint32_t)hcryp
->pCrypInBuffPtr
;
1943 /* Write the Input block in the IN FIFO */
1944 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1946 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1948 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1950 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
1951 hcryp
->pCrypInBuffPtr
+= 16;
1952 hcryp
->CrypInCount
-= 16;
1953 if(hcryp
->CrypInCount
== 0)
1955 __HAL_CRYP_DISABLE_IT(hcryp
, CRYP_IT_INI
);
1956 /* Call the Input data transfer complete callback */
1957 HAL_CRYP_InCpltCallback(hcryp
);
1960 else if (__HAL_CRYP_GET_IT(hcryp
, CRYP_IT_OUTI
))
1962 outputaddr
= (uint32_t)hcryp
->pCrypOutBuffPtr
;
1963 /* Read the Output block from the Output FIFO */
1964 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1966 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1968 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1970 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
1971 hcryp
->pCrypOutBuffPtr
+= 16;
1972 hcryp
->CrypOutCount
-= 16;
1973 if(hcryp
->CrypOutCount
== 0)
1975 __HAL_CRYP_DISABLE_IT(hcryp
, CRYP_IT_OUTI
);
1976 /* Process Unlocked */
1977 __HAL_UNLOCK(hcryp
);
1978 /* Change the CRYP peripheral state */
1979 hcryp
->State
= HAL_CRYP_STATE_READY
;
1980 /* Call Input transfer complete callback */
1981 HAL_CRYP_OutCpltCallback(hcryp
);
1985 /* Return function status */
1990 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using interrupt
1991 * then decrypted pCypherData. The cypher data are available in pPlainData.
1992 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1993 * the configuration information for CRYP module
1994 * @param pCypherData: Pointer to the cyphertext buffer
1995 * @param Size: Length of the plaintext buffer, must be a multiple of 16
1996 * @param pPlainData: Pointer to the plaintext buffer
1997 * @retval HAL status
1999 HAL_StatusTypeDef
HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef
*hcryp
, uint8_t *pCypherData
, uint16_t Size
, uint8_t *pPlainData
)
2002 uint32_t outputaddr
;
2003 uint32_t tickstart
= 0;
2004 uint32_t headersize
= hcryp
->Init
.HeaderSize
;
2005 uint32_t headeraddr
= (uint32_t)hcryp
->Init
.Header
;
2006 uint32_t loopcounter
= 0;
2007 uint32_t bufferidx
= 0;
2008 uint8_t blockb0
[16] = {0};/* Block B0 */
2009 uint8_t ctr
[16] = {0}; /* Counter */
2010 uint32_t b0addr
= (uint32_t)blockb0
;
2012 if(hcryp
->State
== HAL_CRYP_STATE_READY
)
2014 /* Process Locked */
2017 hcryp
->CrypInCount
= Size
;
2018 hcryp
->pCrypInBuffPtr
= pCypherData
;
2019 hcryp
->pCrypOutBuffPtr
= pPlainData
;
2020 hcryp
->CrypOutCount
= Size
;
2022 /* Change the CRYP peripheral state */
2023 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
2025 /* Check if initialization phase has already been performed */
2026 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
2028 /************************ Formatting the header block *******************/
2031 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2032 if(headersize
< 65280)
2034 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
>> 8) & 0xFFU
);
2035 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
) & 0xFFU
);
2040 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2041 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFFU
;
2042 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFEU
;
2043 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0xff000000U
;
2044 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x00ff0000U
;
2045 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x0000ff00U
;
2046 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x000000ffU
;
2049 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2050 for(loopcounter
= 0; loopcounter
< headersize
; loopcounter
++)
2052 hcryp
->Init
.pScratch
[bufferidx
++] = hcryp
->Init
.Header
[loopcounter
];
2054 /* Check if the header size is modulo 16 */
2055 if ((headersize
% 16) != 0)
2057 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2058 for(loopcounter
= headersize
; loopcounter
<= ((headersize
/16) + 1) * 16; loopcounter
++)
2060 hcryp
->Init
.pScratch
[loopcounter
] = 0;
2062 /* Set the header size to modulo 16 */
2063 headersize
= ((headersize
/16) + 1) * 16;
2065 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2066 headeraddr
= (uint32_t)hcryp
->Init
.pScratch
;
2068 /*********************** Formatting the block B0 ************************/
2074 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2075 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp
->Init
.TagSize
- (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2076 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp
->Init
.IVSize
) - (uint8_t)1) & (uint8_t)0x07);
2078 for (loopcounter
= 0; loopcounter
< hcryp
->Init
.IVSize
; loopcounter
++)
2080 blockb0
[loopcounter
+1] = hcryp
->Init
.pInitVect
[loopcounter
];
2082 for ( ; loopcounter
< 13; loopcounter
++)
2084 blockb0
[loopcounter
+1] = 0;
2087 blockb0
[14] = (Size
>> 8);
2088 blockb0
[15] = (Size
& 0xFF);
2090 /************************* Formatting the initial counter ***************/
2092 Bits 7 and 6 are reserved and shall be set to 0
2093 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2094 blocks are distinct from B0
2095 Bits 0, 1, and 2 contain the same encoding of q as in B0
2097 ctr
[0] = blockb0
[0] & 0x07;
2098 /* byte 1 to NonceSize is the IV (Nonce) */
2099 for(loopcounter
= 1; loopcounter
< hcryp
->Init
.IVSize
+ 1; loopcounter
++)
2101 ctr
[loopcounter
] = blockb0
[loopcounter
];
2103 /* Set the LSB to 1 */
2107 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
2109 /* Set the CRYP peripheral in AES CCM mode */
2110 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT
);
2112 /* Set the Initialization Vector */
2113 CRYPEx_GCMCCM_SetInitVector(hcryp
, ctr
);
2115 /* Select init phase */
2116 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_INIT
);
2118 b0addr
= (uint32_t)blockb0
;
2119 /* Write the blockb0 block in the IN FIFO */
2120 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2122 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2124 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2126 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2128 /* Enable the CRYP peripheral */
2129 __HAL_CRYP_ENABLE(hcryp
);
2132 tickstart
= HAL_GetTick();
2134 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
2136 /* Check for the Timeout */
2137 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2140 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2142 /* Process Unlocked */
2143 __HAL_UNLOCK(hcryp
);
2148 /***************************** Header phase *****************************/
2151 /* Select header phase */
2152 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_HEADER
);
2154 /* Enable Crypto processor */
2155 __HAL_CRYP_ENABLE(hcryp
);
2157 for(loopcounter
= 0; (loopcounter
< headersize
); loopcounter
+=16)
2160 tickstart
= HAL_GetTick();
2162 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_IFEM
))
2164 /* Check for the Timeout */
2165 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2168 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2170 /* Process Unlocked */
2171 __HAL_UNLOCK(hcryp
);
2176 /* Write the header block in the IN FIFO */
2177 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2179 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2181 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2183 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2188 tickstart
= HAL_GetTick();
2190 while((hcryp
->Instance
->SR
& CRYP_FLAG_BUSY
) == CRYP_FLAG_BUSY
)
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
);
2205 /* Save formatted counter into the scratch buffer pScratch */
2206 for(loopcounter
= 0; (loopcounter
< 16); loopcounter
++)
2208 hcryp
->Init
.pScratch
[loopcounter
] = ctr
[loopcounter
];
2211 hcryp
->Init
.pScratch
[15] &= 0xfe;
2212 /* Select payload phase once the header phase is performed */
2213 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
2216 __HAL_CRYP_FIFO_FLUSH(hcryp
);
2219 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
2222 /* Enable Interrupts */
2223 __HAL_CRYP_ENABLE_IT(hcryp
, CRYP_IT_INI
| CRYP_IT_OUTI
);
2225 /* Enable the CRYP peripheral */
2226 __HAL_CRYP_ENABLE(hcryp
);
2228 /* Return function status */
2231 else if (__HAL_CRYP_GET_IT(hcryp
, CRYP_IT_INI
))
2233 inputaddr
= (uint32_t)hcryp
->pCrypInBuffPtr
;
2234 /* Write the Input block in the IN FIFO */
2235 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
2237 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
2239 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
2241 hcryp
->Instance
->DR
= *(uint32_t*)(inputaddr
);
2242 hcryp
->pCrypInBuffPtr
+= 16;
2243 hcryp
->CrypInCount
-= 16;
2244 if(hcryp
->CrypInCount
== 0)
2246 __HAL_CRYP_DISABLE_IT(hcryp
, CRYP_IT_INI
);
2247 /* Call the Input data transfer complete callback */
2248 HAL_CRYP_InCpltCallback(hcryp
);
2251 else if (__HAL_CRYP_GET_IT(hcryp
, CRYP_IT_OUTI
))
2253 outputaddr
= (uint32_t)hcryp
->pCrypOutBuffPtr
;
2254 /* Read the Output block from the Output FIFO */
2255 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
2257 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
2259 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
2261 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->DOUT
;
2262 hcryp
->pCrypOutBuffPtr
+= 16;
2263 hcryp
->CrypOutCount
-= 16;
2264 if(hcryp
->CrypOutCount
== 0)
2266 __HAL_CRYP_DISABLE_IT(hcryp
, CRYP_IT_OUTI
);
2267 /* Process Unlocked */
2268 __HAL_UNLOCK(hcryp
);
2269 /* Change the CRYP peripheral state */
2270 hcryp
->State
= HAL_CRYP_STATE_READY
;
2271 /* Call Input transfer complete callback */
2272 HAL_CRYP_OutCpltCallback(hcryp
);
2276 /* Return function status */
2281 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using DMA.
2282 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2283 * the configuration information for CRYP module
2284 * @param pPlainData: Pointer to the plaintext buffer
2285 * @param Size: Length of the plaintext buffer, must be a multiple of 16
2286 * @param pCypherData: Pointer to the cyphertext buffer
2287 * @retval HAL status
2289 HAL_StatusTypeDef
HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef
*hcryp
, uint8_t *pPlainData
, uint16_t Size
, uint8_t *pCypherData
)
2291 uint32_t tickstart
= 0;
2293 uint32_t outputaddr
;
2295 if((hcryp
->State
== HAL_CRYP_STATE_READY
) || (hcryp
->Phase
== HAL_CRYP_PHASE_PROCESS
))
2297 /* Process Locked */
2300 inputaddr
= (uint32_t)pPlainData
;
2301 outputaddr
= (uint32_t)pCypherData
;
2303 /* Change the CRYP peripheral state */
2304 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
2306 /* Check if initialization phase has already been performed */
2307 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
2310 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
2312 /* Set the CRYP peripheral in AES GCM mode */
2313 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT
);
2315 /* Set the Initialization Vector */
2316 CRYPEx_GCMCCM_SetInitVector(hcryp
, hcryp
->Init
.pInitVect
);
2319 __HAL_CRYP_FIFO_FLUSH(hcryp
);
2321 /* Enable CRYP to start the init phase */
2322 __HAL_CRYP_ENABLE(hcryp
);
2325 tickstart
= HAL_GetTick();
2327 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
2329 /* Check for the Timeout */
2330 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2333 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2335 /* Process Unlocked */
2336 __HAL_UNLOCK(hcryp
);
2342 __HAL_CRYP_FIFO_FLUSH(hcryp
);
2344 /* Set the header phase */
2345 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp
, hcryp
->Init
.Header
, hcryp
->Init
.HeaderSize
, 1) != HAL_OK
)
2349 /* Disable the CRYP peripheral */
2350 __HAL_CRYP_DISABLE(hcryp
);
2352 /* Select payload phase once the header phase is performed */
2353 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
2356 __HAL_CRYP_FIFO_FLUSH(hcryp
);
2359 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
2362 /* Set the input and output addresses and start DMA transfer */
2363 CRYPEx_GCMCCM_SetDMAConfig(hcryp
, inputaddr
, Size
, outputaddr
);
2365 /* Unlock process */
2366 __HAL_UNLOCK(hcryp
);
2368 /* Return function status */
2378 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
2379 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2380 * the configuration information for CRYP module
2381 * @param pPlainData: Pointer to the plaintext buffer
2382 * @param Size: Length of the plaintext buffer, must be a multiple of 16
2383 * @param pCypherData: Pointer to the cyphertext buffer
2384 * @retval HAL status
2386 HAL_StatusTypeDef
HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef
*hcryp
, uint8_t *pPlainData
, uint16_t Size
, uint8_t *pCypherData
)
2388 uint32_t tickstart
= 0;
2390 uint32_t outputaddr
;
2391 uint32_t headersize
;
2392 uint32_t headeraddr
;
2393 uint32_t loopcounter
= 0;
2394 uint32_t bufferidx
= 0;
2395 uint8_t blockb0
[16] = {0};/* Block B0 */
2396 uint8_t ctr
[16] = {0}; /* Counter */
2397 uint32_t b0addr
= (uint32_t)blockb0
;
2399 if((hcryp
->State
== HAL_CRYP_STATE_READY
) || (hcryp
->Phase
== HAL_CRYP_PHASE_PROCESS
))
2401 /* Process Locked */
2404 inputaddr
= (uint32_t)pPlainData
;
2405 outputaddr
= (uint32_t)pCypherData
;
2407 headersize
= hcryp
->Init
.HeaderSize
;
2408 headeraddr
= (uint32_t)hcryp
->Init
.Header
;
2410 hcryp
->CrypInCount
= Size
;
2411 hcryp
->pCrypInBuffPtr
= pPlainData
;
2412 hcryp
->pCrypOutBuffPtr
= pCypherData
;
2413 hcryp
->CrypOutCount
= Size
;
2415 /* Change the CRYP peripheral state */
2416 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
2418 /* Check if initialization phase has already been performed */
2419 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
2421 /************************ Formatting the header block *******************/
2424 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2425 if(headersize
< 65280)
2427 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
>> 8) & 0xFFU
);
2428 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
) & 0xFFU
);
2433 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2434 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFFU
;
2435 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFEU
;
2436 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0xff000000U
;
2437 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x00ff0000U
;
2438 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x0000ff00U
;
2439 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x000000ffU
;
2442 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2443 for(loopcounter
= 0; loopcounter
< headersize
; loopcounter
++)
2445 hcryp
->Init
.pScratch
[bufferidx
++] = hcryp
->Init
.Header
[loopcounter
];
2447 /* Check if the header size is modulo 16 */
2448 if ((headersize
% 16) != 0)
2450 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2451 for(loopcounter
= headersize
; loopcounter
<= ((headersize
/16) + 1) * 16; loopcounter
++)
2453 hcryp
->Init
.pScratch
[loopcounter
] = 0;
2455 /* Set the header size to modulo 16 */
2456 headersize
= ((headersize
/16) + 1) * 16;
2458 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2459 headeraddr
= (uint32_t)hcryp
->Init
.pScratch
;
2461 /*********************** Formatting the block B0 ************************/
2467 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2468 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp
->Init
.TagSize
- (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2469 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp
->Init
.IVSize
) - (uint8_t)1) & (uint8_t)0x07);
2471 for (loopcounter
= 0; loopcounter
< hcryp
->Init
.IVSize
; loopcounter
++)
2473 blockb0
[loopcounter
+1] = hcryp
->Init
.pInitVect
[loopcounter
];
2475 for ( ; loopcounter
< 13; loopcounter
++)
2477 blockb0
[loopcounter
+1] = 0;
2480 blockb0
[14] = (Size
>> 8);
2481 blockb0
[15] = (Size
& 0xFF);
2483 /************************* Formatting the initial counter ***************/
2485 Bits 7 and 6 are reserved and shall be set to 0
2486 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2487 blocks are distinct from B0
2488 Bits 0, 1, and 2 contain the same encoding of q as in B0
2490 ctr
[0] = blockb0
[0] & 0x07;
2491 /* byte 1 to NonceSize is the IV (Nonce) */
2492 for(loopcounter
= 1; loopcounter
< hcryp
->Init
.IVSize
+ 1; loopcounter
++)
2494 ctr
[loopcounter
] = blockb0
[loopcounter
];
2496 /* Set the LSB to 1 */
2500 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
2502 /* Set the CRYP peripheral in AES CCM mode */
2503 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT
);
2505 /* Set the Initialization Vector */
2506 CRYPEx_GCMCCM_SetInitVector(hcryp
, ctr
);
2508 /* Select init phase */
2509 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_INIT
);
2511 b0addr
= (uint32_t)blockb0
;
2512 /* Write the blockb0 block in the IN FIFO */
2513 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2515 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2517 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2519 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2521 /* Enable the CRYP peripheral */
2522 __HAL_CRYP_ENABLE(hcryp
);
2525 tickstart
= HAL_GetTick();
2527 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
2529 /* Check for the Timeout */
2530 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2533 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2535 /* Process Unlocked */
2536 __HAL_UNLOCK(hcryp
);
2541 /***************************** Header phase *****************************/
2544 /* Select header phase */
2545 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_HEADER
);
2547 /* Enable Crypto processor */
2548 __HAL_CRYP_ENABLE(hcryp
);
2550 for(loopcounter
= 0; (loopcounter
< headersize
); loopcounter
+=16)
2553 tickstart
= HAL_GetTick();
2555 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_IFEM
))
2557 /* Check for the Timeout */
2558 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2561 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2563 /* Process Unlocked */
2564 __HAL_UNLOCK(hcryp
);
2569 /* Write the header block in the IN FIFO */
2570 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2572 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2574 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2576 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2581 tickstart
= HAL_GetTick();
2583 while((hcryp
->Instance
->SR
& CRYP_FLAG_BUSY
) == CRYP_FLAG_BUSY
)
2585 /* Check for the Timeout */
2586 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2589 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2591 /* Process Unlocked */
2592 __HAL_UNLOCK(hcryp
);
2598 /* Save formatted counter into the scratch buffer pScratch */
2599 for(loopcounter
= 0; (loopcounter
< 16); loopcounter
++)
2601 hcryp
->Init
.pScratch
[loopcounter
] = ctr
[loopcounter
];
2604 hcryp
->Init
.pScratch
[15] &= 0xfe;
2606 /* Select payload phase once the header phase is performed */
2607 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
2610 __HAL_CRYP_FIFO_FLUSH(hcryp
);
2613 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
2616 /* Set the input and output addresses and start DMA transfer */
2617 CRYPEx_GCMCCM_SetDMAConfig(hcryp
, inputaddr
, Size
, outputaddr
);
2619 /* Unlock process */
2620 __HAL_UNLOCK(hcryp
);
2622 /* Return function status */
2632 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using DMA.
2633 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2634 * the configuration information for CRYP module
2635 * @param pCypherData: Pointer to the cyphertext buffer.
2636 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
2637 * @param pPlainData: Pointer to the plaintext buffer
2638 * @retval HAL status
2640 HAL_StatusTypeDef
HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef
*hcryp
, uint8_t *pCypherData
, uint16_t Size
, uint8_t *pPlainData
)
2642 uint32_t tickstart
= 0;
2644 uint32_t outputaddr
;
2646 if((hcryp
->State
== HAL_CRYP_STATE_READY
) || (hcryp
->Phase
== HAL_CRYP_PHASE_PROCESS
))
2648 /* Process Locked */
2651 inputaddr
= (uint32_t)pCypherData
;
2652 outputaddr
= (uint32_t)pPlainData
;
2654 /* Change the CRYP peripheral state */
2655 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
2657 /* Check if initialization phase has already been performed */
2658 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
2661 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
2663 /* Set the CRYP peripheral in AES GCM decryption mode */
2664 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT
);
2666 /* Set the Initialization Vector */
2667 CRYPEx_GCMCCM_SetInitVector(hcryp
, hcryp
->Init
.pInitVect
);
2669 /* Enable CRYP to start the init phase */
2670 __HAL_CRYP_ENABLE(hcryp
);
2673 tickstart
= HAL_GetTick();
2675 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
2677 /* Check for the Timeout */
2678 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2681 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2683 /* Process Unlocked */
2684 __HAL_UNLOCK(hcryp
);
2690 /* Set the header phase */
2691 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp
, hcryp
->Init
.Header
, hcryp
->Init
.HeaderSize
, 1) != HAL_OK
)
2695 /* Disable the CRYP peripheral */
2696 __HAL_CRYP_DISABLE(hcryp
);
2698 /* Select payload phase once the header phase is performed */
2699 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
2702 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
2705 /* Set the input and output addresses and start DMA transfer */
2706 CRYPEx_GCMCCM_SetDMAConfig(hcryp
, inputaddr
, Size
, outputaddr
);
2708 /* Unlock process */
2709 __HAL_UNLOCK(hcryp
);
2711 /* Return function status */
2721 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using DMA
2722 * then decrypted pCypherData. The cypher data are available in pPlainData.
2723 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2724 * the configuration information for CRYP module
2725 * @param pCypherData: Pointer to the cyphertext buffer
2726 * @param Size: Length of the plaintext buffer, must be a multiple of 16
2727 * @param pPlainData: Pointer to the plaintext buffer
2728 * @retval HAL status
2730 HAL_StatusTypeDef
HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef
*hcryp
, uint8_t *pCypherData
, uint16_t Size
, uint8_t *pPlainData
)
2732 uint32_t tickstart
= 0;
2734 uint32_t outputaddr
;
2735 uint32_t headersize
;
2736 uint32_t headeraddr
;
2737 uint32_t loopcounter
= 0;
2738 uint32_t bufferidx
= 0;
2739 uint8_t blockb0
[16] = {0};/* Block B0 */
2740 uint8_t ctr
[16] = {0}; /* Counter */
2741 uint32_t b0addr
= (uint32_t)blockb0
;
2743 if((hcryp
->State
== HAL_CRYP_STATE_READY
) || (hcryp
->Phase
== HAL_CRYP_PHASE_PROCESS
))
2745 /* Process Locked */
2748 inputaddr
= (uint32_t)pCypherData
;
2749 outputaddr
= (uint32_t)pPlainData
;
2751 headersize
= hcryp
->Init
.HeaderSize
;
2752 headeraddr
= (uint32_t)hcryp
->Init
.Header
;
2754 hcryp
->CrypInCount
= Size
;
2755 hcryp
->pCrypInBuffPtr
= pCypherData
;
2756 hcryp
->pCrypOutBuffPtr
= pPlainData
;
2757 hcryp
->CrypOutCount
= Size
;
2759 /* Change the CRYP peripheral state */
2760 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
2762 /* Check if initialization phase has already been performed */
2763 if(hcryp
->Phase
== HAL_CRYP_PHASE_READY
)
2765 /************************ Formatting the header block *******************/
2768 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2769 if(headersize
< 65280)
2771 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
>> 8) & 0xFFU
);
2772 hcryp
->Init
.pScratch
[bufferidx
++] = (uint8_t) ((headersize
) & 0xFFU
);
2777 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2778 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFFU
;
2779 hcryp
->Init
.pScratch
[bufferidx
++] = 0xFEU
;
2780 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0xff000000U
;
2781 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x00ff0000U
;
2782 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x0000ff00U
;
2783 hcryp
->Init
.pScratch
[bufferidx
++] = headersize
& 0x000000ffU
;
2786 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2787 for(loopcounter
= 0; loopcounter
< headersize
; loopcounter
++)
2789 hcryp
->Init
.pScratch
[bufferidx
++] = hcryp
->Init
.Header
[loopcounter
];
2791 /* Check if the header size is modulo 16 */
2792 if ((headersize
% 16) != 0)
2794 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2795 for(loopcounter
= headersize
; loopcounter
<= ((headersize
/16) + 1) * 16; loopcounter
++)
2797 hcryp
->Init
.pScratch
[loopcounter
] = 0;
2799 /* Set the header size to modulo 16 */
2800 headersize
= ((headersize
/16) + 1) * 16;
2802 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2803 headeraddr
= (uint32_t)hcryp
->Init
.pScratch
;
2805 /*********************** Formatting the block B0 ************************/
2811 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
2812 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp
->Init
.TagSize
- (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
2813 blockb0
[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp
->Init
.IVSize
) - (uint8_t)1) & (uint8_t)0x07);
2815 for (loopcounter
= 0; loopcounter
< hcryp
->Init
.IVSize
; loopcounter
++)
2817 blockb0
[loopcounter
+1] = hcryp
->Init
.pInitVect
[loopcounter
];
2819 for ( ; loopcounter
< 13; loopcounter
++)
2821 blockb0
[loopcounter
+1] = 0;
2824 blockb0
[14] = (Size
>> 8);
2825 blockb0
[15] = (Size
& 0xFF);
2827 /************************* Formatting the initial counter ***************/
2829 Bits 7 and 6 are reserved and shall be set to 0
2830 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2831 blocks are distinct from B0
2832 Bits 0, 1, and 2 contain the same encoding of q as in B0
2834 ctr
[0] = blockb0
[0] & 0x07;
2835 /* byte 1 to NonceSize is the IV (Nonce) */
2836 for(loopcounter
= 1; loopcounter
< hcryp
->Init
.IVSize
+ 1; loopcounter
++)
2838 ctr
[loopcounter
] = blockb0
[loopcounter
];
2840 /* Set the LSB to 1 */
2844 CRYPEx_GCMCCM_SetKey(hcryp
, hcryp
->Init
.pKey
, hcryp
->Init
.KeySize
);
2846 /* Set the CRYP peripheral in AES CCM mode */
2847 __HAL_CRYP_SET_MODE(hcryp
, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT
);
2849 /* Set the Initialization Vector */
2850 CRYPEx_GCMCCM_SetInitVector(hcryp
, ctr
);
2852 /* Select init phase */
2853 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_INIT
);
2855 b0addr
= (uint32_t)blockb0
;
2856 /* Write the blockb0 block in the IN FIFO */
2857 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2859 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2861 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2863 hcryp
->Instance
->DR
= *(uint32_t*)(b0addr
);
2865 /* Enable the CRYP peripheral */
2866 __HAL_CRYP_ENABLE(hcryp
);
2869 tickstart
= HAL_GetTick();
2871 while((CRYP
->CR
& CRYP_CR_CRYPEN
) == CRYP_CR_CRYPEN
)
2873 /* Check for the Timeout */
2875 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2878 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2880 /* Process Unlocked */
2881 __HAL_UNLOCK(hcryp
);
2887 /***************************** Header phase *****************************/
2890 /* Select header phase */
2891 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_HEADER
);
2893 /* Enable Crypto processor */
2894 __HAL_CRYP_ENABLE(hcryp
);
2896 for(loopcounter
= 0; (loopcounter
< headersize
); loopcounter
+=16)
2899 tickstart
= HAL_GetTick();
2901 while(HAL_IS_BIT_CLR(hcryp
->Instance
->SR
, CRYP_FLAG_IFEM
))
2903 /* Check for the Timeout */
2904 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2907 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2909 /* Process Unlocked */
2910 __HAL_UNLOCK(hcryp
);
2915 /* Write the header block in the IN FIFO */
2916 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2918 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2920 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2922 hcryp
->Instance
->DR
= *(uint32_t*)(headeraddr
);
2927 tickstart
= HAL_GetTick();
2929 while((hcryp
->Instance
->SR
& CRYP_FLAG_BUSY
) == CRYP_FLAG_BUSY
)
2931 /* Check for the Timeout */
2932 if((HAL_GetTick() - tickstart
) > CRYPEx_TIMEOUT_VALUE
)
2935 hcryp
->State
= HAL_CRYP_STATE_TIMEOUT
;
2937 /* Process Unlocked */
2938 __HAL_UNLOCK(hcryp
);
2944 /* Save formatted counter into the scratch buffer pScratch */
2945 for(loopcounter
= 0; (loopcounter
< 16); loopcounter
++)
2947 hcryp
->Init
.pScratch
[loopcounter
] = ctr
[loopcounter
];
2950 hcryp
->Init
.pScratch
[15] &= 0xfe;
2951 /* Select payload phase once the header phase is performed */
2952 __HAL_CRYP_SET_PHASE(hcryp
, CRYP_PHASE_PAYLOAD
);
2955 __HAL_CRYP_FIFO_FLUSH(hcryp
);
2958 hcryp
->Phase
= HAL_CRYP_PHASE_PROCESS
;
2960 /* Set the input and output addresses and start DMA transfer */
2961 CRYPEx_GCMCCM_SetDMAConfig(hcryp
, inputaddr
, Size
, outputaddr
);
2963 /* Unlock process */
2964 __HAL_UNLOCK(hcryp
);
2966 /* Return function status */
2979 /** @defgroup CRYPEx_Exported_Functions_Group2 CRYPEx IRQ handler management
2980 * @brief CRYPEx IRQ handler.
2983 ==============================================================================
2984 ##### CRYPEx IRQ handler management #####
2985 ==============================================================================
2986 [..] This section provides CRYPEx IRQ handler function.
2993 * @brief This function handles CRYPEx interrupt request.
2994 * @param hcryp: pointer to a CRYPEx_HandleTypeDef structure that contains
2995 * the configuration information for CRYP module
2998 void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef
*hcryp
)
3000 switch(CRYP
->CR
& CRYP_CR_ALGOMODE_DIRECTION
)
3002 case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT
:
3003 HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp
, NULL
, 0, NULL
);
3006 case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT
:
3007 HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp
, NULL
, 0, NULL
);
3010 case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT
:
3011 HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp
, NULL
, 0, NULL
);
3014 case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT
:
3015 HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp
, NULL
, 0, NULL
);
3030 #endif /* HAL_CRYP_MODULE_ENABLED */
3035 #endif /* STM32F756xx || STM32F777xx || STM32F779xx */
3040 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/