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