STM32L443xx HAL User Manual
stm32l4xx_hal_cryp_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_cryp_ex.c
00004   * @author  MCD Application Team
00005   * @brief   CRYPEx HAL module driver.
00006   *          This file provides firmware functions to manage the extended
00007   *          functionalities of the Cryptography (CRYP) peripheral.
00008   *
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * Copyright (c) 2017 STMicroelectronics.
00013   * All rights reserved.
00014   *
00015   * This software is licensed under terms that can be found in the LICENSE file in
00016   * the root directory of this software component.
00017   * If no LICENSE file comes with this software, it is provided AS-IS.
00018   ******************************************************************************
00019   */
00020 
00021 /* Includes ------------------------------------------------------------------*/
00022 #include "stm32l4xx_hal.h"
00023 
00024 #ifdef HAL_CRYP_MODULE_ENABLED
00025 
00026 #if defined(AES)
00027 
00028 /** @addtogroup STM32L4xx_HAL_Driver
00029   * @{
00030   */
00031 
00032 /** @defgroup CRYPEx CRYPEx
00033   * @brief CRYP Extended HAL module driver
00034   * @{
00035   */
00036 
00037 /* Private typedef -----------------------------------------------------------*/
00038 /* Private define ------------------------------------------------------------*/
00039 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
00040   * @{
00041   */
00042 #define CRYP_CCF_TIMEOUTVALUE                      22000  /*!< CCF flag raising time-out value */
00043 #define CRYP_BUSY_TIMEOUTVALUE                     22000  /*!< BUSY flag reset time-out value  */
00044 
00045 #define CRYP_POLLING_OFF                             0x0  /*!< No polling when padding */
00046 #define CRYP_POLLING_ON                              0x1  /*!< Polling when padding    */
00047 
00048 #if defined(AES_CR_NPBLB)
00049 #define AES_POSITION_CR_NPBLB     (uint32_t)POSITION_VAL(AES_CR_NPBLB)    /*!< Required left shift to set background CLUT size */
00050 #endif
00051 /**
00052   * @}
00053   */
00054 
00055 /* Private macro -------------------------------------------------------------*/
00056 /* Private variables ---------------------------------------------------------*/
00057 /* Private function prototypes -----------------------------------------------*/
00058 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
00059  * @{
00060  */
00061 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
00062 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
00063 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
00064 static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
00065 static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma);
00066 static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma);
00067 static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma);
00068 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
00069 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
00070 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
00071 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
00072 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
00073 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
00074 /**
00075   * @}
00076   */
00077 
00078 /* Exported functions ---------------------------------------------------------*/
00079 
00080 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
00081   * @{
00082   */
00083 
00084 
00085 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function
00086  *  @brief    Extended callback functions.
00087  *
00088 @verbatim
00089  ===============================================================================
00090                  ##### Extended callback functions #####
00091  ===============================================================================
00092     [..]  This section provides callback function:
00093       (+) Computation completed.
00094 
00095 @endverbatim
00096   * @{
00097   */
00098 
00099 
00100 /**
00101   * @brief  Computation completed callbacks.
00102   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00103   *         the configuration information for CRYP module
00104   * @retval None
00105   */
00106 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
00107 {
00108   /* Prevent unused argument(s) compilation warning */
00109   UNUSED(hcryp);
00110 
00111   /* NOTE : This function should not be modified; when the callback is needed,
00112             the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
00113    */
00114 }
00115 
00116 /**
00117   * @}
00118   */
00119 
00120 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions
00121  *  @brief   Extended processing functions.
00122  *
00123 @verbatim
00124   ==============================================================================
00125                       ##### AES extended processing functions #####
00126   ==============================================================================
00127     [..]  This section provides functions allowing to:
00128       (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
00129           Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
00130           based on the processing type. Three processing types are available:
00131           (++) Polling mode
00132           (++) Interrupt mode
00133           (++) DMA mode
00134       (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES
00135           algorithm in different chaining modes.
00136           Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase
00137           so that steps can be skipped if so required. Functions are only differentiated based on the processing type.
00138           Three processing types are available:
00139           (++) Polling mode
00140           (++) Interrupt mode
00141           (++) DMA mode
00142 
00143 @endverbatim
00144   * @{
00145   */
00146 
00147 /**
00148   * @brief  Carry out in polling mode the ciphering or deciphering operation according to
00149   *         hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
00150   *         chaining modes ECB, CBC and CTR are managed by this function in polling mode.
00151   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00152   *         the configuration information for CRYP module
00153   * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
00154   *                     or key derivation+decryption.
00155   *                     Parameter is meaningless in case of key derivation.
00156   * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
00157   *               Parameter is meaningless in case of key derivation.
00158   * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of
00159   *                     decryption/key derivation+decryption, or pointer to the derivative keys in
00160   *                     case of key derivation only.
00161   * @param  Timeout Specify Timeout value
00162   * @retval HAL status
00163   */
00164 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
00165 {
00166 
00167   if (hcryp->State == HAL_CRYP_STATE_READY)
00168   {
00169     /* Check parameters setting */
00170     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
00171     {
00172       if (pOutputData == NULL)
00173       {
00174         return  HAL_ERROR;
00175       }
00176     }
00177     else
00178     {
00179       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
00180       {
00181         return  HAL_ERROR;
00182       }
00183     }
00184 
00185     /* Process Locked */
00186     __HAL_LOCK(hcryp);
00187 
00188     /* Change the CRYP state */
00189     hcryp->State = HAL_CRYP_STATE_BUSY;
00190 
00191     /* Call CRYP_ReadKey() API if the operating mode is set to
00192        key derivation, CRYP_ProcessData() otherwise  */
00193     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
00194     {
00195       if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
00196       {
00197         return HAL_TIMEOUT;
00198       }
00199     }
00200     else
00201     {
00202       if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
00203       {
00204         return HAL_TIMEOUT;
00205       }
00206     }
00207 
00208     /* If the state has not been set to SUSPENDED, set it to
00209        READY, otherwise keep it as it is */
00210     if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
00211     {
00212       hcryp->State = HAL_CRYP_STATE_READY;
00213     }
00214 
00215     /* Process Unlocked */
00216     __HAL_UNLOCK(hcryp);
00217 
00218     return HAL_OK;
00219   }
00220   else
00221   {
00222     return HAL_BUSY;
00223   }
00224 }
00225 
00226 
00227 
00228 /**
00229   * @brief  Carry out in interrupt mode the ciphering or deciphering operation according to
00230   *         hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
00231   *         chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
00232   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00233   *         the configuration information for CRYP module
00234   * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
00235   *                     or key derivation+decryption.
00236   *                     Parameter is meaningless in case of key derivation.
00237   * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
00238   *               Parameter is meaningless in case of key derivation.
00239   * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of
00240   *                     decryption/key derivation+decryption, or pointer to the derivative keys in
00241   *                     case of key derivation only.
00242   * @retval HAL status
00243   */
00244 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp,  uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
00245 {
00246   uint32_t inputaddr;
00247 
00248   if(hcryp->State == HAL_CRYP_STATE_READY)
00249   {
00250     /* Check parameters setting */
00251     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
00252     {
00253       if (pOutputData == NULL)
00254       {
00255         return  HAL_ERROR;
00256       }
00257     }
00258     else
00259     {
00260       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
00261       {
00262         return  HAL_ERROR;
00263       }
00264     }
00265     /* Process Locked */
00266     __HAL_LOCK(hcryp);
00267 
00268     /* If operating mode is not limited to key derivation only,
00269        get the buffers addresses and sizes */
00270     if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
00271     {
00272 
00273       hcryp->CrypInCount = Size;
00274       hcryp->pCrypInBuffPtr = pInputData;
00275       hcryp->pCrypOutBuffPtr = pOutputData;
00276       hcryp->CrypOutCount = Size;
00277     }
00278     else
00279     {
00280       /* For key derivation, set output buffer only
00281         (will point at derivated key) */
00282       hcryp->pCrypOutBuffPtr = pOutputData;
00283     }
00284 
00285     /* Change the CRYP state */
00286     hcryp->State = HAL_CRYP_STATE_BUSY;
00287 
00288       /* Process Unlocked */
00289     __HAL_UNLOCK(hcryp);
00290 
00291     /* Enable Computation Complete Flag and Error Interrupts */
00292     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
00293 
00294 
00295     /* If operating mode is key derivation only, the input data have
00296        already been entered during the initialization process. For
00297        the other operating modes, they are fed to the CRYP hardware
00298        block at this point. */
00299     if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
00300     {
00301       /* Initiate the processing under interrupt in entering
00302          the first input data */
00303       inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
00304       /* Increment/decrement instance pointer/counter */
00305       hcryp->pCrypInBuffPtr += 16;
00306       hcryp->CrypInCount -= 16U;
00307       /* Write the first input block in the Data Input register */
00308       hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00309       inputaddr+=4U;
00310       hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00311       inputaddr+=4U;
00312       hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
00313       inputaddr+=4U;
00314       hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00315     }
00316 
00317     /* Return function status */
00318     return HAL_OK;
00319   }
00320   else
00321   {
00322     return HAL_BUSY;
00323   }
00324 }
00325 
00326 
00327 
00328 
00329 
00330 /**
00331   * @brief  Carry out in DMA mode the ciphering or deciphering operation according to
00332   *         hcryp->Init structure fields.
00333   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00334   *         the configuration information for CRYP module
00335   * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
00336   *                     or key derivation+decryption.
00337   * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
00338   * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of
00339   *                     decryption/key derivation+decryption.
00340   * @note   Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.
00341   * @note   Supported operating modes are encryption, decryption and key derivation with decryption.
00342   * @note   No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx
00343   *         registers must be done by software.
00344   * @note   This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx
00345   *         registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
00346   * @note   pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
00347   * @retval HAL status
00348   */
00349 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp,  uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
00350 {
00351   uint32_t inputaddr;
00352   uint32_t outputaddr;
00353 
00354   if (hcryp->State == HAL_CRYP_STATE_READY)
00355   {
00356     /* Check parameters setting */
00357     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
00358     {
00359       /* no DMA channel is provided for key derivation operating mode,
00360          access to AES_KEYRx registers must be done by software */
00361       return  HAL_ERROR;
00362     }
00363     else
00364     {
00365       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
00366       {
00367         return  HAL_ERROR;
00368       }
00369     }
00370 
00371 
00372     /* Process Locked */
00373     __HAL_LOCK(hcryp);
00374 
00375     inputaddr  = (uint32_t)pInputData;
00376     outputaddr = (uint32_t)pOutputData;
00377 
00378     /* Change the CRYP state */
00379     hcryp->State = HAL_CRYP_STATE_BUSY;
00380 
00381     /* Set the input and output addresses and start DMA transfer */
00382     CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
00383 
00384     /* Process Unlocked */
00385     __HAL_UNLOCK(hcryp);
00386 
00387     /* Return function status */
00388     return HAL_OK;
00389   }
00390   else
00391   {
00392     return HAL_BUSY;
00393   }
00394 }
00395 
00396 
00397 
00398 
00399 
00400 
00401 /**
00402   * @brief  Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering
00403   *         operation according to hcryp->Init structure fields.
00404   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00405   *         the configuration information for CRYP module
00406   * @param  pInputData
00407   *         - pointer to payload data in GCM or CCM payload phase,
00408   *         - pointer to B0 block in CMAC header phase,
00409   *         - pointer to C block in CMAC final phase.
00410   *         - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
00411   * @param  Size
00412   *         - length of the input payload data buffer in bytes in GCM or CCM payload phase,
00413   *         - length of B0 block (in bytes) in CMAC header phase,
00414   *         - length of C block (in bytes) in CMAC final phase.
00415   *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
00416   *         - Parameter is meaningless in case of CCM final phase.
00417   *         - Parameter is message length in bytes in case of GCM final phase.
00418   *         - Parameter must be set to zero in case of GMAC final phase.
00419   * @param  pOutputData
00420   *         - pointer to plain or cipher text in GCM/CCM payload phase,
00421   *         - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
00422   *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
00423   *         - Parameter is meaningless in case of CMAC header phase.
00424   * @param  Timeout Specify Timeout value
00425   * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable.
00426   * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
00427   *         can be skipped by the user if so required.
00428   * @retval HAL status
00429   */
00430 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
00431 {
00432   uint32_t index             ;
00433   uint32_t inputaddr         ;
00434   uint32_t outputaddr        ;
00435   uint32_t tagaddr           ;
00436   uint64_t headerlength      ;
00437   uint64_t inputlength       ;
00438   uint64_t payloadlength     ;
00439   uint32_t difflength     = 0;
00440   uint32_t addhoc_process = 0;
00441 
00442   if (hcryp->State == HAL_CRYP_STATE_READY)
00443   {
00444     /* input/output parameters check */
00445     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
00446     {
00447        /* No processing required */
00448     }
00449     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
00450     {
00451       if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
00452           ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
00453       {
00454         return  HAL_ERROR;
00455       }
00456 #if defined(AES_CR_NPBLB)
00457       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
00458 #else
00459       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
00460 #endif
00461       {
00462         /* In case of CMAC or CCM (when applicable) header phase resumption, we can have pInputData = NULL and  Size = 0 */
00463         if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
00464         {
00465           return  HAL_ERROR;
00466         }
00467       }
00468     }
00469     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
00470     {
00471       if (((pInputData == NULL) && (Size != 0U)) || \
00472           ((pInputData != NULL) && (Size == 0U)) || \
00473           ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL)))
00474       {
00475         return  HAL_ERROR;
00476       }
00477     }
00478     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
00479     {
00480       if (pOutputData == NULL)
00481       {
00482         return  HAL_ERROR;
00483       }
00484 #if !defined(AES_CR_NPBLB)
00485       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
00486       {
00487         return  HAL_ERROR;
00488       }
00489 #endif
00490     }
00491     else
00492     {
00493       /* Unspecified Phase */
00494       return  HAL_ERROR;
00495     }
00496 
00497 
00498     /* Process Locked */
00499     __HAL_LOCK(hcryp);
00500 
00501     /* Change the CRYP state */
00502     hcryp->State = HAL_CRYP_STATE_BUSY;
00503 
00504     /*==============================================*/
00505     /* GCM/GMAC (or CCM when applicable) init phase */
00506     /*==============================================*/
00507     /* In case of init phase, the input data (Key and Initialization Vector) have
00508        already been entered during the initialization process. Therefore, the
00509        API just waits for the CCF flag to be set. */
00510     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
00511     {
00512       /* just wait for hash computation */
00513       if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
00514       {
00515         hcryp->State = HAL_CRYP_STATE_READY;
00516         __HAL_UNLOCK(hcryp);
00517         return HAL_TIMEOUT;
00518       }
00519 
00520       /* Clear CCF Flag */
00521       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
00522       /* Mark that the initialization phase is over */
00523       hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
00524     }
00525     /*=======================================================*/
00526     /* GCM/GMAC or (CCM / CMAC when applicable) header phase */
00527     /*=======================================================*/
00528     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
00529     {
00530 #if !defined(AES_CR_NPBLB)
00531       /* Set header phase; for GCM or GMAC, set data-byte at this point */
00532       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
00533       {
00534         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
00535       }
00536       else
00537 #endif
00538       {
00539         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
00540       }
00541 
00542       /* Enable the Peripheral */
00543       __HAL_CRYP_ENABLE(hcryp);
00544 
00545 #if !defined(AES_CR_NPBLB)
00546       /* in case of CMAC, enter B0 block in header phase, before the header itself. */
00547       /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
00548          skip these steps and go directly to header buffer feeding to the HW */
00549       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U))
00550       {
00551         uint64_t index_test;
00552         inputaddr = (uint32_t)pInputData;
00553 
00554         for(index=0U ; (index < Size); index += 16U)
00555         {
00556           /* Write the Input block in the Data Input register */
00557           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00558           inputaddr+=4U;
00559           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00560           inputaddr+=4U;
00561           hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
00562           inputaddr+=4U;
00563           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00564           inputaddr+=4U;
00565 
00566           if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
00567           {
00568             hcryp->State = HAL_CRYP_STATE_READY;
00569             __HAL_UNLOCK(hcryp);
00570             return HAL_TIMEOUT;
00571           }
00572           /* Clear CCF Flag */
00573           __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
00574 
00575           /* If the suspension flag has been raised and if the processing is not about
00576            to end, suspend processing */
00577           index_test = (uint64_t)index + 16U;
00578           if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_test < Size))
00579           {
00580             /* reset SuspendRequest */
00581             hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
00582             /* Change the CRYP state */
00583             hcryp->State = HAL_CRYP_STATE_SUSPENDED;
00584             /* Mark that the header phase is over */
00585             hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
00586 
00587            /* Save current reading and writing locations of Input and Output buffers */
00588            hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
00589            /* Save the total number of bytes (B blocks + header) that remain to be
00590               processed at this point */
00591            hcryp->CrypInCount     =  (uint32_t) (hcryp->Init.HeaderSize + Size - index_test);
00592 
00593            /* Process Unlocked */
00594             __HAL_UNLOCK(hcryp);
00595 
00596             return HAL_OK;
00597           }
00598         } /* for(index=0; (index < Size); index += 16) */
00599       }
00600 #endif /* !defined(AES_CR_NPBLB) */
00601 
00602       /* Enter header */
00603       inputaddr = (uint32_t)hcryp->Init.Header;
00604       /* Local variable headerlength is a number of bytes multiple of 128 bits,
00605          remaining header data (if any) are handled after this loop */
00606       headerlength =  (((hcryp->Init.HeaderSize)/16U)*16U) ;
00607       if ((hcryp->Init.HeaderSize % 16U) != 0U)
00608       {
00609         difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);
00610       }
00611       for(index=0U ; index < headerlength; index += 16U)
00612       {
00613         uint64_t index_temp;
00614         /* Write the Input block in the Data Input register */
00615         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00616         inputaddr+=4U;
00617         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00618         inputaddr+=4U;
00619         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
00620         inputaddr+=4U;
00621         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00622         inputaddr+=4U;
00623 
00624         if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
00625         {
00626           hcryp->State = HAL_CRYP_STATE_READY;
00627           __HAL_UNLOCK(hcryp);
00628           return HAL_TIMEOUT;
00629         }
00630         /* Clear CCF Flag */
00631         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
00632 
00633         /* If the suspension flag has been raised and if the processing is not about
00634          to end, suspend processing */
00635         index_temp = (uint64_t)index + 16U;
00636         if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < headerlength))
00637         {
00638           /* reset SuspendRequest */
00639           hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
00640           /* Change the CRYP state */
00641           hcryp->State = HAL_CRYP_STATE_SUSPENDED;
00642           /* Mark that the header phase is over */
00643           hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
00644 
00645          /* Save current reading and writing locations of Input and Output buffers */
00646          hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
00647          /* Save the total number of bytes that remain to be processed at this point */
00648           hcryp->CrypInCount =  (uint32_t) (hcryp->Init.HeaderSize - index_temp);
00649 
00650          /* Process Unlocked */
00651           __HAL_UNLOCK(hcryp);
00652 
00653           return HAL_OK;
00654         }
00655       }
00656 
00657       /* Case header length is not a multiple of 16 bytes */
00658       if (difflength != 0U)
00659       {
00660         hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
00661         CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
00662       }
00663 
00664       /* Mark that the header phase is over */
00665       hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
00666     }
00667     /*============================================*/
00668     /* GCM (or CCM when applicable) payload phase */
00669     /*============================================*/
00670     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
00671     {
00672 
00673       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
00674 
00675       /* if the header phase has been bypassed, AES must be enabled again */
00676       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
00677       {
00678         __HAL_CRYP_ENABLE(hcryp);
00679       }
00680 
00681       inputaddr  = (uint32_t)pInputData;
00682       outputaddr = (uint32_t)pOutputData;
00683 
00684       /* Enter payload */
00685       /* Specific handling to manage payload last block size less than 128 bits */
00686       if ((Size % 16U) != 0U)
00687       {
00688         payloadlength = (Size/16U) * 16U;
00689         difflength = (uint32_t) (Size - payloadlength);
00690         addhoc_process = 1;
00691       }
00692       else
00693       {
00694         payloadlength = Size;
00695       }
00696 
00697       /* Feed payload */
00698       for(index=0U ; index < payloadlength; index += 16U)
00699       {
00700         uint64_t index_temp;
00701         /* Write the Input block in the Data Input register */
00702         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00703         inputaddr+=4U;
00704         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00705         inputaddr+=4U;
00706         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
00707         inputaddr+=4U;
00708         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00709         inputaddr+=4U;
00710 
00711         if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
00712         {
00713           hcryp->State = HAL_CRYP_STATE_READY;
00714           __HAL_UNLOCK(hcryp);
00715           return HAL_TIMEOUT;
00716         }
00717 
00718         /* Clear CCF Flag */
00719         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
00720 
00721         /* Retrieve output data: read the output block
00722            from the Data Output Register */
00723         *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
00724         outputaddr+=4U;
00725         *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
00726         outputaddr+=4U;
00727         *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
00728         outputaddr+=4U;
00729         *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
00730         outputaddr+=4U;
00731 
00732         /* If the suspension flag has been raised and if the processing is not about
00733          to end, suspend processing */
00734         index_temp = (uint64_t)index + 16U;
00735         if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < payloadlength))
00736         {
00737           /* no flag waiting under IRQ handling */
00738           if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
00739           {
00740             /* Ensure that Busy flag is reset */
00741             if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
00742             {
00743               hcryp->State = HAL_CRYP_STATE_READY;
00744               __HAL_UNLOCK(hcryp);
00745               return HAL_TIMEOUT;
00746             }
00747           }
00748           /* reset SuspendRequest */
00749           hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
00750           /* Change the CRYP state */
00751           hcryp->State = HAL_CRYP_STATE_SUSPENDED;
00752           /* Mark that the header phase is over */
00753           hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
00754 
00755           /* Save current reading and writing locations of Input and Output buffers */
00756           hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
00757           hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
00758           /* Save the number of bytes that remain to be processed at this point */
00759           hcryp->CrypInCount     =  (uint32_t) (Size - index_temp);
00760 
00761           /* Process Unlocked */
00762           __HAL_UNLOCK(hcryp);
00763 
00764           return HAL_OK;
00765         }
00766 
00767       }
00768 
00769       /* Additional processing to manage GCM(/CCM) encryption and decryption cases when
00770          payload last block size less than 128 bits */
00771       if (addhoc_process == 1U)
00772       {
00773 
00774         hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
00775         hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
00776         CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
00777 
00778       } /* (addhoc_process == 1) */
00779 
00780       /* Mark that the payload phase is over */
00781       hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
00782     }
00783     /*==================================*/
00784     /* GCM/GMAC/CCM or CMAC final phase */
00785     /*==================================*/
00786     else
00787     {
00788       tagaddr = (uint32_t)pOutputData;
00789 
00790 #if defined(AES_CR_NPBLB)
00791      /* By default, clear NPBLB field */
00792       CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
00793 #endif
00794 
00795       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
00796 
00797       /* if the header and payload phases have been bypassed, AES must be enabled again */
00798       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
00799       {
00800         __HAL_CRYP_ENABLE(hcryp);
00801       }
00802 
00803       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
00804       {
00805         headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
00806         inputlength = Size * 8U;                    /* input length in bits */
00807 
00808 #if !defined(AES_CR_NPBLB)
00809         if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
00810         {
00811           hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
00812           hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
00813           hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
00814           hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
00815         }
00816         else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
00817         {
00818           hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
00819           hcryp->Instance->DINR = __REV((uint32_t)headerlength);
00820           hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
00821           hcryp->Instance->DINR = __REV((uint32_t)inputlength);
00822         }
00823         else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
00824         {
00825           hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
00826           hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
00827           hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
00828           hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
00829         }
00830         else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
00831         {
00832           hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
00833           hcryp->Instance->DINR = (uint32_t)(headerlength);
00834           hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
00835           hcryp->Instance->DINR = (uint32_t)(inputlength);
00836         }
00837         else
00838         {
00839           /* Unspecified Data Type */
00840          return  HAL_ERROR;
00841         }
00842 #else
00843         hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
00844         hcryp->Instance->DINR = (uint32_t)(headerlength);
00845         hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
00846         hcryp->Instance->DINR = (uint32_t)(inputlength);
00847 #endif
00848       }
00849 #if !defined(AES_CR_NPBLB)
00850       else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
00851       {
00852         inputaddr  = (uint32_t)pInputData;
00853         /* Enter the last block made of a 128-bit value formatted
00854            from the original B0 packet. */
00855         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00856         inputaddr+=4U;
00857         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00858         inputaddr+=4U;
00859         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
00860         inputaddr+=4U;
00861         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
00862       }
00863       else
00864       {
00865          /* Unspecified Chaining Mode */
00866          return  HAL_ERROR;
00867        }
00868 #endif
00869 
00870 
00871       if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
00872       {
00873           hcryp->State = HAL_CRYP_STATE_READY;
00874           __HAL_UNLOCK(hcryp);
00875           return HAL_TIMEOUT;
00876       }
00877 
00878       /* Read the Auth TAG in the Data Out register */
00879       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
00880       tagaddr+=4U;
00881       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
00882       tagaddr+=4U;
00883       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
00884       tagaddr+=4U;
00885       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
00886 
00887 
00888       /* Clear CCF Flag */
00889       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
00890       /* Mark that the final phase is over */
00891       hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
00892       /* Disable the Peripheral */
00893       __HAL_CRYP_DISABLE(hcryp);
00894     }
00895 
00896     /* Change the CRYP state */
00897     hcryp->State = HAL_CRYP_STATE_READY;
00898 
00899     /* Process Unlocked */
00900     __HAL_UNLOCK(hcryp);
00901 
00902     return HAL_OK;
00903   }
00904   else
00905   {
00906     return HAL_BUSY;
00907   }
00908 }
00909 
00910 
00911 
00912 
00913 /**
00914   * @brief  Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering
00915   *         operation according to hcryp->Init structure fields.
00916   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00917   *         the configuration information for CRYP module
00918   * @param  pInputData
00919   *         - pointer to payload data in GCM or CCM payload phase,
00920   *         - pointer to B0 block in CMAC header phase,
00921   *         - pointer to C block in CMAC final phase.
00922   *         - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
00923   * @param  Size
00924   *         - length of the input payload data buffer in bytes in GCM or CCM payload phase,
00925   *         - length of B0 block (in bytes) in CMAC header phase,
00926   *         - length of C block (in bytes) in CMAC final phase.
00927   *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
00928   *         - Parameter is meaningless in case of CCM final phase.
00929   *         - Parameter is message length in bytes in case of GCM final phase.
00930   *         - Parameter must be set to zero in case of GMAC final phase.
00931   * @param  pOutputData
00932   *         - pointer to plain or cipher text in GCM/CCM payload phase,
00933   *         - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
00934   *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
00935   *         - Parameter is meaningless in case of CMAC header phase.
00936   * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
00937   * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
00938   *         can be skipped by the user if so required.
00939   * @retval HAL status
00940   */
00941 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
00942 {
00943 
00944   uint32_t inputaddr         ;
00945   uint64_t headerlength      ;
00946   uint64_t inputlength       ;
00947   uint32_t index             ;
00948   uint32_t addhoc_process = 0;
00949   uint32_t difflength     = 0;
00950   uint32_t difflengthmod4 = 0;
00951   uint32_t mask[4][3];
00952 
00953   uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
00954 
00955   mask[0][0] = 0xFF000000U;  mask[0][1] = 0xFFFF0000U;  mask[0][2] = 0xFFFFFF00U;  /* 32-bit data */
00956   mask[1][0] = 0x0000FF00U;  mask[1][1] = 0x0000FFFFU;  mask[1][2] = 0xFF00FFFFU;  /* 16-bit data */
00957   mask[2][0] = 0x000000FFU;  mask[2][1] = 0x0000FFFFU;  mask[2][2] = 0x00FFFFFFU;  /* 8-bit data  */
00958   mask[3][0] = 0x000000FFU;  mask[3][1] = 0x0000FFFFU;  mask[3][2] = 0x00FFFFFFU;  /* Bit data    */
00959 
00960   if (hcryp->State == HAL_CRYP_STATE_READY)
00961   {
00962     /* input/output parameters check */
00963     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
00964     {
00965        /* No processing required */
00966     }
00967     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
00968     {
00969       if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
00970           ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
00971       {
00972         return  HAL_ERROR;
00973       }
00974 #if defined(AES_CR_NPBLB)
00975       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
00976 #else
00977       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
00978 #endif
00979       {
00980         /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and  Size = 0 */
00981         if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
00982         {
00983           return  HAL_ERROR;
00984         }
00985       }
00986     }
00987     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
00988     {
00989       if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
00990       {
00991         return  HAL_ERROR;
00992       }
00993     }
00994     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
00995     {
00996       if (pOutputData == NULL)
00997       {
00998         return  HAL_ERROR;
00999       }
01000 #if !defined(AES_CR_NPBLB)
01001       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
01002       {
01003         return  HAL_ERROR;
01004       }
01005 #endif
01006     }
01007     else
01008     {
01009       /* Unspecified Phase */
01010       return  HAL_ERROR;
01011      }
01012 
01013 
01014     /* Process Locked */
01015     __HAL_LOCK(hcryp);
01016 
01017     /* Change the CRYP state */
01018     hcryp->State = HAL_CRYP_STATE_BUSY;
01019 
01020     /* Process Unlocked */
01021     __HAL_UNLOCK(hcryp);
01022 
01023     /* Enable Computation Complete Flag and Error Interrupts */
01024     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
01025 
01026 
01027 
01028     /*==============================================*/
01029     /* GCM/GMAC (or CCM when applicable) init phase */
01030     /*==============================================*/
01031     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
01032     {
01033     /* In case of init phase, the input data (Key and Initialization Vector) have
01034        already been entered during the initialization process. Therefore, the
01035        software just waits for the CCF interrupt to be raised and which will
01036        be handled by CRYP_AES_Auth_IT() API. */
01037     }
01038     /*===================================*/
01039     /* GCM/GMAC/CCM or CMAC header phase */
01040     /*===================================*/
01041     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
01042     {
01043 
01044 #if defined(AES_CR_NPBLB)
01045       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
01046 #else
01047       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
01048 #endif
01049       {
01050         /* In case of CMAC, B blocks are first entered, before the header.
01051            Therefore, B blocks and the header are entered back-to-back
01052            as if it was only one single block.
01053            However, in case of resumption after suspension, if all the
01054            B blocks have been entered (in that case, Size = 0), only the
01055            remainder of the non-processed header bytes are entered. */
01056           if (Size != 0U)
01057           {
01058             hcryp->CrypInCount = (uint32_t)(Size + hcryp->Init.HeaderSize);
01059             hcryp->pCrypInBuffPtr = pInputData;
01060           }
01061           else
01062           {
01063             hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
01064             hcryp->pCrypInBuffPtr = hcryp->Init.Header;
01065           }
01066       }
01067       else
01068       {
01069         /* Get the header addresses and sizes */
01070         hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
01071         hcryp->pCrypInBuffPtr = hcryp->Init.Header;
01072       }
01073 
01074       inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
01075 
01076 
01077 #if !defined(AES_CR_NPBLB)
01078       /* Set header phase; for GCM or GMAC, set data-byte at this point */
01079       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
01080       {
01081         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
01082       }
01083       else
01084 #endif
01085       {
01086         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
01087       }
01088 
01089       /* Enable the Peripheral */
01090       __HAL_CRYP_ENABLE(hcryp);
01091 
01092       /* Increment/decrement instance pointer/counter */
01093       if (hcryp->CrypInCount == 0U)
01094       {
01095         /* Case of no header */
01096         hcryp->State = HAL_CRYP_STATE_READY;
01097         /* Mark that the header phase is over */
01098         hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
01099         return HAL_OK;
01100       }
01101       else if (hcryp->CrypInCount < 16U)
01102       {
01103         hcryp->CrypInCount = 0;
01104         addhoc_process = 1;
01105         difflength = (uint32_t) (hcryp->Init.HeaderSize);
01106         difflengthmod4 = difflength%4U;
01107       }
01108       else
01109       {
01110         hcryp->pCrypInBuffPtr += 16;
01111         hcryp->CrypInCount -= 16U;
01112       }
01113 
01114 
01115 #if defined(AES_CR_NPBLB)
01116       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
01117 #else
01118       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
01119 #endif
01120       {
01121         if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
01122         {
01123           /* All B blocks will have been entered after the next
01124              four DINR writing, so point at header buffer for
01125              the next iteration */
01126           hcryp->pCrypInBuffPtr = hcryp->Init.Header;
01127         }
01128       }
01129 
01130       /* Enter header first block to initiate the process
01131          in the Data Input register */
01132       if (addhoc_process == 0U)
01133       {
01134         /* Header has size equal or larger than 128 bits */
01135         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01136         inputaddr+=4U;
01137         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01138         inputaddr+=4U;
01139         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
01140         inputaddr+=4U;
01141         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01142       }
01143       else
01144       {
01145         /* Header has size less than 128 bits */
01146         /* Enter complete words when possible */
01147         for(index=0U ; index < (difflength/4U); index ++)
01148         {
01149           /* Write the Input block in the Data Input register */
01150           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01151           inputaddr+=4U;
01152         }
01153         /* Enter incomplete word padded with zeroes if applicable
01154           (case of header length not a multiple of 32-bits) */
01155         if (difflengthmod4 != 0U)
01156         {
01157           hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
01158         }
01159         /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
01160         for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
01161         {
01162           hcryp->Instance->DINR = 0;
01163         }
01164 
01165       }
01166     }
01167     /*============================================*/
01168     /* GCM (or CCM when applicable) payload phase */
01169     /*============================================*/
01170     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
01171     {
01172       /* Get the buffer addresses and sizes */
01173       hcryp->CrypInCount = (uint32_t)Size;
01174       hcryp->pCrypInBuffPtr = pInputData;
01175       hcryp->pCrypOutBuffPtr = pOutputData;
01176       hcryp->CrypOutCount = (uint32_t)Size;
01177 
01178       inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
01179 
01180       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
01181 
01182       /* if the header phase has been bypassed, AES must be enabled again */
01183       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
01184       {
01185         __HAL_CRYP_ENABLE(hcryp);
01186       }
01187 
01188       /* No payload case */
01189       if (pInputData == NULL)
01190       {
01191         hcryp->State = HAL_CRYP_STATE_READY;
01192         /* Mark that the header phase is over */
01193         hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
01194         /* Process Unlocked */
01195         __HAL_UNLOCK(hcryp);
01196 
01197         return HAL_OK;
01198       }
01199 
01200      /* Specific handling to manage payload size less than 128 bits */
01201       if (Size < 16U)
01202       {
01203         difflength = (uint32_t) (Size);
01204 #if defined(AES_CR_NPBLB)
01205         /* In case of GCM encryption or CCM decryption, specify the number of padding
01206            bytes in last block of payload */
01207         if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
01208         {
01209           uint32_t cr_temp = hcryp->Instance->CR;
01210 
01211           if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
01212            ||  ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
01213           {
01214             /* Set NPBLB field in writing the number of padding bytes
01215                for the last block of payload */
01216             MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
01217           }
01218         }
01219 #else
01220         /* Software workaround applied to GCM encryption only */
01221         if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
01222         {
01223           /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
01224           __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
01225         }
01226 #endif
01227 
01228 
01229         /* Set hcryp->CrypInCount to 0 (no more data to enter) */
01230         hcryp->CrypInCount = 0;
01231 
01232         /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes,
01233             to have a complete block of 128 bits */
01234         difflengthmod4 = difflength%4U;
01235         /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes
01236             to have a complete block of 128 bits */
01237         for(index=0U; index < (difflength/4U); index ++)
01238         {
01239           /* Write the Input block in the Data Input register */
01240           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01241           inputaddr+=4U;
01242         }
01243         /* If required, manage input data size not multiple of 32 bits */
01244         if (difflengthmod4 != 0U)
01245         {
01246           hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
01247         }
01248         /* Wrap-up in padding with zero-words if applicable */
01249         for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
01250         {
01251           hcryp->Instance->DINR = 0;
01252         }
01253       }
01254       else
01255       {
01256         /* Increment/decrement instance pointer/counter */
01257         hcryp->pCrypInBuffPtr += 16;
01258         hcryp->CrypInCount -= 16U;
01259 
01260         /* Enter payload first block to initiate the process
01261            in the Data Input register */
01262         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01263         inputaddr+=4U;
01264         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01265         inputaddr+=4U;
01266         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
01267         inputaddr+=4U;
01268         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01269       }
01270     }
01271     /*==================================*/
01272     /* GCM/GMAC/CCM or CMAC final phase */
01273     /*==================================*/
01274     else
01275     {
01276        hcryp->pCrypOutBuffPtr = pOutputData;
01277 
01278 #if defined(AES_CR_NPBLB)
01279      /* By default, clear NPBLB field */
01280       CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
01281 #endif
01282 
01283        MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
01284 
01285       /* if the header and payload phases have been bypassed, AES must be enabled again */
01286       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
01287       {
01288         __HAL_CRYP_ENABLE(hcryp);
01289       }
01290 
01291       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
01292       {
01293         headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
01294         inputlength = Size * 8U;                    /* Input length in bits */
01295         /* Write the number of bits in the header on 64 bits followed by the number
01296            of bits in the payload on 64 bits as well */
01297 
01298 #if !defined(AES_CR_NPBLB)
01299         if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
01300         {
01301           hcryp->Instance->DINR = __RBIT((uint32_t)((headerlength)>>32));
01302           hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
01303           hcryp->Instance->DINR = __RBIT((uint32_t)((inputlength)>>32));
01304           hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
01305         }
01306         else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
01307         {
01308           hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
01309           hcryp->Instance->DINR = __REV((uint32_t)headerlength);
01310           hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
01311           hcryp->Instance->DINR = __REV((uint32_t)inputlength);
01312         }
01313         else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
01314         {
01315           hcryp->Instance->DINR = __ROR((uint32_t)((headerlength)>>32), 16);
01316           hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
01317           hcryp->Instance->DINR = __ROR((uint32_t)((inputlength)>>32), 16);
01318           hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
01319         }
01320         else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
01321         {
01322           hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
01323           hcryp->Instance->DINR = (uint32_t)(headerlength);
01324           hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
01325           hcryp->Instance->DINR = (uint32_t)(inputlength);
01326         }
01327         else
01328         {
01329           /* Unspecified Data Type */
01330           return  HAL_ERROR;
01331         }
01332 #else
01333         hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
01334         hcryp->Instance->DINR = (uint32_t)(headerlength);
01335         hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
01336         hcryp->Instance->DINR = (uint32_t)(inputlength);
01337 #endif
01338       }
01339 #if !defined(AES_CR_NPBLB)
01340       else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
01341       {
01342         inputaddr  = (uint32_t)pInputData;
01343         /* Enter the last block made of a 128-bit value formatted
01344            from the original B0 packet. */
01345         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01346         inputaddr+=4U;
01347         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01348         inputaddr+=4U;
01349         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
01350         inputaddr+=4U;
01351         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01352       }
01353       else
01354       {
01355         /* Unspecified Chaining Mode */
01356         return  HAL_ERROR;
01357       }
01358 #endif
01359     }
01360 
01361     return HAL_OK;
01362   }
01363   else
01364   {
01365     return HAL_BUSY;
01366   }
01367 }
01368 
01369 
01370 
01371 
01372 /**
01373   * @brief  Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering
01374   *         operation according to hcryp->Init structure fields.
01375   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01376   *         the configuration information for CRYP module
01377   * @param  pInputData
01378   *         - pointer to payload data in GCM or CCM payload phase,
01379   *         - pointer to B0 block in CMAC header phase,
01380   *         - pointer to C block in CMAC final phase.
01381   *         - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
01382   * @param  Size
01383   *         - length of the input payload data buffer in bytes in GCM or CCM payload phase,
01384   *         - length of B0 block (in bytes) in CMAC header phase,
01385   *         - length of C block (in bytes) in CMAC final phase.
01386   *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
01387   *         - Parameter is meaningless in case of CCM final phase.
01388   *         - Parameter is message length in bytes in case of GCM final phase.
01389   *         - Parameter must be set to zero in case of GMAC final phase.
01390   * @param  pOutputData
01391   *         - pointer to plain or cipher text in GCM/CCM payload phase,
01392   *         - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
01393   *         - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
01394   *         - Parameter is meaningless in case of CMAC header phase.
01395   * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
01396   * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
01397   *         can be skipped by the user if so required.
01398   * @note   pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
01399   * @retval HAL status
01400   */
01401 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
01402 {
01403   uint32_t inputaddr      ;
01404   uint32_t outputaddr     ;
01405   uint32_t tagaddr        ;
01406   uint64_t headerlength   ;
01407   uint64_t inputlength    ;
01408   uint64_t payloadlength  ;
01409 
01410 
01411   if (hcryp->State == HAL_CRYP_STATE_READY)
01412   {
01413     /* input/output parameters check */
01414     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
01415     {
01416        /* No processing required */
01417     }
01418     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
01419     {
01420       if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
01421       {
01422         return  HAL_ERROR;
01423       }
01424 #if defined(AES_CR_NPBLB)
01425       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
01426       {
01427         /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and  Size = 0 */
01428         if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
01429         {
01430           return  HAL_ERROR;
01431         }
01432       }
01433 #else
01434       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
01435       {
01436         if ((pInputData == NULL) || (Size == 0U))
01437         {
01438           return  HAL_ERROR;
01439         }
01440       }
01441 #endif
01442     }
01443     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
01444     {
01445       if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
01446       {
01447         return  HAL_ERROR;
01448       }
01449     }
01450     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
01451     {
01452       if (pOutputData == NULL)
01453       {
01454         return  HAL_ERROR;
01455       }
01456 #if !defined(AES_CR_NPBLB)
01457       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
01458       {
01459         return  HAL_ERROR;
01460       }
01461 #endif
01462     }
01463     else
01464     {
01465       /* Unspecified Phase */
01466       return  HAL_ERROR;
01467     }
01468 
01469 
01470     /* Process Locked */
01471     __HAL_LOCK(hcryp);
01472 
01473     /* Change the CRYP state */
01474     hcryp->State = HAL_CRYP_STATE_BUSY;
01475 
01476     /*==============================================*/
01477     /* GCM/GMAC (or CCM when applicable) init phase */
01478     /*==============================================*/
01479     /* In case of init phase, the input data (Key and Initialization Vector) have
01480        already been entered during the initialization process. No DMA transfer is
01481        required at that point therefore, the software just waits for the CCF flag
01482        to be raised. */
01483     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
01484     {
01485       /* just wait for hash computation */
01486       if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
01487       {
01488         hcryp->State = HAL_CRYP_STATE_READY;
01489         __HAL_UNLOCK(hcryp);
01490         return HAL_TIMEOUT;
01491       }
01492 
01493       /* Clear CCF Flag */
01494       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
01495       /* Mark that the initialization phase is over */
01496       hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
01497       hcryp->State = HAL_CRYP_STATE_READY;
01498     }
01499     /*====================================*/
01500     /* GCM/GMAC/ CCM or CMAC header phase */
01501     /*====================================*/
01502     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
01503     {
01504 #if !defined(AES_CR_NPBLB)
01505       /* Set header phase; for GCM or GMAC, set data-byte at this point */
01506       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
01507       {
01508         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
01509       }
01510       else
01511 #endif
01512       {
01513         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
01514       }
01515 
01516       /* Enable the CRYP peripheral */
01517       __HAL_CRYP_ENABLE(hcryp);
01518 
01519 #if !defined(AES_CR_NPBLB)
01520       /* enter first B0 block in polling mode (no DMA transfer for B0) */
01521       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
01522       {
01523         inputaddr  = (uint32_t)pInputData;
01524         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01525         inputaddr+=4U;
01526         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01527         inputaddr+=4U;
01528         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
01529         inputaddr+=4U;
01530         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01531 
01532         if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
01533         {
01534           hcryp->State = HAL_CRYP_STATE_READY;
01535           __HAL_UNLOCK(hcryp);
01536           return HAL_TIMEOUT;
01537         }
01538         /* Clear CCF Flag */
01539         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
01540       }
01541 #endif
01542 
01543       /* No header case */
01544       if (hcryp->Init.Header == NULL)
01545       {
01546         hcryp->State = HAL_CRYP_STATE_READY;
01547         /* Mark that the header phase is over */
01548         hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
01549         /* Process Unlocked */
01550         __HAL_UNLOCK(hcryp);
01551 
01552         return HAL_OK;
01553       }
01554 
01555       inputaddr = (uint32_t)hcryp->Init.Header;
01556       if ((hcryp->Init.HeaderSize % 16U) != 0U)
01557       {
01558 
01559         if (hcryp->Init.HeaderSize < 16U)
01560         {
01561           hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
01562           CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);
01563 
01564           hcryp->State = HAL_CRYP_STATE_READY;
01565           /* Mark that the header phase is over */
01566           hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
01567 
01568           /* CCF flag indicating header phase AES processing completion
01569              will be checked at the start of the next phase:
01570             - payload phase (GCM / CCM when applicable)
01571             - final phase (GMAC or CMAC when applicable).  */
01572         }
01573         else
01574         {
01575           /* Local variable headerlength is a number of bytes multiple of 128 bits,
01576             remaining header data (if any) are handled after this loop */
01577           headerlength =  (((hcryp->Init.HeaderSize)/16U)*16U) ;
01578           /* Store the ending transfer point */
01579           hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
01580           hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */
01581 
01582           /* Set the input and output addresses and start DMA transfer */
01583           /* (incomplete DMA transfer, will be wrapped up after completion of
01584              the first one (initiated here) with data padding */
01585           CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)headerlength, 0);
01586         }
01587       }
01588       else
01589       {
01590         hcryp->CrypInCount = 0;
01591         /* Set the input address and start DMA transfer */
01592         CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)hcryp->Init.HeaderSize, 0);
01593       }
01594     }
01595     /*============================================*/
01596     /* GCM (or CCM when applicable) payload phase */
01597     /*============================================*/
01598     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
01599     {
01600       /* Coming from header phase, wait for CCF flag to be raised
01601           if header present and fed to the IP in the previous phase */
01602       if (hcryp->Init.Header != NULL)
01603       {
01604         if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
01605         {
01606           hcryp->State = HAL_CRYP_STATE_READY;
01607           __HAL_UNLOCK(hcryp);
01608           return HAL_TIMEOUT;
01609         }
01610       }
01611       else
01612       {
01613         /* Enable the Peripheral since wasn't in header phase (no header case) */
01614         __HAL_CRYP_ENABLE(hcryp);
01615       }
01616       /* Clear CCF Flag */
01617       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
01618 
01619       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
01620 
01621       /* No payload case */
01622       if (pInputData == NULL)
01623       {
01624         hcryp->State = HAL_CRYP_STATE_READY;
01625         /* Mark that the header phase is over */
01626         hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
01627         /* Process Unlocked */
01628         __HAL_UNLOCK(hcryp);
01629 
01630         return HAL_OK;
01631       }
01632 
01633 
01634       /* Specific handling to manage payload size less than 128 bits */
01635       if ((Size % 16U) != 0U)
01636       {
01637         inputaddr  = (uint32_t)pInputData;
01638         outputaddr = (uint32_t)pOutputData;
01639         if (Size < 16U)
01640         {
01641           /* Block is now entered in polling mode, no actual gain in resorting to DMA */
01642           hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
01643           hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
01644 
01645           CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON);
01646 
01647           /* Change the CRYP state to ready */
01648           hcryp->State = HAL_CRYP_STATE_READY;
01649           /* Mark that the payload phase is over */
01650           hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
01651 
01652           /* Call output data transfer complete callback */
01653 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
01654           hcryp->OutCpltCallback(hcryp);
01655 #else
01656           HAL_CRYP_OutCpltCallback(hcryp);
01657 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
01658         }
01659         else
01660         {
01661           payloadlength = (Size/16U) * 16U;
01662 
01663           /* Store the ending transfer points */
01664           hcryp->pCrypInBuffPtr = pInputData;
01665           hcryp->pCrypInBuffPtr += payloadlength;
01666           hcryp->pCrypOutBuffPtr = pOutputData;
01667           hcryp->pCrypOutBuffPtr += payloadlength;
01668           hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */
01669 
01670           /* Set the input and output addresses and start DMA transfer */
01671           /* (incomplete DMA transfer, will be wrapped up with data padding
01672              after completion of the one initiated here) */
01673           CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)payloadlength, outputaddr);
01674         }
01675       }
01676       else
01677       {
01678         hcryp->CrypInCount = 0;
01679         inputaddr  = (uint32_t)pInputData;
01680         outputaddr = (uint32_t)pOutputData;
01681 
01682         /* Set the input and output addresses and start DMA transfer */
01683         CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)Size, outputaddr);
01684       }
01685     }
01686     /*==================================*/
01687     /* GCM/GMAC/CCM or CMAC final phase */
01688     /*==================================*/
01689     else
01690     {
01691       /* If coming from header phase (GMAC or CMAC case when applicable),
01692          wait for CCF flag to be raised */
01693       if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE)
01694       {
01695         if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
01696         {
01697           hcryp->State = HAL_CRYP_STATE_READY;
01698           __HAL_UNLOCK(hcryp);
01699           return HAL_TIMEOUT;
01700         }
01701         /* Clear CCF Flag */
01702         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
01703       }
01704 
01705       tagaddr = (uint32_t)pOutputData;
01706 
01707 #if defined(AES_CR_NPBLB)
01708      /* By default, clear NPBLB field */
01709       CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
01710 #endif
01711       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
01712 
01713       /* if the header and payload phases have been bypassed, AES must be enabled again */
01714       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
01715       {
01716         __HAL_CRYP_ENABLE(hcryp);
01717       }
01718 
01719       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
01720       {
01721         headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
01722         inputlength = Size * 8U;  /* input length in bits */
01723         /* Write the number of bits in the header on 64 bits followed by the number
01724            of bits in the payload on 64 bits as well */
01725 #if !defined(AES_CR_NPBLB)
01726         if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
01727         {
01728           hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
01729           hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
01730           hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
01731           hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
01732         }
01733         else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
01734         {
01735           hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
01736           hcryp->Instance->DINR = __REV((uint32_t)headerlength);
01737           hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
01738           hcryp->Instance->DINR = __REV((uint32_t)inputlength);
01739         }
01740         else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
01741         {
01742           hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
01743           hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
01744           hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
01745           hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
01746         }
01747         else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
01748         {
01749           hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
01750           hcryp->Instance->DINR = (uint32_t)(headerlength);
01751           hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
01752           hcryp->Instance->DINR = (uint32_t)(inputlength);
01753         }
01754         else
01755         {
01756           /* Unspecified Data Type */
01757           return  HAL_ERROR;
01758         }
01759 #else
01760         hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
01761         hcryp->Instance->DINR = (uint32_t)(headerlength);
01762         hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
01763         hcryp->Instance->DINR = (uint32_t)(inputlength);
01764 #endif
01765       }
01766 #if !defined(AES_CR_NPBLB)
01767       else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
01768       {
01769         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
01770 
01771         inputaddr  = (uint32_t)pInputData;
01772         /* Enter the last block made of a 128-bit value formatted
01773            from the original B0 packet. */
01774         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01775         inputaddr+=4U;
01776         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01777         inputaddr+=4U;
01778         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
01779         inputaddr+=4U;
01780         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
01781       }
01782       else
01783       {
01784         /* Unspecified Chaining Mode */
01785         return  HAL_ERROR;
01786       }
01787 #endif
01788 
01789       /* No DMA transfer is required at that point therefore, the software
01790          just waits for the CCF flag to be raised. */
01791       if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
01792       {
01793           hcryp->State = HAL_CRYP_STATE_READY;
01794           __HAL_UNLOCK(hcryp);
01795           return HAL_TIMEOUT;
01796       }
01797 
01798       /* Read the Auth TAG in the IN FIFO */
01799       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
01800       tagaddr+=4U;
01801       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
01802       tagaddr+=4U;
01803       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
01804       tagaddr+=4U;
01805       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
01806 
01807       /* Clear CCF Flag */
01808       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
01809 
01810       /* Mark that the final phase is over */
01811       hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
01812       hcryp->State = HAL_CRYP_STATE_READY;
01813       /* Disable the Peripheral */
01814       __HAL_CRYP_DISABLE(hcryp);
01815 
01816     }
01817 
01818     /* Process Unlocked */
01819     __HAL_UNLOCK(hcryp);
01820 
01821     return HAL_OK;
01822   }
01823   else
01824   {
01825     return HAL_BUSY;
01826   }
01827 }
01828 
01829 /**
01830   * @}
01831   */
01832 
01833 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions
01834  *  @brief   Extended processing functions.
01835  *
01836 @verbatim
01837   ==============================================================================
01838                     ##### AES extended suspension and resumption functions #####
01839   ==============================================================================
01840     [..]  This section provides functions allowing to:
01841       (+) save in memory the Initialization Vector, the Key registers, the Control register or
01842           the Suspend registers when a process is suspended by a higher priority message
01843       (+) write back in CRYP hardware block the saved values listed above when the suspended
01844           lower priority message processing is resumed.
01845 
01846 @endverbatim
01847   * @{
01848   */
01849 
01850 
01851 /**
01852   * @brief  In case of message processing suspension, read the Initialization Vector.
01853   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01854   *         the configuration information for CRYP module.
01855   * @param  Output Pointer to the buffer containing the saved Initialization Vector.
01856   * @note   This value has to be stored for reuse by writing the AES_IVRx registers
01857   *         as soon as the interrupted processing has to be resumed.
01858   *         Applicable to all chaining modes.
01859   * @note   AES must be disabled when reading or resetting the IV values.
01860   * @retval None
01861   */
01862 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
01863 {
01864   uint32_t outputaddr = (uint32_t)Output;
01865 
01866   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
01867   outputaddr+=4U;
01868   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
01869   outputaddr+=4U;
01870   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
01871   outputaddr+=4U;
01872   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
01873 }
01874 
01875 /**
01876   * @brief  In case of message processing resumption, rewrite the Initialization
01877   *         Vector in the AES_IVRx registers.
01878   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01879   *         the configuration information for CRYP module.
01880   * @param  Input Pointer to the buffer containing the saved Initialization Vector to
01881   *         write back in the CRYP hardware block.
01882   * @note   Applicable to all chaining modes.
01883   * @note   AES must be disabled when reading or resetting the IV values.
01884   * @retval None
01885   */
01886 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
01887 {
01888   uint32_t ivaddr = (uint32_t)Input;
01889 
01890   hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
01891   ivaddr+=4U;
01892   hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
01893   ivaddr+=4U;
01894   hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
01895   ivaddr+=4U;
01896   hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
01897 }
01898 
01899 
01900 /**
01901   * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension,
01902   *         read the Suspend Registers.
01903   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01904   *         the configuration information for CRYP module.
01905   * @param  Output Pointer to the buffer containing the saved Suspend Registers.
01906   * @note   These values have to be stored for reuse by writing back the AES_SUSPxR registers
01907   *         as soon as the interrupted processing has to be resumed.
01908   * @retval None
01909   */
01910 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
01911 {
01912   uint32_t outputaddr = (uint32_t)Output;
01913 
01914   /* In case of GCM payload phase encryption, check that suspension can be carried out */
01915   if (READ_BIT(hcryp->Instance->CR, (AES_CR_CHMOD|AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
01916   {
01917     /* Ensure that Busy flag is reset */
01918     if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
01919     {
01920       hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
01921       hcryp->State = HAL_CRYP_STATE_ERROR;
01922 
01923       /* Process Unlocked */
01924       __HAL_UNLOCK(hcryp);
01925 
01926 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
01927       hcryp->ErrorCallback(hcryp);
01928 #else
01929       HAL_CRYP_ErrorCallback(hcryp);
01930 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
01931       return ;
01932     }
01933   }
01934 
01935   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
01936   outputaddr+=4U;
01937   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
01938   outputaddr+=4U;
01939   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
01940   outputaddr+=4U;
01941   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
01942   outputaddr+=4U;
01943   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
01944   outputaddr+=4U;
01945   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
01946   outputaddr+=4U;
01947   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R);
01948   outputaddr+=4U;
01949   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);
01950 }
01951 
01952 /**
01953   * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Suspend
01954   *         Registers in the AES_SUSPxR registers.
01955   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01956   *         the configuration information for CRYP module.
01957   * @param  Input Pointer to the buffer containing the saved suspend registers to
01958   *         write back in the CRYP hardware block.
01959   * @retval None
01960   */
01961 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
01962 {
01963   uint32_t ivaddr = (uint32_t)Input;
01964 
01965   hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
01966   ivaddr+=4U;
01967   hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
01968   ivaddr+=4U;
01969   hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
01970   ivaddr+=4U;
01971   hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
01972   ivaddr+=4U;
01973   hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
01974   ivaddr+=4U;
01975   hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
01976   ivaddr+=4U;
01977   hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
01978   ivaddr+=4U;
01979   hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));
01980 }
01981 
01982 
01983 /**
01984   * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Key Registers.
01985   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01986   *         the configuration information for CRYP module.
01987   * @param  Output Pointer to the buffer containing the saved Key Registers.
01988   * @param  KeySize Indicates the key size (128 or 256 bits).
01989   * @note   These values have to be stored for reuse by writing back the AES_KEYRx registers
01990   *         as soon as the interrupted processing has to be resumed.
01991   * @retval None
01992   */
01993 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
01994 {
01995   uint32_t keyaddr = (uint32_t)Output;
01996 
01997   if (KeySize == CRYP_KEYSIZE_256B)
01998   {
01999     *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
02000     keyaddr+=4U;
02001     *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
02002     keyaddr+=4U;
02003     *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
02004     keyaddr+=4U;
02005     *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
02006     keyaddr+=4U;
02007   }
02008 
02009   *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
02010   keyaddr+=4U;
02011   *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
02012   keyaddr+=4U;
02013   *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
02014   keyaddr+=4U;
02015   *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0);
02016 }
02017 
02018 /**
02019   * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key
02020   *         Registers in the AES_KEYRx registers.
02021   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02022   *         the configuration information for CRYP module.
02023   * @param  Input Pointer to the buffer containing the saved key registers to
02024   *         write back in the CRYP hardware block.
02025   * @param  KeySize Indicates the key size (128 or 256 bits)
02026   * @retval None
02027   */
02028 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
02029 {
02030   uint32_t keyaddr = (uint32_t)Input;
02031 
02032   if (KeySize == CRYP_KEYSIZE_256B)
02033   {
02034     hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
02035     keyaddr+=4U;
02036     hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
02037     keyaddr+=4U;
02038     hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
02039     keyaddr+=4U;
02040     hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
02041     keyaddr+=4U;
02042   }
02043 
02044     hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
02045     keyaddr+=4U;
02046     hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
02047     keyaddr+=4U;
02048     hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
02049     keyaddr+=4U;
02050     hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));
02051 }
02052 
02053 
02054 /**
02055   * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Control Register.
02056   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02057   *         the configuration information for CRYP module.
02058   * @param  Output Pointer to the buffer containing the saved Control Register.
02059   * @note   This values has to be stored for reuse by writing back the AES_CR register
02060   *         as soon as the interrupted processing has to be resumed.
02061   * @retval None
02062   */
02063 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
02064 {
02065   *(uint32_t*)(void *)(Output) = hcryp->Instance->CR;                           /* Derogation MisraC2012 R.11.5 */
02066 }
02067 
02068 /**
02069   * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Control
02070   *         Registers in the AES_CR register.
02071   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02072   *         the configuration information for CRYP module.
02073   * @param  Input Pointer to the buffer containing the saved Control Register to
02074   *         write back in the CRYP hardware block.
02075   * @retval None
02076   */
02077 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
02078 {
02079   hcryp->Instance->CR = *(uint32_t*)(void *)(Input);                            /* Derogation MisraC2012 R.11.5 */
02080   /* At the same time, set handle state back to READY to be able to resume the AES calculations
02081      without the processing APIs returning HAL_BUSY when called. */
02082   hcryp->State        = HAL_CRYP_STATE_READY;
02083 }
02084 
02085 /**
02086   * @brief  Request CRYP processing suspension when in polling or interruption mode.
02087   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02088   *         the configuration information for CRYP module.
02089   * @note   Set the handle field SuspendRequest to the appropriate value so that
02090   *         the on-going CRYP processing is suspended as soon as the required
02091   *         conditions are met.
02092   * @note   It is advised not to suspend the CRYP processing when the DMA controller
02093   *         is managing the data transfer
02094   * @retval None
02095   */
02096 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
02097 {
02098   /* Set Handle Suspend Request field */
02099   hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
02100 }
02101 
02102 /**
02103   * @}
02104   */
02105 
02106 /**
02107   * @}
02108   */
02109 
02110 /** @addtogroup CRYPEx_Private_Functions
02111   * @{
02112   */
02113 
02114 /**
02115   * @brief  DMA CRYP Input Data process complete callback
02116   *         for GCM, GMAC, CCM or CMAC chaining modes.
02117   * @note   Specific setting of hcryp fields are required only
02118   *         in the case of header phase where no output data DMA
02119   *         transfer is on-going (only input data transfer is enabled
02120   *         in such a case).
02121   * @param  hdma DMA handle.
02122   * @retval None
02123   */
02124 static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma)
02125 {
02126   uint32_t difflength;
02127   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */
02128 
02129   /* Disable the DMA transfer for input request  */
02130   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
02131 
02132   if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
02133   {
02134 
02135     if (hcryp->CrypInCount != 0U)
02136     {
02137       /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
02138       difflength = hcryp->CrypInCount;
02139       hcryp->CrypInCount = 0;
02140 
02141       CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);
02142     }
02143     hcryp->State = HAL_CRYP_STATE_READY;
02144     /* Mark that the header phase is over */
02145     hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
02146   }
02147   /* CCF flag indicating header phase AES processing completion
02148      will be checked at the start of the next phase:
02149      - payload phase (GCM or CCM when applicable)
02150      - final phase (GMAC or CMAC).
02151     This allows to avoid the Wait on Flag within the IRQ handling.  */
02152 
02153   /* Call input data transfer complete callback */
02154 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02155   hcryp->InCpltCallback(hcryp);
02156 #else
02157   HAL_CRYP_InCpltCallback(hcryp);
02158 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02159 }
02160 
02161 /**
02162   * @brief  DMA CRYP Output Data process complete callback
02163   *         for GCM, GMAC, CCM or CMAC chaining modes.
02164   * @note   This callback is called only in the payload phase.
02165   * @param  hdma DMA handle.
02166   * @retval None
02167   */
02168 static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma)
02169 {
02170   uint32_t difflength;
02171   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */
02172 
02173   /* Disable the DMA transfer for output request */
02174   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
02175 
02176   /* Clear CCF Flag */
02177   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02178 
02179   /* Initiate additional transfer to wrap-up data feeding to the IP */
02180   if (hcryp->CrypInCount != 0U)
02181   {
02182     /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
02183     difflength = hcryp->CrypInCount;
02184     hcryp->CrypInCount = 0;
02185 
02186     CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
02187   }
02188 
02189   /* Change the CRYP state to ready */
02190   hcryp->State = HAL_CRYP_STATE_READY;
02191   /* Mark that the payload phase is over */
02192   hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
02193 
02194   /* Call output data transfer complete callback */
02195 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02196   hcryp->OutCpltCallback(hcryp);
02197 #else
02198   HAL_CRYP_OutCpltCallback(hcryp);
02199 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02200 }
02201 
02202 /**
02203   * @brief  DMA CRYP communication error callback
02204   *         for GCM, GMAC, CCM or CMAC chaining modes.
02205   * @param  hdma DMA handle
02206   * @retval None
02207   */
02208 static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma)
02209 {
02210   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */
02211 
02212   hcryp->State= HAL_CRYP_STATE_ERROR;
02213   hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
02214 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02215   hcryp->ErrorCallback(hcryp);
02216 #else
02217   HAL_CRYP_ErrorCallback(hcryp);
02218 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02219   /* Clear Error Flag */
02220   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
02221 }
02222 
02223 
02224 
02225 /**
02226   * @brief  Handle CRYP block input/output data handling under interruption
02227   *         for GCM, GMAC, CCM  or CMAC chaining modes.
02228   * @note   The function is called under interruption only, once
02229   *         interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().
02230   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02231   *         the configuration information for CRYP module
02232   * @retval HAL status
02233   */
02234 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
02235 {
02236   uint32_t inputaddr         ;
02237   uint32_t outputaddr        ;
02238   uint32_t index             ;
02239   uint32_t addhoc_process = 0;
02240   uint32_t difflength     = 0;
02241   uint32_t difflengthmod4 = 0;
02242   uint32_t mask[4][3]        ;
02243   uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
02244   uint32_t intermediate_data[4] = {0};
02245 
02246   mask[0][0] = 0xFF000000U;  mask[0][1] = 0xFFFF0000U;  mask[0][2] = 0xFFFFFF00U;  /* 32-bit data */
02247   mask[1][0] = 0x0000FF00U;  mask[1][1] = 0x0000FFFFU;  mask[1][2] = 0xFF00FFFFU;  /* 16-bit data */
02248   mask[2][0] = 0x000000FFU;  mask[2][1] = 0x0000FFFFU;  mask[2][2] = 0x00FFFFFFU;  /* 8-bit data  */
02249   mask[3][0] = 0x000000FFU;  mask[3][1] = 0x0000FFFFU;  mask[3][2] = 0x00FFFFFFU;  /* Bit data    */
02250 
02251   if(hcryp->State == HAL_CRYP_STATE_BUSY)
02252   {
02253     /*===========================*/
02254     /* GCM/GMAC(/CCM) init phase */
02255     /*===========================*/
02256     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
02257     {
02258       /* Clear Computation Complete Flag */
02259       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02260       /* Disable Computation Complete Flag and Errors Interrupts */
02261       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
02262       /* Change the CRYP state */
02263       hcryp->State = HAL_CRYP_STATE_READY;
02264 
02265       /* Mark that the initialization phase is over */
02266       hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
02267 
02268       /* Process Unlocked */
02269       __HAL_UNLOCK(hcryp);
02270       /* Call computation complete callback */
02271 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02272       hcryp->CompCpltCallback(hcryp);
02273 #else
02274       HAL_CRYPEx_ComputationCpltCallback(hcryp);
02275 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02276       return HAL_OK;
02277     }
02278     /*========================================*/
02279     /* GCM/GMAC (or CCM or CMAC) header phase */
02280     /*========================================*/
02281     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
02282     {
02283       /* Check if all input header data have been entered */
02284       if (hcryp->CrypInCount == 0U)
02285       {
02286         /* Clear Computation Complete Flag */
02287         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02288         /* Disable Computation Complete Flag and Errors Interrupts */
02289         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
02290         /* Change the CRYP state */
02291         hcryp->State = HAL_CRYP_STATE_READY;
02292        /* Mark that the header phase is over */
02293         hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
02294 
02295        /* Process Unlocked */
02296         __HAL_UNLOCK(hcryp);
02297 
02298         /* Call computation complete callback */
02299 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02300         hcryp->CompCpltCallback(hcryp);
02301 #else
02302         HAL_CRYPEx_ComputationCpltCallback(hcryp);
02303 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02304 
02305         return HAL_OK;
02306       }
02307       /* If suspension flag has been raised, suspend processing */
02308       else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
02309       {
02310         /* Clear CCF Flag */
02311         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02312 
02313         /* reset SuspendRequest */
02314         hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
02315         /* Disable Computation Complete Flag and Errors Interrupts */
02316         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
02317         /* Change the CRYP state */
02318         hcryp->State = HAL_CRYP_STATE_SUSPENDED;
02319         /* Mark that the header phase is suspended */
02320         hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
02321 
02322        /* Process Unlocked */
02323         __HAL_UNLOCK(hcryp);
02324 
02325         return HAL_OK;
02326       }
02327       else /* Carry on feeding input data to the CRYP hardware block */
02328       {
02329         /* Clear Computation Complete Flag */
02330         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02331         /* Get the last Input data address */
02332         inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
02333 
02334         /* Increment/decrement instance pointer/counter */
02335         if (hcryp->CrypInCount < 16U)
02336         {
02337           difflength = hcryp->CrypInCount;
02338           hcryp->CrypInCount = 0;
02339           addhoc_process = 1;
02340           difflengthmod4 = difflength%4U;
02341         }
02342         else
02343         {
02344           hcryp->pCrypInBuffPtr += 16;
02345           hcryp->CrypInCount -= 16U;
02346         }
02347 
02348 #if defined(AES_CR_NPBLB)
02349         if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
02350 #else
02351         if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
02352 #endif
02353         {
02354           if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
02355           {
02356             /* All B blocks will have been entered after the next
02357               four DINR writing, so point at header buffer for
02358               the next iteration */
02359             hcryp->pCrypInBuffPtr = hcryp->Init.Header;
02360           }
02361         }
02362 
02363         /* Write the Input block in the Data Input register */
02364         if (addhoc_process == 0U)
02365         {
02366           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02367           inputaddr+=4U;
02368           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02369           inputaddr+=4U;
02370           hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
02371           inputaddr+=4U;
02372           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02373         }
02374         else
02375         {
02376           /* Header remainder has size less than 128 bits */
02377           /* Enter complete words when possible */
02378           for(index=0U ; index < (difflength/4U); index ++)
02379           {
02380             /* Write the Input block in the Data Input register */
02381             hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02382             inputaddr+=4U;
02383           }
02384           /* Enter incomplete word padded with zeroes if applicable
02385             (case of header length not a multiple of 32-bits) */
02386           if (difflengthmod4 != 0U)
02387           {
02388             hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
02389           }
02390           /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
02391           for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
02392           {
02393             hcryp->Instance->DINR = 0;
02394           }
02395         }
02396 
02397         return HAL_OK;
02398       }
02399     }
02400     /*=======================*/
02401     /* GCM/CCM payload phase */
02402     /*=======================*/
02403     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
02404     {
02405       /* Get the last output data address */
02406       outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
02407 
02408      /* Specific handling to manage payload size less than 128 bits
02409         when GCM (or CCM when applicable) encryption or decryption is selected.
02410         Check here if the last block output data are read */
02411 #if defined(AES_CR_NPBLB)
02412       if ((hcryp->CrypOutCount < 16U)                                && \
02413           (hcryp->CrypOutCount > 0U))
02414 #else
02415       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
02416           (hcryp->CrypOutCount < 16U)                                && \
02417           (hcryp->CrypOutCount > 0U))
02418 #endif
02419       {
02420         difflength = hcryp->CrypOutCount;
02421         difflengthmod4 = difflength%4U;
02422         hcryp->CrypOutCount = 0;   /* mark that no more output data will be needed */
02423         /* Retrieve intermediate data */
02424         for(index=0U ; index < 4U; index ++)
02425         {
02426           intermediate_data[index] = hcryp->Instance->DOUTR;
02427         }
02428         /* Retrieve last words of cyphered data */
02429         /* First, retrieve complete output words */
02430         for(index=0U ; index < (difflength/4U); index ++)
02431         {
02432           *(uint32_t*)(outputaddr) = intermediate_data[index];
02433           outputaddr+=4U;
02434         }
02435         /* Next, retrieve partial output word if applicable;
02436            at the same time, start masking intermediate data
02437            with a mask of zeros of same size than the padding
02438            applied to the last block of payload */
02439         if (difflengthmod4 != 0U)
02440         {
02441           intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
02442           *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
02443         }
02444 
02445 #if !defined(AES_CR_NPBLB)
02446         if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
02447         {
02448           /* Change again CHMOD configuration to GCM mode */
02449           __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);
02450 
02451           /* Select FINAL phase */
02452           MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
02453 
02454           /* Before inserting the intermediate data, carry on masking operation
02455              with a mask of zeros of same size than the padding applied to the last block of payload */
02456           for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
02457           {
02458             intermediate_data[((difflength+3U)/4U)+index] = 0;
02459           }
02460 
02461           /* Insert intermediate data to trigger an additional DOUTR reading round */
02462           /* Clear Computation Complete Flag before entering new block */
02463           __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02464           for(index=0U ; index < 4U; index ++)
02465           {
02466             hcryp->Instance->DINR = intermediate_data[index];
02467           }
02468         }
02469         else
02470 #endif
02471         {
02472           /* Payload phase is now over */
02473           /* Clear Computation Complete Flag */
02474           __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02475           /* Disable Computation Complete Flag and Errors Interrupts */
02476           __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
02477           /* Change the CRYP state */
02478           hcryp->State = HAL_CRYP_STATE_READY;
02479           /* Mark that the payload phase is over */
02480           hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
02481 
02482           /* Process Unlocked */
02483           __HAL_UNLOCK(hcryp);
02484 
02485           /* Call computation complete callback */
02486 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02487           hcryp->CompCpltCallback(hcryp);
02488 #else
02489           HAL_CRYPEx_ComputationCpltCallback(hcryp);
02490 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02491         }
02492         return HAL_OK;
02493       }
02494       else
02495       {
02496         if (hcryp->CrypOutCount != 0U)
02497         {
02498           /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */
02499           /* Retrieve the last block available from the CRYP hardware block:
02500             read the output block from the Data Output Register */
02501           *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02502           outputaddr+=4U;
02503           *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02504           outputaddr+=4U;
02505           *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02506           outputaddr+=4U;
02507           *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02508 
02509           /* Increment/decrement instance pointer/counter */
02510           hcryp->pCrypOutBuffPtr += 16;
02511           hcryp->CrypOutCount -= 16U;
02512         }
02513 #if !defined(AES_CR_NPBLB)
02514         else
02515         {
02516           /* Software work-around: additional DOUTR reading round to discard the data */
02517           for(index=0U ; index < 4U; index ++)
02518           {
02519             intermediate_data[index] = hcryp->Instance->DOUTR;
02520           }
02521         }
02522 #endif
02523       }
02524 
02525       /* Check if all output text has been retrieved */
02526       if (hcryp->CrypOutCount == 0U)
02527       {
02528         /* Clear Computation Complete Flag */
02529         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02530         /* Disable Computation Complete Flag and Errors Interrupts */
02531         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
02532         /* Change the CRYP state */
02533         hcryp->State = HAL_CRYP_STATE_READY;
02534        /* Mark that the payload phase is over */
02535         hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
02536 
02537        /* Process Unlocked */
02538         __HAL_UNLOCK(hcryp);
02539 
02540         /* Call computation complete callback */
02541 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02542         hcryp->CompCpltCallback(hcryp);
02543 #else
02544         HAL_CRYPEx_ComputationCpltCallback(hcryp);
02545 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02546 
02547         return HAL_OK;
02548       }
02549       /* If suspension flag has been raised, suspend processing */
02550       else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
02551       {
02552         /* Clear CCF Flag */
02553         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02554 
02555         /* reset SuspendRequest */
02556         hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
02557         /* Disable Computation Complete Flag and Errors Interrupts */
02558         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
02559         /* Change the CRYP state */
02560         hcryp->State = HAL_CRYP_STATE_SUSPENDED;
02561         /* Mark that the payload phase is suspended */
02562         hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_SUSPENDED;
02563 
02564        /* Process Unlocked */
02565         __HAL_UNLOCK(hcryp);
02566 
02567         return HAL_OK;
02568       }
02569       else /* Output data are still expected, carry on feeding the CRYP
02570                hardware block with input data */
02571       {
02572         /* Clear Computation Complete Flag */
02573         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02574         /* Get the last Input data address */
02575         inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
02576 
02577         /* Usual input data feeding case */
02578         if (hcryp->CrypInCount < 16U)
02579         {
02580           difflength = (uint32_t) (hcryp->CrypInCount);
02581           difflengthmod4 = difflength%4U;
02582           hcryp->CrypInCount = 0;
02583 
02584 #if defined(AES_CR_NPBLB)
02585           /* In case of GCM encryption or CCM decryption, specify the number of padding
02586              bytes in last block of payload */
02587           {
02588             uint32_t cr_temp = hcryp->Instance->CR;
02589 
02590             if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
02591              ||  ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
02592             {
02593               /* Set NPBLB field in writing the number of padding bytes
02594               for the last block of payload */
02595               MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
02596              }
02597           }
02598 #else
02599           /* Software workaround applied to GCM encryption only */
02600           if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
02601           {
02602             /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
02603             __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
02604           }
02605 #endif
02606 
02607           /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes
02608               to have a complete block of 128 bits */
02609           for(index=0U ; index < (difflength/4U); index ++)
02610           {
02611             /* Write the Input block in the Data Input register */
02612             hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02613             inputaddr+=4U;
02614           }
02615           /* If required, manage input data size not multiple of 32 bits */
02616           if (difflengthmod4 != 0U)
02617           {
02618             hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
02619           }
02620           /* Wrap-up in padding with zero-words if applicable */
02621           for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
02622           {
02623             hcryp->Instance->DINR = 0;
02624           }
02625 
02626         }
02627         else
02628         {
02629           hcryp->pCrypInBuffPtr += 16;
02630           hcryp->CrypInCount -= 16U;
02631 
02632           /* Write the Input block in the Data Input register */
02633           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02634           inputaddr+=4U;
02635           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02636           inputaddr+=4U;
02637           hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
02638           inputaddr+=4U;
02639           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02640         }
02641 
02642 
02643         return HAL_OK;
02644       }
02645     }
02646     /*=======================================*/
02647     /* GCM/GMAC (or CCM or CMAC) final phase */
02648     /*=======================================*/
02649     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
02650     {
02651       /* Clear Computation Complete Flag */
02652       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02653 
02654       /* Get the last output data address */
02655       outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
02656 
02657       /* Retrieve the last expected data from the CRYP hardware block:
02658          read the output block from the Data Output Register */
02659       *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02660       outputaddr+=4U;
02661       *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02662       outputaddr+=4U;
02663       *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02664       outputaddr+=4U;
02665       *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02666 
02667       /* Disable Computation Complete Flag and Errors Interrupts */
02668       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
02669       /* Change the CRYP state */
02670       hcryp->State = HAL_CRYP_STATE_READY;
02671       /* Mark that the header phase is over */
02672       hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
02673 
02674       /* Disable the Peripheral */
02675       __HAL_CRYP_DISABLE(hcryp);
02676       /* Process Unlocked */
02677        __HAL_UNLOCK(hcryp);
02678 
02679       /* Call computation complete callback */
02680 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02681       hcryp->CompCpltCallback(hcryp);
02682 #else
02683       HAL_CRYPEx_ComputationCpltCallback(hcryp);
02684 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02685 
02686       return HAL_OK;
02687     }
02688     else
02689     {
02690       /* Clear Computation Complete Flag */
02691       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02692       hcryp->State = HAL_CRYP_STATE_ERROR;
02693       __HAL_UNLOCK(hcryp);
02694       return HAL_ERROR;
02695     }
02696   }
02697   else
02698   {
02699     return HAL_BUSY;
02700   }
02701 }
02702 
02703 
02704 
02705 /**
02706   * @brief  Set the DMA configuration and start the DMA transfer
02707   *         for GCM, GMAC, CCM  or CMAC chaining modes.
02708   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02709   *         the configuration information for CRYP module.
02710   * @param  inputaddr Address of the Input buffer.
02711   * @param  Size Size of the Input buffer un bytes, must be a multiple of 16.
02712   * @param  outputaddr Address of the Output buffer, null pointer when no output DMA stream
02713   *         has to be configured.
02714   * @retval None
02715   */
02716 static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
02717 {
02718 
02719   /* Set the input CRYP DMA transfer complete callback */
02720   hcryp->hdmain->XferCpltCallback = CRYP_Authentication_DMAInCplt;
02721   /* Set the DMA error callback */
02722   hcryp->hdmain->XferErrorCallback = CRYP_Authentication_DMAError;
02723 
02724   if (outputaddr != 0U)
02725   {
02726     /* Set the output CRYP DMA transfer complete callback */
02727     hcryp->hdmaout->XferCpltCallback = CRYP_Authentication_DMAOutCplt;
02728     /* Set the DMA error callback */
02729     hcryp->hdmaout->XferErrorCallback = CRYP_Authentication_DMAError;
02730   }
02731 
02732   /* Enable the CRYP peripheral */
02733   __HAL_CRYP_ENABLE(hcryp);
02734 
02735   /* Enable the DMA input stream */
02736   if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
02737   {
02738 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02739     hcryp->ErrorCallback(hcryp);
02740 #else
02741     HAL_CRYP_ErrorCallback(hcryp);
02742 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02743   }
02744 
02745   /* Enable the DMA input request */
02746   SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
02747 
02748 
02749   if (outputaddr != 0U)
02750   {
02751     /* Enable the DMA output stream */
02752     if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
02753     {
02754 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02755       hcryp->ErrorCallback(hcryp);
02756 #else
02757       HAL_CRYP_ErrorCallback(hcryp);
02758 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02759     }
02760 
02761     /* Enable the DMA output request */
02762     SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
02763   }
02764 }
02765 
02766 
02767 
02768 /**
02769   * @brief  Write/read input/output data in polling mode.
02770   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02771   *         the configuration information for CRYP module.
02772   * @param  Input Pointer to the Input buffer.
02773   * @param  Ilength Length of the Input buffer in bytes, must be a multiple of 16.
02774   * @param  Output Pointer to the returned buffer.
02775   * @param  Timeout Specify Timeout value.
02776   * @retval HAL status
02777   */
02778 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
02779 {
02780   uint32_t index;
02781   uint32_t inputaddr  = (uint32_t)Input;
02782   uint32_t outputaddr = (uint32_t)Output;
02783 
02784 
02785   for(index=0U ; (index < Ilength); index += 16U)
02786   {
02787     /* Write the Input block in the Data Input register */
02788     hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02789     inputaddr+=4U;
02790     hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02791     inputaddr+=4U;
02792     hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
02793     inputaddr+=4U;
02794     hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
02795     inputaddr+=4U;
02796 
02797     /* Wait for CCF flag to be raised */
02798     if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
02799     {
02800       hcryp->State = HAL_CRYP_STATE_READY;
02801       __HAL_UNLOCK(hcryp);
02802       return HAL_TIMEOUT;
02803     }
02804 
02805     /* Clear CCF Flag */
02806     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02807 
02808     /* Read the Output block from the Data Output Register */
02809     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02810     outputaddr+=4U;
02811     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02812     outputaddr+=4U;
02813     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02814     outputaddr+=4U;
02815     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
02816     outputaddr+=4U;
02817 
02818     /* If the suspension flag has been raised and if the processing is not about
02819        to end, suspend processing */
02820     if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength))
02821     {
02822       /* Reset SuspendRequest */
02823       hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
02824 
02825       /* Save current reading and writing locations of Input and Output buffers */
02826       hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
02827       hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
02828       /* Save the number of bytes that remain to be processed at this point */
02829       hcryp->CrypInCount     =  Ilength - (index+16U);
02830 
02831       /* Change the CRYP state */
02832       hcryp->State = HAL_CRYP_STATE_SUSPENDED;
02833 
02834       return HAL_OK;
02835     }
02836 
02837 
02838   }
02839   /* Return function status */
02840   return HAL_OK;
02841 
02842 }
02843 
02844 
02845 
02846 
02847 
02848 /**
02849   * @brief  Read derivative key in polling mode when CRYP hardware block is set
02850   *         in key derivation operating mode (mode 2).
02851   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02852   *         the configuration information for CRYP module.
02853   * @param  Output Pointer to the returned buffer.
02854   * @param  Timeout Specify Timeout value.
02855   * @retval HAL status
02856   */
02857 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
02858 {
02859   uint32_t outputaddr = (uint32_t)Output;
02860 
02861   /* Wait for CCF flag to be raised */
02862   if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
02863   {
02864     hcryp->State = HAL_CRYP_STATE_READY;
02865     __HAL_UNLOCK(hcryp);
02866     return HAL_TIMEOUT;
02867   }
02868   /* Clear CCF Flag */
02869   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
02870 
02871     /* Read the derivative key from the AES_KEYRx registers */
02872   if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
02873   {
02874     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
02875     outputaddr+=4U;
02876     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
02877     outputaddr+=4U;
02878     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
02879     outputaddr+=4U;
02880     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
02881     outputaddr+=4U;
02882   }
02883 
02884     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
02885     outputaddr+=4U;
02886     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
02887     outputaddr+=4U;
02888     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
02889     outputaddr+=4U;
02890     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);
02891 
02892 
02893   /* Return function status */
02894   return HAL_OK;
02895 }
02896 
02897 /**
02898   * @brief  Set the DMA configuration and start the DMA transfer.
02899   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02900   *         the configuration information for CRYP module.
02901   * @param  inputaddr Address of the Input buffer.
02902   * @param  Size Size of the Input buffer in bytes, must be a multiple of 16.
02903   * @param  outputaddr Address of the Output buffer.
02904   * @retval None
02905   */
02906 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
02907 {
02908   /* Set the CRYP DMA transfer complete callback */
02909   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
02910   /* Set the DMA error callback */
02911   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
02912 
02913   /* Set the CRYP DMA transfer complete callback */
02914   hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
02915   /* Set the DMA error callback */
02916   hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
02917 
02918   /* Enable the DMA input stream */
02919   if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
02920   {
02921 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02922     hcryp->ErrorCallback(hcryp);
02923 #else
02924     HAL_CRYP_ErrorCallback(hcryp);
02925 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02926   }
02927 
02928   /* Enable the DMA output stream */
02929   if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
02930   {
02931 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02932     hcryp->ErrorCallback(hcryp);
02933 #else
02934     HAL_CRYP_ErrorCallback(hcryp);
02935 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02936   }
02937 
02938   /* Enable In and Out DMA requests */
02939   SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
02940 
02941   /* Enable the CRYP peripheral */
02942   __HAL_CRYP_ENABLE(hcryp);
02943 }
02944 
02945 
02946 /**
02947   * @brief  Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
02948   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02949   *         the configuration information for CRYP module.
02950   * @param  Timeout Timeout duration.
02951   * @retval HAL status
02952   */
02953 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
02954 {
02955   uint32_t tickstart;
02956 
02957   /* Get timeout */
02958   tickstart = HAL_GetTick();
02959 
02960   while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
02961   {
02962     /* Check for the Timeout */
02963     if(Timeout != HAL_MAX_DELAY)
02964     {
02965       if((HAL_GetTick() - tickstart ) > Timeout)
02966       {
02967         return HAL_TIMEOUT;
02968       }
02969     }
02970   }
02971   return HAL_OK;
02972 }
02973 
02974 /**
02975   * @brief  Wait for Busy Flag to be reset during a GCM payload encryption process suspension.
02976   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02977   *         the configuration information for CRYP module.
02978   * @param  Timeout Timeout duration.
02979   * @retval HAL status
02980   */
02981 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
02982 {
02983   uint32_t tickstart;
02984 
02985   /* Get timeout */
02986   tickstart = HAL_GetTick();
02987 
02988   while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
02989   {
02990     /* Check for the Timeout */
02991     if(Timeout != HAL_MAX_DELAY)
02992     {
02993       if((HAL_GetTick() - tickstart ) > Timeout)
02994       {
02995         return HAL_TIMEOUT;
02996       }
02997     }
02998   }
02999   return HAL_OK;
03000 }
03001 
03002 
03003 /**
03004   * @brief  DMA CRYP Input Data process complete callback.
03005   * @param  hdma DMA handle.
03006   * @retval None
03007   */
03008 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
03009 {
03010   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */
03011 
03012   /* Disable the DMA transfer for input request  */
03013   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
03014 
03015   /* Call input data transfer complete callback */
03016 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
03017   hcryp->InCpltCallback(hcryp);
03018 #else
03019   HAL_CRYP_InCpltCallback(hcryp);
03020 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
03021 }
03022 
03023 /**
03024   * @brief  DMA CRYP Output Data process complete callback.
03025   * @param  hdma DMA handle.
03026   * @retval None
03027   */
03028 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
03029 {
03030   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */
03031 
03032   /* Disable the DMA transfer for output request */
03033   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
03034 
03035   /* Clear CCF Flag */
03036   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
03037 
03038   /* Disable CRYP */
03039   __HAL_CRYP_DISABLE(hcryp);
03040 
03041   /* Change the CRYP state to ready */
03042   hcryp->State = HAL_CRYP_STATE_READY;
03043 
03044   /* Call output data transfer complete callback */
03045 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
03046   hcryp->OutCpltCallback(hcryp);
03047 #else
03048   HAL_CRYP_OutCpltCallback(hcryp);
03049 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
03050 }
03051 
03052 /**
03053   * @brief  DMA CRYP communication error callback.
03054   * @param  hdma DMA handle.
03055   * @retval None
03056   */
03057 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
03058 {
03059   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;   /* Derogation MisraC2012 R.11.5 */
03060 
03061   hcryp->State= HAL_CRYP_STATE_ERROR;
03062   hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
03063 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
03064   hcryp->ErrorCallback(hcryp);
03065 #else
03066   HAL_CRYP_ErrorCallback(hcryp);
03067 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
03068   /* Clear Error Flag */
03069   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
03070 }
03071 
03072 /**
03073   * @brief  Last header or payload block padding when size is not a multiple of 128 bits.
03074   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
03075   *         the configuration information for CRYP module.
03076   * @param  difflength size remainder after having fed all complete 128-bit blocks.
03077   * @param  polling specifies whether or not polling on CCF must be done after having
03078   *                  entered a complete block.
03079   * @retval None
03080   */
03081 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
03082 {
03083   uint32_t index;
03084   uint32_t difflengthmod4 = difflength%4U;
03085   uint32_t inputaddr      = (uint32_t)hcryp->pCrypInBuffPtr;
03086   uint32_t outputaddr     = (uint32_t)hcryp->pCrypOutBuffPtr;
03087   uint32_t mask[4][3];
03088   uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
03089 
03090   uint32_t intermediate_data[4] = {0};
03091 
03092   mask[0][0] = 0xFF000000U;  mask[0][1] = 0xFFFF0000U;  mask[0][2] = 0xFFFFFF00U;  /* 32-bit data */
03093   mask[1][0] = 0x0000FF00U;  mask[1][1] = 0x0000FFFFU;  mask[1][2] = 0xFF00FFFFU;  /* 16-bit data */
03094   mask[2][0] = 0x000000FFU;  mask[2][1] = 0x0000FFFFU;  mask[2][2] = 0x00FFFFFFU;  /* 8-bit data  */
03095   mask[3][0] = 0x000000FFU;  mask[3][1] = 0x0000FFFFU;  mask[3][2] = 0x00FFFFFFU;  /* Bit data    */
03096 
03097 #if defined(AES_CR_NPBLB)
03098   /* In case of GCM encryption or CCM decryption, specify the number of padding
03099      bytes in last block of payload */
03100      if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
03101      {
03102        uint32_t cr_temp = hcryp->Instance->CR;
03103 
03104        if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
03105        ||  ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
03106        {
03107          /* Set NPBLB field in writing the number of padding bytes
03108             for the last block of payload */
03109          MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
03110        }
03111      }
03112 #else
03113   /* Software workaround applied to GCM encryption only */
03114   if ((hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) &&
03115       (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
03116   {
03117     /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
03118     __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
03119   }
03120 #endif
03121 
03122   /* Wrap-up entering header or payload data */
03123   /* Enter complete words when possible */
03124   for(index=0U ; index < (difflength/4U); index ++)
03125   {
03126     /* Write the Input block in the Data Input register */
03127     hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03128     inputaddr+=4U;
03129   }
03130   /* Enter incomplete word padded with zeroes if applicable
03131     (case of header length not a multiple of 32-bits) */
03132   if (difflengthmod4 != 0U)
03133   {
03134     hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
03135   }
03136   /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
03137   for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
03138   {
03139     hcryp->Instance->DINR = 0;
03140   }
03141 
03142   if (polling == (uint32_t)CRYP_POLLING_ON)
03143   {
03144     if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
03145     {
03146         hcryp->State = HAL_CRYP_STATE_READY;
03147         __HAL_UNLOCK(hcryp);
03148 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
03149         hcryp->ErrorCallback(hcryp);
03150 #else
03151        HAL_CRYP_ErrorCallback(hcryp);
03152 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
03153       }
03154 
03155     /* Clear CCF Flag */
03156     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
03157   }
03158 
03159   /* if payload */
03160   if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
03161   {
03162 
03163     /* Retrieve intermediate data */
03164     for(index=0U ; index < 4U; index ++)
03165     {
03166       intermediate_data[index] = hcryp->Instance->DOUTR;
03167     }
03168     /* Retrieve last words of cyphered data */
03169     /* First, retrieve complete output words */
03170     for(index=0U ; index < (difflength/4U); index ++)
03171     {
03172       *(uint32_t*)(outputaddr) = intermediate_data[index];
03173       outputaddr+=4U;
03174     }
03175     /* Next, retrieve partial output word if applicable;
03176        at the same time, start masking intermediate data
03177        with a mask of zeros of same size than the padding
03178        applied to the last block of payload */
03179     if (difflengthmod4 != 0U)
03180     {
03181       intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
03182       *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
03183     }
03184 
03185 
03186 #if !defined(AES_CR_NPBLB)
03187     /* Software workaround applied to GCM encryption only,
03188        applicable for AES IP v2 version (where NPBLB is not defined) */
03189     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
03190     {
03191       /* Change again CHMOD configuration to GCM mode */
03192       __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);
03193 
03194       /* Select FINAL phase */
03195       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
03196 
03197       /* Before inserting the intermediate data, carry on masking operation
03198          with a mask of zeros of same size than the padding applied to the last block of payload */
03199       for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
03200       {
03201         intermediate_data[((difflength+3U)/4U)+index] = 0;
03202       }
03203       /* Insert intermediate data */
03204       for(index=0U ; index < 4U; index ++)
03205       {
03206         hcryp->Instance->DINR = intermediate_data[index];
03207       }
03208 
03209       /*  Wait for completion, and read data on DOUT. This data is to discard. */
03210       if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
03211       {
03212         hcryp->State = HAL_CRYP_STATE_READY;
03213         __HAL_UNLOCK(hcryp);
03214         HAL_CRYP_ErrorCallback(hcryp);
03215       }
03216 
03217       /* Read data to discard */
03218       /* Clear CCF Flag */
03219       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
03220       for(index=0U ; index < 4U; index ++)
03221       {
03222         intermediate_data[index] = hcryp->Instance->DOUTR;
03223       }
03224 
03225     } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
03226 #endif  /* !defined(AES_CR_NPBLB) */
03227   }   /* if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) */
03228 
03229 }
03230 
03231 /**
03232   * @}
03233   */
03234 
03235 /**
03236   * @}
03237   */
03238 
03239 /**
03240   * @}
03241   */
03242 
03243 #endif /* AES */
03244 
03245 #endif /* HAL_CRYP_MODULE_ENABLED */