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