1 /**
2 ******************************************************************************
3 * @file stm32l4xx_hal_cryp_ex.c
4 * @author MCD Application Team
5 * @brief CRYPEx HAL module driver.
6 * This file provides firmware functions to manage the extended
7 * functionalities of the Cryptography (CRYP) peripheral.
8 *
9 ******************************************************************************
10 * @attention
11 *
12 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
13 * All rights reserved.</center></h2>
14 *
15 * This software component is licensed by ST under BSD 3-Clause license,
16 * the "License"; You may not use this file except in compliance with the
17 * License. You may obtain a copy of the License at:
18 * opensource.org/licenses/BSD-3-Clause
19 *
20 ******************************************************************************
21 */
22
23 /* Includes ------------------------------------------------------------------*/
24 #include "stm32l4xx_hal.h"
25
26 #ifdef HAL_CRYP_MODULE_ENABLED
27
28 #if defined(AES)
29
30 /** @addtogroup STM32L4xx_HAL_Driver
31 * @{
32 */
33
34 /** @defgroup CRYPEx CRYPEx
35 * @brief CRYP Extended HAL module driver
36 * @{
37 */
38
39 /* Private typedef -----------------------------------------------------------*/
40 /* Private define ------------------------------------------------------------*/
41 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
42 * @{
43 */
44 #define CRYP_CCF_TIMEOUTVALUE 22000 /*!< CCF flag raising time-out value */
45 #define CRYP_BUSY_TIMEOUTVALUE 22000 /*!< BUSY flag reset time-out value */
46
47 #define CRYP_POLLING_OFF 0x0 /*!< No polling when padding */
48 #define CRYP_POLLING_ON 0x1 /*!< Polling when padding */
49
50 #if defined(AES_CR_NPBLB)
51 #define AES_POSITION_CR_NPBLB (uint32_t)POSITION_VAL(AES_CR_NPBLB) /*!< Required left shift to set background CLUT size */
52 #endif
53 /**
54 * @}
55 */
56
57 /* Private macro -------------------------------------------------------------*/
58 /* Private variables ---------------------------------------------------------*/
59 /* Private function prototypes -----------------------------------------------*/
60 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
61 * @{
62 */
63 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
64 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
65 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
66 static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
67 static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma);
68 static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma);
69 static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma);
70 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
71 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
72 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
73 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
74 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
75 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
76 /**
77 * @}
78 */
79
80 /* Exported functions ---------------------------------------------------------*/
81
82 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
83 * @{
84 */
85
86
87 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function
88 * @brief Extended callback functions.
89 *
90 @verbatim
91 ===============================================================================
92 ##### Extended callback functions #####
93 ===============================================================================
94 [..] This section provides callback function:
95 (+) Computation completed.
96
97 @endverbatim
98 * @{
99 */
100
101
102 /**
103 * @brief Computation completed callbacks.
104 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
105 * the configuration information for CRYP module
106 * @retval None
107 */
HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef * hcryp)108 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
109 {
110 /* Prevent unused argument(s) compilation warning */
111 UNUSED(hcryp);
112
113 /* NOTE : This function should not be modified; when the callback is needed,
114 the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
115 */
116 }
117
118 /**
119 * @}
120 */
121
122 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions
123 * @brief Extended processing functions.
124 *
125 @verbatim
126 ==============================================================================
127 ##### AES extended processing functions #####
128 ==============================================================================
129 [..] This section provides functions allowing to:
130 (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
131 Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
132 based on the processing type. Three processing types are available:
133 (++) Polling mode
134 (++) Interrupt mode
135 (++) DMA mode
136 (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES
137 algorithm in different chaining modes.
138 Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase
139 so that steps can be skipped if so required. Functions are only differentiated based on the processing type.
140 Three processing types are available:
141 (++) Polling mode
142 (++) Interrupt mode
143 (++) DMA mode
144
145 @endverbatim
146 * @{
147 */
148
149 /**
150 * @brief Carry out in polling mode the ciphering or deciphering operation according to
151 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
152 * chaining modes ECB, CBC and CTR are managed by this function in polling mode.
153 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
154 * the configuration information for CRYP module
155 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
156 * or key derivation+decryption.
157 * Parameter is meaningless in case of key derivation.
158 * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
159 * Parameter is meaningless in case of key derivation.
160 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
161 * decryption/key derivation+decryption, or pointer to the derivative keys in
162 * case of key derivation only.
163 * @param Timeout Specify Timeout value
164 * @retval HAL status
165 */
HAL_CRYPEx_AES(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint16_t Size,uint8_t * pOutputData,uint32_t Timeout)166 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
167 {
168
169 if (hcryp->State == HAL_CRYP_STATE_READY)
170 {
171 /* Check parameters setting */
172 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
173 {
174 if (pOutputData == NULL)
175 {
176 return HAL_ERROR;
177 }
178 }
179 else
180 {
181 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
182 {
183 return HAL_ERROR;
184 }
185 }
186
187 /* Process Locked */
188 __HAL_LOCK(hcryp);
189
190 /* Change the CRYP state */
191 hcryp->State = HAL_CRYP_STATE_BUSY;
192
193 /* Call CRYP_ReadKey() API if the operating mode is set to
194 key derivation, CRYP_ProcessData() otherwise */
195 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
196 {
197 if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
198 {
199 return HAL_TIMEOUT;
200 }
201 }
202 else
203 {
204 if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
205 {
206 return HAL_TIMEOUT;
207 }
208 }
209
210 /* If the state has not been set to SUSPENDED, set it to
211 READY, otherwise keep it as it is */
212 if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
213 {
214 hcryp->State = HAL_CRYP_STATE_READY;
215 }
216
217 /* Process Unlocked */
218 __HAL_UNLOCK(hcryp);
219
220 return HAL_OK;
221 }
222 else
223 {
224 return HAL_BUSY;
225 }
226 }
227
228
229
230 /**
231 * @brief Carry out in interrupt mode the ciphering or deciphering operation according to
232 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
233 * chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
234 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
235 * the configuration information for CRYP module
236 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
237 * or key derivation+decryption.
238 * Parameter is meaningless in case of key derivation.
239 * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
240 * Parameter is meaningless in case of key derivation.
241 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
242 * decryption/key derivation+decryption, or pointer to the derivative keys in
243 * case of key derivation only.
244 * @retval HAL status
245 */
HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint16_t Size,uint8_t * pOutputData)246 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
247 {
248 uint32_t inputaddr;
249
250 if(hcryp->State == HAL_CRYP_STATE_READY)
251 {
252 /* Check parameters setting */
253 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
254 {
255 if (pOutputData == NULL)
256 {
257 return HAL_ERROR;
258 }
259 }
260 else
261 {
262 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
263 {
264 return HAL_ERROR;
265 }
266 }
267 /* Process Locked */
268 __HAL_LOCK(hcryp);
269
270 /* If operating mode is not limited to key derivation only,
271 get the buffers addresses and sizes */
272 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
273 {
274
275 hcryp->CrypInCount = Size;
276 hcryp->pCrypInBuffPtr = pInputData;
277 hcryp->pCrypOutBuffPtr = pOutputData;
278 hcryp->CrypOutCount = Size;
279 }
280 else
281 {
282 /* For key derivation, set output buffer only
283 (will point at derivated key) */
284 hcryp->pCrypOutBuffPtr = pOutputData;
285 }
286
287 /* Change the CRYP state */
288 hcryp->State = HAL_CRYP_STATE_BUSY;
289
290 /* Process Unlocked */
291 __HAL_UNLOCK(hcryp);
292
293 /* Enable Computation Complete Flag and Error Interrupts */
294 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
295
296
297 /* If operating mode is key derivation only, the input data have
298 already been entered during the initialization process. For
299 the other operating modes, they are fed to the CRYP hardware
300 block at this point. */
301 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
302 {
303 /* Initiate the processing under interrupt in entering
304 the first input data */
305 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
306 /* Increment/decrement instance pointer/counter */
307 hcryp->pCrypInBuffPtr += 16;
308 hcryp->CrypInCount -= 16U;
309 /* Write the first input block in the Data Input register */
310 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
311 inputaddr+=4U;
312 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
313 inputaddr+=4U;
314 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
315 inputaddr+=4U;
316 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
317 }
318
319 /* Return function status */
320 return HAL_OK;
321 }
322 else
323 {
324 return HAL_BUSY;
325 }
326 }
327
328
329
330
331
332 /**
333 * @brief Carry out in DMA mode the ciphering or deciphering operation according to
334 * hcryp->Init structure fields.
335 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
336 * the configuration information for CRYP module
337 * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
338 * or key derivation+decryption.
339 * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
340 * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
341 * decryption/key derivation+decryption.
342 * @note Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.
343 * @note Supported operating modes are encryption, decryption and key derivation with decryption.
344 * @note No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx
345 * registers must be done by software.
346 * @note This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx
347 * registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
348 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
349 * @retval HAL status
350 */
HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint16_t Size,uint8_t * pOutputData)351 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
352 {
353 uint32_t inputaddr;
354 uint32_t outputaddr;
355
356 if (hcryp->State == HAL_CRYP_STATE_READY)
357 {
358 /* Check parameters setting */
359 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
360 {
361 /* no DMA channel is provided for key derivation operating mode,
362 access to AES_KEYRx registers must be done by software */
363 return HAL_ERROR;
364 }
365 else
366 {
367 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
368 {
369 return HAL_ERROR;
370 }
371 }
372
373
374 /* Process Locked */
375 __HAL_LOCK(hcryp);
376
377 inputaddr = (uint32_t)pInputData;
378 outputaddr = (uint32_t)pOutputData;
379
380 /* Change the CRYP state */
381 hcryp->State = HAL_CRYP_STATE_BUSY;
382
383 /* Set the input and output addresses and start DMA transfer */
384 CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
385
386 /* Process Unlocked */
387 __HAL_UNLOCK(hcryp);
388
389 /* Return function status */
390 return HAL_OK;
391 }
392 else
393 {
394 return HAL_BUSY;
395 }
396 }
397
398
399
400
401
402
403 /**
404 * @brief Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering
405 * operation according to hcryp->Init structure fields.
406 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
407 * the configuration information for CRYP module
408 * @param pInputData
409 * - pointer to payload data in GCM or CCM payload phase,
410 * - pointer to B0 block in CMAC header phase,
411 * - pointer to C block in CMAC final phase.
412 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
413 * @param Size
414 * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
415 * - length of B0 block (in bytes) in CMAC header phase,
416 * - length of C block (in bytes) in CMAC final phase.
417 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
418 * - Parameter is meaningless in case of CCM final phase.
419 * - Parameter is message length in bytes in case of GCM final phase.
420 * - Parameter must be set to zero in case of GMAC final phase.
421 * @param pOutputData
422 * - pointer to plain or cipher text in GCM/CCM payload phase,
423 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
424 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
425 * - Parameter is meaningless in case of CMAC header phase.
426 * @param Timeout Specify Timeout value
427 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable.
428 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
429 * can be skipped by the user if so required.
430 * @retval HAL status
431 */
HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint64_t Size,uint8_t * pOutputData,uint32_t Timeout)432 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
433 {
434 uint32_t index ;
435 uint32_t inputaddr ;
436 uint32_t outputaddr ;
437 uint32_t tagaddr ;
438 uint64_t headerlength ;
439 uint64_t inputlength ;
440 uint64_t payloadlength ;
441 uint32_t difflength = 0;
442 uint32_t addhoc_process = 0;
443
444 if (hcryp->State == HAL_CRYP_STATE_READY)
445 {
446 /* input/output parameters check */
447 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
448 {
449 /* No processing required */
450 }
451 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
452 {
453 if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
454 ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
455 {
456 return HAL_ERROR;
457 }
458 #if defined(AES_CR_NPBLB)
459 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
460 #else
461 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
462 #endif
463 {
464 /* In case of CMAC or CCM (when applicable) header phase resumption, we can have pInputData = NULL and Size = 0 */
465 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
466 {
467 return HAL_ERROR;
468 }
469 }
470 }
471 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
472 {
473 if (((pInputData == NULL) && (Size != 0U)) || \
474 ((pInputData != NULL) && (Size == 0U)) || \
475 ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL)))
476 {
477 return HAL_ERROR;
478 }
479 }
480 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
481 {
482 if (pOutputData == NULL)
483 {
484 return HAL_ERROR;
485 }
486 #if !defined(AES_CR_NPBLB)
487 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
488 {
489 return HAL_ERROR;
490 }
491 #endif
492 }
493 else
494 {
495 /* Unspecified Phase */
496 return HAL_ERROR;
497 }
498
499
500 /* Process Locked */
501 __HAL_LOCK(hcryp);
502
503 /* Change the CRYP state */
504 hcryp->State = HAL_CRYP_STATE_BUSY;
505
506 /*==============================================*/
507 /* GCM/GMAC (or CCM when applicable) init phase */
508 /*==============================================*/
509 /* In case of init phase, the input data (Key and Initialization Vector) have
510 already been entered during the initialization process. Therefore, the
511 API just waits for the CCF flag to be set. */
512 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
513 {
514 /* just wait for hash computation */
515 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
516 {
517 hcryp->State = HAL_CRYP_STATE_READY;
518 __HAL_UNLOCK(hcryp);
519 return HAL_TIMEOUT;
520 }
521
522 /* Clear CCF Flag */
523 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
524 /* Mark that the initialization phase is over */
525 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
526 }
527 /*=======================================================*/
528 /* GCM/GMAC or (CCM / CMAC when applicable) header phase */
529 /*=======================================================*/
530 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
531 {
532 #if !defined(AES_CR_NPBLB)
533 /* Set header phase; for GCM or GMAC, set data-byte at this point */
534 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
535 {
536 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
537 }
538 else
539 #endif
540 {
541 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
542 }
543
544 /* Enable the Peripheral */
545 __HAL_CRYP_ENABLE(hcryp);
546
547 #if !defined(AES_CR_NPBLB)
548 /* in case of CMAC, enter B0 block in header phase, before the header itself. */
549 /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
550 skip these steps and go directly to header buffer feeding to the HW */
551 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U))
552 {
553 uint64_t index_test;
554 inputaddr = (uint32_t)pInputData;
555
556 for(index=0U ; (index < Size); index += 16U)
557 {
558 /* Write the Input block in the Data Input register */
559 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
560 inputaddr+=4U;
561 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
562 inputaddr+=4U;
563 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
564 inputaddr+=4U;
565 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
566 inputaddr+=4U;
567
568 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
569 {
570 hcryp->State = HAL_CRYP_STATE_READY;
571 __HAL_UNLOCK(hcryp);
572 return HAL_TIMEOUT;
573 }
574 /* Clear CCF Flag */
575 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
576
577 /* If the suspension flag has been raised and if the processing is not about
578 to end, suspend processing */
579 index_test = (uint64_t)index + 16U;
580 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_test < Size))
581 {
582 /* reset SuspendRequest */
583 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
584 /* Change the CRYP state */
585 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
586 /* Mark that the header phase is over */
587 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
588
589 /* Save current reading and writing locations of Input and Output buffers */
590 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
591 /* Save the total number of bytes (B blocks + header) that remain to be
592 processed at this point */
593 hcryp->CrypInCount = (uint32_t) (hcryp->Init.HeaderSize + Size - index_test);
594
595 /* Process Unlocked */
596 __HAL_UNLOCK(hcryp);
597
598 return HAL_OK;
599 }
600 } /* for(index=0; (index < Size); index += 16) */
601 }
602 #endif /* !defined(AES_CR_NPBLB) */
603
604 /* Enter header */
605 inputaddr = (uint32_t)hcryp->Init.Header;
606 /* Local variable headerlength is a number of bytes multiple of 128 bits,
607 remaining header data (if any) are handled after this loop */
608 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
609 if ((hcryp->Init.HeaderSize % 16U) != 0U)
610 {
611 difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);
612 }
613 for(index=0U ; index < headerlength; index += 16U)
614 {
615 uint64_t index_temp;
616 /* Write the Input block in the Data Input register */
617 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
618 inputaddr+=4U;
619 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
620 inputaddr+=4U;
621 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
622 inputaddr+=4U;
623 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
624 inputaddr+=4U;
625
626 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
627 {
628 hcryp->State = HAL_CRYP_STATE_READY;
629 __HAL_UNLOCK(hcryp);
630 return HAL_TIMEOUT;
631 }
632 /* Clear CCF Flag */
633 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
634
635 /* If the suspension flag has been raised and if the processing is not about
636 to end, suspend processing */
637 index_temp = (uint64_t)index + 16U;
638 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < headerlength))
639 {
640 /* reset SuspendRequest */
641 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
642 /* Change the CRYP state */
643 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
644 /* Mark that the header phase is over */
645 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
646
647 /* Save current reading and writing locations of Input and Output buffers */
648 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
649 /* Save the total number of bytes that remain to be processed at this point */
650 hcryp->CrypInCount = (uint32_t) (hcryp->Init.HeaderSize - index_temp);
651
652 /* Process Unlocked */
653 __HAL_UNLOCK(hcryp);
654
655 return HAL_OK;
656 }
657 }
658
659 /* Case header length is not a multiple of 16 bytes */
660 if (difflength != 0U)
661 {
662 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
663 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
664 }
665
666 /* Mark that the header phase is over */
667 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
668 }
669 /*============================================*/
670 /* GCM (or CCM when applicable) payload phase */
671 /*============================================*/
672 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
673 {
674
675 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
676
677 /* if the header phase has been bypassed, AES must be enabled again */
678 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
679 {
680 __HAL_CRYP_ENABLE(hcryp);
681 }
682
683 inputaddr = (uint32_t)pInputData;
684 outputaddr = (uint32_t)pOutputData;
685
686 /* Enter payload */
687 /* Specific handling to manage payload last block size less than 128 bits */
688 if ((Size % 16U) != 0U)
689 {
690 payloadlength = (Size/16U) * 16U;
691 difflength = (uint32_t) (Size - payloadlength);
692 addhoc_process = 1;
693 }
694 else
695 {
696 payloadlength = Size;
697 }
698
699 /* Feed payload */
700 for(index=0U ; index < payloadlength; index += 16U)
701 {
702 uint64_t index_temp;
703 /* Write the Input block in the Data Input register */
704 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
705 inputaddr+=4U;
706 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
707 inputaddr+=4U;
708 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
709 inputaddr+=4U;
710 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
711 inputaddr+=4U;
712
713 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
714 {
715 hcryp->State = HAL_CRYP_STATE_READY;
716 __HAL_UNLOCK(hcryp);
717 return HAL_TIMEOUT;
718 }
719
720 /* Clear CCF Flag */
721 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
722
723 /* Retrieve output data: read the output block
724 from the Data Output Register */
725 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
726 outputaddr+=4U;
727 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
728 outputaddr+=4U;
729 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
730 outputaddr+=4U;
731 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
732 outputaddr+=4U;
733
734 /* If the suspension flag has been raised and if the processing is not about
735 to end, suspend processing */
736 index_temp = (uint64_t)index + 16U;
737 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < payloadlength))
738 {
739 /* no flag waiting under IRQ handling */
740 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
741 {
742 /* Ensure that Busy flag is reset */
743 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
744 {
745 hcryp->State = HAL_CRYP_STATE_READY;
746 __HAL_UNLOCK(hcryp);
747 return HAL_TIMEOUT;
748 }
749 }
750 /* reset SuspendRequest */
751 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
752 /* Change the CRYP state */
753 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
754 /* Mark that the header phase is over */
755 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
756
757 /* Save current reading and writing locations of Input and Output buffers */
758 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
759 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
760 /* Save the number of bytes that remain to be processed at this point */
761 hcryp->CrypInCount = (uint32_t) (Size - index_temp);
762
763 /* Process Unlocked */
764 __HAL_UNLOCK(hcryp);
765
766 return HAL_OK;
767 }
768
769 }
770
771 /* Additional processing to manage GCM(/CCM) encryption and decryption cases when
772 payload last block size less than 128 bits */
773 if (addhoc_process == 1U)
774 {
775
776 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
777 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
778 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
779
780 } /* (addhoc_process == 1) */
781
782 /* Mark that the payload phase is over */
783 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
784 }
785 /*==================================*/
786 /* GCM/GMAC/CCM or CMAC final phase */
787 /*==================================*/
788 else
789 {
790 tagaddr = (uint32_t)pOutputData;
791
792 #if defined(AES_CR_NPBLB)
793 /* By default, clear NPBLB field */
794 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
795 #endif
796
797 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
798
799 /* if the header and payload phases have been bypassed, AES must be enabled again */
800 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
801 {
802 __HAL_CRYP_ENABLE(hcryp);
803 }
804
805 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
806 {
807 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
808 inputlength = Size * 8U; /* input length in bits */
809
810 #if !defined(AES_CR_NPBLB)
811 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
812 {
813 hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
814 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
815 hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
816 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
817 }
818 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
819 {
820 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
821 hcryp->Instance->DINR = __REV((uint32_t)headerlength);
822 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
823 hcryp->Instance->DINR = __REV((uint32_t)inputlength);
824 }
825 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
826 {
827 hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
828 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
829 hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
830 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
831 }
832 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
833 {
834 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
835 hcryp->Instance->DINR = (uint32_t)(headerlength);
836 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
837 hcryp->Instance->DINR = (uint32_t)(inputlength);
838 }
839 else
840 {
841 /* Unspecified Data Type */
842 return HAL_ERROR;
843 }
844 #else
845 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
846 hcryp->Instance->DINR = (uint32_t)(headerlength);
847 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
848 hcryp->Instance->DINR = (uint32_t)(inputlength);
849 #endif
850 }
851 #if !defined(AES_CR_NPBLB)
852 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
853 {
854 inputaddr = (uint32_t)pInputData;
855 /* Enter the last block made of a 128-bit value formatted
856 from the original B0 packet. */
857 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
858 inputaddr+=4U;
859 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
860 inputaddr+=4U;
861 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
862 inputaddr+=4U;
863 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
864 }
865 else
866 {
867 /* Unspecified Chaining Mode */
868 return HAL_ERROR;
869 }
870 #endif
871
872
873 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
874 {
875 hcryp->State = HAL_CRYP_STATE_READY;
876 __HAL_UNLOCK(hcryp);
877 return HAL_TIMEOUT;
878 }
879
880 /* Read the Auth TAG in the Data Out register */
881 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
882 tagaddr+=4U;
883 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
884 tagaddr+=4U;
885 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
886 tagaddr+=4U;
887 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
888
889
890 /* Clear CCF Flag */
891 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
892 /* Mark that the final phase is over */
893 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
894 /* Disable the Peripheral */
895 __HAL_CRYP_DISABLE(hcryp);
896 }
897
898 /* Change the CRYP state */
899 hcryp->State = HAL_CRYP_STATE_READY;
900
901 /* Process Unlocked */
902 __HAL_UNLOCK(hcryp);
903
904 return HAL_OK;
905 }
906 else
907 {
908 return HAL_BUSY;
909 }
910 }
911
912
913
914
915 /**
916 * @brief Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering
917 * operation according to hcryp->Init structure fields.
918 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
919 * the configuration information for CRYP module
920 * @param pInputData
921 * - pointer to payload data in GCM or CCM payload phase,
922 * - pointer to B0 block in CMAC header phase,
923 * - pointer to C block in CMAC final phase.
924 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
925 * @param Size
926 * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
927 * - length of B0 block (in bytes) in CMAC header phase,
928 * - length of C block (in bytes) in CMAC final phase.
929 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
930 * - Parameter is meaningless in case of CCM final phase.
931 * - Parameter is message length in bytes in case of GCM final phase.
932 * - Parameter must be set to zero in case of GMAC final phase.
933 * @param pOutputData
934 * - pointer to plain or cipher text in GCM/CCM payload phase,
935 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
936 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
937 * - Parameter is meaningless in case of CMAC header phase.
938 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
939 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
940 * can be skipped by the user if so required.
941 * @retval HAL status
942 */
HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint64_t Size,uint8_t * pOutputData)943 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
944 {
945
946 uint32_t inputaddr ;
947 uint64_t headerlength ;
948 uint64_t inputlength ;
949 uint32_t index ;
950 uint32_t addhoc_process = 0;
951 uint32_t difflength = 0;
952 uint32_t difflengthmod4 = 0;
953 uint32_t mask[4][3];
954
955 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
956
957 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
958 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
959 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
960 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
961
962 if (hcryp->State == HAL_CRYP_STATE_READY)
963 {
964 /* input/output parameters check */
965 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
966 {
967 /* No processing required */
968 }
969 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
970 {
971 if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
972 ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
973 {
974 return HAL_ERROR;
975 }
976 #if defined(AES_CR_NPBLB)
977 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
978 #else
979 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
980 #endif
981 {
982 /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and Size = 0 */
983 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
984 {
985 return HAL_ERROR;
986 }
987 }
988 }
989 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
990 {
991 if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
992 {
993 return HAL_ERROR;
994 }
995 }
996 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
997 {
998 if (pOutputData == NULL)
999 {
1000 return HAL_ERROR;
1001 }
1002 #if !defined(AES_CR_NPBLB)
1003 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
1004 {
1005 return HAL_ERROR;
1006 }
1007 #endif
1008 }
1009 else
1010 {
1011 /* Unspecified Phase */
1012 return HAL_ERROR;
1013 }
1014
1015
1016 /* Process Locked */
1017 __HAL_LOCK(hcryp);
1018
1019 /* Change the CRYP state */
1020 hcryp->State = HAL_CRYP_STATE_BUSY;
1021
1022 /* Process Unlocked */
1023 __HAL_UNLOCK(hcryp);
1024
1025 /* Enable Computation Complete Flag and Error Interrupts */
1026 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
1027
1028
1029
1030 /*==============================================*/
1031 /* GCM/GMAC (or CCM when applicable) init phase */
1032 /*==============================================*/
1033 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
1034 {
1035 /* In case of init phase, the input data (Key and Initialization Vector) have
1036 already been entered during the initialization process. Therefore, the
1037 software just waits for the CCF interrupt to be raised and which will
1038 be handled by CRYP_AES_Auth_IT() API. */
1039 }
1040 /*===================================*/
1041 /* GCM/GMAC/CCM or CMAC header phase */
1042 /*===================================*/
1043 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
1044 {
1045
1046 #if defined(AES_CR_NPBLB)
1047 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
1048 #else
1049 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1050 #endif
1051 {
1052 /* In case of CMAC, B blocks are first entered, before the header.
1053 Therefore, B blocks and the header are entered back-to-back
1054 as if it was only one single block.
1055 However, in case of resumption after suspension, if all the
1056 B blocks have been entered (in that case, Size = 0), only the
1057 remainder of the non-processed header bytes are entered. */
1058 if (Size != 0U)
1059 {
1060 hcryp->CrypInCount = (uint32_t)(Size + hcryp->Init.HeaderSize);
1061 hcryp->pCrypInBuffPtr = pInputData;
1062 }
1063 else
1064 {
1065 hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
1066 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
1067 }
1068 }
1069 else
1070 {
1071 /* Get the header addresses and sizes */
1072 hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
1073 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
1074 }
1075
1076 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1077
1078
1079 #if !defined(AES_CR_NPBLB)
1080 /* Set header phase; for GCM or GMAC, set data-byte at this point */
1081 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
1082 {
1083 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
1084 }
1085 else
1086 #endif
1087 {
1088 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
1089 }
1090
1091 /* Enable the Peripheral */
1092 __HAL_CRYP_ENABLE(hcryp);
1093
1094 /* Increment/decrement instance pointer/counter */
1095 if (hcryp->CrypInCount == 0U)
1096 {
1097 /* Case of no header */
1098 hcryp->State = HAL_CRYP_STATE_READY;
1099 /* Mark that the header phase is over */
1100 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
1101 return HAL_OK;
1102 }
1103 else if (hcryp->CrypInCount < 16U)
1104 {
1105 hcryp->CrypInCount = 0;
1106 addhoc_process = 1;
1107 difflength = (uint32_t) (hcryp->Init.HeaderSize);
1108 difflengthmod4 = difflength%4U;
1109 }
1110 else
1111 {
1112 hcryp->pCrypInBuffPtr += 16;
1113 hcryp->CrypInCount -= 16U;
1114 }
1115
1116
1117 #if defined(AES_CR_NPBLB)
1118 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
1119 #else
1120 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1121 #endif
1122 {
1123 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
1124 {
1125 /* All B blocks will have been entered after the next
1126 four DINR writing, so point at header buffer for
1127 the next iteration */
1128 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
1129 }
1130 }
1131
1132 /* Enter header first block to initiate the process
1133 in the Data Input register */
1134 if (addhoc_process == 0U)
1135 {
1136 /* Header has size equal or larger than 128 bits */
1137 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1138 inputaddr+=4U;
1139 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1140 inputaddr+=4U;
1141 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1142 inputaddr+=4U;
1143 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1144 }
1145 else
1146 {
1147 /* Header has size less than 128 bits */
1148 /* Enter complete words when possible */
1149 for(index=0U ; index < (difflength/4U); index ++)
1150 {
1151 /* Write the Input block in the Data Input register */
1152 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1153 inputaddr+=4U;
1154 }
1155 /* Enter incomplete word padded with zeroes if applicable
1156 (case of header length not a multiple of 32-bits) */
1157 if (difflengthmod4 != 0U)
1158 {
1159 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
1160 }
1161 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
1162 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
1163 {
1164 hcryp->Instance->DINR = 0;
1165 }
1166
1167 }
1168 }
1169 /*============================================*/
1170 /* GCM (or CCM when applicable) payload phase */
1171 /*============================================*/
1172 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
1173 {
1174 /* Get the buffer addresses and sizes */
1175 hcryp->CrypInCount = (uint32_t)Size;
1176 hcryp->pCrypInBuffPtr = pInputData;
1177 hcryp->pCrypOutBuffPtr = pOutputData;
1178 hcryp->CrypOutCount = (uint32_t)Size;
1179
1180 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
1181
1182 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
1183
1184 /* if the header phase has been bypassed, AES must be enabled again */
1185 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
1186 {
1187 __HAL_CRYP_ENABLE(hcryp);
1188 }
1189
1190 /* No payload case */
1191 if (pInputData == NULL)
1192 {
1193 hcryp->State = HAL_CRYP_STATE_READY;
1194 /* Mark that the header phase is over */
1195 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
1196 /* Process Unlocked */
1197 __HAL_UNLOCK(hcryp);
1198
1199 return HAL_OK;
1200 }
1201
1202 /* Specific handling to manage payload size less than 128 bits */
1203 if (Size < 16U)
1204 {
1205 difflength = (uint32_t) (Size);
1206 #if defined(AES_CR_NPBLB)
1207 /* In case of GCM encryption or CCM decryption, specify the number of padding
1208 bytes in last block of payload */
1209 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
1210 {
1211 uint32_t cr_temp = hcryp->Instance->CR;
1212
1213 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
1214 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
1215 {
1216 /* Set NPBLB field in writing the number of padding bytes
1217 for the last block of payload */
1218 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
1219 }
1220 }
1221 #else
1222 /* Software workaround applied to GCM encryption only */
1223 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
1224 {
1225 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
1226 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
1227 }
1228 #endif
1229
1230
1231 /* Set hcryp->CrypInCount to 0 (no more data to enter) */
1232 hcryp->CrypInCount = 0;
1233
1234 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes,
1235 to have a complete block of 128 bits */
1236 difflengthmod4 = difflength%4U;
1237 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
1238 to have a complete block of 128 bits */
1239 for(index=0U; index < (difflength/4U); index ++)
1240 {
1241 /* Write the Input block in the Data Input register */
1242 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1243 inputaddr+=4U;
1244 }
1245 /* If required, manage input data size not multiple of 32 bits */
1246 if (difflengthmod4 != 0U)
1247 {
1248 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
1249 }
1250 /* Wrap-up in padding with zero-words if applicable */
1251 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
1252 {
1253 hcryp->Instance->DINR = 0;
1254 }
1255 }
1256 else
1257 {
1258 /* Increment/decrement instance pointer/counter */
1259 hcryp->pCrypInBuffPtr += 16;
1260 hcryp->CrypInCount -= 16U;
1261
1262 /* Enter payload first block to initiate the process
1263 in the Data Input register */
1264 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1265 inputaddr+=4U;
1266 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1267 inputaddr+=4U;
1268 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1269 inputaddr+=4U;
1270 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1271 }
1272 }
1273 /*==================================*/
1274 /* GCM/GMAC/CCM or CMAC final phase */
1275 /*==================================*/
1276 else
1277 {
1278 hcryp->pCrypOutBuffPtr = pOutputData;
1279
1280 #if defined(AES_CR_NPBLB)
1281 /* By default, clear NPBLB field */
1282 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
1283 #endif
1284
1285 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
1286
1287 /* if the header and payload phases have been bypassed, AES must be enabled again */
1288 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
1289 {
1290 __HAL_CRYP_ENABLE(hcryp);
1291 }
1292
1293 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
1294 {
1295 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
1296 inputlength = Size * 8U; /* Input length in bits */
1297 /* Write the number of bits in the header on 64 bits followed by the number
1298 of bits in the payload on 64 bits as well */
1299
1300 #if !defined(AES_CR_NPBLB)
1301 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
1302 {
1303 hcryp->Instance->DINR = __RBIT((uint32_t)((headerlength)>>32));
1304 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
1305 hcryp->Instance->DINR = __RBIT((uint32_t)((inputlength)>>32));
1306 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
1307 }
1308 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
1309 {
1310 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
1311 hcryp->Instance->DINR = __REV((uint32_t)headerlength);
1312 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
1313 hcryp->Instance->DINR = __REV((uint32_t)inputlength);
1314 }
1315 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
1316 {
1317 hcryp->Instance->DINR = __ROR((uint32_t)((headerlength)>>32), 16);
1318 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
1319 hcryp->Instance->DINR = __ROR((uint32_t)((inputlength)>>32), 16);
1320 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
1321 }
1322 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
1323 {
1324 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
1325 hcryp->Instance->DINR = (uint32_t)(headerlength);
1326 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
1327 hcryp->Instance->DINR = (uint32_t)(inputlength);
1328 }
1329 else
1330 {
1331 /* Unspecified Data Type */
1332 return HAL_ERROR;
1333 }
1334 #else
1335 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
1336 hcryp->Instance->DINR = (uint32_t)(headerlength);
1337 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
1338 hcryp->Instance->DINR = (uint32_t)(inputlength);
1339 #endif
1340 }
1341 #if !defined(AES_CR_NPBLB)
1342 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1343 {
1344 inputaddr = (uint32_t)pInputData;
1345 /* Enter the last block made of a 128-bit value formatted
1346 from the original B0 packet. */
1347 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1348 inputaddr+=4U;
1349 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1350 inputaddr+=4U;
1351 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1352 inputaddr+=4U;
1353 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1354 }
1355 else
1356 {
1357 /* Unspecified Chaining Mode */
1358 return HAL_ERROR;
1359 }
1360 #endif
1361 }
1362
1363 return HAL_OK;
1364 }
1365 else
1366 {
1367 return HAL_BUSY;
1368 }
1369 }
1370
1371
1372
1373
1374 /**
1375 * @brief Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering
1376 * operation according to hcryp->Init structure fields.
1377 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1378 * the configuration information for CRYP module
1379 * @param pInputData
1380 * - pointer to payload data in GCM or CCM payload phase,
1381 * - pointer to B0 block in CMAC header phase,
1382 * - pointer to C block in CMAC final phase.
1383 * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
1384 * @param Size
1385 * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
1386 * - length of B0 block (in bytes) in CMAC header phase,
1387 * - length of C block (in bytes) in CMAC final phase.
1388 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
1389 * - Parameter is meaningless in case of CCM final phase.
1390 * - Parameter is message length in bytes in case of GCM final phase.
1391 * - Parameter must be set to zero in case of GMAC final phase.
1392 * @param pOutputData
1393 * - pointer to plain or cipher text in GCM/CCM payload phase,
1394 * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
1395 * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
1396 * - Parameter is meaningless in case of CMAC header phase.
1397 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
1398 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
1399 * can be skipped by the user if so required.
1400 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
1401 * @retval HAL status
1402 */
HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef * hcryp,uint8_t * pInputData,uint64_t Size,uint8_t * pOutputData)1403 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
1404 {
1405 uint32_t inputaddr ;
1406 uint32_t outputaddr ;
1407 uint32_t tagaddr ;
1408 uint64_t headerlength ;
1409 uint64_t inputlength ;
1410 uint64_t payloadlength ;
1411
1412
1413 if (hcryp->State == HAL_CRYP_STATE_READY)
1414 {
1415 /* input/output parameters check */
1416 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
1417 {
1418 /* No processing required */
1419 }
1420 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
1421 {
1422 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
1423 {
1424 return HAL_ERROR;
1425 }
1426 #if defined(AES_CR_NPBLB)
1427 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
1428 {
1429 /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and Size = 0 */
1430 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
1431 {
1432 return HAL_ERROR;
1433 }
1434 }
1435 #else
1436 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1437 {
1438 if ((pInputData == NULL) || (Size == 0U))
1439 {
1440 return HAL_ERROR;
1441 }
1442 }
1443 #endif
1444 }
1445 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
1446 {
1447 if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
1448 {
1449 return HAL_ERROR;
1450 }
1451 }
1452 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
1453 {
1454 if (pOutputData == NULL)
1455 {
1456 return HAL_ERROR;
1457 }
1458 #if !defined(AES_CR_NPBLB)
1459 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
1460 {
1461 return HAL_ERROR;
1462 }
1463 #endif
1464 }
1465 else
1466 {
1467 /* Unspecified Phase */
1468 return HAL_ERROR;
1469 }
1470
1471
1472 /* Process Locked */
1473 __HAL_LOCK(hcryp);
1474
1475 /* Change the CRYP state */
1476 hcryp->State = HAL_CRYP_STATE_BUSY;
1477
1478 /*==============================================*/
1479 /* GCM/GMAC (or CCM when applicable) init phase */
1480 /*==============================================*/
1481 /* In case of init phase, the input data (Key and Initialization Vector) have
1482 already been entered during the initialization process. No DMA transfer is
1483 required at that point therefore, the software just waits for the CCF flag
1484 to be raised. */
1485 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
1486 {
1487 /* just wait for hash computation */
1488 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1489 {
1490 hcryp->State = HAL_CRYP_STATE_READY;
1491 __HAL_UNLOCK(hcryp);
1492 return HAL_TIMEOUT;
1493 }
1494
1495 /* Clear CCF Flag */
1496 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1497 /* Mark that the initialization phase is over */
1498 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
1499 hcryp->State = HAL_CRYP_STATE_READY;
1500 }
1501 /*====================================*/
1502 /* GCM/GMAC/ CCM or CMAC header phase */
1503 /*====================================*/
1504 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
1505 {
1506 #if !defined(AES_CR_NPBLB)
1507 /* Set header phase; for GCM or GMAC, set data-byte at this point */
1508 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
1509 {
1510 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
1511 }
1512 else
1513 #endif
1514 {
1515 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
1516 }
1517
1518 /* Enable the CRYP peripheral */
1519 __HAL_CRYP_ENABLE(hcryp);
1520
1521 #if !defined(AES_CR_NPBLB)
1522 /* enter first B0 block in polling mode (no DMA transfer for B0) */
1523 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1524 {
1525 inputaddr = (uint32_t)pInputData;
1526 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1527 inputaddr+=4U;
1528 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1529 inputaddr+=4U;
1530 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1531 inputaddr+=4U;
1532 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1533
1534 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1535 {
1536 hcryp->State = HAL_CRYP_STATE_READY;
1537 __HAL_UNLOCK(hcryp);
1538 return HAL_TIMEOUT;
1539 }
1540 /* Clear CCF Flag */
1541 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1542 }
1543 #endif
1544
1545 /* No header case */
1546 if (hcryp->Init.Header == NULL)
1547 {
1548 hcryp->State = HAL_CRYP_STATE_READY;
1549 /* Mark that the header phase is over */
1550 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
1551 /* Process Unlocked */
1552 __HAL_UNLOCK(hcryp);
1553
1554 return HAL_OK;
1555 }
1556
1557 inputaddr = (uint32_t)hcryp->Init.Header;
1558 if ((hcryp->Init.HeaderSize % 16U) != 0U)
1559 {
1560
1561 if (hcryp->Init.HeaderSize < 16U)
1562 {
1563 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
1564 CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);
1565
1566 hcryp->State = HAL_CRYP_STATE_READY;
1567 /* Mark that the header phase is over */
1568 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
1569
1570 /* CCF flag indicating header phase AES processing completion
1571 will be checked at the start of the next phase:
1572 - payload phase (GCM / CCM when applicable)
1573 - final phase (GMAC or CMAC when applicable). */
1574 }
1575 else
1576 {
1577 /* Local variable headerlength is a number of bytes multiple of 128 bits,
1578 remaining header data (if any) are handled after this loop */
1579 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
1580 /* Store the ending transfer point */
1581 hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
1582 hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */
1583
1584 /* Set the input and output addresses and start DMA transfer */
1585 /* (incomplete DMA transfer, will be wrapped up after completion of
1586 the first one (initiated here) with data padding */
1587 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)headerlength, 0);
1588 }
1589 }
1590 else
1591 {
1592 hcryp->CrypInCount = 0;
1593 /* Set the input address and start DMA transfer */
1594 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)hcryp->Init.HeaderSize, 0);
1595 }
1596 }
1597 /*============================================*/
1598 /* GCM (or CCM when applicable) payload phase */
1599 /*============================================*/
1600 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
1601 {
1602 /* Coming from header phase, wait for CCF flag to be raised
1603 if header present and fed to the IP in the previous phase */
1604 if (hcryp->Init.Header != NULL)
1605 {
1606 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1607 {
1608 hcryp->State = HAL_CRYP_STATE_READY;
1609 __HAL_UNLOCK(hcryp);
1610 return HAL_TIMEOUT;
1611 }
1612 }
1613 else
1614 {
1615 /* Enable the Peripheral since wasn't in header phase (no header case) */
1616 __HAL_CRYP_ENABLE(hcryp);
1617 }
1618 /* Clear CCF Flag */
1619 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1620
1621 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
1622
1623 /* No payload case */
1624 if (pInputData == NULL)
1625 {
1626 hcryp->State = HAL_CRYP_STATE_READY;
1627 /* Mark that the header phase is over */
1628 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
1629 /* Process Unlocked */
1630 __HAL_UNLOCK(hcryp);
1631
1632 return HAL_OK;
1633 }
1634
1635
1636 /* Specific handling to manage payload size less than 128 bits */
1637 if ((Size % 16U) != 0U)
1638 {
1639 inputaddr = (uint32_t)pInputData;
1640 outputaddr = (uint32_t)pOutputData;
1641 if (Size < 16U)
1642 {
1643 /* Block is now entered in polling mode, no actual gain in resorting to DMA */
1644 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
1645 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
1646
1647 CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON);
1648
1649 /* Change the CRYP state to ready */
1650 hcryp->State = HAL_CRYP_STATE_READY;
1651 /* Mark that the payload phase is over */
1652 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
1653
1654 /* Call output data transfer complete callback */
1655 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1656 hcryp->OutCpltCallback(hcryp);
1657 #else
1658 HAL_CRYP_OutCpltCallback(hcryp);
1659 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1660 }
1661 else
1662 {
1663 payloadlength = (Size/16U) * 16U;
1664
1665 /* Store the ending transfer points */
1666 hcryp->pCrypInBuffPtr = pInputData;
1667 hcryp->pCrypInBuffPtr += payloadlength;
1668 hcryp->pCrypOutBuffPtr = pOutputData;
1669 hcryp->pCrypOutBuffPtr += payloadlength;
1670 hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */
1671
1672 /* Set the input and output addresses and start DMA transfer */
1673 /* (incomplete DMA transfer, will be wrapped up with data padding
1674 after completion of the one initiated here) */
1675 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)payloadlength, outputaddr);
1676 }
1677 }
1678 else
1679 {
1680 hcryp->CrypInCount = 0;
1681 inputaddr = (uint32_t)pInputData;
1682 outputaddr = (uint32_t)pOutputData;
1683
1684 /* Set the input and output addresses and start DMA transfer */
1685 CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)Size, outputaddr);
1686 }
1687 }
1688 /*==================================*/
1689 /* GCM/GMAC/CCM or CMAC final phase */
1690 /*==================================*/
1691 else
1692 {
1693 /* If coming from header phase (GMAC or CMAC case when applicable),
1694 wait for CCF flag to be raised */
1695 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE)
1696 {
1697 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1698 {
1699 hcryp->State = HAL_CRYP_STATE_READY;
1700 __HAL_UNLOCK(hcryp);
1701 return HAL_TIMEOUT;
1702 }
1703 /* Clear CCF Flag */
1704 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1705 }
1706
1707 tagaddr = (uint32_t)pOutputData;
1708
1709 #if defined(AES_CR_NPBLB)
1710 /* By default, clear NPBLB field */
1711 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
1712 #endif
1713 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
1714
1715 /* if the header and payload phases have been bypassed, AES must be enabled again */
1716 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
1717 {
1718 __HAL_CRYP_ENABLE(hcryp);
1719 }
1720
1721 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
1722 {
1723 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
1724 inputlength = Size * 8U; /* input length in bits */
1725 /* Write the number of bits in the header on 64 bits followed by the number
1726 of bits in the payload on 64 bits as well */
1727 #if !defined(AES_CR_NPBLB)
1728 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
1729 {
1730 hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
1731 hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
1732 hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
1733 hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
1734 }
1735 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
1736 {
1737 hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
1738 hcryp->Instance->DINR = __REV((uint32_t)headerlength);
1739 hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
1740 hcryp->Instance->DINR = __REV((uint32_t)inputlength);
1741 }
1742 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
1743 {
1744 hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
1745 hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
1746 hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
1747 hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
1748 }
1749 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
1750 {
1751 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
1752 hcryp->Instance->DINR = (uint32_t)(headerlength);
1753 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
1754 hcryp->Instance->DINR = (uint32_t)(inputlength);
1755 }
1756 else
1757 {
1758 /* Unspecified Data Type */
1759 return HAL_ERROR;
1760 }
1761 #else
1762 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
1763 hcryp->Instance->DINR = (uint32_t)(headerlength);
1764 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
1765 hcryp->Instance->DINR = (uint32_t)(inputlength);
1766 #endif
1767 }
1768 #if !defined(AES_CR_NPBLB)
1769 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
1770 {
1771 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1772
1773 inputaddr = (uint32_t)pInputData;
1774 /* Enter the last block made of a 128-bit value formatted
1775 from the original B0 packet. */
1776 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1777 inputaddr+=4U;
1778 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1779 inputaddr+=4U;
1780 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1781 inputaddr+=4U;
1782 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
1783 }
1784 else
1785 {
1786 /* Unspecified Chaining Mode */
1787 return HAL_ERROR;
1788 }
1789 #endif
1790
1791 /* No DMA transfer is required at that point therefore, the software
1792 just waits for the CCF flag to be raised. */
1793 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
1794 {
1795 hcryp->State = HAL_CRYP_STATE_READY;
1796 __HAL_UNLOCK(hcryp);
1797 return HAL_TIMEOUT;
1798 }
1799
1800 /* Read the Auth TAG in the IN FIFO */
1801 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
1802 tagaddr+=4U;
1803 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
1804 tagaddr+=4U;
1805 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
1806 tagaddr+=4U;
1807 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
1808
1809 /* Clear CCF Flag */
1810 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1811
1812 /* Mark that the final phase is over */
1813 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
1814 hcryp->State = HAL_CRYP_STATE_READY;
1815 /* Disable the Peripheral */
1816 __HAL_CRYP_DISABLE(hcryp);
1817
1818 }
1819
1820 /* Process Unlocked */
1821 __HAL_UNLOCK(hcryp);
1822
1823 return HAL_OK;
1824 }
1825 else
1826 {
1827 return HAL_BUSY;
1828 }
1829 }
1830
1831 /**
1832 * @}
1833 */
1834
1835 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions
1836 * @brief Extended processing functions.
1837 *
1838 @verbatim
1839 ==============================================================================
1840 ##### AES extended suspension and resumption functions #####
1841 ==============================================================================
1842 [..] This section provides functions allowing to:
1843 (+) save in memory the Initialization Vector, the Key registers, the Control register or
1844 the Suspend registers when a process is suspended by a higher priority message
1845 (+) write back in CRYP hardware block the saved values listed above when the suspended
1846 lower priority message processing is resumed.
1847
1848 @endverbatim
1849 * @{
1850 */
1851
1852
1853 /**
1854 * @brief In case of message processing suspension, read the Initialization Vector.
1855 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1856 * the configuration information for CRYP module.
1857 * @param Output Pointer to the buffer containing the saved Initialization Vector.
1858 * @note This value has to be stored for reuse by writing the AES_IVRx registers
1859 * as soon as the interrupted processing has to be resumed.
1860 * Applicable to all chaining modes.
1861 * @note AES must be disabled when reading or resetting the IV values.
1862 * @retval None
1863 */
HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Output)1864 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
1865 {
1866 uint32_t outputaddr = (uint32_t)Output;
1867
1868 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
1869 outputaddr+=4U;
1870 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
1871 outputaddr+=4U;
1872 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
1873 outputaddr+=4U;
1874 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
1875 }
1876
1877 /**
1878 * @brief In case of message processing resumption, rewrite the Initialization
1879 * Vector in the AES_IVRx registers.
1880 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1881 * the configuration information for CRYP module.
1882 * @param Input Pointer to the buffer containing the saved Initialization Vector to
1883 * write back in the CRYP hardware block.
1884 * @note Applicable to all chaining modes.
1885 * @note AES must be disabled when reading or resetting the IV values.
1886 * @retval None
1887 */
HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Input)1888 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
1889 {
1890 uint32_t ivaddr = (uint32_t)Input;
1891
1892 hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
1893 ivaddr+=4U;
1894 hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
1895 ivaddr+=4U;
1896 hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
1897 ivaddr+=4U;
1898 hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
1899 }
1900
1901
1902 /**
1903 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension,
1904 * read the Suspend Registers.
1905 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1906 * the configuration information for CRYP module.
1907 * @param Output Pointer to the buffer containing the saved Suspend Registers.
1908 * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers
1909 * as soon as the interrupted processing has to be resumed.
1910 * @retval None
1911 */
HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Output)1912 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
1913 {
1914 uint32_t outputaddr = (uint32_t)Output;
1915
1916 /* In case of GCM payload phase encryption, check that suspension can be carried out */
1917 if (READ_BIT(hcryp->Instance->CR, (AES_CR_CHMOD|AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
1918 {
1919 /* Ensure that Busy flag is reset */
1920 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
1921 {
1922 hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
1923 hcryp->State = HAL_CRYP_STATE_ERROR;
1924
1925 /* Process Unlocked */
1926 __HAL_UNLOCK(hcryp);
1927
1928 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1929 hcryp->ErrorCallback(hcryp);
1930 #else
1931 HAL_CRYP_ErrorCallback(hcryp);
1932 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1933 return ;
1934 }
1935 }
1936
1937 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
1938 outputaddr+=4U;
1939 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
1940 outputaddr+=4U;
1941 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
1942 outputaddr+=4U;
1943 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
1944 outputaddr+=4U;
1945 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
1946 outputaddr+=4U;
1947 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
1948 outputaddr+=4U;
1949 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R);
1950 outputaddr+=4U;
1951 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);
1952 }
1953
1954 /**
1955 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Suspend
1956 * Registers in the AES_SUSPxR registers.
1957 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1958 * the configuration information for CRYP module.
1959 * @param Input Pointer to the buffer containing the saved suspend registers to
1960 * write back in the CRYP hardware block.
1961 * @retval None
1962 */
HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Input)1963 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
1964 {
1965 uint32_t ivaddr = (uint32_t)Input;
1966
1967 hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
1968 ivaddr+=4U;
1969 hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
1970 ivaddr+=4U;
1971 hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
1972 ivaddr+=4U;
1973 hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
1974 ivaddr+=4U;
1975 hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
1976 ivaddr+=4U;
1977 hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
1978 ivaddr+=4U;
1979 hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
1980 ivaddr+=4U;
1981 hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));
1982 }
1983
1984
1985 /**
1986 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Key Registers.
1987 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1988 * the configuration information for CRYP module.
1989 * @param Output Pointer to the buffer containing the saved Key Registers.
1990 * @param KeySize Indicates the key size (128 or 256 bits).
1991 * @note These values have to be stored for reuse by writing back the AES_KEYRx registers
1992 * as soon as the interrupted processing has to be resumed.
1993 * @retval None
1994 */
HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Output,uint32_t KeySize)1995 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
1996 {
1997 uint32_t keyaddr = (uint32_t)Output;
1998
1999 if (KeySize == CRYP_KEYSIZE_256B)
2000 {
2001 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
2002 keyaddr+=4U;
2003 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
2004 keyaddr+=4U;
2005 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
2006 keyaddr+=4U;
2007 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
2008 keyaddr+=4U;
2009 }
2010
2011 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
2012 keyaddr+=4U;
2013 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
2014 keyaddr+=4U;
2015 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
2016 keyaddr+=4U;
2017 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0);
2018 }
2019
2020 /**
2021 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key
2022 * Registers in the AES_KEYRx registers.
2023 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2024 * the configuration information for CRYP module.
2025 * @param Input Pointer to the buffer containing the saved key registers to
2026 * write back in the CRYP hardware block.
2027 * @param KeySize Indicates the key size (128 or 256 bits)
2028 * @retval None
2029 */
HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef * hcryp,uint8_t * Input,uint32_t KeySize)2030 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
2031 {
2032 uint32_t keyaddr = (uint32_t)Input;
2033
2034 if (KeySize == CRYP_KEYSIZE_256B)
2035 {
2036 hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
2037 keyaddr+=4U;
2038 hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
2039 keyaddr+=4U;
2040 hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
2041 keyaddr+=4U;
2042 hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
2043 keyaddr+=4U;
2044 }
2045
2046 hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
2047 keyaddr+=4U;
2048 hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
2049 keyaddr+=4U;
2050 hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
2051 keyaddr+=4U;
2052 hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));
2053 }
2054
2055
2056 /**
2057 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Control Register.
2058 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2059 * the configuration information for CRYP module.
2060 * @param Output Pointer to the buffer containing the saved Control Register.
2061 * @note This values has to be stored for reuse by writing back the AES_CR register
2062 * as soon as the interrupted processing has to be resumed.
2063 * @retval None
2064 */
HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef * hcryp,uint8_t * Output)2065 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
2066 {
2067 *(uint32_t*)(void *)(Output) = hcryp->Instance->CR; /* Derogation MisraC2012 R.11.5 */
2068 }
2069
2070 /**
2071 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Control
2072 * Registers in the AES_CR register.
2073 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2074 * the configuration information for CRYP module.
2075 * @param Input Pointer to the buffer containing the saved Control Register to
2076 * write back in the CRYP hardware block.
2077 * @retval None
2078 */
HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef * hcryp,uint8_t * Input)2079 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
2080 {
2081 hcryp->Instance->CR = *(uint32_t*)(void *)(Input); /* Derogation MisraC2012 R.11.5 */
2082 /* At the same time, set handle state back to READY to be able to resume the AES calculations
2083 without the processing APIs returning HAL_BUSY when called. */
2084 hcryp->State = HAL_CRYP_STATE_READY;
2085 }
2086
2087 /**
2088 * @brief Request CRYP processing suspension when in polling or interruption mode.
2089 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2090 * the configuration information for CRYP module.
2091 * @note Set the handle field SuspendRequest to the appropriate value so that
2092 * the on-going CRYP processing is suspended as soon as the required
2093 * conditions are met.
2094 * @note It is advised not to suspend the CRYP processing when the DMA controller
2095 * is managing the data transfer
2096 * @retval None
2097 */
HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef * hcryp)2098 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
2099 {
2100 /* Set Handle Suspend Request field */
2101 hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
2102 }
2103
2104 /**
2105 * @}
2106 */
2107
2108 /**
2109 * @}
2110 */
2111
2112 /** @addtogroup CRYPEx_Private_Functions
2113 * @{
2114 */
2115
2116 /**
2117 * @brief DMA CRYP Input Data process complete callback
2118 * for GCM, GMAC, CCM or CMAC chaining modes.
2119 * @note Specific setting of hcryp fields are required only
2120 * in the case of header phase where no output data DMA
2121 * transfer is on-going (only input data transfer is enabled
2122 * in such a case).
2123 * @param hdma DMA handle.
2124 * @retval None
2125 */
CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef * hdma)2126 static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma)
2127 {
2128 uint32_t difflength;
2129 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
2130
2131 /* Disable the DMA transfer for input request */
2132 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
2133
2134 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
2135 {
2136
2137 if (hcryp->CrypInCount != 0U)
2138 {
2139 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
2140 difflength = hcryp->CrypInCount;
2141 hcryp->CrypInCount = 0;
2142
2143 CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);
2144 }
2145 hcryp->State = HAL_CRYP_STATE_READY;
2146 /* Mark that the header phase is over */
2147 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
2148 }
2149 /* CCF flag indicating header phase AES processing completion
2150 will be checked at the start of the next phase:
2151 - payload phase (GCM or CCM when applicable)
2152 - final phase (GMAC or CMAC).
2153 This allows to avoid the Wait on Flag within the IRQ handling. */
2154
2155 /* Call input data transfer complete callback */
2156 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2157 hcryp->InCpltCallback(hcryp);
2158 #else
2159 HAL_CRYP_InCpltCallback(hcryp);
2160 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2161 }
2162
2163 /**
2164 * @brief DMA CRYP Output Data process complete callback
2165 * for GCM, GMAC, CCM or CMAC chaining modes.
2166 * @note This callback is called only in the payload phase.
2167 * @param hdma DMA handle.
2168 * @retval None
2169 */
CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef * hdma)2170 static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma)
2171 {
2172 uint32_t difflength;
2173 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
2174
2175 /* Disable the DMA transfer for output request */
2176 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
2177
2178 /* Clear CCF Flag */
2179 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2180
2181 /* Initiate additional transfer to wrap-up data feeding to the IP */
2182 if (hcryp->CrypInCount != 0U)
2183 {
2184 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
2185 difflength = hcryp->CrypInCount;
2186 hcryp->CrypInCount = 0;
2187
2188 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
2189 }
2190
2191 /* Change the CRYP state to ready */
2192 hcryp->State = HAL_CRYP_STATE_READY;
2193 /* Mark that the payload phase is over */
2194 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
2195
2196 /* Call output data transfer complete callback */
2197 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2198 hcryp->OutCpltCallback(hcryp);
2199 #else
2200 HAL_CRYP_OutCpltCallback(hcryp);
2201 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2202 }
2203
2204 /**
2205 * @brief DMA CRYP communication error callback
2206 * for GCM, GMAC, CCM or CMAC chaining modes.
2207 * @param hdma DMA handle
2208 * @retval None
2209 */
CRYP_Authentication_DMAError(DMA_HandleTypeDef * hdma)2210 static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma)
2211 {
2212 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
2213
2214 hcryp->State= HAL_CRYP_STATE_ERROR;
2215 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
2216 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2217 hcryp->ErrorCallback(hcryp);
2218 #else
2219 HAL_CRYP_ErrorCallback(hcryp);
2220 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2221 /* Clear Error Flag */
2222 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
2223 }
2224
2225
2226
2227 /**
2228 * @brief Handle CRYP block input/output data handling under interruption
2229 * for GCM, GMAC, CCM or CMAC chaining modes.
2230 * @note The function is called under interruption only, once
2231 * interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().
2232 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2233 * the configuration information for CRYP module
2234 * @retval HAL status
2235 */
CRYP_AES_Auth_IT(CRYP_HandleTypeDef * hcryp)2236 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
2237 {
2238 uint32_t inputaddr ;
2239 uint32_t outputaddr ;
2240 uint32_t index ;
2241 uint32_t addhoc_process = 0;
2242 uint32_t difflength = 0;
2243 uint32_t difflengthmod4 = 0;
2244 uint32_t mask[4][3] ;
2245 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
2246 uint32_t intermediate_data[4] = {0};
2247
2248 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
2249 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
2250 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
2251 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
2252
2253 if(hcryp->State == HAL_CRYP_STATE_BUSY)
2254 {
2255 /*===========================*/
2256 /* GCM/GMAC(/CCM) init phase */
2257 /*===========================*/
2258 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
2259 {
2260 /* Clear Computation Complete Flag */
2261 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2262 /* Disable Computation Complete Flag and Errors Interrupts */
2263 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2264 /* Change the CRYP state */
2265 hcryp->State = HAL_CRYP_STATE_READY;
2266
2267 /* Mark that the initialization phase is over */
2268 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
2269
2270 /* Process Unlocked */
2271 __HAL_UNLOCK(hcryp);
2272 /* Call computation complete callback */
2273 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2274 hcryp->CompCpltCallback(hcryp);
2275 #else
2276 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2277 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2278 return HAL_OK;
2279 }
2280 /*========================================*/
2281 /* GCM/GMAC (or CCM or CMAC) header phase */
2282 /*========================================*/
2283 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
2284 {
2285 /* Check if all input header data have been entered */
2286 if (hcryp->CrypInCount == 0U)
2287 {
2288 /* Clear Computation Complete Flag */
2289 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2290 /* Disable Computation Complete Flag and Errors Interrupts */
2291 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2292 /* Change the CRYP state */
2293 hcryp->State = HAL_CRYP_STATE_READY;
2294 /* Mark that the header phase is over */
2295 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
2296
2297 /* Process Unlocked */
2298 __HAL_UNLOCK(hcryp);
2299
2300 /* Call computation complete callback */
2301 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2302 hcryp->CompCpltCallback(hcryp);
2303 #else
2304 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2305 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2306
2307 return HAL_OK;
2308 }
2309 /* If suspension flag has been raised, suspend processing */
2310 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
2311 {
2312 /* Clear CCF Flag */
2313 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2314
2315 /* reset SuspendRequest */
2316 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
2317 /* Disable Computation Complete Flag and Errors Interrupts */
2318 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2319 /* Change the CRYP state */
2320 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
2321 /* Mark that the header phase is suspended */
2322 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
2323
2324 /* Process Unlocked */
2325 __HAL_UNLOCK(hcryp);
2326
2327 return HAL_OK;
2328 }
2329 else /* Carry on feeding input data to the CRYP hardware block */
2330 {
2331 /* Clear Computation Complete Flag */
2332 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2333 /* Get the last Input data address */
2334 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
2335
2336 /* Increment/decrement instance pointer/counter */
2337 if (hcryp->CrypInCount < 16U)
2338 {
2339 difflength = hcryp->CrypInCount;
2340 hcryp->CrypInCount = 0;
2341 addhoc_process = 1;
2342 difflengthmod4 = difflength%4U;
2343 }
2344 else
2345 {
2346 hcryp->pCrypInBuffPtr += 16;
2347 hcryp->CrypInCount -= 16U;
2348 }
2349
2350 #if defined(AES_CR_NPBLB)
2351 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
2352 #else
2353 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
2354 #endif
2355 {
2356 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
2357 {
2358 /* All B blocks will have been entered after the next
2359 four DINR writing, so point at header buffer for
2360 the next iteration */
2361 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
2362 }
2363 }
2364
2365 /* Write the Input block in the Data Input register */
2366 if (addhoc_process == 0U)
2367 {
2368 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2369 inputaddr+=4U;
2370 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2371 inputaddr+=4U;
2372 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2373 inputaddr+=4U;
2374 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2375 }
2376 else
2377 {
2378 /* Header remainder has size less than 128 bits */
2379 /* Enter complete words when possible */
2380 for(index=0U ; index < (difflength/4U); index ++)
2381 {
2382 /* Write the Input block in the Data Input register */
2383 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2384 inputaddr+=4U;
2385 }
2386 /* Enter incomplete word padded with zeroes if applicable
2387 (case of header length not a multiple of 32-bits) */
2388 if (difflengthmod4 != 0U)
2389 {
2390 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
2391 }
2392 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
2393 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
2394 {
2395 hcryp->Instance->DINR = 0;
2396 }
2397 }
2398
2399 return HAL_OK;
2400 }
2401 }
2402 /*=======================*/
2403 /* GCM/CCM payload phase */
2404 /*=======================*/
2405 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
2406 {
2407 /* Get the last output data address */
2408 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
2409
2410 /* Specific handling to manage payload size less than 128 bits
2411 when GCM (or CCM when applicable) encryption or decryption is selected.
2412 Check here if the last block output data are read */
2413 #if defined(AES_CR_NPBLB)
2414 if ((hcryp->CrypOutCount < 16U) && \
2415 (hcryp->CrypOutCount > 0U))
2416 #else
2417 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
2418 (hcryp->CrypOutCount < 16U) && \
2419 (hcryp->CrypOutCount > 0U))
2420 #endif
2421 {
2422 difflength = hcryp->CrypOutCount;
2423 difflengthmod4 = difflength%4U;
2424 hcryp->CrypOutCount = 0; /* mark that no more output data will be needed */
2425 /* Retrieve intermediate data */
2426 for(index=0U ; index < 4U; index ++)
2427 {
2428 intermediate_data[index] = hcryp->Instance->DOUTR;
2429 }
2430 /* Retrieve last words of cyphered data */
2431 /* First, retrieve complete output words */
2432 for(index=0U ; index < (difflength/4U); index ++)
2433 {
2434 *(uint32_t*)(outputaddr) = intermediate_data[index];
2435 outputaddr+=4U;
2436 }
2437 /* Next, retrieve partial output word if applicable;
2438 at the same time, start masking intermediate data
2439 with a mask of zeros of same size than the padding
2440 applied to the last block of payload */
2441 if (difflengthmod4 != 0U)
2442 {
2443 intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
2444 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
2445 }
2446
2447 #if !defined(AES_CR_NPBLB)
2448 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
2449 {
2450 /* Change again CHMOD configuration to GCM mode */
2451 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);
2452
2453 /* Select FINAL phase */
2454 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
2455
2456 /* Before inserting the intermediate data, carry on masking operation
2457 with a mask of zeros of same size than the padding applied to the last block of payload */
2458 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
2459 {
2460 intermediate_data[((difflength+3U)/4U)+index] = 0;
2461 }
2462
2463 /* Insert intermediate data to trigger an additional DOUTR reading round */
2464 /* Clear Computation Complete Flag before entering new block */
2465 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2466 for(index=0U ; index < 4U; index ++)
2467 {
2468 hcryp->Instance->DINR = intermediate_data[index];
2469 }
2470 }
2471 else
2472 #endif
2473 {
2474 /* Payload phase is now over */
2475 /* Clear Computation Complete Flag */
2476 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2477 /* Disable Computation Complete Flag and Errors Interrupts */
2478 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2479 /* Change the CRYP state */
2480 hcryp->State = HAL_CRYP_STATE_READY;
2481 /* Mark that the payload phase is over */
2482 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
2483
2484 /* Process Unlocked */
2485 __HAL_UNLOCK(hcryp);
2486
2487 /* Call computation complete callback */
2488 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2489 hcryp->CompCpltCallback(hcryp);
2490 #else
2491 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2492 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2493 }
2494 return HAL_OK;
2495 }
2496 else
2497 {
2498 if (hcryp->CrypOutCount != 0U)
2499 {
2500 /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */
2501 /* Retrieve the last block available from the CRYP hardware block:
2502 read the output block from the Data Output Register */
2503 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2504 outputaddr+=4U;
2505 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2506 outputaddr+=4U;
2507 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2508 outputaddr+=4U;
2509 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2510
2511 /* Increment/decrement instance pointer/counter */
2512 hcryp->pCrypOutBuffPtr += 16;
2513 hcryp->CrypOutCount -= 16U;
2514 }
2515 #if !defined(AES_CR_NPBLB)
2516 else
2517 {
2518 /* Software work-around: additional DOUTR reading round to discard the data */
2519 for(index=0U ; index < 4U; index ++)
2520 {
2521 intermediate_data[index] = hcryp->Instance->DOUTR;
2522 }
2523 }
2524 #endif
2525 }
2526
2527 /* Check if all output text has been retrieved */
2528 if (hcryp->CrypOutCount == 0U)
2529 {
2530 /* Clear Computation Complete Flag */
2531 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2532 /* Disable Computation Complete Flag and Errors Interrupts */
2533 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2534 /* Change the CRYP state */
2535 hcryp->State = HAL_CRYP_STATE_READY;
2536 /* Mark that the payload phase is over */
2537 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
2538
2539 /* Process Unlocked */
2540 __HAL_UNLOCK(hcryp);
2541
2542 /* Call computation complete callback */
2543 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2544 hcryp->CompCpltCallback(hcryp);
2545 #else
2546 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2547 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2548
2549 return HAL_OK;
2550 }
2551 /* If suspension flag has been raised, suspend processing */
2552 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
2553 {
2554 /* Clear CCF Flag */
2555 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2556
2557 /* reset SuspendRequest */
2558 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
2559 /* Disable Computation Complete Flag and Errors Interrupts */
2560 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2561 /* Change the CRYP state */
2562 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
2563 /* Mark that the payload phase is suspended */
2564 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_SUSPENDED;
2565
2566 /* Process Unlocked */
2567 __HAL_UNLOCK(hcryp);
2568
2569 return HAL_OK;
2570 }
2571 else /* Output data are still expected, carry on feeding the CRYP
2572 hardware block with input data */
2573 {
2574 /* Clear Computation Complete Flag */
2575 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2576 /* Get the last Input data address */
2577 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
2578
2579 /* Usual input data feeding case */
2580 if (hcryp->CrypInCount < 16U)
2581 {
2582 difflength = (uint32_t) (hcryp->CrypInCount);
2583 difflengthmod4 = difflength%4U;
2584 hcryp->CrypInCount = 0;
2585
2586 #if defined(AES_CR_NPBLB)
2587 /* In case of GCM encryption or CCM decryption, specify the number of padding
2588 bytes in last block of payload */
2589 {
2590 uint32_t cr_temp = hcryp->Instance->CR;
2591
2592 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
2593 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
2594 {
2595 /* Set NPBLB field in writing the number of padding bytes
2596 for the last block of payload */
2597 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
2598 }
2599 }
2600 #else
2601 /* Software workaround applied to GCM encryption only */
2602 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
2603 {
2604 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
2605 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
2606 }
2607 #endif
2608
2609 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
2610 to have a complete block of 128 bits */
2611 for(index=0U ; index < (difflength/4U); index ++)
2612 {
2613 /* Write the Input block in the Data Input register */
2614 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2615 inputaddr+=4U;
2616 }
2617 /* If required, manage input data size not multiple of 32 bits */
2618 if (difflengthmod4 != 0U)
2619 {
2620 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
2621 }
2622 /* Wrap-up in padding with zero-words if applicable */
2623 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
2624 {
2625 hcryp->Instance->DINR = 0;
2626 }
2627
2628 }
2629 else
2630 {
2631 hcryp->pCrypInBuffPtr += 16;
2632 hcryp->CrypInCount -= 16U;
2633
2634 /* Write the Input block in the Data Input register */
2635 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2636 inputaddr+=4U;
2637 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2638 inputaddr+=4U;
2639 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2640 inputaddr+=4U;
2641 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2642 }
2643
2644
2645 return HAL_OK;
2646 }
2647 }
2648 /*=======================================*/
2649 /* GCM/GMAC (or CCM or CMAC) final phase */
2650 /*=======================================*/
2651 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
2652 {
2653 /* Clear Computation Complete Flag */
2654 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2655
2656 /* Get the last output data address */
2657 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
2658
2659 /* Retrieve the last expected data from the CRYP hardware block:
2660 read the output block from the Data Output Register */
2661 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2662 outputaddr+=4U;
2663 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2664 outputaddr+=4U;
2665 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2666 outputaddr+=4U;
2667 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2668
2669 /* Disable Computation Complete Flag and Errors Interrupts */
2670 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2671 /* Change the CRYP state */
2672 hcryp->State = HAL_CRYP_STATE_READY;
2673 /* Mark that the header phase is over */
2674 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
2675
2676 /* Disable the Peripheral */
2677 __HAL_CRYP_DISABLE(hcryp);
2678 /* Process Unlocked */
2679 __HAL_UNLOCK(hcryp);
2680
2681 /* Call computation complete callback */
2682 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2683 hcryp->CompCpltCallback(hcryp);
2684 #else
2685 HAL_CRYPEx_ComputationCpltCallback(hcryp);
2686 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2687
2688 return HAL_OK;
2689 }
2690 else
2691 {
2692 /* Clear Computation Complete Flag */
2693 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2694 hcryp->State = HAL_CRYP_STATE_ERROR;
2695 __HAL_UNLOCK(hcryp);
2696 return HAL_ERROR;
2697 }
2698 }
2699 else
2700 {
2701 return HAL_BUSY;
2702 }
2703 }
2704
2705
2706
2707 /**
2708 * @brief Set the DMA configuration and start the DMA transfer
2709 * for GCM, GMAC, CCM or CMAC chaining modes.
2710 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2711 * the configuration information for CRYP module.
2712 * @param inputaddr Address of the Input buffer.
2713 * @param Size Size of the Input buffer un bytes, must be a multiple of 16.
2714 * @param outputaddr Address of the Output buffer, null pointer when no output DMA stream
2715 * has to be configured.
2716 * @retval None
2717 */
CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size,uint32_t outputaddr)2718 static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2719 {
2720
2721 /* Set the input CRYP DMA transfer complete callback */
2722 hcryp->hdmain->XferCpltCallback = CRYP_Authentication_DMAInCplt;
2723 /* Set the DMA error callback */
2724 hcryp->hdmain->XferErrorCallback = CRYP_Authentication_DMAError;
2725
2726 if (outputaddr != 0U)
2727 {
2728 /* Set the output CRYP DMA transfer complete callback */
2729 hcryp->hdmaout->XferCpltCallback = CRYP_Authentication_DMAOutCplt;
2730 /* Set the DMA error callback */
2731 hcryp->hdmaout->XferErrorCallback = CRYP_Authentication_DMAError;
2732 }
2733
2734 /* Enable the CRYP peripheral */
2735 __HAL_CRYP_ENABLE(hcryp);
2736
2737 /* Enable the DMA input stream */
2738 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
2739 {
2740 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2741 hcryp->ErrorCallback(hcryp);
2742 #else
2743 HAL_CRYP_ErrorCallback(hcryp);
2744 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2745 }
2746
2747 /* Enable the DMA input request */
2748 SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
2749
2750
2751 if (outputaddr != 0U)
2752 {
2753 /* Enable the DMA output stream */
2754 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
2755 {
2756 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2757 hcryp->ErrorCallback(hcryp);
2758 #else
2759 HAL_CRYP_ErrorCallback(hcryp);
2760 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2761 }
2762
2763 /* Enable the DMA output request */
2764 SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
2765 }
2766 }
2767
2768
2769
2770 /**
2771 * @brief Write/read input/output data in polling mode.
2772 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2773 * the configuration information for CRYP module.
2774 * @param Input Pointer to the Input buffer.
2775 * @param Ilength Length of the Input buffer in bytes, must be a multiple of 16.
2776 * @param Output Pointer to the returned buffer.
2777 * @param Timeout Specify Timeout value.
2778 * @retval HAL status
2779 */
CRYP_ProcessData(CRYP_HandleTypeDef * hcryp,uint8_t * Input,uint16_t Ilength,uint8_t * Output,uint32_t Timeout)2780 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
2781 {
2782 uint32_t index;
2783 uint32_t inputaddr = (uint32_t)Input;
2784 uint32_t outputaddr = (uint32_t)Output;
2785
2786
2787 for(index=0U ; (index < Ilength); index += 16U)
2788 {
2789 /* Write the Input block in the Data Input register */
2790 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2791 inputaddr+=4U;
2792 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2793 inputaddr+=4U;
2794 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2795 inputaddr+=4U;
2796 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
2797 inputaddr+=4U;
2798
2799 /* Wait for CCF flag to be raised */
2800 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2801 {
2802 hcryp->State = HAL_CRYP_STATE_READY;
2803 __HAL_UNLOCK(hcryp);
2804 return HAL_TIMEOUT;
2805 }
2806
2807 /* Clear CCF Flag */
2808 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2809
2810 /* Read the Output block from the Data Output Register */
2811 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2812 outputaddr+=4U;
2813 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2814 outputaddr+=4U;
2815 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2816 outputaddr+=4U;
2817 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
2818 outputaddr+=4U;
2819
2820 /* If the suspension flag has been raised and if the processing is not about
2821 to end, suspend processing */
2822 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength))
2823 {
2824 /* Reset SuspendRequest */
2825 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
2826
2827 /* Save current reading and writing locations of Input and Output buffers */
2828 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
2829 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
2830 /* Save the number of bytes that remain to be processed at this point */
2831 hcryp->CrypInCount = Ilength - (index+16U);
2832
2833 /* Change the CRYP state */
2834 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
2835
2836 return HAL_OK;
2837 }
2838
2839
2840 }
2841 /* Return function status */
2842 return HAL_OK;
2843
2844 }
2845
2846
2847
2848
2849
2850 /**
2851 * @brief Read derivative key in polling mode when CRYP hardware block is set
2852 * in key derivation operating mode (mode 2).
2853 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2854 * the configuration information for CRYP module.
2855 * @param Output Pointer to the returned buffer.
2856 * @param Timeout Specify Timeout value.
2857 * @retval HAL status
2858 */
CRYP_ReadKey(CRYP_HandleTypeDef * hcryp,uint8_t * Output,uint32_t Timeout)2859 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
2860 {
2861 uint32_t outputaddr = (uint32_t)Output;
2862
2863 /* Wait for CCF flag to be raised */
2864 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2865 {
2866 hcryp->State = HAL_CRYP_STATE_READY;
2867 __HAL_UNLOCK(hcryp);
2868 return HAL_TIMEOUT;
2869 }
2870 /* Clear CCF Flag */
2871 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2872
2873 /* Read the derivative key from the AES_KEYRx registers */
2874 if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
2875 {
2876 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
2877 outputaddr+=4U;
2878 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
2879 outputaddr+=4U;
2880 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
2881 outputaddr+=4U;
2882 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
2883 outputaddr+=4U;
2884 }
2885
2886 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
2887 outputaddr+=4U;
2888 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
2889 outputaddr+=4U;
2890 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
2891 outputaddr+=4U;
2892 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);
2893
2894
2895 /* Return function status */
2896 return HAL_OK;
2897 }
2898
2899 /**
2900 * @brief Set the DMA configuration and start the DMA transfer.
2901 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2902 * the configuration information for CRYP module.
2903 * @param inputaddr Address of the Input buffer.
2904 * @param Size Size of the Input buffer in bytes, must be a multiple of 16.
2905 * @param outputaddr Address of the Output buffer.
2906 * @retval None
2907 */
CRYP_SetDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size,uint32_t outputaddr)2908 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2909 {
2910 /* Set the CRYP DMA transfer complete callback */
2911 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2912 /* Set the DMA error callback */
2913 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2914
2915 /* Set the CRYP DMA transfer complete callback */
2916 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2917 /* Set the DMA error callback */
2918 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2919
2920 /* Enable the DMA input stream */
2921 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
2922 {
2923 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2924 hcryp->ErrorCallback(hcryp);
2925 #else
2926 HAL_CRYP_ErrorCallback(hcryp);
2927 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2928 }
2929
2930 /* Enable the DMA output stream */
2931 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
2932 {
2933 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2934 hcryp->ErrorCallback(hcryp);
2935 #else
2936 HAL_CRYP_ErrorCallback(hcryp);
2937 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2938 }
2939
2940 /* Enable In and Out DMA requests */
2941 SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
2942
2943 /* Enable the CRYP peripheral */
2944 __HAL_CRYP_ENABLE(hcryp);
2945 }
2946
2947
2948 /**
2949 * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
2950 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2951 * the configuration information for CRYP module.
2952 * @param Timeout Timeout duration.
2953 * @retval HAL status
2954 */
CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp,uint32_t Timeout)2955 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
2956 {
2957 uint32_t tickstart;
2958
2959 /* Get timeout */
2960 tickstart = HAL_GetTick();
2961
2962 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
2963 {
2964 /* Check for the Timeout */
2965 if(Timeout != HAL_MAX_DELAY)
2966 {
2967 if((HAL_GetTick() - tickstart ) > Timeout)
2968 {
2969 return HAL_TIMEOUT;
2970 }
2971 }
2972 }
2973 return HAL_OK;
2974 }
2975
2976 /**
2977 * @brief Wait for Busy Flag to be reset during a GCM payload encryption process suspension.
2978 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2979 * the configuration information for CRYP module.
2980 * @param Timeout Timeout duration.
2981 * @retval HAL status
2982 */
CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp,uint32_t Timeout)2983 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
2984 {
2985 uint32_t tickstart;
2986
2987 /* Get timeout */
2988 tickstart = HAL_GetTick();
2989
2990 while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
2991 {
2992 /* Check for the Timeout */
2993 if(Timeout != HAL_MAX_DELAY)
2994 {
2995 if((HAL_GetTick() - tickstart ) > Timeout)
2996 {
2997 return HAL_TIMEOUT;
2998 }
2999 }
3000 }
3001 return HAL_OK;
3002 }
3003
3004
3005 /**
3006 * @brief DMA CRYP Input Data process complete callback.
3007 * @param hdma DMA handle.
3008 * @retval None
3009 */
CRYP_DMAInCplt(DMA_HandleTypeDef * hdma)3010 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
3011 {
3012 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
3013
3014 /* Disable the DMA transfer for input request */
3015 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
3016
3017 /* Call input data transfer complete callback */
3018 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3019 hcryp->InCpltCallback(hcryp);
3020 #else
3021 HAL_CRYP_InCpltCallback(hcryp);
3022 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3023 }
3024
3025 /**
3026 * @brief DMA CRYP Output Data process complete callback.
3027 * @param hdma DMA handle.
3028 * @retval None
3029 */
CRYP_DMAOutCplt(DMA_HandleTypeDef * hdma)3030 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
3031 {
3032 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
3033
3034 /* Disable the DMA transfer for output request */
3035 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
3036
3037 /* Clear CCF Flag */
3038 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3039
3040 /* Disable CRYP */
3041 __HAL_CRYP_DISABLE(hcryp);
3042
3043 /* Change the CRYP state to ready */
3044 hcryp->State = HAL_CRYP_STATE_READY;
3045
3046 /* Call output data transfer complete callback */
3047 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3048 hcryp->OutCpltCallback(hcryp);
3049 #else
3050 HAL_CRYP_OutCpltCallback(hcryp);
3051 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3052 }
3053
3054 /**
3055 * @brief DMA CRYP communication error callback.
3056 * @param hdma DMA handle.
3057 * @retval None
3058 */
CRYP_DMAError(DMA_HandleTypeDef * hdma)3059 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
3060 {
3061 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
3062
3063 hcryp->State= HAL_CRYP_STATE_ERROR;
3064 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
3065 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3066 hcryp->ErrorCallback(hcryp);
3067 #else
3068 HAL_CRYP_ErrorCallback(hcryp);
3069 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3070 /* Clear Error Flag */
3071 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
3072 }
3073
3074 /**
3075 * @brief Last header or payload block padding when size is not a multiple of 128 bits.
3076 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3077 * the configuration information for CRYP module.
3078 * @param difflength size remainder after having fed all complete 128-bit blocks.
3079 * @param polling specifies whether or not polling on CCF must be done after having
3080 * entered a complete block.
3081 * @retval None
3082 */
CRYP_Padding(CRYP_HandleTypeDef * hcryp,uint32_t difflength,uint32_t polling)3083 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
3084 {
3085 uint32_t index;
3086 uint32_t difflengthmod4 = difflength%4U;
3087 uint32_t inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
3088 uint32_t outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
3089 uint32_t mask[4][3];
3090 uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
3091
3092 uint32_t intermediate_data[4] = {0};
3093
3094 mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
3095 mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
3096 mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
3097 mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
3098
3099 #if defined(AES_CR_NPBLB)
3100 /* In case of GCM encryption or CCM decryption, specify the number of padding
3101 bytes in last block of payload */
3102 if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
3103 {
3104 uint32_t cr_temp = hcryp->Instance->CR;
3105
3106 if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
3107 || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
3108 {
3109 /* Set NPBLB field in writing the number of padding bytes
3110 for the last block of payload */
3111 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
3112 }
3113 }
3114 #else
3115 /* Software workaround applied to GCM encryption only */
3116 if ((hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) &&
3117 (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
3118 {
3119 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
3120 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
3121 }
3122 #endif
3123
3124 /* Wrap-up entering header or payload data */
3125 /* Enter complete words when possible */
3126 for(index=0U ; index < (difflength/4U); index ++)
3127 {
3128 /* Write the Input block in the Data Input register */
3129 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
3130 inputaddr+=4U;
3131 }
3132 /* Enter incomplete word padded with zeroes if applicable
3133 (case of header length not a multiple of 32-bits) */
3134 if (difflengthmod4 != 0U)
3135 {
3136 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
3137 }
3138 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
3139 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
3140 {
3141 hcryp->Instance->DINR = 0;
3142 }
3143
3144 if (polling == (uint32_t)CRYP_POLLING_ON)
3145 {
3146 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
3147 {
3148 hcryp->State = HAL_CRYP_STATE_READY;
3149 __HAL_UNLOCK(hcryp);
3150 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3151 hcryp->ErrorCallback(hcryp);
3152 #else
3153 HAL_CRYP_ErrorCallback(hcryp);
3154 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3155 }
3156
3157 /* Clear CCF Flag */
3158 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3159 }
3160
3161 /* if payload */
3162 if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
3163 {
3164
3165 /* Retrieve intermediate data */
3166 for(index=0U ; index < 4U; index ++)
3167 {
3168 intermediate_data[index] = hcryp->Instance->DOUTR;
3169 }
3170 /* Retrieve last words of cyphered data */
3171 /* First, retrieve complete output words */
3172 for(index=0U ; index < (difflength/4U); index ++)
3173 {
3174 *(uint32_t*)(outputaddr) = intermediate_data[index];
3175 outputaddr+=4U;
3176 }
3177 /* Next, retrieve partial output word if applicable;
3178 at the same time, start masking intermediate data
3179 with a mask of zeros of same size than the padding
3180 applied to the last block of payload */
3181 if (difflengthmod4 != 0U)
3182 {
3183 intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
3184 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
3185 }
3186
3187
3188 #if !defined(AES_CR_NPBLB)
3189 /* Software workaround applied to GCM encryption only,
3190 applicable for AES IP v2 version (where NPBLB is not defined) */
3191 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
3192 {
3193 /* Change again CHMOD configuration to GCM mode */
3194 __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);
3195
3196 /* Select FINAL phase */
3197 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
3198
3199 /* Before inserting the intermediate data, carry on masking operation
3200 with a mask of zeros of same size than the padding applied to the last block of payload */
3201 for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
3202 {
3203 intermediate_data[((difflength+3U)/4U)+index] = 0;
3204 }
3205 /* Insert intermediate data */
3206 for(index=0U ; index < 4U; index ++)
3207 {
3208 hcryp->Instance->DINR = intermediate_data[index];
3209 }
3210
3211 /* Wait for completion, and read data on DOUT. This data is to discard. */
3212 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
3213 {
3214 hcryp->State = HAL_CRYP_STATE_READY;
3215 __HAL_UNLOCK(hcryp);
3216 HAL_CRYP_ErrorCallback(hcryp);
3217 }
3218
3219 /* Read data to discard */
3220 /* Clear CCF Flag */
3221 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3222 for(index=0U ; index < 4U; index ++)
3223 {
3224 intermediate_data[index] = hcryp->Instance->DOUTR;
3225 }
3226
3227 } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
3228 #endif /* !defined(AES_CR_NPBLB) */
3229 } /* if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) */
3230
3231 }
3232
3233 /**
3234 * @}
3235 */
3236
3237 /**
3238 * @}
3239 */
3240
3241 /**
3242 * @}
3243 */
3244
3245 #endif /* AES */
3246
3247 #endif /* HAL_CRYP_MODULE_ENABLED */
3248 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
3249