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