comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c @ 128:c78bcbd5deda FlipDisplay

Added current STM32 standandard libraries in version independend folder structure
author Ideenmodellierer
date Sun, 17 Feb 2019 21:12:22 +0100
parents
children
comparison
equal deleted inserted replaced
127:1369f8660eaa 128:c78bcbd5deda
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_cryp_ex.c
4 * @author MCD Application Team
5 * @brief Extended CRYP HAL module driver
6 * This file provides firmware functions to manage the following
7 * functionalities of CRYP extension peripheral:
8 * + Extended AES processing functions
9 *
10 @verbatim
11 ==============================================================================
12 ##### How to use this driver #####
13 ==============================================================================
14 [..]
15 The CRYP Extension HAL driver can be used as follows:
16 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
17 (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
18 (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT())
19 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
20 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
21 (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
22 (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA())
23 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
24 (+++) Configure and enable two DMA streams one for managing data transfer from
25 memory to peripheral (input stream) and another stream for managing data
26 transfer from peripheral to memory (output stream)
27 (+++) Associate the initialized DMA handle to the CRYP DMA handle
28 using __HAL_LINKDMA()
29 (+++) Configure the priority and enable the NVIC for the transfer complete
30 interrupt on the two DMA Streams. The output stream should have higher
31 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
32 (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly:
33 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit
34 (##) The key size: 128, 192 and 256. This parameter is relevant only for AES
35 (##) The encryption/decryption key. Its size depends on the algorithm
36 used for encryption/decryption
37 (##) The initialization vector (counter). It is not used ECB mode.
38 (#)Three processing (encryption/decryption) functions are available:
39 (##) Polling mode: encryption and decryption APIs are blocking functions
40 i.e. they process the data and wait till the processing is finished
41 e.g. HAL_CRYPEx_AESGCM_Encrypt()
42 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
43 i.e. they process the data under interrupt
44 e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()
45 (##) DMA mode: encryption and decryption APIs are not blocking functions
46 i.e. the data transfer is ensured by DMA
47 e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA()
48 (#)When the processing function is called at first time after HAL_CRYP_Init()
49 the CRYP peripheral is initialized and processes the buffer in input.
50 At second call, the processing function performs an append of the already
51 processed buffer.
52 When a new data block is to be processed, call HAL_CRYP_Init() then the
53 processing function.
54 (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms
55 which provide authentication messages.
56 HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those
57 authentication messages.
58 Call those functions after the processing ones (polling, interrupt or DMA).
59 e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data
60 then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message
61 -@- For CCM Encrypt/Decrypt API's, only DataType = 8-bit is supported by this version.
62 -@- The HAL_CRYPEx_AESGCM_xxxx() implementation is limited to 32bits inputs data length
63 (Plain/Cyphertext, Header) compared with GCM standards specifications (800-38D).
64 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
65
66 @endverbatim
67 ******************************************************************************
68 * @attention
69 *
70 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
71 *
72 * Redistribution and use in source and binary forms, with or without modification,
73 * are permitted provided that the following conditions are met:
74 * 1. Redistributions of source code must retain the above copyright notice,
75 * this list of conditions and the following disclaimer.
76 * 2. Redistributions in binary form must reproduce the above copyright notice,
77 * this list of conditions and the following disclaimer in the documentation
78 * and/or other materials provided with the distribution.
79 * 3. Neither the name of STMicroelectronics nor the names of its contributors
80 * may be used to endorse or promote products derived from this software
81 * without specific prior written permission.
82 *
83 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
84 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
85 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
86 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
87 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
88 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
89 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
90 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
91 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
92 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93 *
94 ******************************************************************************
95 */
96
97 /* Includes ------------------------------------------------------------------*/
98 #include "stm32f4xx_hal.h"
99
100 /** @addtogroup STM32F4xx_HAL_Driver
101 * @{
102 */
103
104 /** @defgroup CRYPEx CRYPEx
105 * @brief CRYP Extension HAL module driver.
106 * @{
107 */
108
109 #ifdef HAL_CRYP_MODULE_ENABLED
110
111 #if defined(CRYP)
112
113 /* Private typedef -----------------------------------------------------------*/
114 /* Private define ------------------------------------------------------------*/
115 /** @addtogroup CRYPEx_Private_define
116 * @{
117 */
118 #define CRYPEx_TIMEOUT_VALUE 1U
119 /**
120 * @}
121 */
122
123 /* Private macro -------------------------------------------------------------*/
124 /* Private variables ---------------------------------------------------------*/
125 /* Private function prototypes -----------------------------------------------*/
126 /** @defgroup CRYPEx_Private_Functions_prototypes CRYP Private Functions Prototypes
127 * @{
128 */
129 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector);
130 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize);
131 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout);
132 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout);
133 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma);
134 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma);
135 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma);
136 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
137 /**
138 * @}
139 */
140
141 /* Private functions ---------------------------------------------------------*/
142 /** @addtogroup CRYPEx_Private_Functions
143 * @{
144 */
145
146 /**
147 * @brief DMA CRYP Input Data process complete callback.
148 * @param hdma DMA handle
149 * @retval None
150 */
151 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma)
152 {
153 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
154
155 /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit
156 in the DMACR register */
157 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
158
159 /* Call input data transfer complete callback */
160 HAL_CRYP_InCpltCallback(hcryp);
161 }
162
163 /**
164 * @brief DMA CRYP Output Data process complete callback.
165 * @param hdma DMA handle
166 * @retval None
167 */
168 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma)
169 {
170 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
171
172 /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit
173 in the DMACR register */
174 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
175
176 /* Enable the CRYP peripheral */
177 __HAL_CRYP_DISABLE(hcryp);
178
179 /* Change the CRYP peripheral state */
180 hcryp->State = HAL_CRYP_STATE_READY;
181
182 /* Call output data transfer complete callback */
183 HAL_CRYP_OutCpltCallback(hcryp);
184 }
185
186 /**
187 * @brief DMA CRYP communication error callback.
188 * @param hdma DMA handle
189 * @retval None
190 */
191 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma)
192 {
193 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
194 hcryp->State= HAL_CRYP_STATE_READY;
195 HAL_CRYP_ErrorCallback(hcryp);
196 }
197
198 /**
199 * @brief Writes the Key in Key registers.
200 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
201 * the configuration information for CRYP module
202 * @param Key Pointer to Key buffer
203 * @param KeySize Size of Key
204 * @retval None
205 */
206 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize)
207 {
208 uint32_t keyaddr = (uint32_t)Key;
209
210 switch(KeySize)
211 {
212 case CRYP_KEYSIZE_256B:
213 /* Key Initialisation */
214 hcryp->Instance->K0LR = __REV(*(uint32_t*)(keyaddr));
215 keyaddr+=4U;
216 hcryp->Instance->K0RR = __REV(*(uint32_t*)(keyaddr));
217 keyaddr+=4U;
218 hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
219 keyaddr+=4U;
220 hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
221 keyaddr+=4U;
222 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
223 keyaddr+=4U;
224 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
225 keyaddr+=4U;
226 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
227 keyaddr+=4U;
228 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
229 break;
230 case CRYP_KEYSIZE_192B:
231 hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
232 keyaddr+=4U;
233 hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
234 keyaddr+=4U;
235 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
236 keyaddr+=4U;
237 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
238 keyaddr+=4U;
239 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
240 keyaddr+=4U;
241 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
242 break;
243 case CRYP_KEYSIZE_128B:
244 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
245 keyaddr+=4U;
246 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
247 keyaddr+=4U;
248 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
249 keyaddr+=4U;
250 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
251 break;
252 default:
253 break;
254 }
255 }
256
257 /**
258 * @brief Writes the InitVector/InitCounter in IV registers.
259 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
260 * the configuration information for CRYP module
261 * @param InitVector Pointer to InitVector/InitCounter buffer
262 * @retval None
263 */
264 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector)
265 {
266 uint32_t ivaddr = (uint32_t)InitVector;
267
268 hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr));
269 ivaddr+=4U;
270 hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr));
271 ivaddr+=4U;
272 hcryp->Instance->IV1LR = __REV(*(uint32_t*)(ivaddr));
273 ivaddr+=4U;
274 hcryp->Instance->IV1RR = __REV(*(uint32_t*)(ivaddr));
275 }
276
277 /**
278 * @brief Process Data: Writes Input data in polling mode and read the Output data.
279 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
280 * the configuration information for CRYP module
281 * @param Input Pointer to the Input buffer.
282 * @param Ilength Length of the Input buffer, must be a multiple of 16
283 * @param Output Pointer to the returned buffer
284 * @param Timeout Timeout value
285 * @retval None
286 */
287 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout)
288 {
289 uint32_t tickstart = 0U;
290 uint32_t i = 0U;
291 uint32_t inputaddr = (uint32_t)Input;
292 uint32_t outputaddr = (uint32_t)Output;
293
294 for(i=0U; (i < Ilength); i+=16U)
295 {
296 /* Write the Input block in the IN FIFO */
297 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
298 inputaddr+=4U;
299 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
300 inputaddr+=4U;
301 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
302 inputaddr+=4U;
303 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
304 inputaddr+=4U;
305
306 /* Get tick */
307 tickstart = HAL_GetTick();
308
309 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
310 {
311 /* Check for the Timeout */
312 if(Timeout != HAL_MAX_DELAY)
313 {
314 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
315 {
316 /* Change state */
317 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
318
319 /* Process Unlocked */
320 __HAL_UNLOCK(hcryp);
321
322 return HAL_TIMEOUT;
323 }
324 }
325 }
326 /* Read the Output block from the OUT FIFO */
327 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
328 outputaddr+=4U;
329 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
330 outputaddr+=4U;
331 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
332 outputaddr+=4U;
333 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
334 outputaddr+=4U;
335 }
336 /* Return function status */
337 return HAL_OK;
338 }
339
340 /**
341 * @brief Sets the header phase
342 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
343 * the configuration information for CRYP module
344 * @param Input Pointer to the Input buffer.
345 * @param Ilength Length of the Input buffer, must be a multiple of 16
346 * @param Timeout Timeout value
347 * @retval None
348 */
349 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout)
350 {
351 uint32_t tickstart = 0U;
352 uint32_t loopcounter = 0U;
353 uint32_t headeraddr = (uint32_t)Input;
354
355 /* Prevent unused argument(s) compilation warning */
356 UNUSED(Ilength);
357
358 /***************************** Header phase *********************************/
359 if(hcryp->Init.HeaderSize != 0U)
360 {
361 /* Select header phase */
362 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
363 /* Enable the CRYP peripheral */
364 __HAL_CRYP_ENABLE(hcryp);
365
366 for(loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16U)
367 {
368 /* Get tick */
369 tickstart = HAL_GetTick();
370
371 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
372 {
373 /* Check for the Timeout */
374 if(Timeout != HAL_MAX_DELAY)
375 {
376 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
377 {
378 /* Change state */
379 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
380
381 /* Process Unlocked */
382 __HAL_UNLOCK(hcryp);
383
384 return HAL_TIMEOUT;
385 }
386 }
387 }
388 /* Write the Input block in the IN FIFO */
389 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
390 headeraddr+=4U;
391 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
392 headeraddr+=4U;
393 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
394 headeraddr+=4U;
395 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
396 headeraddr+=4U;
397 }
398
399 /* Wait until the complete message has been processed */
400
401 /* Get tick */
402 tickstart = HAL_GetTick();
403
404 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
405 {
406 /* Check for the Timeout */
407 if(Timeout != HAL_MAX_DELAY)
408 {
409 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
410 {
411 /* Change state */
412 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
413
414 /* Process Unlocked */
415 __HAL_UNLOCK(hcryp);
416
417 return HAL_TIMEOUT;
418 }
419 }
420 }
421 }
422 /* Return function status */
423 return HAL_OK;
424 }
425
426 /**
427 * @brief Sets the DMA configuration and start the DMA transfer.
428 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
429 * the configuration information for CRYP module
430 * @param inputaddr Address of the Input buffer
431 * @param Size Size of the Input buffer, must be a multiple of 16
432 * @param outputaddr Address of the Output buffer
433 * @retval None
434 */
435 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
436 {
437 /* Set the CRYP DMA transfer complete callback */
438 hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt;
439 /* Set the DMA error callback */
440 hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
441
442 /* Set the CRYP DMA transfer complete callback */
443 hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt;
444 /* Set the DMA error callback */
445 hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
446
447 /* Enable the CRYP peripheral */
448 __HAL_CRYP_ENABLE(hcryp);
449
450 /* Enable the DMA In DMA Stream */
451 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DR, Size/4U);
452
453 /* Enable In DMA request */
454 hcryp->Instance->DMACR = CRYP_DMACR_DIEN;
455
456 /* Enable the DMA Out DMA Stream */
457 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size/4U);
458
459 /* Enable Out DMA request */
460 hcryp->Instance->DMACR |= CRYP_DMACR_DOEN;
461 }
462
463 /**
464 * @}
465 */
466
467 /* Exported functions---------------------------------------------------------*/
468 /** @addtogroup CRYPEx_Exported_Functions
469 * @{
470 */
471
472 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
473 * @brief Extended processing functions.
474 *
475 @verbatim
476 ==============================================================================
477 ##### Extended AES processing functions #####
478 ==============================================================================
479 [..] This section provides functions allowing to:
480 (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes
481 (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes
482 (+) Finish the processing. This function is available only for GCM and CCM
483 [..] Three processing methods are available:
484 (+) Polling mode
485 (+) Interrupt mode
486 (+) DMA mode
487
488 @endverbatim
489 * @{
490 */
491
492
493 /**
494 * @brief Initializes the CRYP peripheral in AES CCM encryption mode then
495 * encrypt pPlainData. The cypher data are available in pCypherData.
496 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
497 * the configuration information for CRYP module
498 * @param pPlainData Pointer to the plaintext buffer
499 * @param Size Length of the plaintext buffer, must be a multiple of 16
500 * @param pCypherData Pointer to the cyphertext buffer
501 * @param Timeout Timeout duration
502 * @retval HAL status
503 */
504 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
505 {
506 uint32_t tickstart = 0U;
507 uint32_t headersize = hcryp->Init.HeaderSize;
508 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
509 uint32_t loopcounter = 0U;
510 uint32_t bufferidx = 0U;
511 uint8_t blockb0[16U] = {0};/* Block B0 */
512 uint8_t ctr[16U] = {0}; /* Counter */
513 uint32_t b0addr = (uint32_t)blockb0;
514
515 /* Process Locked */
516 __HAL_LOCK(hcryp);
517
518 /* Change the CRYP peripheral state */
519 hcryp->State = HAL_CRYP_STATE_BUSY;
520
521 /* Check if initialization phase has already been performed */
522 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
523 {
524 /************************ Formatting the header block *********************/
525 if(headersize != 0U)
526 {
527 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
528 if(headersize < 65280U)
529 {
530 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
531 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
532 headersize += 2U;
533 }
534 else
535 {
536 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
537 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
538 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
539 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
540 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
541 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
542 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
543 headersize += 6U;
544 }
545 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
546 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
547 {
548 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
549 }
550 /* Check if the header size is modulo 16 */
551 if ((headersize % 16U) != 0U)
552 {
553 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
554 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
555 {
556 hcryp->Init.pScratch[loopcounter] = 0U;
557 }
558 /* Set the header size to modulo 16 */
559 headersize = ((headersize/16U) + 1U) * 16U;
560 }
561 /* Set the pointer headeraddr to hcryp->Init.pScratch */
562 headeraddr = (uint32_t)hcryp->Init.pScratch;
563 }
564 /*********************** Formatting the block B0 **************************/
565 if(headersize != 0U)
566 {
567 blockb0[0U] = 0x40U;
568 }
569 /* Flags byte */
570 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
571 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
572 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
573
574 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
575 {
576 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
577 }
578 for ( ; loopcounter < 13U; loopcounter++)
579 {
580 blockb0[loopcounter+1U] = 0U;
581 }
582
583 blockb0[14U] = (Size >> 8U);
584 blockb0[15U] = (Size & 0xFFU);
585
586 /************************* Formatting the initial counter *****************/
587 /* Byte 0:
588 Bits 7 and 6 are reserved and shall be set to 0
589 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
590 are distinct from B0
591 Bits 0, 1, and 2 contain the same encoding of q as in B0
592 */
593 ctr[0U] = blockb0[0U] & 0x07U;
594 /* byte 1 to NonceSize is the IV (Nonce) */
595 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
596 {
597 ctr[loopcounter] = blockb0[loopcounter];
598 }
599 /* Set the LSB to 1 */
600 ctr[15U] |= 0x01U;
601
602 /* Set the key */
603 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
604
605 /* Set the CRYP peripheral in AES CCM mode */
606 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
607
608 /* Set the Initialization Vector */
609 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
610
611 /* Select init phase */
612 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
613
614 b0addr = (uint32_t)blockb0;
615 /* Write the blockb0 block in the IN FIFO */
616 hcryp->Instance->DR = *(uint32_t*)(b0addr);
617 b0addr+=4U;
618 hcryp->Instance->DR = *(uint32_t*)(b0addr);
619 b0addr+=4U;
620 hcryp->Instance->DR = *(uint32_t*)(b0addr);
621 b0addr+=4U;
622 hcryp->Instance->DR = *(uint32_t*)(b0addr);
623
624 /* Enable the CRYP peripheral */
625 __HAL_CRYP_ENABLE(hcryp);
626
627 /* Get tick */
628 tickstart = HAL_GetTick();
629
630 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
631 {
632 /* Check for the Timeout */
633 if(Timeout != HAL_MAX_DELAY)
634 {
635 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
636 {
637 /* Change state */
638 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
639
640 /* Process Unlocked */
641 __HAL_UNLOCK(hcryp);
642
643 return HAL_TIMEOUT;
644 }
645 }
646 }
647 /***************************** Header phase *******************************/
648 if(headersize != 0U)
649 {
650 /* Select header phase */
651 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
652
653 /* Enable the CRYP peripheral */
654 __HAL_CRYP_ENABLE(hcryp);
655
656 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
657 {
658 /* Get tick */
659 tickstart = HAL_GetTick();
660
661 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
662 {
663 {
664 /* Check for the Timeout */
665 if(Timeout != HAL_MAX_DELAY)
666 {
667 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
668 {
669 /* Change state */
670 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
671
672 /* Process Unlocked */
673 __HAL_UNLOCK(hcryp);
674
675 return HAL_TIMEOUT;
676 }
677 }
678 }
679 }
680 /* Write the header block in the IN FIFO */
681 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
682 headeraddr+=4U;
683 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
684 headeraddr+=4U;
685 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
686 headeraddr+=4U;
687 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
688 headeraddr+=4U;
689 }
690
691 /* Get tick */
692 tickstart = HAL_GetTick();
693
694 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
695 {
696 /* Check for the Timeout */
697 if(Timeout != HAL_MAX_DELAY)
698 {
699 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
700 {
701 /* Change state */
702 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
703
704 /* Process Unlocked */
705 __HAL_UNLOCK(hcryp);
706
707 return HAL_TIMEOUT;
708 }
709 }
710 }
711 }
712 /* Save formatted counter into the scratch buffer pScratch */
713 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
714 {
715 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
716 }
717 /* Reset bit 0 */
718 hcryp->Init.pScratch[15U] &= 0xFEU;
719
720 /* Select payload phase once the header phase is performed */
721 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
722
723 /* Flush FIFO */
724 __HAL_CRYP_FIFO_FLUSH(hcryp);
725
726 /* Enable the CRYP peripheral */
727 __HAL_CRYP_ENABLE(hcryp);
728
729 /* Set the phase */
730 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
731 }
732
733 /* Write Plain Data and Get Cypher Data */
734 if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK)
735 {
736 return HAL_TIMEOUT;
737 }
738
739 /* Change the CRYP peripheral state */
740 hcryp->State = HAL_CRYP_STATE_READY;
741
742 /* Process Unlocked */
743 __HAL_UNLOCK(hcryp);
744
745 /* Return function status */
746 return HAL_OK;
747 }
748
749 /**
750 * @brief Initializes the CRYP peripheral in AES GCM encryption mode then
751 * encrypt pPlainData. The cypher data are available in pCypherData.
752 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
753 * the configuration information for CRYP module
754 * @param pPlainData Pointer to the plaintext buffer
755 * @param Size Length of the plaintext buffer, must be a multiple of 16
756 * @param pCypherData Pointer to the cyphertext buffer
757 * @param Timeout Timeout duration
758 * @retval HAL status
759 */
760 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
761 {
762 uint32_t tickstart = 0U;
763
764 /* Process Locked */
765 __HAL_LOCK(hcryp);
766
767 /* Change the CRYP peripheral state */
768 hcryp->State = HAL_CRYP_STATE_BUSY;
769
770 /* Check if initialization phase has already been performed */
771 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
772 {
773 /* Set the key */
774 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
775
776 /* Set the CRYP peripheral in AES GCM mode */
777 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
778
779 /* Set the Initialization Vector */
780 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
781
782 /* Flush FIFO */
783 __HAL_CRYP_FIFO_FLUSH(hcryp);
784
785 /* Enable the CRYP peripheral */
786 __HAL_CRYP_ENABLE(hcryp);
787
788 /* Get tick */
789 tickstart = HAL_GetTick();
790
791 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
792 {
793 /* Check for the Timeout */
794 if(Timeout != HAL_MAX_DELAY)
795 {
796 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
797 {
798 /* Change state */
799 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
800
801 /* Process Unlocked */
802 __HAL_UNLOCK(hcryp);
803
804 return HAL_TIMEOUT;
805 }
806 }
807 }
808
809 /* Set the header phase */
810 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
811 {
812 return HAL_TIMEOUT;
813 }
814
815 /* Disable the CRYP peripheral */
816 __HAL_CRYP_DISABLE(hcryp);
817
818 /* Select payload phase once the header phase is performed */
819 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
820
821 /* Flush FIFO */
822 __HAL_CRYP_FIFO_FLUSH(hcryp);
823
824 /* Enable the CRYP peripheral */
825 __HAL_CRYP_ENABLE(hcryp);
826
827 /* Set the phase */
828 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
829 }
830
831 /* Write Plain Data and Get Cypher Data */
832 if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK)
833 {
834 return HAL_TIMEOUT;
835 }
836
837 /* Change the CRYP peripheral state */
838 hcryp->State = HAL_CRYP_STATE_READY;
839
840 /* Process Unlocked */
841 __HAL_UNLOCK(hcryp);
842
843 /* Return function status */
844 return HAL_OK;
845 }
846
847 /**
848 * @brief Initializes the CRYP peripheral in AES GCM decryption mode then
849 * decrypted pCypherData. The cypher data are available in pPlainData.
850 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
851 * the configuration information for CRYP module
852 * @param pCypherData Pointer to the cyphertext buffer
853 * @param Size Length of the cyphertext buffer, must be a multiple of 16
854 * @param pPlainData Pointer to the plaintext buffer
855 * @param Timeout Timeout duration
856 * @retval HAL status
857 */
858 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
859 {
860 uint32_t tickstart = 0U;
861
862 /* Process Locked */
863 __HAL_LOCK(hcryp);
864
865 /* Change the CRYP peripheral state */
866 hcryp->State = HAL_CRYP_STATE_BUSY;
867
868 /* Check if initialization phase has already been performed */
869 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
870 {
871 /* Set the key */
872 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
873
874 /* Set the CRYP peripheral in AES GCM decryption mode */
875 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
876
877 /* Set the Initialization Vector */
878 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
879
880 /* Flush FIFO */
881 __HAL_CRYP_FIFO_FLUSH(hcryp);
882
883 /* Enable the CRYP peripheral */
884 __HAL_CRYP_ENABLE(hcryp);
885
886 /* Get tick */
887 tickstart = HAL_GetTick();
888
889 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
890 {
891 /* Check for the Timeout */
892 if(Timeout != HAL_MAX_DELAY)
893 {
894 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
895 {
896 /* Change state */
897 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
898
899 /* Process Unlocked */
900 __HAL_UNLOCK(hcryp);
901
902 return HAL_TIMEOUT;
903 }
904 }
905 }
906
907 /* Set the header phase */
908 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
909 {
910 return HAL_TIMEOUT;
911 }
912 /* Disable the CRYP peripheral */
913 __HAL_CRYP_DISABLE(hcryp);
914
915 /* Select payload phase once the header phase is performed */
916 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
917
918 /* Enable the CRYP peripheral */
919 __HAL_CRYP_ENABLE(hcryp);
920
921 /* Set the phase */
922 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
923 }
924
925 /* Write Plain Data and Get Cypher Data */
926 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
927 {
928 return HAL_TIMEOUT;
929 }
930
931 /* Change the CRYP peripheral state */
932 hcryp->State = HAL_CRYP_STATE_READY;
933
934 /* Process Unlocked */
935 __HAL_UNLOCK(hcryp);
936
937 /* Return function status */
938 return HAL_OK;
939 }
940
941 /**
942 * @brief Computes the authentication TAG.
943 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
944 * the configuration information for CRYP module
945 * @param Size Total length of the plain/cyphertext buffer
946 * @param AuthTag Pointer to the authentication buffer
947 * @param Timeout Timeout duration
948 * @retval HAL status
949 */
950 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint32_t Size, uint8_t *AuthTag, uint32_t Timeout)
951 {
952 uint32_t tickstart = 0U;
953 uint64_t headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
954 uint64_t inputlength = Size * 8U; /* input length in bits */
955 uint32_t tagaddr = (uint32_t)AuthTag;
956
957 /* Process Locked */
958 __HAL_LOCK(hcryp);
959
960 /* Change the CRYP peripheral state */
961 hcryp->State = HAL_CRYP_STATE_BUSY;
962
963 /* Check if initialization phase has already been performed */
964 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
965 {
966 /* Change the CRYP phase */
967 hcryp->Phase = HAL_CRYP_PHASE_FINAL;
968
969 /* Disable CRYP to start the final phase */
970 __HAL_CRYP_DISABLE(hcryp);
971
972 /* Select final phase */
973 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
974
975 /* Enable the CRYP peripheral */
976 __HAL_CRYP_ENABLE(hcryp);
977
978 /* Write the number of bits in header (64 bits) followed by the number of bits
979 in the payload */
980 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
981 {
982 hcryp->Instance->DR = __RBIT(headerlength >> 32U);
983 hcryp->Instance->DR = __RBIT(headerlength);
984 hcryp->Instance->DR = __RBIT(inputlength >> 32U);
985 hcryp->Instance->DR = __RBIT(inputlength);
986 }
987 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
988 {
989 hcryp->Instance->DR = __REV(headerlength >> 32U);
990 hcryp->Instance->DR = __REV(headerlength);
991 hcryp->Instance->DR = __REV(inputlength >> 32U);
992 hcryp->Instance->DR = __REV(inputlength);
993 }
994 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
995 {
996 hcryp->Instance->DR = __ROR((uint32_t)(headerlength >> 32U), 16U);
997 hcryp->Instance->DR = __ROR((uint32_t)headerlength, 16U);
998 hcryp->Instance->DR = __ROR((uint32_t)(inputlength >> 32U), 16U);
999 hcryp->Instance->DR = __ROR((uint32_t)inputlength, 16U);
1000 }
1001 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
1002 {
1003 hcryp->Instance->DR = (uint32_t)(headerlength >> 32U);
1004 hcryp->Instance->DR = (uint32_t)(headerlength);
1005 hcryp->Instance->DR = (uint32_t)(inputlength >> 32U);
1006 hcryp->Instance->DR = (uint32_t)(inputlength);
1007 }
1008 /* Get tick */
1009 tickstart = HAL_GetTick();
1010
1011 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
1012 {
1013 /* Check for the Timeout */
1014 if(Timeout != HAL_MAX_DELAY)
1015 {
1016 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1017 {
1018 /* Change state */
1019 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1020
1021 /* Process Unlocked */
1022 __HAL_UNLOCK(hcryp);
1023
1024 return HAL_TIMEOUT;
1025 }
1026 }
1027 }
1028
1029 /* Read the Auth TAG in the IN FIFO */
1030 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
1031 tagaddr+=4U;
1032 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
1033 tagaddr+=4U;
1034 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
1035 tagaddr+=4U;
1036 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
1037 }
1038
1039 /* Change the CRYP peripheral state */
1040 hcryp->State = HAL_CRYP_STATE_READY;
1041
1042 /* Process Unlocked */
1043 __HAL_UNLOCK(hcryp);
1044
1045 /* Return function status */
1046 return HAL_OK;
1047 }
1048
1049 /**
1050 * @brief Computes the authentication TAG for AES CCM mode.
1051 * @note This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt()
1052 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1053 * the configuration information for CRYP module
1054 * @param AuthTag Pointer to the authentication buffer
1055 * @param Timeout Timeout duration
1056 * @retval HAL status
1057 */
1058 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout)
1059 {
1060 uint32_t tickstart = 0U;
1061 uint32_t tagaddr = (uint32_t)AuthTag;
1062 uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch;
1063 uint32_t temptag[4U] = {0U}; /* Temporary TAG (MAC) */
1064 uint32_t loopcounter;
1065
1066 /* Process Locked */
1067 __HAL_LOCK(hcryp);
1068
1069 /* Change the CRYP peripheral state */
1070 hcryp->State = HAL_CRYP_STATE_BUSY;
1071
1072 /* Check if initialization phase has already been performed */
1073 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
1074 {
1075 /* Change the CRYP phase */
1076 hcryp->Phase = HAL_CRYP_PHASE_FINAL;
1077
1078 /* Disable CRYP to start the final phase */
1079 __HAL_CRYP_DISABLE(hcryp);
1080
1081 /* Select final phase */
1082 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
1083
1084 /* Enable the CRYP peripheral */
1085 __HAL_CRYP_ENABLE(hcryp);
1086
1087 /* Write the counter block in the IN FIFO */
1088 hcryp->Instance->DR = *(uint32_t*)ctraddr;
1089 ctraddr+=4U;
1090 hcryp->Instance->DR = *(uint32_t*)ctraddr;
1091 ctraddr+=4U;
1092 hcryp->Instance->DR = *(uint32_t*)ctraddr;
1093 ctraddr+=4U;
1094 hcryp->Instance->DR = *(uint32_t*)ctraddr;
1095
1096 /* Get tick */
1097 tickstart = HAL_GetTick();
1098
1099 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
1100 {
1101 /* Check for the Timeout */
1102 if(Timeout != HAL_MAX_DELAY)
1103 {
1104 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1105 {
1106 /* Change state */
1107 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1108
1109 /* Process Unlocked */
1110 __HAL_UNLOCK(hcryp);
1111
1112 return HAL_TIMEOUT;
1113 }
1114 }
1115 }
1116
1117 /* Read the Auth TAG in the IN FIFO */
1118 temptag[0U] = hcryp->Instance->DOUT;
1119 temptag[1U] = hcryp->Instance->DOUT;
1120 temptag[2U] = hcryp->Instance->DOUT;
1121 temptag[3U] = hcryp->Instance->DOUT;
1122 }
1123
1124 /* Copy temporary authentication TAG in user TAG buffer */
1125 for(loopcounter = 0U; loopcounter < hcryp->Init.TagSize ; loopcounter++)
1126 {
1127 /* Set the authentication TAG buffer */
1128 *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
1129 }
1130
1131 /* Change the CRYP peripheral state */
1132 hcryp->State = HAL_CRYP_STATE_READY;
1133
1134 /* Process Unlocked */
1135 __HAL_UNLOCK(hcryp);
1136
1137 /* Return function status */
1138 return HAL_OK;
1139 }
1140
1141 /**
1142 * @brief Initializes the CRYP peripheral in AES CCM decryption mode then
1143 * decrypted pCypherData. The cypher data are available in pPlainData.
1144 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1145 * the configuration information for CRYP module
1146 * @param pPlainData Pointer to the plaintext buffer
1147 * @param Size Length of the plaintext buffer, must be a multiple of 16
1148 * @param pCypherData Pointer to the cyphertext buffer
1149 * @param Timeout Timeout duration
1150 * @retval HAL status
1151 */
1152 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
1153 {
1154 uint32_t tickstart = 0U;
1155 uint32_t headersize = hcryp->Init.HeaderSize;
1156 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
1157 uint32_t loopcounter = 0U;
1158 uint32_t bufferidx = 0U;
1159 uint8_t blockb0[16U] = {0};/* Block B0 */
1160 uint8_t ctr[16U] = {0}; /* Counter */
1161 uint32_t b0addr = (uint32_t)blockb0;
1162
1163 /* Process Locked */
1164 __HAL_LOCK(hcryp);
1165
1166 /* Change the CRYP peripheral state */
1167 hcryp->State = HAL_CRYP_STATE_BUSY;
1168
1169 /* Check if initialization phase has already been performed */
1170 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1171 {
1172 /************************ Formatting the header block *********************/
1173 if(headersize != 0U)
1174 {
1175 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1176 if(headersize < 65280U)
1177 {
1178 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1179 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1180 headersize += 2U;
1181 }
1182 else
1183 {
1184 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1185 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
1186 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
1187 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
1188 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
1189 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
1190 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
1191 headersize += 6U;
1192 }
1193 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1194 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
1195 {
1196 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
1197 }
1198 /* Check if the header size is modulo 16 */
1199 if ((headersize % 16U) != 0U)
1200 {
1201 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1202 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
1203 {
1204 hcryp->Init.pScratch[loopcounter] = 0U;
1205 }
1206 /* Set the header size to modulo 16 */
1207 headersize = ((headersize/16U) + 1U) * 16U;
1208 }
1209 /* Set the pointer headeraddr to hcryp->Init.pScratch */
1210 headeraddr = (uint32_t)hcryp->Init.pScratch;
1211 }
1212 /*********************** Formatting the block B0 **************************/
1213 if(headersize != 0U)
1214 {
1215 blockb0[0U] = 0x40U;
1216 }
1217 /* Flags byte */
1218 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
1219 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2U))) >> 1U) & (uint8_t)0x07U) << 3U);
1220 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15U) - hcryp->Init.IVSize) - (uint8_t)1U) & (uint8_t)0x07U);
1221
1222 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
1223 {
1224 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
1225 }
1226 for ( ; loopcounter < 13U; loopcounter++)
1227 {
1228 blockb0[loopcounter+1U] = 0U;
1229 }
1230
1231 blockb0[14U] = (Size >> 8U);
1232 blockb0[15U] = (Size & 0xFFU);
1233
1234 /************************* Formatting the initial counter *****************/
1235 /* Byte 0:
1236 Bits 7 and 6 are reserved and shall be set to 0
1237 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
1238 blocks are distinct from B0
1239 Bits 0, 1, and 2 contain the same encoding of q as in B0
1240 */
1241 ctr[0U] = blockb0[0U] & 0x07U;
1242 /* byte 1 to NonceSize is the IV (Nonce) */
1243 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
1244 {
1245 ctr[loopcounter] = blockb0[loopcounter];
1246 }
1247 /* Set the LSB to 1 */
1248 ctr[15U] |= 0x01U;
1249
1250 /* Set the key */
1251 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1252
1253 /* Set the CRYP peripheral in AES CCM mode */
1254 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
1255
1256 /* Set the Initialization Vector */
1257 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
1258
1259 /* Select init phase */
1260 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
1261
1262 b0addr = (uint32_t)blockb0;
1263 /* Write the blockb0 block in the IN FIFO */
1264 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1265 b0addr+=4U;
1266 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1267 b0addr+=4U;
1268 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1269 b0addr+=4U;
1270 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1271
1272 /* Enable the CRYP peripheral */
1273 __HAL_CRYP_ENABLE(hcryp);
1274
1275 /* Get tick */
1276 tickstart = HAL_GetTick();
1277
1278 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1279 {
1280 /* Check for the Timeout */
1281 if(Timeout != HAL_MAX_DELAY)
1282 {
1283 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1284 {
1285 /* Change state */
1286 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1287
1288 /* Process Unlocked */
1289 __HAL_UNLOCK(hcryp);
1290
1291 return HAL_TIMEOUT;
1292 }
1293 }
1294 }
1295 /***************************** Header phase *******************************/
1296 if(headersize != 0U)
1297 {
1298 /* Select header phase */
1299 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
1300
1301 /* Enable Crypto processor */
1302 __HAL_CRYP_ENABLE(hcryp);
1303
1304 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
1305 {
1306 /* Get tick */
1307 tickstart = HAL_GetTick();
1308
1309 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
1310 {
1311 /* Check for the Timeout */
1312 if(Timeout != HAL_MAX_DELAY)
1313 {
1314 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1315 {
1316 /* Change state */
1317 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1318
1319 /* Process Unlocked */
1320 __HAL_UNLOCK(hcryp);
1321
1322 return HAL_TIMEOUT;
1323 }
1324 }
1325 }
1326 /* Write the header block in the IN FIFO */
1327 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1328 headeraddr+=4U;
1329 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1330 headeraddr+=4U;
1331 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1332 headeraddr+=4U;
1333 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1334 headeraddr+=4U;
1335 }
1336
1337 /* Get tick */
1338 tickstart = HAL_GetTick();
1339
1340 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1341 {
1342 /* Check for the Timeout */
1343 if(Timeout != HAL_MAX_DELAY)
1344 {
1345 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1346 {
1347 /* Change state */
1348 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1349
1350 /* Process Unlocked */
1351 __HAL_UNLOCK(hcryp);
1352
1353 return HAL_TIMEOUT;
1354 }
1355 }
1356 }
1357 }
1358 /* Save formatted counter into the scratch buffer pScratch */
1359 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
1360 {
1361 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1362 }
1363 /* Reset bit 0 */
1364 hcryp->Init.pScratch[15U] &= 0xFEU;
1365 /* Select payload phase once the header phase is performed */
1366 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
1367
1368 /* Flush FIFO */
1369 __HAL_CRYP_FIFO_FLUSH(hcryp);
1370
1371 /* Enable the CRYP peripheral */
1372 __HAL_CRYP_ENABLE(hcryp);
1373
1374 /* Set the phase */
1375 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1376 }
1377
1378 /* Write Plain Data and Get Cypher Data */
1379 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
1380 {
1381 return HAL_TIMEOUT;
1382 }
1383
1384 /* Change the CRYP peripheral state */
1385 hcryp->State = HAL_CRYP_STATE_READY;
1386
1387 /* Process Unlocked */
1388 __HAL_UNLOCK(hcryp);
1389
1390 /* Return function status */
1391 return HAL_OK;
1392 }
1393
1394 /**
1395 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using IT.
1396 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1397 * the configuration information for CRYP module
1398 * @param pPlainData Pointer to the plaintext buffer
1399 * @param Size Length of the plaintext buffer, must be a multiple of 16
1400 * @param pCypherData Pointer to the cyphertext buffer
1401 * @retval HAL status
1402 */
1403 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1404 {
1405 uint32_t tickstart = 0U;
1406 uint32_t inputaddr;
1407 uint32_t outputaddr;
1408
1409 if(hcryp->State == HAL_CRYP_STATE_READY)
1410 {
1411 /* Process Locked */
1412 __HAL_LOCK(hcryp);
1413
1414 /* Get the buffer addresses and sizes */
1415 hcryp->CrypInCount = Size;
1416 hcryp->pCrypInBuffPtr = pPlainData;
1417 hcryp->pCrypOutBuffPtr = pCypherData;
1418 hcryp->CrypOutCount = Size;
1419
1420 /* Change the CRYP peripheral state */
1421 hcryp->State = HAL_CRYP_STATE_BUSY;
1422
1423 /* Check if initialization phase has already been performed */
1424 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1425 {
1426 /* Set the key */
1427 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1428
1429 /* Set the CRYP peripheral in AES GCM mode */
1430 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
1431
1432 /* Set the Initialization Vector */
1433 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
1434
1435 /* Flush FIFO */
1436 __HAL_CRYP_FIFO_FLUSH(hcryp);
1437
1438 /* Enable CRYP to start the init phase */
1439 __HAL_CRYP_ENABLE(hcryp);
1440
1441 /* Get tick */
1442 tickstart = HAL_GetTick();
1443
1444 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1445 {
1446 /* Check for the Timeout */
1447
1448 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1449 {
1450 /* Change state */
1451 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1452
1453 /* Process Unlocked */
1454 __HAL_UNLOCK(hcryp);
1455
1456 return HAL_TIMEOUT;
1457
1458 }
1459 }
1460
1461 /* Set the header phase */
1462 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
1463 {
1464 return HAL_TIMEOUT;
1465 }
1466 /* Disable the CRYP peripheral */
1467 __HAL_CRYP_DISABLE(hcryp);
1468
1469 /* Select payload phase once the header phase is performed */
1470 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
1471
1472 /* Flush FIFO */
1473 __HAL_CRYP_FIFO_FLUSH(hcryp);
1474
1475 /* Set the phase */
1476 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1477 }
1478
1479 if(Size != 0U)
1480 {
1481 /* Enable Interrupts */
1482 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1483 /* Enable the CRYP peripheral */
1484 __HAL_CRYP_ENABLE(hcryp);
1485 }
1486 else
1487 {
1488 /* Process Locked */
1489 __HAL_UNLOCK(hcryp);
1490 /* Change the CRYP state and phase */
1491 hcryp->State = HAL_CRYP_STATE_READY;
1492 }
1493 /* Return function status */
1494 return HAL_OK;
1495 }
1496 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
1497 {
1498 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1499 /* Write the Input block in the IN FIFO */
1500 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1501 inputaddr+=4U;
1502 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1503 inputaddr+=4U;
1504 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1505 inputaddr+=4U;
1506 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1507 hcryp->pCrypInBuffPtr += 16U;
1508 hcryp->CrypInCount -= 16U;
1509 if(hcryp->CrypInCount == 0U)
1510 {
1511 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1512 /* Call the Input data transfer complete callback */
1513 HAL_CRYP_InCpltCallback(hcryp);
1514 }
1515 }
1516 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
1517 {
1518 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1519 /* Read the Output block from the Output FIFO */
1520 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1521 outputaddr+=4U;
1522 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1523 outputaddr+=4U;
1524 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1525 outputaddr+=4U;
1526 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1527 hcryp->pCrypOutBuffPtr += 16U;
1528 hcryp->CrypOutCount -= 16U;
1529 if(hcryp->CrypOutCount == 0U)
1530 {
1531 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1532 /* Process Unlocked */
1533 __HAL_UNLOCK(hcryp);
1534 /* Change the CRYP peripheral state */
1535 hcryp->State = HAL_CRYP_STATE_READY;
1536 /* Call Input transfer complete callback */
1537 HAL_CRYP_OutCpltCallback(hcryp);
1538 }
1539 }
1540
1541 /* Return function status */
1542 return HAL_OK;
1543 }
1544
1545 /**
1546 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
1547 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1548 * the configuration information for CRYP module
1549 * @param pPlainData Pointer to the plaintext buffer
1550 * @param Size Length of the plaintext buffer, must be a multiple of 16
1551 * @param pCypherData Pointer to the cyphertext buffer
1552 * @retval HAL status
1553 */
1554 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
1555 {
1556 uint32_t tickstart = 0U;
1557 uint32_t inputaddr;
1558 uint32_t outputaddr;
1559
1560 uint32_t headersize = hcryp->Init.HeaderSize;
1561 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
1562 uint32_t loopcounter = 0U;
1563 uint32_t bufferidx = 0U;
1564 uint8_t blockb0[16U] = {0};/* Block B0 */
1565 uint8_t ctr[16U] = {0}; /* Counter */
1566 uint32_t b0addr = (uint32_t)blockb0;
1567
1568 if(hcryp->State == HAL_CRYP_STATE_READY)
1569 {
1570 /* Process Locked */
1571 __HAL_LOCK(hcryp);
1572
1573 hcryp->CrypInCount = Size;
1574 hcryp->pCrypInBuffPtr = pPlainData;
1575 hcryp->pCrypOutBuffPtr = pCypherData;
1576 hcryp->CrypOutCount = Size;
1577
1578 /* Change the CRYP peripheral state */
1579 hcryp->State = HAL_CRYP_STATE_BUSY;
1580
1581 /* Check if initialization phase has already been performed */
1582 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1583 {
1584 /************************ Formatting the header block *******************/
1585 if(headersize != 0U)
1586 {
1587 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
1588 if(headersize < 65280U)
1589 {
1590 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
1591 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
1592 headersize += 2U;
1593 }
1594 else
1595 {
1596 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
1597 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
1598 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
1599 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
1600 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
1601 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
1602 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
1603 headersize += 6U;
1604 }
1605 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
1606 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
1607 {
1608 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
1609 }
1610 /* Check if the header size is modulo 16 */
1611 if ((headersize % 16U) != 0U)
1612 {
1613 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
1614 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
1615 {
1616 hcryp->Init.pScratch[loopcounter] = 0U;
1617 }
1618 /* Set the header size to modulo 16 */
1619 headersize = ((headersize/16U) + 1U) * 16U;
1620 }
1621 /* Set the pointer headeraddr to hcryp->Init.pScratch */
1622 headeraddr = (uint32_t)hcryp->Init.pScratch;
1623 }
1624 /*********************** Formatting the block B0 ************************/
1625 if(headersize != 0U)
1626 {
1627 blockb0[0U] = 0x40U;
1628 }
1629 /* Flags byte */
1630 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
1631 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
1632 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
1633
1634 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
1635 {
1636 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
1637 }
1638 for ( ; loopcounter < 13U; loopcounter++)
1639 {
1640 blockb0[loopcounter+1U] = 0U;
1641 }
1642
1643 blockb0[14U] = (Size >> 8U);
1644 blockb0[15U] = (Size & 0xFFU);
1645
1646 /************************* Formatting the initial counter ***************/
1647 /* Byte 0:
1648 Bits 7 and 6 are reserved and shall be set to 0
1649 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
1650 blocks are distinct from B0
1651 Bits 0, 1, and 2 contain the same encoding of q as in B0
1652 */
1653 ctr[0U] = blockb0[0U] & 0x07U;
1654 /* byte 1 to NonceSize is the IV (Nonce) */
1655 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
1656 {
1657 ctr[loopcounter] = blockb0[loopcounter];
1658 }
1659 /* Set the LSB to 1 */
1660 ctr[15U] |= 0x01U;
1661
1662 /* Set the key */
1663 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1664
1665 /* Set the CRYP peripheral in AES CCM mode */
1666 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
1667
1668 /* Set the Initialization Vector */
1669 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
1670
1671 /* Select init phase */
1672 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
1673
1674 b0addr = (uint32_t)blockb0;
1675 /* Write the blockb0 block in the IN FIFO */
1676 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1677 b0addr+=4U;
1678 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1679 b0addr+=4U;
1680 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1681 b0addr+=4U;
1682 hcryp->Instance->DR = *(uint32_t*)(b0addr);
1683
1684 /* Enable the CRYP peripheral */
1685 __HAL_CRYP_ENABLE(hcryp);
1686
1687 /* Get tick */
1688 tickstart = HAL_GetTick();
1689
1690 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1691 {
1692 /* Check for the Timeout */
1693 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1694 {
1695 /* Change state */
1696 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1697
1698 /* Process Unlocked */
1699 __HAL_UNLOCK(hcryp);
1700
1701 return HAL_TIMEOUT;
1702 }
1703 }
1704 /***************************** Header phase *****************************/
1705 if(headersize != 0U)
1706 {
1707 /* Select header phase */
1708 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
1709
1710 /* Enable Crypto processor */
1711 __HAL_CRYP_ENABLE(hcryp);
1712
1713 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
1714 {
1715 /* Get tick */
1716 tickstart = HAL_GetTick();
1717
1718 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
1719 {
1720 /* Check for the Timeout */
1721 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1722 {
1723 /* Change state */
1724 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1725
1726 /* Process Unlocked */
1727 __HAL_UNLOCK(hcryp);
1728
1729 return HAL_TIMEOUT;
1730 }
1731 }
1732 /* Write the header block in the IN FIFO */
1733 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1734 headeraddr+=4U;
1735 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1736 headeraddr+=4U;
1737 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1738 headeraddr+=4U;
1739 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
1740 headeraddr+=4U;
1741 }
1742
1743 /* Get tick */
1744 tickstart = HAL_GetTick();
1745
1746 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
1747 {
1748 /* Check for the Timeout */
1749 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1750 {
1751 /* Change state */
1752 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1753
1754 /* Process Unlocked */
1755 __HAL_UNLOCK(hcryp);
1756
1757 return HAL_TIMEOUT;
1758 }
1759 }
1760 }
1761 /* Save formatted counter into the scratch buffer pScratch */
1762 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
1763 {
1764 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
1765 }
1766 /* Reset bit 0 */
1767 hcryp->Init.pScratch[15U] &= 0xFEU;
1768
1769 /* Select payload phase once the header phase is performed */
1770 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
1771
1772 /* Flush FIFO */
1773 __HAL_CRYP_FIFO_FLUSH(hcryp);
1774
1775 /* Set the phase */
1776 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1777 }
1778
1779 if(Size != 0U)
1780 {
1781 /* Enable Interrupts */
1782 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1783 /* Enable the CRYP peripheral */
1784 __HAL_CRYP_ENABLE(hcryp);
1785 }
1786 else
1787 {
1788 /* Change the CRYP state and phase */
1789 hcryp->State = HAL_CRYP_STATE_READY;
1790 }
1791
1792 /* Return function status */
1793 return HAL_OK;
1794 }
1795 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
1796 {
1797 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1798 /* Write the Input block in the IN FIFO */
1799 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1800 inputaddr+=4U;
1801 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1802 inputaddr+=4U;
1803 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1804 inputaddr+=4U;
1805 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1806 hcryp->pCrypInBuffPtr += 16U;
1807 hcryp->CrypInCount -= 16U;
1808 if(hcryp->CrypInCount == 0U)
1809 {
1810 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1811 /* Call Input transfer complete callback */
1812 HAL_CRYP_InCpltCallback(hcryp);
1813 }
1814 }
1815 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
1816 {
1817 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1818 /* Read the Output block from the Output FIFO */
1819 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1820 outputaddr+=4U;
1821 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1822 outputaddr+=4U;
1823 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1824 outputaddr+=4U;
1825 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1826 hcryp->pCrypOutBuffPtr += 16U;
1827 hcryp->CrypOutCount -= 16U;
1828 if(hcryp->CrypOutCount == 0U)
1829 {
1830 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1831 /* Process Unlocked */
1832 __HAL_UNLOCK(hcryp);
1833 /* Change the CRYP peripheral state */
1834 hcryp->State = HAL_CRYP_STATE_READY;
1835 /* Call Input transfer complete callback */
1836 HAL_CRYP_OutCpltCallback(hcryp);
1837 }
1838 }
1839
1840 /* Return function status */
1841 return HAL_OK;
1842 }
1843
1844 /**
1845 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using IT.
1846 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1847 * the configuration information for CRYP module
1848 * @param pCypherData Pointer to the cyphertext buffer
1849 * @param Size Length of the cyphertext buffer, must be a multiple of 16
1850 * @param pPlainData Pointer to the plaintext buffer
1851 * @retval HAL status
1852 */
1853 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
1854 {
1855 uint32_t tickstart = 0U;
1856 uint32_t inputaddr;
1857 uint32_t outputaddr;
1858
1859 if(hcryp->State == HAL_CRYP_STATE_READY)
1860 {
1861 /* Process Locked */
1862 __HAL_LOCK(hcryp);
1863
1864 /* Get the buffer addresses and sizes */
1865 hcryp->CrypInCount = Size;
1866 hcryp->pCrypInBuffPtr = pCypherData;
1867 hcryp->pCrypOutBuffPtr = pPlainData;
1868 hcryp->CrypOutCount = Size;
1869
1870 /* Change the CRYP peripheral state */
1871 hcryp->State = HAL_CRYP_STATE_BUSY;
1872
1873 /* Check if initialization phase has already been performed */
1874 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
1875 {
1876 /* Set the key */
1877 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
1878
1879 /* Set the CRYP peripheral in AES GCM decryption mode */
1880 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
1881
1882 /* Set the Initialization Vector */
1883 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
1884
1885 /* Flush FIFO */
1886 __HAL_CRYP_FIFO_FLUSH(hcryp);
1887
1888 /* Enable CRYP to start the init phase */
1889 __HAL_CRYP_ENABLE(hcryp);
1890
1891 /* Get tick */
1892 tickstart = HAL_GetTick();
1893
1894 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
1895 {
1896 /* Check for the Timeout */
1897 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
1898 {
1899 /* Change state */
1900 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
1901
1902 /* Process Unlocked */
1903 __HAL_UNLOCK(hcryp);
1904
1905 return HAL_TIMEOUT;
1906 }
1907 }
1908
1909 /* Set the header phase */
1910 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
1911 {
1912 return HAL_TIMEOUT;
1913 }
1914 /* Disable the CRYP peripheral */
1915 __HAL_CRYP_DISABLE(hcryp);
1916
1917 /* Select payload phase once the header phase is performed */
1918 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
1919
1920 /* Set the phase */
1921 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
1922 }
1923
1924 if(Size != 0U)
1925 {
1926 /* Enable Interrupts */
1927 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1928 /* Enable the CRYP peripheral */
1929 __HAL_CRYP_ENABLE(hcryp);
1930 }
1931 else
1932 {
1933 /* Process Locked */
1934 __HAL_UNLOCK(hcryp);
1935 /* Change the CRYP state and phase */
1936 hcryp->State = HAL_CRYP_STATE_READY;
1937 }
1938
1939 /* Return function status */
1940 return HAL_OK;
1941 }
1942 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
1943 {
1944 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1945 /* Write the Input block in the IN FIFO */
1946 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1947 inputaddr+=4U;
1948 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1949 inputaddr+=4U;
1950 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1951 inputaddr+=4U;
1952 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
1953 hcryp->pCrypInBuffPtr += 16U;
1954 hcryp->CrypInCount -= 16U;
1955 if(hcryp->CrypInCount == 0U)
1956 {
1957 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1958 /* Call the Input data transfer complete callback */
1959 HAL_CRYP_InCpltCallback(hcryp);
1960 }
1961 }
1962 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
1963 {
1964 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
1965 /* Read the Output block from the Output FIFO */
1966 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1967 outputaddr+=4U;
1968 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1969 outputaddr+=4U;
1970 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1971 outputaddr+=4U;
1972 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
1973 hcryp->pCrypOutBuffPtr += 16U;
1974 hcryp->CrypOutCount -= 16U;
1975 if(hcryp->CrypOutCount == 0U)
1976 {
1977 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1978 /* Process Unlocked */
1979 __HAL_UNLOCK(hcryp);
1980 /* Change the CRYP peripheral state */
1981 hcryp->State = HAL_CRYP_STATE_READY;
1982 /* Call Input transfer complete callback */
1983 HAL_CRYP_OutCpltCallback(hcryp);
1984 }
1985 }
1986
1987 /* Return function status */
1988 return HAL_OK;
1989 }
1990
1991 /**
1992 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using interrupt
1993 * then decrypted pCypherData. The cypher data are available in pPlainData.
1994 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1995 * the configuration information for CRYP module
1996 * @param pCypherData Pointer to the cyphertext buffer
1997 * @param Size Length of the plaintext buffer, must be a multiple of 16
1998 * @param pPlainData Pointer to the plaintext buffer
1999 * @retval HAL status
2000 */
2001 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2002 {
2003 uint32_t inputaddr;
2004 uint32_t outputaddr;
2005 uint32_t tickstart = 0U;
2006 uint32_t headersize = hcryp->Init.HeaderSize;
2007 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
2008 uint32_t loopcounter = 0U;
2009 uint32_t bufferidx = 0U;
2010 uint8_t blockb0[16U] = {0};/* Block B0 */
2011 uint8_t ctr[16U] = {0}; /* Counter */
2012 uint32_t b0addr = (uint32_t)blockb0;
2013
2014 if(hcryp->State == HAL_CRYP_STATE_READY)
2015 {
2016 /* Process Locked */
2017 __HAL_LOCK(hcryp);
2018
2019 hcryp->CrypInCount = Size;
2020 hcryp->pCrypInBuffPtr = pCypherData;
2021 hcryp->pCrypOutBuffPtr = pPlainData;
2022 hcryp->CrypOutCount = Size;
2023
2024 /* Change the CRYP peripheral state */
2025 hcryp->State = HAL_CRYP_STATE_BUSY;
2026
2027 /* Check if initialization phase has already been performed */
2028 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2029 {
2030 /************************ Formatting the header block *******************/
2031 if(headersize != 0U)
2032 {
2033 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2034 if(headersize < 65280U)
2035 {
2036 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
2037 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
2038 headersize += 2U;
2039 }
2040 else
2041 {
2042 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2043 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
2044 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
2045 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
2046 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
2047 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
2048 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
2049 headersize += 6U;
2050 }
2051 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2052 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
2053 {
2054 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2055 }
2056 /* Check if the header size is modulo 16 */
2057 if ((headersize % 16U) != 0U)
2058 {
2059 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2060 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
2061 {
2062 hcryp->Init.pScratch[loopcounter] = 0U;
2063 }
2064 /* Set the header size to modulo 16 */
2065 headersize = ((headersize/16U) + 1U) * 16U;
2066 }
2067 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2068 headeraddr = (uint32_t)hcryp->Init.pScratch;
2069 }
2070 /*********************** Formatting the block B0 ************************/
2071 if(headersize != 0U)
2072 {
2073 blockb0[0U] = 0x40U;
2074 }
2075 /* Flags byte */
2076 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
2077 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
2078 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2079
2080 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
2081 {
2082 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
2083 }
2084 for ( ; loopcounter < 13U; loopcounter++)
2085 {
2086 blockb0[loopcounter+1U] = 0U;
2087 }
2088
2089 blockb0[14U] = (Size >> 8U);
2090 blockb0[15U] = (Size & 0xFFU);
2091
2092 /************************* Formatting the initial counter ***************/
2093 /* Byte 0:
2094 Bits 7 and 6 are reserved and shall be set to 0
2095 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2096 blocks are distinct from B0
2097 Bits 0, 1, and 2 contain the same encoding of q as in B0
2098 */
2099 ctr[0U] = blockb0[0U] & 0x07U;
2100 /* byte 1 to NonceSize is the IV (Nonce) */
2101 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
2102 {
2103 ctr[loopcounter] = blockb0[loopcounter];
2104 }
2105 /* Set the LSB to 1 */
2106 ctr[15U] |= 0x01U;
2107
2108 /* Set the key */
2109 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2110
2111 /* Set the CRYP peripheral in AES CCM mode */
2112 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
2113
2114 /* Set the Initialization Vector */
2115 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
2116
2117 /* Select init phase */
2118 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2119
2120 b0addr = (uint32_t)blockb0;
2121 /* Write the blockb0 block in the IN FIFO */
2122 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2123 b0addr+=4U;
2124 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2125 b0addr+=4U;
2126 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2127 b0addr+=4U;
2128 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2129
2130 /* Enable the CRYP peripheral */
2131 __HAL_CRYP_ENABLE(hcryp);
2132
2133 /* Get tick */
2134 tickstart = HAL_GetTick();
2135
2136 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2137 {
2138 /* Check for the Timeout */
2139 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2140 {
2141 /* Change state */
2142 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2143
2144 /* Process Unlocked */
2145 __HAL_UNLOCK(hcryp);
2146
2147 return HAL_TIMEOUT;
2148 }
2149 }
2150 /***************************** Header phase *****************************/
2151 if(headersize != 0U)
2152 {
2153 /* Select header phase */
2154 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
2155
2156 /* Enable Crypto processor */
2157 __HAL_CRYP_ENABLE(hcryp);
2158
2159 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
2160 {
2161 /* Get tick */
2162 tickstart = HAL_GetTick();
2163
2164 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
2165 {
2166 /* Check for the Timeout */
2167 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2168 {
2169 /* Change state */
2170 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2171
2172 /* Process Unlocked */
2173 __HAL_UNLOCK(hcryp);
2174
2175 return HAL_TIMEOUT;
2176 }
2177 }
2178 /* Write the header block in the IN FIFO */
2179 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2180 headeraddr+=4U;
2181 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2182 headeraddr+=4U;
2183 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2184 headeraddr+=4U;
2185 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2186 headeraddr+=4U;
2187 }
2188
2189 /* Get tick */
2190 tickstart = HAL_GetTick();
2191
2192 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2193 {
2194 /* Check for the Timeout */
2195 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2196 {
2197 /* Change state */
2198 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2199
2200 /* Process Unlocked */
2201 __HAL_UNLOCK(hcryp);
2202
2203 return HAL_TIMEOUT;
2204 }
2205 }
2206 }
2207 /* Save formatted counter into the scratch buffer pScratch */
2208 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
2209 {
2210 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2211 }
2212 /* Reset bit 0 */
2213 hcryp->Init.pScratch[15U] &= 0xFEU;
2214 /* Select payload phase once the header phase is performed */
2215 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2216
2217 /* Flush FIFO */
2218 __HAL_CRYP_FIFO_FLUSH(hcryp);
2219
2220 /* Set the phase */
2221 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2222 }
2223
2224 /* Enable Interrupts */
2225 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2226
2227 /* Enable the CRYP peripheral */
2228 __HAL_CRYP_ENABLE(hcryp);
2229
2230 /* Return function status */
2231 return HAL_OK;
2232 }
2233 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
2234 {
2235 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
2236 /* Write the Input block in the IN FIFO */
2237 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
2238 inputaddr+=4U;
2239 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
2240 inputaddr+=4U;
2241 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
2242 inputaddr+=4U;
2243 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
2244 hcryp->pCrypInBuffPtr += 16U;
2245 hcryp->CrypInCount -= 16U;
2246 if(hcryp->CrypInCount == 0U)
2247 {
2248 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
2249 /* Call the Input data transfer complete callback */
2250 HAL_CRYP_InCpltCallback(hcryp);
2251 }
2252 }
2253 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
2254 {
2255 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
2256 /* Read the Output block from the Output FIFO */
2257 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
2258 outputaddr+=4U;
2259 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
2260 outputaddr+=4U;
2261 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
2262 outputaddr+=4U;
2263 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
2264 hcryp->pCrypOutBuffPtr += 16U;
2265 hcryp->CrypOutCount -= 16U;
2266 if(hcryp->CrypOutCount == 0U)
2267 {
2268 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
2269 /* Process Unlocked */
2270 __HAL_UNLOCK(hcryp);
2271 /* Change the CRYP peripheral state */
2272 hcryp->State = HAL_CRYP_STATE_READY;
2273 /* Call Input transfer complete callback */
2274 HAL_CRYP_OutCpltCallback(hcryp);
2275 }
2276 }
2277
2278 /* Return function status */
2279 return HAL_OK;
2280 }
2281
2282 /**
2283 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using DMA.
2284 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2285 * the configuration information for CRYP module
2286 * @param pPlainData Pointer to the plaintext buffer
2287 * @param Size Length of the plaintext buffer, must be a multiple of 16
2288 * @param pCypherData Pointer to the cyphertext buffer
2289 * @retval HAL status
2290 */
2291 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
2292 {
2293 uint32_t tickstart = 0U;
2294 uint32_t inputaddr;
2295 uint32_t outputaddr;
2296
2297 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2298 {
2299 /* Process Locked */
2300 __HAL_LOCK(hcryp);
2301
2302 inputaddr = (uint32_t)pPlainData;
2303 outputaddr = (uint32_t)pCypherData;
2304
2305 /* Change the CRYP peripheral state */
2306 hcryp->State = HAL_CRYP_STATE_BUSY;
2307
2308 /* Check if initialization phase has already been performed */
2309 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2310 {
2311 /* Set the key */
2312 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2313
2314 /* Set the CRYP peripheral in AES GCM mode */
2315 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
2316
2317 /* Set the Initialization Vector */
2318 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
2319
2320 /* Flush FIFO */
2321 __HAL_CRYP_FIFO_FLUSH(hcryp);
2322
2323 /* Enable CRYP to start the init phase */
2324 __HAL_CRYP_ENABLE(hcryp);
2325
2326 /* Get tick */
2327 tickstart = HAL_GetTick();
2328
2329 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2330 {
2331 /* Check for the Timeout */
2332 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2333 {
2334 /* Change state */
2335 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2336
2337 /* Process Unlocked */
2338 __HAL_UNLOCK(hcryp);
2339
2340 return HAL_TIMEOUT;
2341 }
2342 }
2343 /* Flush FIFO */
2344 __HAL_CRYP_FIFO_FLUSH(hcryp);
2345
2346 /* Set the header phase */
2347 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
2348 {
2349 return HAL_TIMEOUT;
2350 }
2351 /* Disable the CRYP peripheral */
2352 __HAL_CRYP_DISABLE(hcryp);
2353
2354 /* Select payload phase once the header phase is performed */
2355 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2356
2357 /* Flush FIFO */
2358 __HAL_CRYP_FIFO_FLUSH(hcryp);
2359
2360 /* Set the phase */
2361 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2362 }
2363
2364 /* Set the input and output addresses and start DMA transfer */
2365 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2366
2367 /* Unlock process */
2368 __HAL_UNLOCK(hcryp);
2369
2370 /* Return function status */
2371 return HAL_OK;
2372 }
2373 else
2374 {
2375 return HAL_ERROR;
2376 }
2377 }
2378
2379 /**
2380 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
2381 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2382 * the configuration information for CRYP module
2383 * @param pPlainData Pointer to the plaintext buffer
2384 * @param Size Length of the plaintext buffer, must be a multiple of 16
2385 * @param pCypherData Pointer to the cyphertext buffer
2386 * @retval HAL status
2387 */
2388 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
2389 {
2390 uint32_t tickstart = 0U;
2391 uint32_t inputaddr;
2392 uint32_t outputaddr;
2393 uint32_t headersize;
2394 uint32_t headeraddr;
2395 uint32_t loopcounter = 0U;
2396 uint32_t bufferidx = 0U;
2397 uint8_t blockb0[16U] = {0};/* Block B0 */
2398 uint8_t ctr[16U] = {0}; /* Counter */
2399 uint32_t b0addr = (uint32_t)blockb0;
2400
2401 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2402 {
2403 /* Process Locked */
2404 __HAL_LOCK(hcryp);
2405
2406 inputaddr = (uint32_t)pPlainData;
2407 outputaddr = (uint32_t)pCypherData;
2408
2409 headersize = hcryp->Init.HeaderSize;
2410 headeraddr = (uint32_t)hcryp->Init.Header;
2411
2412 hcryp->CrypInCount = Size;
2413 hcryp->pCrypInBuffPtr = pPlainData;
2414 hcryp->pCrypOutBuffPtr = pCypherData;
2415 hcryp->CrypOutCount = Size;
2416
2417 /* Change the CRYP peripheral state */
2418 hcryp->State = HAL_CRYP_STATE_BUSY;
2419
2420 /* Check if initialization phase has already been performed */
2421 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2422 {
2423 /************************ Formatting the header block *******************/
2424 if(headersize != 0U)
2425 {
2426 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2427 if(headersize < 65280U)
2428 {
2429 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
2430 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
2431 headersize += 2U;
2432 }
2433 else
2434 {
2435 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2436 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
2437 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
2438 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
2439 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
2440 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
2441 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
2442 headersize += 6U;
2443 }
2444 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2445 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
2446 {
2447 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2448 }
2449 /* Check if the header size is modulo 16 */
2450 if ((headersize % 16U) != 0U)
2451 {
2452 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2453 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
2454 {
2455 hcryp->Init.pScratch[loopcounter] = 0U;
2456 }
2457 /* Set the header size to modulo 16 */
2458 headersize = ((headersize/16U) + 1U) * 16U;
2459 }
2460 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2461 headeraddr = (uint32_t)hcryp->Init.pScratch;
2462 }
2463 /*********************** Formatting the block B0 ************************/
2464 if(headersize != 0U)
2465 {
2466 blockb0[0U] = 0x40U;
2467 }
2468 /* Flags byte */
2469 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
2470 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07) << 3);
2471 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2472
2473 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
2474 {
2475 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
2476 }
2477 for ( ; loopcounter < 13U; loopcounter++)
2478 {
2479 blockb0[loopcounter+1U] = 0U;
2480 }
2481
2482 blockb0[14U] = (Size >> 8U);
2483 blockb0[15U] = (Size & 0xFFU);
2484
2485 /************************* Formatting the initial counter ***************/
2486 /* Byte 0:
2487 Bits 7 and 6 are reserved and shall be set to 0
2488 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2489 blocks are distinct from B0
2490 Bits 0, 1, and 2 contain the same encoding of q as in B0
2491 */
2492 ctr[0U] = blockb0[0U] & 0x07U;
2493 /* byte 1 to NonceSize is the IV (Nonce) */
2494 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
2495 {
2496 ctr[loopcounter] = blockb0[loopcounter];
2497 }
2498 /* Set the LSB to 1 */
2499 ctr[15U] |= 0x01U;
2500
2501 /* Set the key */
2502 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2503
2504 /* Set the CRYP peripheral in AES CCM mode */
2505 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
2506
2507 /* Set the Initialization Vector */
2508 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
2509
2510 /* Select init phase */
2511 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2512
2513 b0addr = (uint32_t)blockb0;
2514 /* Write the blockb0 block in the IN FIFO */
2515 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2516 b0addr+=4U;
2517 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2518 b0addr+=4U;
2519 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2520 b0addr+=4U;
2521 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2522
2523 /* Enable the CRYP peripheral */
2524 __HAL_CRYP_ENABLE(hcryp);
2525
2526 /* Get tick */
2527 tickstart = HAL_GetTick();
2528
2529 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2530 {
2531 /* Check for the Timeout */
2532 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2533 {
2534 /* Change state */
2535 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2536
2537 /* Process Unlocked */
2538 __HAL_UNLOCK(hcryp);
2539
2540 return HAL_TIMEOUT;
2541 }
2542 }
2543 /***************************** Header phase *****************************/
2544 if(headersize != 0U)
2545 {
2546 /* Select header phase */
2547 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
2548
2549 /* Enable Crypto processor */
2550 __HAL_CRYP_ENABLE(hcryp);
2551
2552 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
2553 {
2554 /* Get tick */
2555 tickstart = HAL_GetTick();
2556
2557 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
2558 {
2559 /* Check for the Timeout */
2560 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2561 {
2562 /* Change state */
2563 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2564
2565 /* Process Unlocked */
2566 __HAL_UNLOCK(hcryp);
2567
2568 return HAL_TIMEOUT;
2569 }
2570 }
2571 /* Write the header block in the IN FIFO */
2572 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2573 headeraddr+=4U;
2574 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2575 headeraddr+=4U;
2576 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2577 headeraddr+=4U;
2578 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2579 headeraddr+=4U;
2580 }
2581
2582 /* Get tick */
2583 tickstart = HAL_GetTick();
2584
2585 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2586 {
2587 /* Check for the Timeout */
2588 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2589 {
2590 /* Change state */
2591 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2592
2593 /* Process Unlocked */
2594 __HAL_UNLOCK(hcryp);
2595
2596 return HAL_TIMEOUT;
2597 }
2598 }
2599 }
2600 /* Save formatted counter into the scratch buffer pScratch */
2601 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
2602 {
2603 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2604 }
2605 /* Reset bit 0 */
2606 hcryp->Init.pScratch[15U] &= 0xFEU;
2607
2608 /* Select payload phase once the header phase is performed */
2609 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2610
2611 /* Flush FIFO */
2612 __HAL_CRYP_FIFO_FLUSH(hcryp);
2613
2614 /* Set the phase */
2615 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2616 }
2617
2618 /* Set the input and output addresses and start DMA transfer */
2619 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2620
2621 /* Unlock process */
2622 __HAL_UNLOCK(hcryp);
2623
2624 /* Return function status */
2625 return HAL_OK;
2626 }
2627 else
2628 {
2629 return HAL_ERROR;
2630 }
2631 }
2632
2633 /**
2634 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using DMA.
2635 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2636 * the configuration information for CRYP module
2637 * @param pCypherData Pointer to the cyphertext buffer.
2638 * @param Size Length of the cyphertext buffer, must be a multiple of 16
2639 * @param pPlainData Pointer to the plaintext buffer
2640 * @retval HAL status
2641 */
2642 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2643 {
2644 uint32_t tickstart = 0U;
2645 uint32_t inputaddr;
2646 uint32_t outputaddr;
2647
2648 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2649 {
2650 /* Process Locked */
2651 __HAL_LOCK(hcryp);
2652
2653 inputaddr = (uint32_t)pCypherData;
2654 outputaddr = (uint32_t)pPlainData;
2655
2656 /* Change the CRYP peripheral state */
2657 hcryp->State = HAL_CRYP_STATE_BUSY;
2658
2659 /* Check if initialization phase has already been performed */
2660 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2661 {
2662 /* Set the key */
2663 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2664
2665 /* Set the CRYP peripheral in AES GCM decryption mode */
2666 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
2667
2668 /* Set the Initialization Vector */
2669 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
2670
2671 /* Enable CRYP to start the init phase */
2672 __HAL_CRYP_ENABLE(hcryp);
2673
2674 /* Get tick */
2675 tickstart = HAL_GetTick();
2676
2677 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2678 {
2679 /* Check for the Timeout */
2680 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2681 {
2682 /* Change state */
2683 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2684
2685 /* Process Unlocked */
2686 __HAL_UNLOCK(hcryp);
2687
2688 return HAL_TIMEOUT;
2689 }
2690 }
2691
2692 /* Set the header phase */
2693 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
2694 {
2695 return HAL_TIMEOUT;
2696 }
2697 /* Disable the CRYP peripheral */
2698 __HAL_CRYP_DISABLE(hcryp);
2699
2700 /* Select payload phase once the header phase is performed */
2701 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2702
2703 /* Set the phase */
2704 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2705 }
2706
2707 /* Set the input and output addresses and start DMA transfer */
2708 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2709
2710 /* Unlock process */
2711 __HAL_UNLOCK(hcryp);
2712
2713 /* Return function status */
2714 return HAL_OK;
2715 }
2716 else
2717 {
2718 return HAL_ERROR;
2719 }
2720 }
2721
2722 /**
2723 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using DMA
2724 * then decrypted pCypherData. The cypher data are available in pPlainData.
2725 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2726 * the configuration information for CRYP module
2727 * @param pCypherData Pointer to the cyphertext buffer
2728 * @param Size Length of the plaintext buffer, must be a multiple of 16
2729 * @param pPlainData Pointer to the plaintext buffer
2730 * @retval HAL status
2731 */
2732 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
2733 {
2734 uint32_t tickstart = 0U;
2735 uint32_t inputaddr;
2736 uint32_t outputaddr;
2737 uint32_t headersize;
2738 uint32_t headeraddr;
2739 uint32_t loopcounter = 0U;
2740 uint32_t bufferidx = 0U;
2741 uint8_t blockb0[16U] = {0};/* Block B0 */
2742 uint8_t ctr[16U] = {0}; /* Counter */
2743 uint32_t b0addr = (uint32_t)blockb0;
2744
2745 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
2746 {
2747 /* Process Locked */
2748 __HAL_LOCK(hcryp);
2749
2750 inputaddr = (uint32_t)pCypherData;
2751 outputaddr = (uint32_t)pPlainData;
2752
2753 headersize = hcryp->Init.HeaderSize;
2754 headeraddr = (uint32_t)hcryp->Init.Header;
2755
2756 hcryp->CrypInCount = Size;
2757 hcryp->pCrypInBuffPtr = pCypherData;
2758 hcryp->pCrypOutBuffPtr = pPlainData;
2759 hcryp->CrypOutCount = Size;
2760
2761 /* Change the CRYP peripheral state */
2762 hcryp->State = HAL_CRYP_STATE_BUSY;
2763
2764 /* Check if initialization phase has already been performed */
2765 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
2766 {
2767 /************************ Formatting the header block *******************/
2768 if(headersize != 0U)
2769 {
2770 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
2771 if(headersize < 65280U)
2772 {
2773 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
2774 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
2775 headersize += 2U;
2776 }
2777 else
2778 {
2779 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
2780 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
2781 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
2782 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
2783 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
2784 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
2785 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
2786 headersize += 6U;
2787 }
2788 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
2789 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
2790 {
2791 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
2792 }
2793 /* Check if the header size is modulo 16 */
2794 if ((headersize % 16U) != 0U)
2795 {
2796 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
2797 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
2798 {
2799 hcryp->Init.pScratch[loopcounter] = 0U;
2800 }
2801 /* Set the header size to modulo 16 */
2802 headersize = ((headersize/16U) + 1U) * 16U;
2803 }
2804 /* Set the pointer headeraddr to hcryp->Init.pScratch */
2805 headeraddr = (uint32_t)hcryp->Init.pScratch;
2806 }
2807 /*********************** Formatting the block B0 ************************/
2808 if(headersize != 0U)
2809 {
2810 blockb0[0U] = 0x40U;
2811 }
2812 /* Flags byte */
2813 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
2814 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07) << 3);
2815 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
2816
2817 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
2818 {
2819 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
2820 }
2821 for ( ; loopcounter < 13U; loopcounter++)
2822 {
2823 blockb0[loopcounter+1U] = 0U;
2824 }
2825
2826 blockb0[14U] = (Size >> 8U);
2827 blockb0[15U] = (Size & 0xFFU);
2828
2829 /************************* Formatting the initial counter ***************/
2830 /* Byte 0:
2831 Bits 7 and 6 are reserved and shall be set to 0
2832 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
2833 blocks are distinct from B0
2834 Bits 0, 1, and 2 contain the same encoding of q as in B0
2835 */
2836 ctr[0U] = blockb0[0U] & 0x07U;
2837 /* byte 1 to NonceSize is the IV (Nonce) */
2838 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
2839 {
2840 ctr[loopcounter] = blockb0[loopcounter];
2841 }
2842 /* Set the LSB to 1 */
2843 ctr[15U] |= 0x01U;
2844
2845 /* Set the key */
2846 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
2847
2848 /* Set the CRYP peripheral in AES CCM mode */
2849 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
2850
2851 /* Set the Initialization Vector */
2852 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
2853
2854 /* Select init phase */
2855 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2856
2857 b0addr = (uint32_t)blockb0;
2858 /* Write the blockb0 block in the IN FIFO */
2859 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2860 b0addr+=4U;
2861 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2862 b0addr+=4U;
2863 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2864 b0addr+=4U;
2865 hcryp->Instance->DR = *(uint32_t*)(b0addr);
2866
2867 /* Enable the CRYP peripheral */
2868 __HAL_CRYP_ENABLE(hcryp);
2869
2870 /* Get tick */
2871 tickstart = HAL_GetTick();
2872
2873 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2874 {
2875 /* Check for the Timeout */
2876
2877 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2878 {
2879 /* Change state */
2880 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2881
2882 /* Process Unlocked */
2883 __HAL_UNLOCK(hcryp);
2884
2885 return HAL_TIMEOUT;
2886
2887 }
2888 }
2889 /***************************** Header phase *****************************/
2890 if(headersize != 0U)
2891 {
2892 /* Select header phase */
2893 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
2894
2895 /* Enable Crypto processor */
2896 __HAL_CRYP_ENABLE(hcryp);
2897
2898 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
2899 {
2900 /* Get tick */
2901 tickstart = HAL_GetTick();
2902
2903 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
2904 {
2905 /* Check for the Timeout */
2906 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2907 {
2908 /* Change state */
2909 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2910
2911 /* Process Unlocked */
2912 __HAL_UNLOCK(hcryp);
2913
2914 return HAL_TIMEOUT;
2915 }
2916 }
2917 /* Write the header block in the IN FIFO */
2918 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2919 headeraddr+=4U;
2920 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2921 headeraddr+=4U;
2922 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2923 headeraddr+=4U;
2924 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
2925 headeraddr+=4U;
2926 }
2927
2928 /* Get tick */
2929 tickstart = HAL_GetTick();
2930
2931 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
2932 {
2933 /* Check for the Timeout */
2934 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
2935 {
2936 /* Change state */
2937 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
2938
2939 /* Process Unlocked */
2940 __HAL_UNLOCK(hcryp);
2941
2942 return HAL_TIMEOUT;
2943 }
2944 }
2945 }
2946 /* Save formatted counter into the scratch buffer pScratch */
2947 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
2948 {
2949 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
2950 }
2951 /* Reset bit 0 */
2952 hcryp->Init.pScratch[15U] &= 0xFEU;
2953 /* Select payload phase once the header phase is performed */
2954 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2955
2956 /* Flush FIFO */
2957 __HAL_CRYP_FIFO_FLUSH(hcryp);
2958
2959 /* Set the phase */
2960 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
2961 }
2962 /* Set the input and output addresses and start DMA transfer */
2963 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
2964
2965 /* Unlock process */
2966 __HAL_UNLOCK(hcryp);
2967
2968 /* Return function status */
2969 return HAL_OK;
2970 }
2971 else
2972 {
2973 return HAL_ERROR;
2974 }
2975 }
2976
2977 /**
2978 * @}
2979 */
2980
2981 /** @defgroup CRYPEx_Exported_Functions_Group2 CRYPEx IRQ handler management
2982 * @brief CRYPEx IRQ handler.
2983 *
2984 @verbatim
2985 ==============================================================================
2986 ##### CRYPEx IRQ handler management #####
2987 ==============================================================================
2988 [..] This section provides CRYPEx IRQ handler function.
2989
2990 @endverbatim
2991 * @{
2992 */
2993
2994 /**
2995 * @brief This function handles CRYPEx interrupt request.
2996 * @param hcryp pointer to a CRYPEx_HandleTypeDef structure that contains
2997 * the configuration information for CRYP module
2998 * @retval None
2999 */
3000
3001 void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp)
3002 {
3003 switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION)
3004 {
3005 case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT:
3006 HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, NULL, 0U, NULL);
3007 break;
3008
3009 case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT:
3010 HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, NULL, 0U, NULL);
3011 break;
3012
3013 case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT:
3014 HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, NULL, 0U, NULL);
3015 break;
3016
3017 case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT:
3018 HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, NULL, 0U, NULL);
3019 break;
3020
3021 default:
3022 break;
3023 }
3024 }
3025
3026 /**
3027 * @}
3028 */
3029
3030 /**
3031 * @}
3032 */
3033 #endif /* CRYP */
3034
3035 #if defined (AES)
3036
3037 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
3038 * @{
3039 */
3040 #define CRYP_CCF_TIMEOUTVALUE 22000U /*!< CCF flag raising time-out value */
3041 #define CRYP_BUSY_TIMEOUTVALUE 22000U /*!< BUSY flag reset time-out value */
3042
3043 #define CRYP_POLLING_OFF 0x0U /*!< No polling when padding */
3044 #define CRYP_POLLING_ON 0x1U /*!< Polling when padding */
3045 /**
3046 * @}
3047 */
3048
3049 /* Private macro -------------------------------------------------------------*/
3050 /* Private variables ---------------------------------------------------------*/
3051 /* Private function prototypes -----------------------------------------------*/
3052 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
3053 * @{
3054 */
3055 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
3056 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
3057 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
3058 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
3059 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma);
3060 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma);
3061 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma);
3062 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
3063 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
3064 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
3065 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
3066 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
3067 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
3068 /**
3069 * @}
3070 */
3071
3072 /* Exported functions ---------------------------------------------------------*/
3073
3074 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
3075 * @{
3076 */
3077
3078
3079 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function
3080 * @brief Extended callback functions.
3081 *
3082 @verbatim
3083 ===============================================================================
3084 ##### Extended callback functions #####
3085 ===============================================================================
3086 [..] This section provides callback function:
3087 (+) Computation completed.
3088
3089 @endverbatim
3090 * @{
3091 */
3092
3093
3094 /**
3095 * @brief Computation completed callbacks.
3096 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3097 * the configuration information for CRYP module
3098 * @retval None
3099 */
3100 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
3101 {
3102 /* Prevent unused argument(s) compilation warning */
3103 UNUSED(hcryp);
3104
3105 /* NOTE : This function should not be modified; when the callback is needed,
3106 the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
3107 */
3108 }
3109
3110 /**
3111 * @}
3112 */
3113
3114 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions
3115 * @brief Extended processing functions.
3116 *
3117 @verbatim
3118 ==============================================================================
3119 ##### AES extended processing functions #####
3120 ==============================================================================
3121 [..] This section provides functions allowing to:
3122 (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
3123 Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
3124 based on the processing type. Three processing types are available:
3125 (++) Polling mode
3126 (++) Interrupt mode
3127 (++) DMA mode
3128 (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES
3129 algorithm in different chaining modes.
3130 Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase
3131 so that steps can be skipped if so required. Functions are only differentiated based on the processing type.
3132 Three processing types are available:
3133 (++) Polling mode
3134 (++) Interrupt mode
3135 (++) DMA mode
3136
3137 @endverbatim
3138 * @{
3139 */
3140
3141 /**
3142 * @brief Carry out in polling mode the ciphering or deciphering operation according to
3143 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
3144 * chaining modes ECB, CBC and CTR are managed by this function in polling mode.
3145 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3146 * the configuration information for CRYP module
3147 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
3148 * or key derivation+decryption.
3149 * Parameter is meaningless in case of key derivation.
3150 * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
3151 * Parameter is meaningless in case of key derivation.
3152 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
3153 * decryption/key derivation+decryption, or pointer to the derivative keys in
3154 * case of key derivation only.
3155 * @param Timeout Specify Timeout value
3156 * @retval HAL status
3157 */
3158 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
3159 {
3160
3161 if (hcryp->State == HAL_CRYP_STATE_READY)
3162 {
3163 /* Check parameters setting */
3164 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
3165 {
3166 if (pOutputData == NULL)
3167 {
3168 return HAL_ERROR;
3169 }
3170 }
3171 else
3172 {
3173 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
3174 {
3175 return HAL_ERROR;
3176 }
3177 }
3178
3179 /* Process Locked */
3180 __HAL_LOCK(hcryp);
3181
3182 /* Change the CRYP state */
3183 hcryp->State = HAL_CRYP_STATE_BUSY;
3184
3185 /* Call CRYP_ReadKey() API if the operating mode is set to
3186 key derivation, CRYP_ProcessData() otherwise */
3187 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
3188 {
3189 if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
3190 {
3191 return HAL_TIMEOUT;
3192 }
3193 }
3194 else
3195 {
3196 if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
3197 {
3198 return HAL_TIMEOUT;
3199 }
3200 }
3201
3202 /* If the state has not been set to SUSPENDED, set it to
3203 READY, otherwise keep it as it is */
3204 if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
3205 {
3206 hcryp->State = HAL_CRYP_STATE_READY;
3207 }
3208
3209 /* Process Unlocked */
3210 __HAL_UNLOCK(hcryp);
3211
3212 return HAL_OK;
3213 }
3214 else
3215 {
3216 return HAL_BUSY;
3217 }
3218 }
3219
3220 /**
3221 * @brief Carry out in interrupt mode the ciphering or deciphering operation according to
3222 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
3223 * chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
3224 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3225 * the configuration information for CRYP module
3226 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
3227 * or key derivation+decryption.
3228 * Parameter is meaningless in case of key derivation.
3229 * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
3230 * Parameter is meaningless in case of key derivation.
3231 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
3232 * decryption/key derivation+decryption, or pointer to the derivative keys in
3233 * case of key derivation only.
3234 * @retval HAL status
3235 */
3236 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
3237 {
3238 uint32_t inputaddr = 0U;
3239
3240 if(hcryp->State == HAL_CRYP_STATE_READY)
3241 {
3242 /* Check parameters setting */
3243 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
3244 {
3245 if (pOutputData == NULL)
3246 {
3247 return HAL_ERROR;
3248 }
3249 }
3250 else
3251 {
3252 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
3253 {
3254 return HAL_ERROR;
3255 }
3256 }
3257 /* Process Locked */
3258 __HAL_LOCK(hcryp);
3259
3260 /* If operating mode is not limited to key derivation only,
3261 get the buffers addresses and sizes */
3262 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
3263 {
3264
3265 hcryp->CrypInCount = Size;
3266 hcryp->pCrypInBuffPtr = pInputData;
3267 hcryp->pCrypOutBuffPtr = pOutputData;
3268 hcryp->CrypOutCount = Size;
3269 }
3270
3271 /* Change the CRYP state */
3272 hcryp->State = HAL_CRYP_STATE_BUSY;
3273
3274 /* Process Unlocked */
3275 __HAL_UNLOCK(hcryp);
3276
3277 /* Enable Computation Complete Flag and Error Interrupts */
3278 __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
3279
3280 /* If operating mode is key derivation only, the input data have
3281 already been entered during the initialization process. For
3282 the other operating modes, they are fed to the CRYP hardware
3283 block at this point. */
3284 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
3285 {
3286 /* Initiate the processing under interrupt in entering
3287 the first input data */
3288 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
3289 /* Increment/decrement instance pointer/counter */
3290 hcryp->pCrypInBuffPtr += 16U;
3291 hcryp->CrypInCount -= 16U;
3292 /* Write the first input block in the Data Input register */
3293 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3294 inputaddr+=4U;
3295 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3296 inputaddr+=4U;
3297 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3298 inputaddr+=4U;
3299 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3300 }
3301
3302 /* Return function status */
3303 return HAL_OK;
3304 }
3305 else
3306 {
3307 return HAL_BUSY;
3308 }
3309 }
3310
3311 /**
3312 * @brief Carry out in DMA mode the ciphering or deciphering operation according to
3313 * hcryp->Init structure fields.
3314 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3315 * the configuration information for CRYP module
3316 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
3317 * or key derivation+decryption.
3318 * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
3319 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
3320 * decryption/key derivation+decryption.
3321 * @note Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.
3322 * @note Supported operating modes are encryption, decryption and key derivation with decryption.
3323 * @note No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx
3324 * registers must be done by software.
3325 * @note This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx
3326 * registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
3327 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
3328 * @retval HAL status
3329 */
3330 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
3331 {
3332 uint32_t inputaddr = 0U;
3333 uint32_t outputaddr = 0U;
3334
3335 if (hcryp->State == HAL_CRYP_STATE_READY)
3336 {
3337 /* Check parameters setting */
3338 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
3339 {
3340 /* no DMA channel is provided for key derivation operating mode,
3341 access to AES_KEYRx registers must be done by software */
3342 return HAL_ERROR;
3343 }
3344 else
3345 {
3346 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
3347 {
3348 return HAL_ERROR;
3349 }
3350 }
3351
3352 /* Process Locked */
3353 __HAL_LOCK(hcryp);
3354
3355 inputaddr = (uint32_t)pInputData;
3356 outputaddr = (uint32_t)pOutputData;
3357
3358 /* Change the CRYP state */
3359 hcryp->State = HAL_CRYP_STATE_BUSY;
3360
3361 /* Set the input and output addresses and start DMA transfer */
3362 CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
3363
3364 /* Process Unlocked */
3365 __HAL_UNLOCK(hcryp);
3366
3367 /* Return function status */
3368 return HAL_OK;
3369 }
3370 else
3371 {
3372 return HAL_BUSY;
3373 }
3374 }
3375
3376 /**
3377 * @brief Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering
3378 * operation according to hcryp->Init structure fields.
3379 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3380 * the configuration information for CRYP module
3381 * @param pInputData
3382 * - pointer to payload data in GCM payload phase,
3383 * - pointer to B0 block in CMAC header phase,
3384 * - pointer to C block in CMAC final phase.
3385 * - Parameter is meaningless in case of GCM/GMAC init, header and final phases.
3386 * @param Size
3387 * - length of the input payload data buffer in bytes,
3388 * - length of B0 block (in bytes) in CMAC header phase,
3389 * - length of C block (in bytes) in CMAC final phase.
3390 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
3391 * @param pOutputData
3392 * - pointer to plain or cipher text in GCM payload phase,
3393 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
3394 * - Parameter is meaningless in case of GCM/GMAC init and header phases
3395 * and in case of CMAC header phase.
3396 * @param Timeout Specify Timeout value
3397 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable.
3398 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
3399 * can be skipped by the user if so required.
3400 * @retval HAL status
3401 */
3402 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
3403 {
3404 uint32_t index = 0U;
3405 uint32_t inputaddr = 0U;
3406 uint32_t outputaddr = 0U;
3407 uint32_t tagaddr = 0U;
3408 uint64_t headerlength = 0U;
3409 uint64_t inputlength = 0U;
3410 uint64_t payloadlength = 0U;
3411 uint32_t difflength = 0U;
3412 uint32_t addhoc_process = 0U;
3413
3414 if (hcryp->State == HAL_CRYP_STATE_READY)
3415 {
3416 /* input/output parameters check */
3417 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
3418 {
3419 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
3420 {
3421 return HAL_ERROR;
3422 }
3423 #if defined(AES_CR_NPBLB)
3424 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
3425 #else
3426 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
3427 #endif
3428 {
3429 /* In case of CMAC (or CCM) header phase resumption, we can have pInputData = NULL and Size = 0 */
3430 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
3431 {
3432 return HAL_ERROR;
3433 }
3434 }
3435 }
3436 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
3437 {
3438 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
3439 {
3440 return HAL_ERROR;
3441 }
3442 }
3443 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
3444 {
3445 if (pOutputData == NULL)
3446 {
3447 return HAL_ERROR;
3448 }
3449 #if defined(AES_CR_NPBLB)
3450 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
3451 #else
3452 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
3453 #endif
3454 {
3455 return HAL_ERROR;
3456 }
3457 }
3458
3459 /* Process Locked */
3460 __HAL_LOCK(hcryp);
3461
3462 /* Change the CRYP state */
3463 hcryp->State = HAL_CRYP_STATE_BUSY;
3464
3465 /*==============================================*/
3466 /* GCM/GMAC (or CCM when applicable) init phase */
3467 /*==============================================*/
3468 /* In case of init phase, the input data (Key and Initialization Vector) have
3469 already been entered during the initialization process. Therefore, the
3470 API just waits for the CCF flag to be set. */
3471 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
3472 {
3473 /* just wait for hash computation */
3474 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3475 {
3476 hcryp->State = HAL_CRYP_STATE_READY;
3477 __HAL_UNLOCK(hcryp);
3478 return HAL_TIMEOUT;
3479 }
3480
3481 /* Clear CCF Flag */
3482 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
3483 /* Mark that the initialization phase is over */
3484 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
3485 }
3486 /*=====================================*/
3487 /* GCM/GMAC or (CCM/)CMAC header phase */
3488 /*=====================================*/
3489 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
3490 {
3491 /* Set header phase; for GCM or GMAC, set data-byte at this point */
3492 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
3493 {
3494 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
3495 }
3496 else
3497 {
3498 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
3499 }
3500
3501 /* Enable the Peripheral */
3502 __HAL_CRYP_ENABLE();
3503
3504 #if !defined(AES_CR_NPBLB)
3505 /* in case of CMAC, enter B0 block in header phase, before the header itself. */
3506 /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
3507 skip these steps and go directly to header buffer feeding to the HW */
3508 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U))
3509 {
3510 inputaddr = (uint32_t)pInputData;
3511
3512 for(index=0U; (index < Size); index += 16U)
3513 {
3514 /* Write the Input block in the Data Input register */
3515 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3516 inputaddr+=4U;
3517 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3518 inputaddr+=4U;
3519 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3520 inputaddr+=4U;
3521 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3522 inputaddr+=4U;
3523
3524 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3525 {
3526 hcryp->State = HAL_CRYP_STATE_READY;
3527 __HAL_UNLOCK(hcryp);
3528 return HAL_TIMEOUT;
3529 }
3530 /* Clear CCF Flag */
3531 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
3532
3533 /* If the suspension flag has been raised and if the processing is not about
3534 to end, suspend processing */
3535 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Size))
3536 {
3537 /* reset SuspendRequest */
3538 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
3539 /* Change the CRYP state */
3540 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
3541 /* Mark that the header phase is over */
3542 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
3543
3544 /* Save current reading and writing locations of Input and Output buffers */
3545 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
3546 /* Save the total number of bytes (B blocks + header) that remain to be
3547 processed at this point */
3548 hcryp->CrypInCount = hcryp->Init.HeaderSize + Size - (index+16U);
3549
3550 /* Process Unlocked */
3551 __HAL_UNLOCK(hcryp);
3552
3553 return HAL_OK;
3554 }
3555 } /* for(index=0; (index < Size); index += 16) */
3556 }
3557 #endif /* !defined(AES_CR_NPBLB) */
3558
3559 /* Enter header */
3560 inputaddr = (uint32_t)hcryp->Init.Header;
3561 /* Local variable headerlength is a number of bytes multiple of 128 bits,
3562 remaining header data (if any) are handled after this loop */
3563 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
3564 if ((hcryp->Init.HeaderSize % 16U) != 0U)
3565 {
3566 difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);
3567 }
3568 for(index=0U; index < headerlength; index += 16U)
3569 {
3570 /* Write the Input block in the Data Input register */
3571 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3572 inputaddr+=4U;
3573 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3574 inputaddr+=4U;
3575 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3576 inputaddr+=4U;
3577 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3578 inputaddr+=4U;
3579
3580 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3581 {
3582 hcryp->State = HAL_CRYP_STATE_READY;
3583 __HAL_UNLOCK(hcryp);
3584 return HAL_TIMEOUT;
3585 }
3586 /* Clear CCF Flag */
3587 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
3588
3589 /* If the suspension flag has been raised and if the processing is not about
3590 to end, suspend processing */
3591 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < headerlength))
3592 {
3593 /* reset SuspendRequest */
3594 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
3595 /* Change the CRYP state */
3596 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
3597 /* Mark that the header phase is over */
3598 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
3599
3600 /* Save current reading and writing locations of Input and Output buffers */
3601 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
3602 /* Save the total number of bytes that remain to be processed at this point */
3603 hcryp->CrypInCount = hcryp->Init.HeaderSize - (index+16U);
3604
3605 /* Process Unlocked */
3606 __HAL_UNLOCK(hcryp);
3607
3608 return HAL_OK;
3609 }
3610 }
3611
3612 /* Case header length is not a multiple of 16 bytes */
3613 if (difflength != 0U)
3614 {
3615 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
3616 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
3617 }
3618
3619 /* Mark that the header phase is over */
3620 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
3621 }
3622 /*============================================*/
3623 /* GCM (or CCM when applicable) payload phase */
3624 /*============================================*/
3625 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
3626 {
3627
3628 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
3629
3630 /* if the header phase has been bypassed, AES must be enabled again */
3631 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
3632 {
3633 __HAL_CRYP_ENABLE();
3634 }
3635
3636 inputaddr = (uint32_t)pInputData;
3637 outputaddr = (uint32_t)pOutputData;
3638
3639 /* Enter payload */
3640 /* Specific handling to manage payload last block size less than 128 bits */
3641 if ((Size % 16U) != 0U)
3642 {
3643 payloadlength = (Size/16U) * 16U;
3644 difflength = (uint32_t) (Size - payloadlength);
3645 addhoc_process = 1U;
3646 }
3647 else
3648 {
3649 payloadlength = Size;
3650 addhoc_process = 0U;
3651 }
3652
3653 /* Feed payload */
3654 for(index=0U; index < payloadlength; index += 16U)
3655 {
3656 /* Write the Input block in the Data Input register */
3657 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3658 inputaddr+=4U;
3659 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3660 inputaddr+=4U;
3661 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3662 inputaddr+=4U;
3663 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3664 inputaddr+=4U;
3665
3666 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3667 {
3668 hcryp->State = HAL_CRYP_STATE_READY;
3669 __HAL_UNLOCK(hcryp);
3670 return HAL_TIMEOUT;
3671 }
3672
3673 /* Clear CCF Flag */
3674 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
3675
3676 /* Retrieve output data: read the output block
3677 from the Data Output Register */
3678 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
3679 outputaddr+=4U;
3680 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
3681 outputaddr+=4U;
3682 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
3683 outputaddr+=4U;
3684 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
3685 outputaddr+=4U;
3686
3687 /* If the suspension flag has been raised and if the processing is not about
3688 to end, suspend processing */
3689 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < payloadlength))
3690 {
3691 /* no flag waiting under IRQ handling */
3692 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
3693 {
3694 /* Ensure that Busy flag is reset */
3695 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
3696 {
3697 hcryp->State = HAL_CRYP_STATE_READY;
3698 __HAL_UNLOCK(hcryp);
3699 return HAL_TIMEOUT;
3700 }
3701 }
3702 /* reset SuspendRequest */
3703 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
3704 /* Change the CRYP state */
3705 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
3706 /* Mark that the header phase is over */
3707 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
3708
3709 /* Save current reading and writing locations of Input and Output buffers */
3710 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
3711 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
3712 /* Save the number of bytes that remain to be processed at this point */
3713 hcryp->CrypInCount = Size - (index+16U);
3714
3715 /* Process Unlocked */
3716 __HAL_UNLOCK(hcryp);
3717
3718 return HAL_OK;
3719 }
3720
3721 }
3722
3723 /* Additional processing to manage GCM(/CCM) encryption and decryption cases when
3724 payload last block size less than 128 bits */
3725 if (addhoc_process == 1U)
3726 {
3727 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
3728 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
3729 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
3730 } /* (addhoc_process == 1) */
3731
3732 /* Mark that the payload phase is over */
3733 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
3734 }
3735 /*====================================*/
3736 /* GCM/GMAC or (CCM/)CMAC final phase */
3737 /*====================================*/
3738 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
3739 {
3740 tagaddr = (uint32_t)pOutputData;
3741
3742 #if defined(AES_CR_NPBLB)
3743 /* By default, clear NPBLB field */
3744 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
3745 #endif
3746
3747 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
3748
3749 /* if the header and payload phases have been bypassed, AES must be enabled again */
3750 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
3751 {
3752 __HAL_CRYP_ENABLE();
3753 }
3754
3755 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
3756 {
3757 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
3758 inputlength = Size * 8U; /* input length in bits */
3759
3760
3761 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
3762 {
3763 hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
3764 hcryp->Instance->DINR = __RBIT(headerlength);
3765 hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
3766 hcryp->Instance->DINR = __RBIT(inputlength);
3767 }
3768 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
3769 {
3770 hcryp->Instance->DINR = __REV((headerlength)>>32U);
3771 hcryp->Instance->DINR = __REV(headerlength);
3772 hcryp->Instance->DINR = __REV((inputlength)>>32U);
3773 hcryp->Instance->DINR = __REV(inputlength);
3774 }
3775 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
3776 {
3777 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
3778 hcryp->Instance->DINR = __ROR(headerlength, 16U);
3779 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
3780 hcryp->Instance->DINR = __ROR(inputlength, 16U);
3781 }
3782 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
3783 {
3784 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
3785 hcryp->Instance->DINR = (uint32_t)(headerlength);
3786 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
3787 hcryp->Instance->DINR = (uint32_t)(inputlength);
3788 }
3789 }
3790 #if !defined(AES_CR_NPBLB)
3791 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
3792 {
3793 inputaddr = (uint32_t)pInputData;
3794 /* Enter the last block made of a 128-bit value formatted
3795 from the original B0 packet. */
3796 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3797 inputaddr+=4U;
3798 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3799 inputaddr+=4U;
3800 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3801 inputaddr+=4U;
3802 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3803 }
3804 #endif
3805
3806
3807 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3808 {
3809 hcryp->State = HAL_CRYP_STATE_READY;
3810 __HAL_UNLOCK(hcryp);
3811 return HAL_TIMEOUT;
3812 }
3813
3814 /* Read the Auth TAG in the Data Out register */
3815 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
3816 tagaddr+=4U;
3817 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
3818 tagaddr+=4U;
3819 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
3820 tagaddr+=4U;
3821 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
3822
3823
3824 /* Clear CCF Flag */
3825 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
3826 /* Mark that the final phase is over */
3827 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
3828 /* Disable the Peripheral */
3829 __HAL_CRYP_DISABLE();
3830 }
3831 /*=================================================*/
3832 /* case incorrect hcryp->Init.GCMCMACPhase setting */
3833 /*=================================================*/
3834 else
3835 {
3836 hcryp->State = HAL_CRYP_STATE_ERROR;
3837 __HAL_UNLOCK(hcryp);
3838 return HAL_ERROR;
3839 }
3840
3841 /* Change the CRYP state */
3842 hcryp->State = HAL_CRYP_STATE_READY;
3843
3844 /* Process Unlocked */
3845 __HAL_UNLOCK(hcryp);
3846
3847 return HAL_OK;
3848 }
3849 else
3850 {
3851 return HAL_BUSY;
3852 }
3853 }
3854
3855
3856
3857
3858 /**
3859 * @brief Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering
3860 * operation according to hcryp->Init structure fields.
3861 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3862 * the configuration information for CRYP module
3863 * @param pInputData
3864 * - pointer to payload data in GCM payload phase,
3865 * - pointer to B0 block in CMAC header phase,
3866 * - pointer to C block in CMAC final phase.
3867 * Parameter is meaningless in case of GCM/GMAC init, header and final phases.
3868 * @param Size
3869 * - length of the input payload data buffer in bytes,
3870 * - length of B0 block (in bytes) in CMAC header phase,
3871 * - length of C block (in bytes) in CMAC final phase.
3872 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
3873 * @param pOutputData
3874 * - pointer to plain or cipher text in GCM payload phase,
3875 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
3876 * - Parameter is meaningless in case of GCM/GMAC init and header phases
3877 * and in case of CMAC header phase.
3878 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
3879 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
3880 * can be skipped by the user if so required.
3881 * @retval HAL status
3882 */
3883 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
3884 {
3885
3886 uint32_t inputaddr = 0U;
3887 uint64_t headerlength = 0U;
3888 uint64_t inputlength = 0U;
3889 uint32_t index = 0U;
3890 uint32_t addhoc_process = 0U;
3891 uint32_t difflength = 0U;
3892 uint32_t difflengthmod4 = 0U;
3893 uint32_t mask[3U] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
3894
3895
3896 if (hcryp->State == HAL_CRYP_STATE_READY)
3897 {
3898 /* input/output parameters check */
3899 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
3900 {
3901 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
3902 {
3903 return HAL_ERROR;
3904 }
3905 #if defined(AES_CR_NPBLB)
3906 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
3907 #else
3908 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
3909 #endif
3910 {
3911 /* In case of CMAC header phase resumption, we can have pInputData = NULL and Size = 0 */
3912 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
3913 {
3914 return HAL_ERROR;
3915 }
3916 }
3917 }
3918 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
3919 {
3920 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
3921 {
3922 return HAL_ERROR;
3923 }
3924 }
3925 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
3926 {
3927 if (pOutputData == NULL)
3928 {
3929 return HAL_ERROR;
3930 }
3931 #if defined(AES_CR_NPBLB)
3932 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
3933 #else
3934 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
3935 #endif
3936 {
3937 return HAL_ERROR;
3938 }
3939 }
3940
3941 /* Process Locked */
3942 __HAL_LOCK(hcryp);
3943
3944 /* Change the CRYP state */
3945 hcryp->State = HAL_CRYP_STATE_BUSY;
3946
3947 /* Process Unlocked */
3948 __HAL_UNLOCK(hcryp);
3949
3950 /* Enable Computation Complete Flag and Error Interrupts */
3951 __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
3952
3953 /*==============================================*/
3954 /* GCM/GMAC (or CCM when applicable) init phase */
3955 /*==============================================*/
3956 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
3957 {
3958 /* In case of init phase, the input data (Key and Initialization Vector) have
3959 already been entered during the initialization process. Therefore, the
3960 software just waits for the CCF interrupt to be raised and which will
3961 be handled by CRYP_AES_Auth_IT() API. */
3962 }
3963 /*=====================================*/
3964 /* GCM/GMAC or (CCM/)CMAC header phase */
3965 /*=====================================*/
3966 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
3967 {
3968
3969 #if defined(AES_CR_NPBLB)
3970 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
3971 #else
3972 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
3973 #endif
3974 {
3975 /* In case of CMAC, B blocks are first entered, before the header.
3976 Therefore, B blocks and the header are entered back-to-back
3977 as if it was only one single block.
3978 However, in case of resumption after suspension, if all the
3979 B blocks have been entered (in that case, Size = 0), only the
3980 remainder of the non-processed header bytes are entered. */
3981 if (Size != 0U)
3982 {
3983 hcryp->CrypInCount = Size + hcryp->Init.HeaderSize;
3984 hcryp->pCrypInBuffPtr = pInputData;
3985 }
3986 else
3987 {
3988 hcryp->CrypInCount = hcryp->Init.HeaderSize;
3989 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
3990 }
3991 }
3992 else
3993 {
3994 /* Get the header addresses and sizes */
3995 hcryp->CrypInCount = hcryp->Init.HeaderSize;
3996 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
3997 }
3998
3999 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
4000
4001 /* Set header phase; for GCM or GMAC, set data-byte at this point */
4002 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
4003 {
4004 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
4005 }
4006 else
4007 {
4008 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
4009 }
4010
4011 /* Enable the Peripheral */
4012 __HAL_CRYP_ENABLE();
4013
4014 /* Increment/decrement instance pointer/counter */
4015 if (hcryp->CrypInCount == 0U)
4016 {
4017 /* Case of no header */
4018 hcryp->State = HAL_CRYP_STATE_READY;
4019 return HAL_OK;
4020 }
4021 else if (hcryp->CrypInCount < 16U)
4022 {
4023 hcryp->CrypInCount = 0U;
4024 addhoc_process = 1U;
4025 difflength = (uint32_t) (hcryp->Init.HeaderSize);
4026 difflengthmod4 = difflength%4U;
4027 }
4028 else
4029 {
4030 hcryp->pCrypInBuffPtr += 16U;
4031 hcryp->CrypInCount -= 16U;
4032 }
4033
4034 #if defined(AES_CR_NPBLB)
4035 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
4036 #else
4037 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
4038 #endif
4039 {
4040 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
4041 {
4042 /* All B blocks will have been entered after the next
4043 four DINR writing, so point at header buffer for
4044 the next iteration */
4045 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
4046 }
4047 }
4048
4049 /* Enter header first block to initiate the process
4050 in the Data Input register */
4051 if (addhoc_process == 0U)
4052 {
4053 /* Header has size equal or larger than 128 bits */
4054 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4055 inputaddr+=4U;
4056 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4057 inputaddr+=4U;
4058 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4059 inputaddr+=4U;
4060 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4061 }
4062 else
4063 {
4064 /* Header has size less than 128 bits */
4065 /* Enter complete words when possible */
4066 for(index=0U; index < (difflength/4U); index ++)
4067 {
4068 /* Write the Input block in the Data Input register */
4069 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4070 inputaddr+=4U;
4071 }
4072 /* Enter incomplete word padded with zeroes if applicable
4073 (case of header length not a multiple of 32-bits) */
4074 if (difflengthmod4 != 0U)
4075 {
4076 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
4077 }
4078 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
4079 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
4080 {
4081 hcryp->Instance->DINR = 0U;
4082 }
4083
4084 }
4085 }
4086 /*============================================*/
4087 /* GCM (or CCM when applicable) payload phase */
4088 /*============================================*/
4089 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
4090 {
4091 /* Get the buffer addresses and sizes */
4092 hcryp->CrypInCount = Size;
4093 hcryp->pCrypInBuffPtr = pInputData;
4094 hcryp->pCrypOutBuffPtr = pOutputData;
4095 hcryp->CrypOutCount = Size;
4096
4097 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
4098
4099 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCM_PAYLOAD_PHASE);
4100
4101 /* if the header phase has been bypassed, AES must be enabled again */
4102 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
4103 {
4104 __HAL_CRYP_ENABLE();
4105 }
4106
4107 /* Specific handling to manage payload size less than 128 bits */
4108 if (Size < 16U)
4109 {
4110 #if defined(AES_CR_NPBLB)
4111 /* In case of GCM encryption or CCM decryption, specify the number of padding
4112 bytes in last block of payload */
4113 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
4114 {
4115 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
4116 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))
4117 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
4118 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
4119 {
4120 /* Set NPBLB field in writing the number of padding bytes
4121 for the last block of payload */
4122 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
4123 }
4124 }
4125 #else
4126 /* Software workaround applied to GCM encryption only */
4127 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
4128 {
4129 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
4130 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
4131 }
4132 #endif
4133
4134 /* Set hcryp->CrypInCount to 0 (no more data to enter) */
4135 hcryp->CrypInCount = 0U;
4136
4137 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes,
4138 to have a complete block of 128 bits */
4139 difflength = (uint32_t) (Size);
4140 difflengthmod4 = difflength%4U;
4141 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
4142 to have a complete block of 128 bits */
4143 for(index=0U; index < (difflength/4U); index ++)
4144 {
4145 /* Write the Input block in the Data Input register */
4146 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4147 inputaddr+=4U;
4148 }
4149 /* If required, manage input data size not multiple of 32 bits */
4150 if (difflengthmod4 != 0U)
4151 {
4152 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
4153 }
4154 /* Wrap-up in padding with zero-words if applicable */
4155 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
4156 {
4157 hcryp->Instance->DINR = 0U;
4158 }
4159 }
4160 else
4161 {
4162 /* Increment/decrement instance pointer/counter */
4163 hcryp->pCrypInBuffPtr += 16U;
4164 hcryp->CrypInCount -= 16U;
4165
4166 /* Enter payload first block to initiate the process
4167 in the Data Input register */
4168 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4169 inputaddr+=4U;
4170 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4171 inputaddr+=4U;
4172 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4173 inputaddr+=4U;
4174 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4175 }
4176 }
4177 /*====================================*/
4178 /* GCM/GMAC or (CCM/)CMAC final phase */
4179 /*====================================*/
4180 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
4181 {
4182 hcryp->pCrypOutBuffPtr = pOutputData;
4183
4184 #if defined(AES_CR_NPBLB)
4185 /* By default, clear NPBLB field */
4186 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
4187 #endif
4188
4189 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
4190
4191 /* if the header and payload phases have been bypassed, AES must be enabled again */
4192 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
4193 {
4194 __HAL_CRYP_ENABLE();
4195 }
4196
4197 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
4198 {
4199 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
4200 inputlength = Size * 8U; /* Input length in bits */
4201 /* Write the number of bits in the header on 64 bits followed by the number
4202 of bits in the payload on 64 bits as well */
4203 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
4204 {
4205 hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
4206 hcryp->Instance->DINR = __RBIT(headerlength);
4207 hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
4208 hcryp->Instance->DINR = __RBIT(inputlength);
4209 }
4210 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
4211 {
4212 hcryp->Instance->DINR = __REV((headerlength)>>32U);
4213 hcryp->Instance->DINR = __REV(headerlength);
4214 hcryp->Instance->DINR = __REV((inputlength)>>32U);
4215 hcryp->Instance->DINR = __REV(inputlength);
4216 }
4217 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
4218 {
4219 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
4220 hcryp->Instance->DINR = __ROR(headerlength, 16U);
4221 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
4222 hcryp->Instance->DINR = __ROR(inputlength, 16U);
4223 }
4224 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
4225 {
4226 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
4227 hcryp->Instance->DINR = (uint32_t)(headerlength);
4228 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
4229 hcryp->Instance->DINR = (uint32_t)(inputlength);
4230 }
4231 }
4232 #if !defined(AES_CR_NPBLB)
4233 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
4234 {
4235 inputaddr = (uint32_t)pInputData;
4236 /* Enter the last block made of a 128-bit value formatted
4237 from the original B0 packet. */
4238 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4239 inputaddr+=4U;
4240 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4241 inputaddr+=4U;
4242 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4243 inputaddr+=4U;
4244 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4245 inputaddr+=4U;
4246 }
4247 #endif
4248 }
4249 /*=================================================*/
4250 /* case incorrect hcryp->Init.GCMCMACPhase setting */
4251 /*=================================================*/
4252 else
4253 {
4254 hcryp->State = HAL_CRYP_STATE_ERROR;
4255 return HAL_ERROR;
4256 }
4257
4258 return HAL_OK;
4259 }
4260 else
4261 {
4262 return HAL_BUSY;
4263 }
4264 }
4265
4266
4267
4268
4269 /**
4270 * @brief Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering
4271 * operation according to hcryp->Init structure fields.
4272 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4273 * the configuration information for CRYP module
4274 * @param pInputData
4275 * - pointer to payload data in GCM payload phase,
4276 * - pointer to B0 block in CMAC header phase,
4277 * - pointer to C block in CMAC final phase.
4278 * - Parameter is meaningless in case of GCM/GMAC init, header and final phases.
4279 * @param Size
4280 * - length of the input payload data buffer in bytes,
4281 * - length of B block (in bytes) in CMAC header phase,
4282 * - length of C block (in bytes) in CMAC final phase.
4283 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
4284 * @param pOutputData
4285 * - pointer to plain or cipher text in GCM payload phase,
4286 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
4287 * - Parameter is meaningless in case of GCM/GMAC init and header phases
4288 * and in case of CMAC header phase.
4289 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
4290 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
4291 * can be skipped by the user if so required.
4292 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
4293 * @retval HAL status
4294 */
4295 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
4296 {
4297 uint32_t inputaddr = 0U;
4298 uint32_t outputaddr = 0U;
4299 uint32_t tagaddr = 0U;
4300 uint64_t headerlength = 0U;
4301 uint64_t inputlength = 0U;
4302 uint64_t payloadlength = 0U;
4303
4304
4305 if (hcryp->State == HAL_CRYP_STATE_READY)
4306 {
4307 /* input/output parameters check */
4308 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
4309 {
4310 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
4311 {
4312 return HAL_ERROR;
4313 }
4314 #if defined(AES_CR_NPBLB)
4315 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
4316 #else
4317 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
4318 #endif
4319 {
4320 if ((pInputData == NULL) || (Size == 0U))
4321 {
4322 return HAL_ERROR;
4323 }
4324 }
4325 }
4326 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
4327 {
4328 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
4329 {
4330 return HAL_ERROR;
4331 }
4332 }
4333 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
4334 {
4335 if (pOutputData == NULL)
4336 {
4337 return HAL_ERROR;
4338 }
4339 #if defined(AES_CR_NPBLB)
4340 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
4341 #else
4342 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
4343 #endif
4344 {
4345 return HAL_ERROR;
4346 }
4347 }
4348
4349 /* Process Locked */
4350 __HAL_LOCK(hcryp);
4351
4352 /* Change the CRYP state */
4353 hcryp->State = HAL_CRYP_STATE_BUSY;
4354
4355 /*==============================================*/
4356 /* GCM/GMAC (or CCM when applicable) init phase */
4357 /*==============================================*/
4358 /* In case of init phase, the input data (Key and Initialization Vector) have
4359 already been entered during the initialization process. No DMA transfer is
4360 required at that point therefore, the software just waits for the CCF flag
4361 to be raised. */
4362 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
4363 {
4364 /* just wait for hash computation */
4365 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
4366 {
4367 hcryp->State = HAL_CRYP_STATE_READY;
4368 __HAL_UNLOCK(hcryp);
4369 return HAL_TIMEOUT;
4370 }
4371
4372 /* Clear CCF Flag */
4373 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
4374 /* Mark that the initialization phase is over */
4375 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
4376 hcryp->State = HAL_CRYP_STATE_READY;
4377 }
4378 /*===============================*/
4379 /* GCM/GMAC or CMAC header phase */
4380 /*===============================*/
4381 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
4382 {
4383 /* Set header phase; for GCM or GMAC, set data-byte at this point */
4384 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
4385 {
4386 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_GCMCMAC_HEADER_PHASE|hcryp->Init.DataType);
4387 }
4388 else
4389 {
4390 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_HEADER_PHASE);
4391 }
4392
4393 #if !defined(AES_CR_NPBLB)
4394 /* enter first B0 block in polling mode (no DMA transfer for B0) */
4395 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
4396 {
4397 /* Enable the CRYP peripheral */
4398 __HAL_CRYP_ENABLE();
4399
4400 inputaddr = (uint32_t)pInputData;
4401 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4402 inputaddr+=4U;
4403 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4404 inputaddr+=4U;
4405 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4406 inputaddr+=4U;
4407 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4408
4409 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
4410 {
4411 hcryp->State = HAL_CRYP_STATE_READY;
4412 __HAL_UNLOCK(hcryp);
4413 return HAL_TIMEOUT;
4414 }
4415 /* Clear CCF Flag */
4416 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
4417 }
4418 #endif
4419
4420 /* No header case */
4421 if (hcryp->Init.Header == NULL)
4422 {
4423 hcryp->State = HAL_CRYP_STATE_READY;
4424 /* Mark that the header phase is over */
4425 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
4426 /* Process Unlocked */
4427 __HAL_UNLOCK(hcryp);
4428
4429 return HAL_OK;
4430 }
4431
4432 inputaddr = (uint32_t)hcryp->Init.Header;
4433 if ((hcryp->Init.HeaderSize % 16U) != 0U)
4434 {
4435
4436 if (hcryp->Init.HeaderSize < 16U)
4437 {
4438 CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);
4439
4440 hcryp->State = HAL_CRYP_STATE_READY;
4441 /* Mark that the header phase is over */
4442 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
4443
4444 /* CCF flag indicating header phase AES processing completion
4445 will be checked at the start of the next phase:
4446 - payload phase (GCM / CCM when applicable)
4447 - final phase (GMAC or CMAC). */
4448 }
4449 else
4450 {
4451 /* Local variable headerlength is a number of bytes multiple of 128 bits,
4452 remaining header data (if any) are handled after this loop */
4453 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
4454 /* Store the ending transfer point */
4455 hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
4456 hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */
4457
4458 /* Set the input and output addresses and start DMA transfer */
4459 /* (incomplete DMA transfer, will be wrapped up after completion of
4460 the first one (initiated here) with data padding */
4461 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, headerlength, 0U);
4462 }
4463 }
4464 else
4465 {
4466 hcryp->CrypInCount = 0U;
4467 /* Set the input address and start DMA transfer */
4468 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, hcryp->Init.HeaderSize, 0U);
4469 }
4470
4471 }
4472 /*============================================*/
4473 /* GCM (or CCM when applicable) payload phase */
4474 /*============================================*/
4475 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
4476 {
4477 /* Coming from header phase, wait for CCF flag to be raised
4478 if header present and fed to the IP in the previous phase */
4479 if (hcryp->Init.Header != NULL)
4480 {
4481 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
4482 {
4483 hcryp->State = HAL_CRYP_STATE_READY;
4484 __HAL_UNLOCK(hcryp);
4485 return HAL_TIMEOUT;
4486 }
4487 }
4488 else
4489 {
4490 /* Enable the Peripheral since wasn't in header phase (no header case) */
4491 __HAL_CRYP_ENABLE();
4492 }
4493 /* Clear CCF Flag */
4494 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
4495
4496 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
4497
4498 /* Specific handling to manage payload size less than 128 bits */
4499 if ((Size % 16U) != 0U)
4500 {
4501 inputaddr = (uint32_t)pInputData;
4502 outputaddr = (uint32_t)pOutputData;
4503 if (Size < 16U)
4504 {
4505 /* Block is now entered in polling mode, no actual gain in resorting to DMA */
4506 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
4507 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
4508
4509 CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON);
4510
4511 /* Change the CRYP state to ready */
4512 hcryp->State = HAL_CRYP_STATE_READY;
4513 /* Mark that the payload phase is over */
4514 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
4515
4516 /* Call output data transfer complete callback */
4517 HAL_CRYP_OutCpltCallback(hcryp);
4518 }
4519 else
4520 {
4521 payloadlength = (Size/16U) * 16U;
4522
4523 /* Store the ending transfer points */
4524 hcryp->pCrypInBuffPtr = pInputData + payloadlength;
4525 hcryp->pCrypOutBuffPtr = pOutputData + payloadlength;
4526 hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */
4527
4528 /* Set the input and output addresses and start DMA transfer */
4529 /* (incomplete DMA transfer, will be wrapped up with data padding
4530 after completion of the one initiated here) */
4531 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, payloadlength, outputaddr);
4532 }
4533 }
4534 else
4535 {
4536 hcryp->CrypInCount = 0U;
4537 inputaddr = (uint32_t)pInputData;
4538 outputaddr = (uint32_t)pOutputData;
4539
4540 /* Set the input and output addresses and start DMA transfer */
4541 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
4542 }
4543 }
4544 /*====================================*/
4545 /* GCM/GMAC or (CCM/)CMAC final phase */
4546 /*====================================*/
4547 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
4548 {
4549 /* If coming from header phase (GMAC or CMAC case),
4550 wait for CCF flag to be raised */
4551 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE)
4552 {
4553 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
4554 {
4555 hcryp->State = HAL_CRYP_STATE_READY;
4556 __HAL_UNLOCK(hcryp);
4557 return HAL_TIMEOUT;
4558 }
4559 /* Clear CCF Flag */
4560 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
4561 }
4562
4563 tagaddr = (uint32_t)pOutputData;
4564
4565 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
4566
4567 /* if the header and payload phases have been bypassed, AES must be enabled again */
4568 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
4569 {
4570 __HAL_CRYP_ENABLE();
4571 }
4572
4573 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
4574 {
4575 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
4576 inputlength = Size * 8U; /* input length in bits */
4577 /* Write the number of bits in the header on 64 bits followed by the number
4578 of bits in the payload on 64 bits as well */
4579 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
4580 {
4581 hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
4582 hcryp->Instance->DINR = __RBIT(headerlength);
4583 hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
4584 hcryp->Instance->DINR = __RBIT(inputlength);
4585 }
4586 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
4587 {
4588 hcryp->Instance->DINR = __REV((headerlength)>>32U);
4589 hcryp->Instance->DINR = __REV(headerlength);
4590 hcryp->Instance->DINR = __REV((inputlength)>>32U);
4591 hcryp->Instance->DINR = __REV(inputlength);
4592 }
4593 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
4594 {
4595 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
4596 hcryp->Instance->DINR = __ROR(headerlength, 16U);
4597 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
4598 hcryp->Instance->DINR = __ROR(inputlength, 16U);
4599 }
4600 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
4601 {
4602 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
4603 hcryp->Instance->DINR = (uint32_t)(headerlength);
4604 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
4605 hcryp->Instance->DINR = (uint32_t)(inputlength);
4606 }
4607 }
4608 #if !defined(AES_CR_NPBLB)
4609 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
4610 {
4611 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
4612
4613 inputaddr = (uint32_t)pInputData;
4614 /* Enter the last block made of a 128-bit value formatted
4615 from the original B0 packet. */
4616 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4617 inputaddr+=4U;
4618 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4619 inputaddr+=4U;
4620 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4621 inputaddr+=4U;
4622 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
4623 inputaddr+=4U;
4624 }
4625 #endif
4626
4627 /* No DMA transfer is required at that point therefore, the software
4628 just waits for the CCF flag to be raised. */
4629 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
4630 {
4631 hcryp->State = HAL_CRYP_STATE_READY;
4632 __HAL_UNLOCK(hcryp);
4633 return HAL_TIMEOUT;
4634 }
4635 /* Clear CCF Flag */
4636 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
4637 /* Read the Auth TAG in the IN FIFO */
4638 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
4639 tagaddr+=4U;
4640 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
4641 tagaddr+=4U;
4642 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
4643 tagaddr+=4U;
4644 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
4645
4646 /* Mark that the final phase is over */
4647 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
4648 hcryp->State = HAL_CRYP_STATE_READY;
4649 /* Disable the Peripheral */
4650 __HAL_CRYP_DISABLE();
4651 }
4652 /*=================================================*/
4653 /* case incorrect hcryp->Init.GCMCMACPhase setting */
4654 /*=================================================*/
4655 else
4656 {
4657 hcryp->State = HAL_CRYP_STATE_ERROR;
4658 __HAL_UNLOCK(hcryp);
4659 return HAL_ERROR;
4660 }
4661
4662 /* Process Unlocked */
4663 __HAL_UNLOCK(hcryp);
4664
4665 return HAL_OK;
4666 }
4667 else
4668 {
4669 return HAL_BUSY;
4670 }
4671 }
4672
4673 /**
4674 * @}
4675 */
4676
4677 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions
4678 * @brief Extended processing functions.
4679 *
4680 @verbatim
4681 ==============================================================================
4682 ##### AES extended suspension and resumption functions #####
4683 ==============================================================================
4684 [..] This section provides functions allowing to:
4685 (+) save in memory the Initialization Vector, the Key registers, the Control register or
4686 the Suspend registers when a process is suspended by a higher priority message
4687 (+) write back in CRYP hardware block the saved values listed above when the suspended
4688 lower priority message processing is resumed.
4689
4690 @endverbatim
4691 * @{
4692 */
4693
4694
4695 /**
4696 * @brief In case of message processing suspension, read the Initialization Vector.
4697 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4698 * the configuration information for CRYP module.
4699 * @param Output Pointer to the buffer containing the saved Initialization Vector.
4700 * @note This value has to be stored for reuse by writing the AES_IVRx registers
4701 * as soon as the interrupted processing has to be resumed.
4702 * Applicable to all chaining modes.
4703 * @note AES must be disabled when reading or resetting the IV values.
4704 * @retval None
4705 */
4706 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
4707 {
4708 uint32_t outputaddr = (uint32_t)Output;
4709
4710 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
4711 outputaddr+=4U;
4712 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
4713 outputaddr+=4U;
4714 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
4715 outputaddr+=4U;
4716 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
4717 }
4718
4719 /**
4720 * @brief In case of message processing resumption, rewrite the Initialization
4721 * Vector in the AES_IVRx registers.
4722 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4723 * the configuration information for CRYP module.
4724 * @param Input Pointer to the buffer containing the saved Initialization Vector to
4725 * write back in the CRYP hardware block.
4726 * @note Applicable to all chaining modes.
4727 * @note AES must be disabled when reading or resetting the IV values.
4728 * @retval None
4729 */
4730 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
4731 {
4732 uint32_t ivaddr = (uint32_t)Input;
4733
4734 hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
4735 ivaddr+=4U;
4736 hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
4737 ivaddr+=4U;
4738 hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
4739 ivaddr+=4U;
4740 hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
4741 }
4742
4743
4744 /**
4745 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Suspend Registers.
4746 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4747 * the configuration information for CRYP module.
4748 * @param Output Pointer to the buffer containing the saved Suspend Registers.
4749 * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers
4750 * as soon as the interrupted processing has to be resumed.
4751 * @retval None
4752 */
4753 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
4754 {
4755 uint32_t outputaddr = (uint32_t)Output;
4756
4757 /* In case of GCM payload phase encryption, check that suspension can be carried out */
4758 if (READ_BIT(hcryp->Instance->CR, (AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_GCM_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
4759 {
4760 /* Ensure that Busy flag is reset */
4761 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
4762 {
4763 hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
4764 hcryp->State = HAL_CRYP_STATE_ERROR;
4765
4766 /* Process Unlocked */
4767 __HAL_UNLOCK(hcryp);
4768
4769 HAL_CRYP_ErrorCallback(hcryp);
4770 return ;
4771 }
4772 }
4773
4774 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
4775 outputaddr+=4U;
4776 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
4777 outputaddr+=4U;
4778 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
4779 outputaddr+=4U;
4780 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
4781 outputaddr+=4U;
4782 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
4783 outputaddr+=4U;
4784 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
4785 outputaddr+=4U;
4786 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R);
4787 outputaddr+=4U;
4788 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);
4789 }
4790
4791 /**
4792 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Suspend
4793 * Registers in the AES_SUSPxR registers.
4794 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4795 * the configuration information for CRYP module.
4796 * @param Input Pointer to the buffer containing the saved suspend registers to
4797 * write back in the CRYP hardware block.
4798 * @retval None
4799 */
4800 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
4801 {
4802 uint32_t ivaddr = (uint32_t)Input;
4803
4804 hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
4805 ivaddr+=4U;
4806 hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
4807 ivaddr+=4U;
4808 hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
4809 ivaddr+=4U;
4810 hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
4811 ivaddr+=4U;
4812 hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
4813 ivaddr+=4U;
4814 hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
4815 ivaddr+=4U;
4816 hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
4817 ivaddr+=4U;
4818 hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));
4819 }
4820
4821
4822 /**
4823 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Key Registers.
4824 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4825 * the configuration information for CRYP module.
4826 * @param Output Pointer to the buffer containing the saved Key Registers.
4827 * @param KeySize Indicates the key size (128 or 256 bits).
4828 * @note These values have to be stored for reuse by writing back the AES_KEYRx registers
4829 * as soon as the interrupted processing has to be resumed.
4830 * @retval None
4831 */
4832 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
4833 {
4834 uint32_t keyaddr = (uint32_t)Output;
4835
4836 if (KeySize == CRYP_KEYSIZE_256B)
4837 {
4838 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
4839 keyaddr+=4U;
4840 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
4841 keyaddr+=4U;
4842 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
4843 keyaddr+=4U;
4844 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
4845 keyaddr+=4U;
4846 }
4847
4848 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
4849 keyaddr+=4U;
4850 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
4851 keyaddr+=4U;
4852 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
4853 keyaddr+=4U;
4854 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0);
4855 }
4856
4857 /**
4858 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Key
4859 * Registers in the AES_KEYRx registers.
4860 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4861 * the configuration information for CRYP module.
4862 * @param Input Pointer to the buffer containing the saved key registers to
4863 * write back in the CRYP hardware block.
4864 * @param KeySize Indicates the key size (128 or 256 bits)
4865 * @retval None
4866 */
4867 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
4868 {
4869 uint32_t keyaddr = (uint32_t)Input;
4870
4871 if (KeySize == CRYP_KEYSIZE_256B)
4872 {
4873 hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
4874 keyaddr+=4U;
4875 hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
4876 keyaddr+=4U;
4877 hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
4878 keyaddr+=4U;
4879 hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
4880 keyaddr+=4U;
4881 }
4882
4883 hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
4884 keyaddr+=4U;
4885 hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
4886 keyaddr+=4U;
4887 hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
4888 keyaddr+=4U;
4889 hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));
4890 }
4891
4892
4893 /**
4894 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Control Register.
4895 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4896 * the configuration information for CRYP module.
4897 * @param Output Pointer to the buffer containing the saved Control Register.
4898 * @note This values has to be stored for reuse by writing back the AES_CR register
4899 * as soon as the interrupted processing has to be resumed.
4900 * @retval None
4901 */
4902 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
4903 {
4904 *(uint32_t*)(Output) = hcryp->Instance->CR;
4905 }
4906
4907 /**
4908 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Control
4909 * Registers in the AES_CR register.
4910 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4911 * the configuration information for CRYP module.
4912 * @param Input Pointer to the buffer containing the saved Control Register to
4913 * write back in the CRYP hardware block.
4914 * @retval None
4915 */
4916 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
4917 {
4918 hcryp->Instance->CR = *(uint32_t*)(Input);
4919 /* At the same time, set handle state back to READY to be able to resume the AES calculations
4920 without the processing APIs returning HAL_BUSY when called. */
4921 hcryp->State = HAL_CRYP_STATE_READY;
4922 }
4923
4924 /**
4925 * @brief Request CRYP processing suspension when in polling or interruption mode.
4926 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4927 * the configuration information for CRYP module.
4928 * @note Set the handle field SuspendRequest to the appropriate value so that
4929 * the on-going CRYP processing is suspended as soon as the required
4930 * conditions are met.
4931 * @note It is advised not to suspend the CRYP processing when the DMA controller
4932 * is managing the data transfer
4933 * @retval None
4934 */
4935 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
4936 {
4937 /* Set Handle Suspend Request field */
4938 hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
4939 }
4940
4941 /**
4942 * @}
4943 */
4944
4945 /**
4946 * @}
4947 */
4948
4949 /** @addtogroup CRYPEx_Private_Functions
4950 * @{
4951 */
4952
4953 /**
4954 * @brief DMA CRYP Input Data process complete callback
4955 * for GCM, GMAC or CMAC chainging modes.
4956 * @note Specific setting of hcryp fields are required only
4957 * in the case of header phase where no output data DMA
4958 * transfer is on-going (only input data transfer is enabled
4959 * in such a case).
4960 * @param hdma DMA handle.
4961 * @retval None
4962 */
4963 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma)
4964 {
4965 uint32_t difflength = 0U;
4966
4967 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
4968
4969 /* Disable the DMA transfer for input request */
4970 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
4971
4972 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
4973 {
4974
4975 if (hcryp->CrypInCount != 0U)
4976 {
4977 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
4978 difflength = hcryp->CrypInCount;
4979 hcryp->CrypInCount = 0U;
4980
4981 CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);
4982 }
4983 hcryp->State = HAL_CRYP_STATE_READY;
4984 /* Mark that the header phase is over */
4985 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
4986 }
4987 /* CCF flag indicating header phase AES processing completion
4988 will be checked at the start of the next phase:
4989 - payload phase (GCM or CCM when applicable)
4990 - final phase (GMAC or CMAC).
4991 This allows to avoid the Wait on Flag within the IRQ handling. */
4992
4993 /* Call input data transfer complete callback */
4994 HAL_CRYP_InCpltCallback(hcryp);
4995 }
4996
4997 /**
4998 * @brief DMA CRYP Output Data process complete callback
4999 * for GCM, GMAC or CMAC chainging modes.
5000 * @note This callback is called only in the payload phase.
5001 * @param hdma DMA handle.
5002 * @retval None
5003 */
5004 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma)
5005 {
5006 uint32_t difflength = 0U;
5007 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
5008
5009 /* Disable the DMA transfer for output request */
5010 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
5011
5012 /* Clear CCF Flag */
5013 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5014
5015 /* Initiate additional transfer to wrap-up data feeding to the IP */
5016 if (hcryp->CrypInCount != 0U)
5017 {
5018 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
5019 difflength = hcryp->CrypInCount;
5020 hcryp->CrypInCount = 0U;
5021
5022 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
5023 }
5024
5025 /* Change the CRYP state to ready */
5026 hcryp->State = HAL_CRYP_STATE_READY;
5027 /* Mark that the payload phase is over */
5028 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
5029
5030 /* Call output data transfer complete callback */
5031 HAL_CRYP_OutCpltCallback(hcryp);
5032 }
5033
5034 /**
5035 * @brief DMA CRYP communication error callback
5036 * for GCM, GMAC or CMAC chainging modes.
5037 * @param hdma DMA handle
5038 * @retval None
5039 */
5040 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma)
5041 {
5042 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
5043
5044 hcryp->State= HAL_CRYP_STATE_ERROR;
5045 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
5046 HAL_CRYP_ErrorCallback(hcryp);
5047 /* Clear Error Flag */
5048 __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR);
5049 }
5050
5051 /**
5052 * @brief Handle CRYP block input/output data handling under interruption
5053 * for GCM, GMAC or CMAC chaining modes.
5054 * @note The function is called under interruption only, once
5055 * interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().
5056 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5057 * the configuration information for CRYP module
5058 * @retval HAL status
5059 */
5060 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
5061 {
5062 uint32_t inputaddr = 0x0U;
5063 uint32_t outputaddr = 0x0U;
5064 uint32_t index = 0x0U;
5065 uint32_t addhoc_process = 0U;
5066 uint32_t difflength = 0U;
5067 uint32_t difflengthmod4 = 0U;
5068 uint32_t mask[3] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
5069 uint32_t intermediate_data[4U] = {0U};
5070
5071 if(hcryp->State == HAL_CRYP_STATE_BUSY)
5072 {
5073 /*===========================*/
5074 /* GCM/GMAC(/CCM) init phase */
5075 /*===========================*/
5076 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
5077 {
5078 /* Clear Computation Complete Flag */
5079 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5080 /* Disable Computation Complete Flag and Errors Interrupts */
5081 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
5082 /* Change the CRYP state */
5083 hcryp->State = HAL_CRYP_STATE_READY;
5084
5085 /* Mark that the initialization phase is over */
5086 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
5087
5088 /* Process Unlocked */
5089 __HAL_UNLOCK(hcryp);
5090 /* Call computation complete callback */
5091 HAL_CRYPEx_ComputationCpltCallback(hcryp);
5092 return HAL_OK;
5093 }
5094 /*=====================================*/
5095 /* GCM/GMAC or (CCM/)CMAC header phase */
5096 /*=====================================*/
5097 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
5098 {
5099 /* Check if all input header data have been entered */
5100 if (hcryp->CrypInCount == 0U)
5101 {
5102 /* Clear Computation Complete Flag */
5103 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5104 /* Disable Computation Complete Flag and Errors Interrupts */
5105 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
5106 /* Change the CRYP state */
5107 hcryp->State = HAL_CRYP_STATE_READY;
5108 /* Mark that the header phase is over */
5109 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
5110
5111 /* Process Unlocked */
5112 __HAL_UNLOCK(hcryp);
5113
5114 /* Call computation complete callback */
5115 HAL_CRYPEx_ComputationCpltCallback(hcryp);
5116
5117 return HAL_OK;
5118 }
5119 /* If suspension flag has been raised, suspend processing */
5120 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
5121 {
5122 /* Clear CCF Flag */
5123 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5124
5125 /* reset SuspendRequest */
5126 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
5127 /* Disable Computation Complete Flag and Errors Interrupts */
5128 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
5129 /* Change the CRYP state */
5130 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
5131 /* Mark that the header phase is over */
5132 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
5133
5134 /* Process Unlocked */
5135 __HAL_UNLOCK(hcryp);
5136
5137 return HAL_OK;
5138 }
5139 else /* Carry on feeding input data to the CRYP hardware block */
5140 {
5141 /* Clear Computation Complete Flag */
5142 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5143 /* Get the last Input data address */
5144 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
5145
5146 /* Increment/decrement instance pointer/counter */
5147 if (hcryp->CrypInCount < 16U)
5148 {
5149 difflength = hcryp->CrypInCount;
5150 hcryp->CrypInCount = 0U;
5151 addhoc_process = 1U;
5152 difflengthmod4 = difflength%4U;
5153 }
5154 else
5155 {
5156 hcryp->pCrypInBuffPtr += 16U;
5157 hcryp->CrypInCount -= 16U;
5158 }
5159
5160 #if defined(AES_CR_NPBLB)
5161 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
5162 #else
5163 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
5164 #endif
5165 {
5166 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
5167 {
5168 /* All B blocks will have been entered after the next
5169 four DINR writing, so point at header buffer for
5170 the next iteration */
5171 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
5172 }
5173 }
5174
5175 /* Write the Input block in the Data Input register */
5176 if (addhoc_process == 0U)
5177 {
5178 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5179 inputaddr+=4U;
5180 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5181 inputaddr+=4U;
5182 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5183 inputaddr+=4U;
5184 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5185 }
5186 else
5187 {
5188 /* Header remainder has size less than 128 bits */
5189 /* Enter complete words when possible */
5190 for(index=0U; index < (difflength/4U); index ++)
5191 {
5192 /* Write the Input block in the Data Input register */
5193 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5194 inputaddr+=4U;
5195 }
5196 /* Enter incomplete word padded with zeroes if applicable
5197 (case of header length not a multiple of 32-bits) */
5198 if (difflengthmod4 != 0U)
5199 {
5200 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
5201 }
5202 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
5203 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
5204 {
5205 hcryp->Instance->DINR = 0U;
5206 }
5207 }
5208
5209 return HAL_OK;
5210 }
5211 }
5212 /*=======================*/
5213 /* GCM/CCM payload phase */
5214 /*=======================*/
5215 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
5216 {
5217 /* Get the last output data address */
5218 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
5219
5220 /* Specific handling to manage payload size less than 128 bits
5221 when GCM (or CCM when applicable) encryption or decryption is selected.
5222 Check here if the last block output data are read */
5223 #if defined(AES_CR_NPBLB)
5224 if ((hcryp->CrypOutCount < 16U) && \
5225 (hcryp->CrypOutCount > 0U))
5226 #else
5227 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
5228 (hcryp->CrypOutCount < 16U) && \
5229 (hcryp->CrypOutCount > 0U))
5230 #endif
5231 {
5232 addhoc_process = 1U;
5233 difflength = hcryp->CrypOutCount;
5234 difflengthmod4 = difflength%4U;
5235 hcryp->CrypOutCount = 0U; /* mark that no more output data will be needed */
5236 /* Retrieve intermediate data */
5237 for(index=0U; index < 4U; index ++)
5238 {
5239 intermediate_data[index] = hcryp->Instance->DOUTR;
5240 }
5241 /* Retrieve last words of cyphered data */
5242 /* First, retrieve complete output words */
5243 for(index=0U; index < (difflength/4U); index ++)
5244 {
5245 *(uint32_t*)(outputaddr) = intermediate_data[index];
5246 outputaddr+=4U;
5247 }
5248 /* Next, retrieve partial output word if applicable;
5249 at the same time, start masking intermediate data
5250 with a mask of zeros of same size than the padding
5251 applied to the last block of payload */
5252 if (difflengthmod4 != 0U)
5253 {
5254 intermediate_data[difflength/4U] &= mask[difflengthmod4-1U];
5255 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
5256 }
5257
5258 #if !defined(AES_CR_NPBLB)
5259 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
5260 {
5261 /* Change again CHMOD configuration to GCM mode */
5262 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC);
5263
5264 /* Select FINAL phase */
5265 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
5266
5267 /* Before inserting the intermediate data, carry on masking operation
5268 with a mask of zeros of same size than the padding applied to the last block of payload */
5269 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
5270 {
5271 intermediate_data[(difflength+3U)/4U+index] = 0U;
5272 }
5273
5274 /* Insert intermediate data to trigger an additional DOUTR reading round */
5275 /* Clear Computation Complete Flag before entering new block */
5276 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5277 for(index=0U; index < 4U; index ++)
5278 {
5279 hcryp->Instance->DINR = intermediate_data[index];
5280 }
5281 }
5282 else
5283 #endif
5284 {
5285 /* Payload phase is now over */
5286 /* Clear Computation Complete Flag */
5287 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5288 /* Disable Computation Complete Flag and Errors Interrupts */
5289 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
5290 /* Change the CRYP state */
5291 hcryp->State = HAL_CRYP_STATE_READY;
5292 /* Mark that the payload phase is over */
5293 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
5294
5295 /* Process Unlocked */
5296 __HAL_UNLOCK(hcryp);
5297
5298 /* Call computation complete callback */
5299 HAL_CRYPEx_ComputationCpltCallback(hcryp);
5300 }
5301 return HAL_OK;
5302 }
5303 else
5304 {
5305 if (hcryp->CrypOutCount != 0U)
5306 {
5307 /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */
5308 /* Retrieve the last block available from the CRYP hardware block:
5309 read the output block from the Data Output Register */
5310 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5311 outputaddr+=4U;
5312 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5313 outputaddr+=4U;
5314 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5315 outputaddr+=4U;
5316 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5317
5318 /* Increment/decrement instance pointer/counter */
5319 hcryp->pCrypOutBuffPtr += 16U;
5320 hcryp->CrypOutCount -= 16U;
5321 }
5322 #if !defined(AES_CR_NPBLB)
5323 else
5324 {
5325 /* Software work-around: additional DOUTR reading round to discard the data */
5326 for(index=0U; index < 4U; index ++)
5327 {
5328 intermediate_data[index] = hcryp->Instance->DOUTR;
5329 }
5330 }
5331 #endif
5332 }
5333
5334 /* Check if all output text has been retrieved */
5335 if (hcryp->CrypOutCount == 0U)
5336 {
5337 #if !defined(AES_CR_NPBLB)
5338 /* Make sure that software-work around is not running before disabling
5339 the interruptions (indeed, if software work-around is running, the
5340 interruptions must not be disabled to allow the additional DOUTR
5341 reading round */
5342 if (addhoc_process == 0U)
5343 #endif
5344 {
5345 /* Clear Computation Complete Flag */
5346 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5347 /* Disable Computation Complete Flag and Errors Interrupts */
5348 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
5349 /* Change the CRYP state */
5350 hcryp->State = HAL_CRYP_STATE_READY;
5351 /* Mark that the payload phase is over */
5352 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
5353
5354 /* Process Unlocked */
5355 __HAL_UNLOCK(hcryp);
5356
5357 /* Call computation complete callback */
5358 HAL_CRYPEx_ComputationCpltCallback(hcryp);
5359 }
5360
5361 return HAL_OK;
5362 }
5363 /* If suspension flag has been raised, suspend processing */
5364 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
5365 {
5366 /* Clear CCF Flag */
5367 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5368
5369 /* reset SuspendRequest */
5370 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
5371 /* Disable Computation Complete Flag and Errors Interrupts */
5372 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
5373 /* Change the CRYP state */
5374 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
5375 /* Mark that the header phase is over */
5376 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
5377
5378 /* Process Unlocked */
5379 __HAL_UNLOCK(hcryp);
5380
5381 return HAL_OK;
5382 }
5383 else /* Output data are still expected, carry on feeding the CRYP
5384 hardware block with input data */
5385 {
5386 /* Clear Computation Complete Flag */
5387 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5388 /* Get the last Input data address */
5389 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
5390
5391 /* Usual input data feeding case */
5392 if (hcryp->CrypInCount < 16U)
5393 {
5394 difflength = (uint32_t) (hcryp->CrypInCount);
5395 difflengthmod4 = difflength%4U;
5396 hcryp->CrypInCount = 0U;
5397
5398 #if defined(AES_CR_NPBLB)
5399 /* In case of GCM encryption or CCM decryption, specify the number of padding
5400 bytes in last block of payload */
5401 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
5402 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))
5403 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
5404 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
5405 {
5406 /* Set NPBLB field in writing the number of padding bytes
5407 for the last block of payload */
5408 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
5409 }
5410 #else
5411 /* Software workaround applied to GCM encryption only */
5412 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
5413 {
5414 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
5415 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
5416 }
5417 #endif
5418
5419 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
5420 to have a complete block of 128 bits */
5421 for(index=0U; index < (difflength/4U); index ++)
5422 {
5423 /* Write the Input block in the Data Input register */
5424 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5425 inputaddr+=4U;
5426 }
5427 /* If required, manage input data size not multiple of 32 bits */
5428 if (difflengthmod4 != 0U)
5429 {
5430 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
5431 }
5432 /* Wrap-up in padding with zero-words if applicable */
5433 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
5434 {
5435 hcryp->Instance->DINR = 0U;
5436 }
5437 }
5438 else
5439 {
5440 hcryp->pCrypInBuffPtr += 16U;
5441 hcryp->CrypInCount -= 16U;
5442
5443 /* Write the Input block in the Data Input register */
5444 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5445 inputaddr+=4U;
5446 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5447 inputaddr+=4U;
5448 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5449 inputaddr+=4U;
5450 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5451 }
5452
5453 return HAL_OK;
5454 }
5455 }
5456 /*====================================*/
5457 /* GCM/GMAC or (CCM/)CMAC final phase */
5458 /*====================================*/
5459 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
5460 {
5461 /* Clear Computation Complete Flag */
5462 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5463
5464 /* Get the last output data address */
5465 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
5466
5467 /* Retrieve the last expected data from the CRYP hardware block:
5468 read the output block from the Data Output Register */
5469 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5470 outputaddr+=4U;
5471 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5472 outputaddr+=4U;
5473 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5474 outputaddr+=4U;
5475 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5476
5477 /* Disable Computation Complete Flag and Errors Interrupts */
5478 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
5479 /* Change the CRYP state */
5480 hcryp->State = HAL_CRYP_STATE_READY;
5481 /* Mark that the header phase is over */
5482 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
5483
5484 /* Disable the Peripheral */
5485 __HAL_CRYP_DISABLE();
5486 /* Process Unlocked */
5487 __HAL_UNLOCK(hcryp);
5488
5489 /* Call computation complete callback */
5490 HAL_CRYPEx_ComputationCpltCallback(hcryp);
5491
5492 return HAL_OK;
5493 }
5494 else
5495 {
5496 /* Clear Computation Complete Flag */
5497 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5498 hcryp->State = HAL_CRYP_STATE_ERROR;
5499 __HAL_UNLOCK(hcryp);
5500 return HAL_ERROR;
5501 }
5502 }
5503 else
5504 {
5505 return HAL_BUSY;
5506 }
5507 }
5508
5509 /**
5510 * @brief Set the DMA configuration and start the DMA transfer
5511 * for GCM, GMAC or CMAC chainging modes.
5512 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5513 * the configuration information for CRYP module.
5514 * @param inputaddr Address of the Input buffer.
5515 * @param Size Size of the Input buffer un bytes, must be a multiple of 16.
5516 * @param outputaddr Address of the Output buffer, null pointer when no output DMA stream
5517 * has to be configured.
5518 * @retval None
5519 */
5520 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
5521 {
5522
5523 /* Set the input CRYP DMA transfer complete callback */
5524 hcryp->hdmain->XferCpltCallback = CRYP_GCMCMAC_DMAInCplt;
5525 /* Set the DMA error callback */
5526 hcryp->hdmain->XferErrorCallback = CRYP_GCMCMAC_DMAError;
5527
5528 if (outputaddr != 0U)
5529 {
5530 /* Set the output CRYP DMA transfer complete callback */
5531 hcryp->hdmaout->XferCpltCallback = CRYP_GCMCMAC_DMAOutCplt;
5532 /* Set the DMA error callback */
5533 hcryp->hdmaout->XferErrorCallback = CRYP_GCMCMAC_DMAError;
5534 }
5535
5536 /* Enable the CRYP peripheral */
5537 __HAL_CRYP_ENABLE();
5538
5539 /* Enable the DMA input stream */
5540 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4U);
5541
5542 /* Enable the DMA input request */
5543 SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
5544
5545
5546 if (outputaddr != 0U)
5547 {
5548 /* Enable the DMA output stream */
5549 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4U);
5550
5551 /* Enable the DMA output request */
5552 SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
5553 }
5554 }
5555
5556 /**
5557 * @brief Write/read input/output data in polling mode.
5558 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5559 * the configuration information for CRYP module.
5560 * @param Input Pointer to the Input buffer.
5561 * @param Ilength Length of the Input buffer in bytes, must be a multiple of 16.
5562 * @param Output Pointer to the returned buffer.
5563 * @param Timeout Specify Timeout value.
5564 * @retval HAL status
5565 */
5566 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
5567 {
5568 uint32_t index = 0U;
5569 uint32_t inputaddr = (uint32_t)Input;
5570 uint32_t outputaddr = (uint32_t)Output;
5571
5572
5573 for(index=0U; (index < Ilength); index += 16U)
5574 {
5575 /* Write the Input block in the Data Input register */
5576 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5577 inputaddr+=4U;
5578 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5579 inputaddr+=4U;
5580 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5581 inputaddr+=4U;
5582 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5583 inputaddr+=4U;
5584
5585 /* Wait for CCF flag to be raised */
5586 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
5587 {
5588 hcryp->State = HAL_CRYP_STATE_READY;
5589 __HAL_UNLOCK(hcryp);
5590 return HAL_TIMEOUT;
5591 }
5592
5593 /* Clear CCF Flag */
5594 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5595
5596 /* Read the Output block from the Data Output Register */
5597 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5598 outputaddr+=4U;
5599 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5600 outputaddr+=4U;
5601 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5602 outputaddr+=4U;
5603 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
5604 outputaddr+=4U;
5605
5606 /* If the suspension flag has been raised and if the processing is not about
5607 to end, suspend processing */
5608 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength))
5609 {
5610 /* Reset SuspendRequest */
5611 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
5612
5613 /* Save current reading and writing locations of Input and Output buffers */
5614 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
5615 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
5616 /* Save the number of bytes that remain to be processed at this point */
5617 hcryp->CrypInCount = Ilength - (index+16U);
5618
5619 /* Change the CRYP state */
5620 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
5621
5622 return HAL_OK;
5623 }
5624
5625 }
5626 /* Return function status */
5627 return HAL_OK;
5628
5629 }
5630
5631 /**
5632 * @brief Read derivative key in polling mode when CRYP hardware block is set
5633 * in key derivation operating mode (mode 2).
5634 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5635 * the configuration information for CRYP module.
5636 * @param Output Pointer to the returned buffer.
5637 * @param Timeout Specify Timeout value.
5638 * @retval HAL status
5639 */
5640 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
5641 {
5642 uint32_t outputaddr = (uint32_t)Output;
5643
5644 /* Wait for CCF flag to be raised */
5645 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
5646 {
5647 hcryp->State = HAL_CRYP_STATE_READY;
5648 __HAL_UNLOCK(hcryp);
5649 return HAL_TIMEOUT;
5650 }
5651 /* Clear CCF Flag */
5652 __HAL_CRYP_CLEAR_FLAG( CRYP_CCF_CLEAR);
5653
5654 /* Read the derivative key from the AES_KEYRx registers */
5655 if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
5656 {
5657 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
5658 outputaddr+=4U;
5659 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
5660 outputaddr+=4U;
5661 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
5662 outputaddr+=4U;
5663 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
5664 outputaddr+=4U;
5665 }
5666
5667 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
5668 outputaddr+=4U;
5669 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
5670 outputaddr+=4U;
5671 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
5672 outputaddr+=4U;
5673 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);
5674
5675 /* Return function status */
5676 return HAL_OK;
5677 }
5678
5679 /**
5680 * @brief Set the DMA configuration and start the DMA transfer.
5681 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5682 * the configuration information for CRYP module.
5683 * @param inputaddr Address of the Input buffer.
5684 * @param Size Size of the Input buffer in bytes, must be a multiple of 16.
5685 * @param outputaddr Address of the Output buffer.
5686 * @retval None
5687 */
5688 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
5689 {
5690 /* Set the CRYP DMA transfer complete callback */
5691 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
5692 /* Set the DMA error callback */
5693 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
5694
5695 /* Set the CRYP DMA transfer complete callback */
5696 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
5697 /* Set the DMA error callback */
5698 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
5699
5700 /* Enable the DMA input stream */
5701 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4U);
5702
5703 /* Enable the DMA output stream */
5704 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4U);
5705
5706 /* Enable In and Out DMA requests */
5707 SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
5708
5709 /* Enable the CRYP peripheral */
5710 __HAL_CRYP_ENABLE();
5711 }
5712
5713 /**
5714 * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
5715 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5716 * the configuration information for CRYP module.
5717 * @param Timeout Timeout duration.
5718 * @retval HAL status
5719 */
5720 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5721 {
5722 uint32_t tickstart = 0U;
5723
5724 /* Get timeout */
5725 tickstart = HAL_GetTick();
5726
5727 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
5728 {
5729 /* Check for the Timeout */
5730 if(Timeout != HAL_MAX_DELAY)
5731 {
5732 if((HAL_GetTick() - tickstart ) > Timeout)
5733 {
5734 return HAL_TIMEOUT;
5735 }
5736 }
5737 }
5738 return HAL_OK;
5739 }
5740
5741 /**
5742 * @brief Wait for Busy Flag to be reset during a GCM payload encryption process suspension.
5743 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5744 * the configuration information for CRYP module.
5745 * @param Timeout Timeout duration.
5746 * @retval HAL status
5747 */
5748 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5749 {
5750 uint32_t tickstart = 0U;
5751
5752 /* Get timeout */
5753 tickstart = HAL_GetTick();
5754
5755 while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
5756 {
5757 /* Check for the Timeout */
5758 if(Timeout != HAL_MAX_DELAY)
5759 {
5760 if((HAL_GetTick() - tickstart ) > Timeout)
5761 {
5762 return HAL_TIMEOUT;
5763 }
5764 }
5765 }
5766 return HAL_OK;
5767 }
5768
5769 /**
5770 * @brief DMA CRYP Input Data process complete callback.
5771 * @param hdma DMA handle.
5772 * @retval None
5773 */
5774 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
5775 {
5776 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
5777
5778 /* Disable the DMA transfer for input request */
5779 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
5780
5781 /* Call input data transfer complete callback */
5782 HAL_CRYP_InCpltCallback(hcryp);
5783 }
5784
5785 /**
5786 * @brief DMA CRYP Output Data process complete callback.
5787 * @param hdma DMA handle.
5788 * @retval None
5789 */
5790 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
5791 {
5792 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
5793
5794 /* Disable the DMA transfer for output request */
5795 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
5796
5797 /* Clear CCF Flag */
5798 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5799
5800 /* Disable CRYP */
5801 __HAL_CRYP_DISABLE();
5802
5803 /* Change the CRYP state to ready */
5804 hcryp->State = HAL_CRYP_STATE_READY;
5805
5806 /* Call output data transfer complete callback */
5807 HAL_CRYP_OutCpltCallback(hcryp);
5808 }
5809
5810 /**
5811 * @brief DMA CRYP communication error callback.
5812 * @param hdma DMA handle.
5813 * @retval None
5814 */
5815 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
5816 {
5817 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
5818
5819 hcryp->State= HAL_CRYP_STATE_ERROR;
5820 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
5821 HAL_CRYP_ErrorCallback(hcryp);
5822 /* Clear Error Flag */
5823 __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR);
5824 }
5825
5826 /**
5827 * @brief Last header or payload block padding when size is not a multiple of 128 bits.
5828 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5829 * the configuration information for CRYP module.
5830 * @param difflength size remainder after having fed all complete 128-bit blocks.
5831 * @param polling specifies whether or not polling on CCF must be done after having
5832 * entered a complete block.
5833 * @retval None
5834 */
5835 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
5836 {
5837 uint32_t index = 0U;
5838 uint32_t difflengthmod4 = difflength%4U;
5839 uint32_t inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
5840 uint32_t outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
5841 uint32_t mask[3U] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
5842 uint32_t intermediate_data[4U] = {0U};
5843
5844 #if defined(AES_CR_NPBLB)
5845 /* In case of GCM encryption or CCM decryption, specify the number of padding
5846 bytes in last block of payload */
5847 if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
5848 {
5849 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
5850 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))
5851 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
5852 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
5853 {
5854 /* Set NPBLB field in writing the number of padding bytes
5855 for the last block of payload */
5856 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
5857 }
5858 }
5859 #else
5860 /* Software workaround applied to GCM encryption only */
5861 if ((hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) &&
5862 (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
5863 {
5864 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
5865 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
5866 }
5867 #endif
5868
5869 /* Wrap-up entering header or payload data */
5870 /* Enter complete words when possible */
5871 for(index=0U; index < (difflength/4U); index ++)
5872 {
5873 /* Write the Input block in the Data Input register */
5874 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
5875 inputaddr+=4U;
5876 }
5877 /* Enter incomplete word padded with zeroes if applicable
5878 (case of header length not a multiple of 32-bits) */
5879 if (difflengthmod4 != 0U)
5880 {
5881 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
5882 }
5883 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
5884 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
5885 {
5886 hcryp->Instance->DINR = 0U;
5887 }
5888
5889 if (polling == CRYP_POLLING_ON)
5890 {
5891 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
5892 {
5893 hcryp->State = HAL_CRYP_STATE_READY;
5894 __HAL_UNLOCK(hcryp);
5895 HAL_CRYP_ErrorCallback(hcryp);
5896 }
5897
5898 /* Clear CCF Flag */
5899 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5900 }
5901
5902 /* if payload */
5903 if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
5904 {
5905
5906 /* Retrieve intermediate data */
5907 for(index=0U; index < 4U; index ++)
5908 {
5909 intermediate_data[index] = hcryp->Instance->DOUTR;
5910 }
5911 /* Retrieve last words of cyphered data */
5912 /* First, retrieve complete output words */
5913 for(index=0U; index < (difflength/4U); index ++)
5914 {
5915 *(uint32_t*)(outputaddr) = intermediate_data[index];
5916 outputaddr+=4U;
5917 }
5918 /* Next, retrieve partial output word if applicable;
5919 at the same time, start masking intermediate data
5920 with a mask of zeros of same size than the padding
5921 applied to the last block of payload */
5922 if (difflengthmod4 != 0U)
5923 {
5924 intermediate_data[difflength/4U] &= mask[difflengthmod4-1U];
5925 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
5926 }
5927
5928 #if !defined(AES_CR_NPBLB)
5929 /* Software workaround applied to GCM encryption only,
5930 applicable for AES IP v2 version (where NPBLB is not defined) */
5931 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
5932 {
5933 /* Change again CHMOD configuration to GCM mode */
5934 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC);
5935
5936 /* Select FINAL phase */
5937 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
5938
5939 /* Before inserting the intermediate data, carry on masking operation
5940 with a mask of zeros of same size than the padding applied to the last block of payload */
5941 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
5942 {
5943 intermediate_data[(difflength+3U)/4U+index] = 0U;
5944 }
5945 /* Insert intermediate data */
5946 for(index=0U; index < 4U; index ++)
5947 {
5948 hcryp->Instance->DINR = intermediate_data[index];
5949 }
5950
5951 /* Wait for completion, and read data on DOUT. This data is to discard. */
5952 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
5953 {
5954 hcryp->State = HAL_CRYP_STATE_READY;
5955 __HAL_UNLOCK(hcryp);
5956 HAL_CRYP_ErrorCallback(hcryp);
5957 }
5958
5959 /* Read data to discard */
5960 /* Clear CCF Flag */
5961 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
5962 for(index=0U; index < 4U; index ++)
5963 {
5964 intermediate_data[index] = hcryp->Instance->DOUTR;
5965 }
5966
5967 } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
5968 #endif /* !defined(AES_CR_NPBLB) */
5969 } /* if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) */
5970
5971 }
5972
5973 /**
5974 * @}
5975 */
5976
5977 #endif /* AES */
5978
5979 #endif /* HAL_CRYP_MODULE_ENABLED */
5980 /**
5981 * @}
5982 */
5983
5984 /**
5985 * @}
5986 */
5987
5988 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/