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