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