STM32F439xx HAL User Manual
stm32f4xx_hal_cryp_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_cryp_ex.c
00004   * @author  MCD Application Team
00005   * @brief   Extended CRYP HAL module driver
00006   *          This file provides firmware functions to manage the following 
00007   *          functionalities of CRYP extension peripheral:
00008   *           + Extended AES processing functions     
00009   *  
00010   @verbatim
00011   ==============================================================================
00012                      ##### How to use this driver #####
00013   ==============================================================================
00014     [..]
00015     The CRYP Extension HAL driver can be used as follows:
00016     (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
00017         (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
00018         (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT())
00019             (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
00020             (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
00021             (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
00022         (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA())
00023             (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
00024             (+++) Configure and enable two DMA streams one for managing data transfer from
00025                 memory to peripheral (input stream) and another stream for managing data
00026                 transfer from peripheral to memory (output stream)
00027             (+++) Associate the initialized DMA handle to the CRYP DMA handle
00028                 using  __HAL_LINKDMA()
00029             (+++) Configure the priority and enable the NVIC for the transfer complete
00030                 interrupt on the two DMA Streams. The output stream should have higher
00031                 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
00032     (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly:
00033         (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit
00034         (##) The key size: 128, 192 and 256. This parameter is relevant only for AES
00035         (##) The encryption/decryption key. Its size depends on the algorithm
00036                 used for encryption/decryption
00037         (##) The initialization vector (counter). It is not used ECB mode.
00038     (#)Three processing (encryption/decryption) functions are available:
00039         (##) Polling mode: encryption and decryption APIs are blocking functions
00040              i.e. they process the data and wait till the processing is finished
00041              e.g. HAL_CRYPEx_AESGCM_Encrypt()
00042         (##) Interrupt mode: encryption and decryption APIs are not blocking functions
00043                 i.e. they process the data under interrupt
00044                 e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()
00045         (##) DMA mode: encryption and decryption APIs are not blocking functions
00046                 i.e. the data transfer is ensured by DMA
00047                 e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA()
00048     (#)When the processing function is called at first time after HAL_CRYP_Init()
00049        the CRYP peripheral is initialized and processes the buffer in input.
00050        At second call, the processing function performs an append of the already
00051        processed buffer.
00052        When a new data block is to be processed, call HAL_CRYP_Init() then the
00053        processing function.
00054     (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms
00055        which provide authentication messages.
00056        HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those
00057        authentication messages.
00058        Call those functions after the processing ones (polling, interrupt or DMA).
00059        e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data
00060             then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message
00061      -@- For CCM Encrypt/Decrypt API's, only DataType = 8-bit is supported by this version.
00062      -@- The HAL_CRYPEx_AESGCM_xxxx() implementation is limited to 32bits inputs data length 
00063            (Plain/Cyphertext, Header) compared with GCM standards specifications (800-38D).
00064     (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
00065 
00066   @endverbatim
00067   ******************************************************************************
00068   * @attention
00069   *
00070   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00071   *
00072   * Redistribution and use in source and binary forms, with or without modification,
00073   * are permitted provided that the following conditions are met:
00074   *   1. Redistributions of source code must retain the above copyright notice,
00075   *      this list of conditions and the following disclaimer.
00076   *   2. Redistributions in binary form must reproduce the above copyright notice,
00077   *      this list of conditions and the following disclaimer in the documentation
00078   *      and/or other materials provided with the distribution.
00079   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00080   *      may be used to endorse or promote products derived from this software
00081   *      without specific prior written permission.
00082   *
00083   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00084   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00085   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00086   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00087   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00088   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00089   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00090   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00091   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00092   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00093   *
00094   ******************************************************************************
00095   */ 
00096 
00097 /* Includes ------------------------------------------------------------------*/
00098 #include "stm32f4xx_hal.h"
00099 
00100 /** @addtogroup STM32F4xx_HAL_Driver
00101   * @{
00102   */
00103 
00104 /** @defgroup CRYPEx CRYPEx
00105   * @brief CRYP Extension HAL module driver.
00106   * @{
00107   */
00108 
00109 #ifdef HAL_CRYP_MODULE_ENABLED
00110 
00111 #if defined(CRYP)
00112 
00113 /* Private typedef -----------------------------------------------------------*/
00114 /* Private define ------------------------------------------------------------*/
00115 /** @addtogroup CRYPEx_Private_define
00116   * @{
00117   */
00118 #define CRYPEx_TIMEOUT_VALUE  1U
00119 /**
00120   * @}
00121   */ 
00122   
00123 /* Private macro -------------------------------------------------------------*/
00124 /* Private variables ---------------------------------------------------------*/
00125 /* Private function prototypes -----------------------------------------------*/
00126 /** @defgroup CRYPEx_Private_Functions_prototypes  CRYP Private Functions Prototypes
00127   * @{
00128   */
00129 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector);
00130 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize);
00131 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout);
00132 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout);
00133 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma);
00134 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma);
00135 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma);
00136 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
00137 /**
00138   * @}
00139   */ 
00140   
00141 /* Private functions ---------------------------------------------------------*/
00142 /** @addtogroup CRYPEx_Private_Functions
00143   * @{
00144   */
00145 
00146 /**
00147   * @brief  DMA CRYP Input Data process complete callback. 
00148   * @param  hdma DMA handle
00149   * @retval None
00150   */
00151 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma)  
00152 {
00153   CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
00154   
00155   /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit
00156      in the DMACR register */
00157   hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
00158   
00159   /* Call input data transfer complete callback */
00160   HAL_CRYP_InCpltCallback(hcryp);
00161 }
00162 
00163 /**
00164   * @brief  DMA CRYP Output Data process complete callback.
00165   * @param  hdma DMA handle
00166   * @retval None
00167   */
00168 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma)
00169 {
00170   CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
00171   
00172   /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit
00173      in the DMACR register */
00174   hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
00175   
00176   /* Enable the CRYP peripheral */
00177   __HAL_CRYP_DISABLE(hcryp);
00178   
00179   /* Change the CRYP peripheral state */
00180   hcryp->State = HAL_CRYP_STATE_READY;
00181   
00182   /* Call output data transfer complete callback */
00183   HAL_CRYP_OutCpltCallback(hcryp);
00184 }
00185 
00186 /**
00187   * @brief  DMA CRYP communication error callback. 
00188   * @param  hdma DMA handle
00189   * @retval None
00190   */
00191 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma)
00192 {
00193   CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
00194   hcryp->State= HAL_CRYP_STATE_READY;
00195   HAL_CRYP_ErrorCallback(hcryp);
00196 }
00197 
00198 /**
00199   * @brief  Writes the Key in Key registers. 
00200   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00201   *         the configuration information for CRYP module
00202   * @param  Key Pointer to Key buffer
00203   * @param  KeySize Size of Key
00204   * @retval None
00205   */
00206 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize)
00207 {
00208   uint32_t keyaddr = (uint32_t)Key;
00209   
00210   switch(KeySize)
00211   {
00212   case CRYP_KEYSIZE_256B:
00213     /* Key Initialisation */
00214     hcryp->Instance->K0LR = __REV(*(uint32_t*)(keyaddr));
00215     keyaddr+=4U;
00216     hcryp->Instance->K0RR = __REV(*(uint32_t*)(keyaddr));
00217     keyaddr+=4U;
00218     hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
00219     keyaddr+=4U;
00220     hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
00221     keyaddr+=4U;
00222     hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
00223     keyaddr+=4U;
00224     hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
00225     keyaddr+=4U;
00226     hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
00227     keyaddr+=4U;
00228     hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
00229     break;
00230   case CRYP_KEYSIZE_192B:
00231     hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
00232     keyaddr+=4U;
00233     hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
00234     keyaddr+=4U;
00235     hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
00236     keyaddr+=4U;
00237     hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
00238     keyaddr+=4U;
00239     hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
00240     keyaddr+=4U;
00241     hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
00242     break;
00243   case CRYP_KEYSIZE_128B:       
00244     hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
00245     keyaddr+=4U;
00246     hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
00247     keyaddr+=4U;
00248     hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
00249     keyaddr+=4U;
00250     hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
00251     break;
00252   default:
00253     break;
00254   }
00255 }
00256 
00257 /**
00258   * @brief  Writes the InitVector/InitCounter in IV registers.
00259   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00260   *         the configuration information for CRYP module
00261   * @param  InitVector Pointer to InitVector/InitCounter buffer
00262   * @retval None
00263   */
00264 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector)
00265 {
00266   uint32_t ivaddr = (uint32_t)InitVector;
00267   
00268   hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr));
00269   ivaddr+=4U;
00270   hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr));
00271   ivaddr+=4U;
00272   hcryp->Instance->IV1LR = __REV(*(uint32_t*)(ivaddr));
00273   ivaddr+=4U;
00274   hcryp->Instance->IV1RR = __REV(*(uint32_t*)(ivaddr));
00275 }
00276 
00277 /**
00278   * @brief  Process Data: Writes Input data in polling mode and read the Output data.
00279   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00280   *         the configuration information for CRYP module
00281   * @param  Input Pointer to the Input buffer.
00282   * @param  Ilength Length of the Input buffer, must be a multiple of 16
00283   * @param  Output Pointer to the returned buffer
00284   * @param  Timeout Timeout value 
00285   * @retval None
00286   */
00287 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout)
00288 {
00289   uint32_t tickstart = 0U;   
00290   uint32_t i = 0U;
00291   uint32_t inputaddr  = (uint32_t)Input;
00292   uint32_t outputaddr = (uint32_t)Output;
00293   
00294   for(i=0U; (i < Ilength); i+=16U)
00295   {
00296     /* Write the Input block in the IN FIFO */
00297     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
00298     inputaddr+=4U;
00299     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
00300     inputaddr+=4U;
00301     hcryp->Instance->DR  = *(uint32_t*)(inputaddr);
00302     inputaddr+=4U;
00303     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
00304     inputaddr+=4U;
00305     
00306     /* Get tick */
00307     tickstart = HAL_GetTick();
00308  
00309     while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
00310     {
00311       /* Check for the Timeout */
00312       if(Timeout != HAL_MAX_DELAY)
00313       {
00314         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
00315         {
00316           /* Change state */
00317           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
00318           
00319           /* Process Unlocked */
00320           __HAL_UNLOCK(hcryp);
00321           
00322           return HAL_TIMEOUT;
00323         }
00324       }
00325     }
00326     /* Read the Output block from the OUT FIFO */
00327     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
00328     outputaddr+=4U;
00329     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
00330     outputaddr+=4U;
00331     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
00332     outputaddr+=4U;
00333     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
00334     outputaddr+=4U;
00335   }
00336   /* Return function status */
00337   return HAL_OK;
00338 }
00339 
00340 /**
00341   * @brief  Sets the header phase
00342   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00343   *         the configuration information for CRYP module
00344   * @param  Input Pointer to the Input buffer.
00345   * @param  Ilength Length of the Input buffer, must be a multiple of 16
00346   * @param  Timeout Timeout value   
00347   * @retval None
00348   */
00349 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout)
00350 {
00351   uint32_t tickstart = 0U;   
00352   uint32_t loopcounter = 0U;
00353   uint32_t headeraddr = (uint32_t)Input;
00354   
00355   /* Prevent unused argument(s) compilation warning */
00356   UNUSED(Ilength);
00357 
00358   /***************************** Header phase *********************************/
00359   if(hcryp->Init.HeaderSize != 0U)
00360   {
00361     /* Select header phase */
00362     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
00363     /* Enable the CRYP peripheral */
00364     __HAL_CRYP_ENABLE(hcryp);
00365     
00366     for(loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16U)
00367     {
00368       /* Get tick */
00369       tickstart = HAL_GetTick();
00370       
00371       while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
00372       {
00373         /* Check for the Timeout */
00374         if(Timeout != HAL_MAX_DELAY)
00375         {
00376           if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00377           {
00378             /* Change state */
00379             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
00380             
00381             /* Process Unlocked */
00382             __HAL_UNLOCK(hcryp);
00383             
00384             return HAL_TIMEOUT;
00385           }
00386         }
00387       }
00388       /* Write the Input block in the IN FIFO */
00389       hcryp->Instance->DR = *(uint32_t*)(headeraddr);
00390       headeraddr+=4U;
00391       hcryp->Instance->DR = *(uint32_t*)(headeraddr);
00392       headeraddr+=4U;
00393       hcryp->Instance->DR = *(uint32_t*)(headeraddr);
00394       headeraddr+=4U;
00395       hcryp->Instance->DR = *(uint32_t*)(headeraddr);
00396       headeraddr+=4U;
00397     }
00398     
00399     /* Wait until the complete message has been processed */
00400 
00401     /* Get tick */
00402     tickstart = HAL_GetTick();
00403 
00404     while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
00405     {
00406       /* Check for the Timeout */
00407       if(Timeout != HAL_MAX_DELAY)
00408       {
00409         if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00410         {
00411           /* Change state */
00412           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
00413           
00414           /* Process Unlocked */
00415           __HAL_UNLOCK(hcryp);
00416           
00417           return HAL_TIMEOUT;
00418         }
00419       }
00420     }
00421   }
00422   /* Return function status */
00423   return HAL_OK;
00424 }
00425 
00426 /**
00427   * @brief  Sets the DMA configuration and start the DMA transfer.
00428   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00429   *         the configuration information for CRYP module
00430   * @param  inputaddr Address of the Input buffer
00431   * @param  Size Size of the Input buffer, must be a multiple of 16
00432   * @param  outputaddr Address of the Output buffer
00433   * @retval None
00434   */
00435 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
00436 {
00437   /* Set the CRYP DMA transfer complete callback */
00438   hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt;
00439   /* Set the DMA error callback */
00440   hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
00441   
00442   /* Set the CRYP DMA transfer complete callback */
00443   hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt;
00444   /* Set the DMA error callback */
00445   hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
00446   
00447   /* Enable the CRYP peripheral */
00448   __HAL_CRYP_ENABLE(hcryp);
00449   
00450   /* Enable the DMA In DMA Stream */
00451   HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DR, Size/4U);
00452   
00453   /* Enable In DMA request */
00454   hcryp->Instance->DMACR = CRYP_DMACR_DIEN;
00455   
00456   /* Enable the DMA Out DMA Stream */
00457   HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size/4U);
00458   
00459   /* Enable Out DMA request */
00460   hcryp->Instance->DMACR |= CRYP_DMACR_DOEN;
00461 }
00462 
00463 /**
00464   * @}
00465   */ 
00466 
00467 /* Exported functions---------------------------------------------------------*/
00468 /** @addtogroup CRYPEx_Exported_Functions
00469   * @{
00470   */
00471 
00472 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions 
00473  *  @brief   Extended processing functions. 
00474  *
00475 @verbatim   
00476   ==============================================================================
00477               ##### Extended AES processing functions #####
00478   ==============================================================================  
00479     [..]  This section provides functions allowing to:
00480       (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes
00481       (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes
00482       (+) Finish the processing. This function is available only for GCM and CCM
00483     [..]  Three processing methods are available:
00484       (+) Polling mode
00485       (+) Interrupt mode
00486       (+) DMA mode
00487 
00488 @endverbatim
00489   * @{
00490   */
00491 
00492 
00493 /**
00494   * @brief  Initializes the CRYP peripheral in AES CCM encryption mode then 
00495   *         encrypt pPlainData. The cypher data are available in pCypherData.
00496   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00497   *         the configuration information for CRYP module
00498   * @param  pPlainData Pointer to the plaintext buffer
00499   * @param  Size Length of the plaintext buffer, must be a multiple of 16
00500   * @param  pCypherData Pointer to the cyphertext buffer
00501   * @param  Timeout Timeout duration
00502   * @retval HAL status
00503   */
00504 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
00505 {
00506   uint32_t tickstart = 0U;
00507   uint32_t headersize = hcryp->Init.HeaderSize;
00508   uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
00509   uint32_t loopcounter = 0U;
00510   uint32_t bufferidx = 0U;
00511   uint8_t blockb0[16U] = {0};/* Block B0 */
00512   uint8_t ctr[16U] = {0}; /* Counter */
00513   uint32_t b0addr = (uint32_t)blockb0;
00514   
00515   /* Process Locked */
00516   __HAL_LOCK(hcryp);
00517   
00518   /* Change the CRYP peripheral state */
00519   hcryp->State = HAL_CRYP_STATE_BUSY;
00520   
00521   /* Check if initialization phase has already been performed */
00522   if(hcryp->Phase == HAL_CRYP_PHASE_READY)
00523   {
00524     /************************ Formatting the header block *********************/
00525     if(headersize != 0U)
00526     {
00527       /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
00528       if(headersize < 65280U)
00529       {
00530         hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
00531         hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
00532         headersize += 2U;
00533       }
00534       else
00535       {
00536         /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
00537         hcryp->Init.pScratch[bufferidx++] = 0xFFU;
00538         hcryp->Init.pScratch[bufferidx++] = 0xFEU;
00539         hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
00540         hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
00541         hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
00542         hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
00543         headersize += 6U;
00544       }
00545       /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
00546       for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
00547       {
00548         hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
00549       }
00550       /* Check if the header size is modulo 16 */
00551       if ((headersize % 16U) != 0U)
00552       {
00553         /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
00554         for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
00555         {
00556           hcryp->Init.pScratch[loopcounter] = 0U;
00557         }
00558         /* Set the header size to modulo 16 */
00559         headersize = ((headersize/16U) + 1U) * 16U;
00560       }
00561       /* Set the pointer headeraddr to hcryp->Init.pScratch */
00562       headeraddr = (uint32_t)hcryp->Init.pScratch;
00563     }
00564     /*********************** Formatting the block B0 **************************/
00565     if(headersize != 0U)
00566     {
00567       blockb0[0U] = 0x40U;
00568     }
00569     /* Flags byte */
00570     /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
00571     blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
00572     blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
00573  
00574     for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
00575     {
00576       blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
00577     }
00578     for ( ; loopcounter < 13U; loopcounter++)
00579     {
00580       blockb0[loopcounter+1U] = 0U;
00581     }
00582     
00583     blockb0[14U] = (Size >> 8U);
00584     blockb0[15U] = (Size & 0xFFU);
00585     
00586     /************************* Formatting the initial counter *****************/
00587     /* Byte 0:
00588        Bits 7 and 6 are reserved and shall be set to 0
00589        Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
00590        are distinct from B0
00591        Bits 0, 1, and 2 contain the same encoding of q as in B0
00592     */
00593     ctr[0U] = blockb0[0U] & 0x07U;
00594     /* byte 1 to NonceSize is the IV (Nonce) */
00595     for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
00596     {
00597       ctr[loopcounter] = blockb0[loopcounter];
00598     }
00599     /* Set the LSB to 1 */
00600     ctr[15U] |= 0x01U;
00601     
00602     /* Set the key */
00603     CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
00604     
00605     /* Set the CRYP peripheral in AES CCM mode */
00606     __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
00607     
00608     /* Set the Initialization Vector */
00609     CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
00610     
00611     /* Select init phase */
00612     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
00613     
00614     b0addr = (uint32_t)blockb0;
00615     /* Write the blockb0 block in the IN FIFO */
00616     hcryp->Instance->DR = *(uint32_t*)(b0addr);
00617     b0addr+=4U;
00618     hcryp->Instance->DR = *(uint32_t*)(b0addr);
00619     b0addr+=4U;
00620     hcryp->Instance->DR = *(uint32_t*)(b0addr);
00621     b0addr+=4U;
00622     hcryp->Instance->DR = *(uint32_t*)(b0addr);
00623     
00624     /* Enable the CRYP peripheral */
00625     __HAL_CRYP_ENABLE(hcryp);
00626     
00627     /* Get tick */
00628     tickstart = HAL_GetTick();
00629 
00630     while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
00631     {
00632       /* Check for the Timeout */
00633       if(Timeout != HAL_MAX_DELAY)
00634       {
00635         if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00636         {
00637           /* Change state */
00638           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
00639           
00640           /* Process Unlocked */
00641           __HAL_UNLOCK(hcryp);
00642         
00643           return HAL_TIMEOUT;
00644         }
00645       }
00646     }
00647     /***************************** Header phase *******************************/
00648     if(headersize != 0U)
00649     {
00650       /* Select header phase */
00651       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
00652       
00653       /* Enable the CRYP peripheral */
00654       __HAL_CRYP_ENABLE(hcryp);
00655       
00656       for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
00657       {
00658         /* Get tick */
00659         tickstart = HAL_GetTick();
00660 
00661         while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
00662         {
00663           {
00664             /* Check for the Timeout */
00665             if(Timeout != HAL_MAX_DELAY)
00666             {
00667               if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00668               {
00669                 /* Change state */
00670                 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
00671                 
00672                 /* Process Unlocked */
00673                 __HAL_UNLOCK(hcryp);
00674                 
00675                 return HAL_TIMEOUT;
00676               }
00677             }
00678           }
00679         }
00680         /* Write the header block in the IN FIFO */
00681         hcryp->Instance->DR = *(uint32_t*)(headeraddr);
00682         headeraddr+=4U;
00683         hcryp->Instance->DR = *(uint32_t*)(headeraddr);
00684         headeraddr+=4U;
00685         hcryp->Instance->DR = *(uint32_t*)(headeraddr);
00686         headeraddr+=4U;
00687         hcryp->Instance->DR = *(uint32_t*)(headeraddr);
00688         headeraddr+=4U;
00689       }
00690       
00691       /* Get tick */
00692       tickstart = HAL_GetTick();
00693 
00694       while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
00695       {
00696         /* Check for the Timeout */
00697         if(Timeout != HAL_MAX_DELAY)
00698         {
00699           if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00700           {
00701             /* Change state */
00702             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
00703             
00704             /* Process Unlocked */
00705             __HAL_UNLOCK(hcryp);
00706             
00707             return HAL_TIMEOUT;
00708           }
00709         }
00710       }
00711     }
00712     /* Save formatted counter into the scratch buffer pScratch */
00713     for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
00714     {
00715       hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
00716     }
00717     /* Reset bit 0 */
00718     hcryp->Init.pScratch[15U] &= 0xFEU;
00719     
00720     /* Select payload phase once the header phase is performed */
00721     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
00722     
00723     /* Flush FIFO */
00724     __HAL_CRYP_FIFO_FLUSH(hcryp);
00725     
00726     /* Enable the CRYP peripheral */
00727     __HAL_CRYP_ENABLE(hcryp);
00728     
00729     /* Set the phase */
00730     hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
00731   }
00732   
00733   /* Write Plain Data and Get Cypher Data */
00734   if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK)
00735   {
00736     return HAL_TIMEOUT;
00737   }
00738   
00739   /* Change the CRYP peripheral state */
00740   hcryp->State = HAL_CRYP_STATE_READY;
00741   
00742   /* Process Unlocked */
00743   __HAL_UNLOCK(hcryp);
00744   
00745   /* Return function status */
00746   return HAL_OK;
00747 }
00748 
00749 /**
00750   * @brief  Initializes the CRYP peripheral in AES GCM encryption mode then 
00751   *         encrypt pPlainData. The cypher data are available in pCypherData.
00752   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00753   *         the configuration information for CRYP module
00754   * @param  pPlainData Pointer to the plaintext buffer
00755   * @param  Size Length of the plaintext buffer, must be a multiple of 16
00756   * @param  pCypherData Pointer to the cyphertext buffer
00757   * @param  Timeout Timeout duration
00758   * @retval HAL status
00759   */
00760 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
00761 {
00762   uint32_t tickstart = 0U;
00763   
00764   /* Process Locked */
00765   __HAL_LOCK(hcryp);
00766   
00767   /* Change the CRYP peripheral state */
00768   hcryp->State = HAL_CRYP_STATE_BUSY;
00769   
00770   /* Check if initialization phase has already been performed */
00771   if(hcryp->Phase == HAL_CRYP_PHASE_READY)
00772   {
00773     /* Set the key */
00774     CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
00775     
00776     /* Set the CRYP peripheral in AES GCM mode */
00777     __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
00778     
00779     /* Set the Initialization Vector */
00780     CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
00781     
00782     /* Flush FIFO */
00783     __HAL_CRYP_FIFO_FLUSH(hcryp);
00784     
00785     /* Enable the CRYP peripheral */
00786     __HAL_CRYP_ENABLE(hcryp);
00787     
00788     /* Get tick */
00789     tickstart = HAL_GetTick();
00790 
00791     while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
00792     {
00793       /* Check for the Timeout */
00794       if(Timeout != HAL_MAX_DELAY)
00795       {
00796         if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00797         {
00798           /* Change state */
00799           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
00800           
00801           /* Process Unlocked */
00802           __HAL_UNLOCK(hcryp);
00803           
00804           return HAL_TIMEOUT;
00805         }
00806       }
00807     }
00808     
00809     /* Set the header phase */
00810     if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
00811     {
00812       return HAL_TIMEOUT;
00813     }
00814     
00815     /* Disable the CRYP peripheral */
00816     __HAL_CRYP_DISABLE(hcryp);
00817     
00818     /* Select payload phase once the header phase is performed */
00819     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
00820     
00821     /* Flush FIFO */
00822     __HAL_CRYP_FIFO_FLUSH(hcryp);
00823     
00824     /* Enable the CRYP peripheral */
00825     __HAL_CRYP_ENABLE(hcryp);
00826     
00827     /* Set the phase */
00828     hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
00829   }
00830   
00831   /* Write Plain Data and Get Cypher Data */
00832   if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK)
00833   {
00834     return HAL_TIMEOUT;
00835   }
00836   
00837   /* Change the CRYP peripheral state */
00838   hcryp->State = HAL_CRYP_STATE_READY;
00839   
00840   /* Process Unlocked */
00841   __HAL_UNLOCK(hcryp);
00842   
00843   /* Return function status */
00844   return HAL_OK;
00845 }
00846 
00847 /**
00848   * @brief  Initializes the CRYP peripheral in AES GCM decryption mode then
00849   *         decrypted pCypherData. The cypher data are available in pPlainData.
00850   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00851   *         the configuration information for CRYP module
00852   * @param  pCypherData Pointer to the cyphertext buffer
00853   * @param  Size Length of the cyphertext buffer, must be a multiple of 16
00854   * @param  pPlainData Pointer to the plaintext buffer 
00855   * @param  Timeout Timeout duration
00856   * @retval HAL status
00857   */
00858 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
00859 {
00860   uint32_t tickstart = 0U;   
00861   
00862   /* Process Locked */
00863   __HAL_LOCK(hcryp);
00864   
00865   /* Change the CRYP peripheral state */
00866   hcryp->State = HAL_CRYP_STATE_BUSY;
00867   
00868   /* Check if initialization phase has already been performed */
00869   if(hcryp->Phase == HAL_CRYP_PHASE_READY)
00870   {
00871     /* Set the key */
00872     CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
00873     
00874     /* Set the CRYP peripheral in AES GCM decryption mode */
00875     __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
00876     
00877     /* Set the Initialization Vector */
00878     CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
00879     
00880     /* Flush FIFO */
00881     __HAL_CRYP_FIFO_FLUSH(hcryp);
00882     
00883     /* Enable the CRYP peripheral */
00884     __HAL_CRYP_ENABLE(hcryp);
00885     
00886     /* Get tick */
00887     tickstart = HAL_GetTick();
00888 
00889     while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
00890     {
00891       /* Check for the Timeout */
00892       if(Timeout != HAL_MAX_DELAY)
00893       {
00894         if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00895         {
00896           /* Change state */
00897           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
00898           
00899           /* Process Unlocked */
00900           __HAL_UNLOCK(hcryp);
00901           
00902           return HAL_TIMEOUT;
00903         }
00904       }
00905     }
00906     
00907     /* Set the header phase */
00908     if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
00909     {
00910       return HAL_TIMEOUT;
00911     }
00912     /* Disable the CRYP peripheral */
00913     __HAL_CRYP_DISABLE(hcryp);
00914     
00915     /* Select payload phase once the header phase is performed */
00916     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
00917     
00918     /* Enable the CRYP peripheral */
00919     __HAL_CRYP_ENABLE(hcryp);
00920     
00921     /* Set the phase */
00922     hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
00923   }
00924   
00925   /* Write Plain Data and Get Cypher Data */
00926   if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
00927   {
00928     return HAL_TIMEOUT;
00929   }
00930   
00931   /* Change the CRYP peripheral state */
00932   hcryp->State = HAL_CRYP_STATE_READY;
00933   
00934   /* Process Unlocked */
00935   __HAL_UNLOCK(hcryp);
00936   
00937   /* Return function status */
00938   return HAL_OK;
00939 }
00940 
00941 /**
00942   * @brief  Computes the authentication TAG.
00943   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
00944   *         the configuration information for CRYP module
00945   * @param  Size Total length of the plain/cyphertext buffer
00946   * @param  AuthTag Pointer to the authentication buffer
00947   * @param  Timeout Timeout duration
00948   * @retval HAL status
00949   */
00950 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint32_t Size, uint8_t *AuthTag, uint32_t Timeout)
00951 {
00952   uint32_t tickstart = 0U;   
00953   uint64_t headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
00954   uint64_t inputlength = Size * 8U; /* input length in bits */
00955   uint32_t tagaddr = (uint32_t)AuthTag;
00956   
00957   /* Process Locked */
00958   __HAL_LOCK(hcryp);
00959   
00960   /* Change the CRYP peripheral state */
00961   hcryp->State = HAL_CRYP_STATE_BUSY;
00962   
00963   /* Check if initialization phase has already been performed */
00964   if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
00965   {
00966     /* Change the CRYP phase */
00967     hcryp->Phase = HAL_CRYP_PHASE_FINAL;
00968     
00969     /* Disable CRYP to start the final phase */
00970     __HAL_CRYP_DISABLE(hcryp);
00971     
00972     /* Select final phase */
00973     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
00974     
00975     /* Enable the CRYP peripheral */
00976     __HAL_CRYP_ENABLE(hcryp);
00977     
00978     /* Write the number of bits in header (64 bits) followed by the number of bits
00979        in the payload */
00980     if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
00981     {
00982       hcryp->Instance->DR = __RBIT(headerlength >> 32U);
00983       hcryp->Instance->DR = __RBIT(headerlength);
00984       hcryp->Instance->DR = __RBIT(inputlength >> 32U);
00985       hcryp->Instance->DR = __RBIT(inputlength);
00986     }
00987     else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
00988     {
00989       hcryp->Instance->DR = __REV(headerlength >> 32U);
00990       hcryp->Instance->DR = __REV(headerlength);
00991       hcryp->Instance->DR = __REV(inputlength >> 32U);
00992       hcryp->Instance->DR = __REV(inputlength);
00993     }
00994     else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
00995     {
00996       hcryp->Instance->DR = __ROR((uint32_t)(headerlength >> 32U), 16U);
00997       hcryp->Instance->DR = __ROR((uint32_t)headerlength, 16U);
00998       hcryp->Instance->DR = __ROR((uint32_t)(inputlength >> 32U), 16U);
00999       hcryp->Instance->DR = __ROR((uint32_t)inputlength, 16U);
01000     }
01001     else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
01002     {
01003       hcryp->Instance->DR = (uint32_t)(headerlength >> 32U);
01004       hcryp->Instance->DR = (uint32_t)(headerlength);
01005       hcryp->Instance->DR = (uint32_t)(inputlength >> 32U);
01006       hcryp->Instance->DR = (uint32_t)(inputlength);
01007     }
01008     /* Get tick */
01009     tickstart = HAL_GetTick();
01010 
01011     while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
01012     {
01013       /* Check for the Timeout */
01014       if(Timeout != HAL_MAX_DELAY)
01015       {
01016         if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01017         {
01018           /* Change state */
01019           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01020           
01021           /* Process Unlocked */
01022           __HAL_UNLOCK(hcryp);
01023         
01024           return HAL_TIMEOUT;
01025         }
01026       }
01027     }
01028     
01029     /* Read the Auth TAG in the IN FIFO */
01030     *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
01031     tagaddr+=4U;
01032     *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
01033     tagaddr+=4U;
01034     *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
01035     tagaddr+=4U;
01036     *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
01037   }
01038   
01039   /* Change the CRYP peripheral state */
01040   hcryp->State = HAL_CRYP_STATE_READY;
01041   
01042   /* Process Unlocked */
01043   __HAL_UNLOCK(hcryp);
01044   
01045   /* Return function status */
01046   return HAL_OK;
01047 }
01048 
01049 /**
01050   * @brief  Computes the authentication TAG for AES CCM mode.
01051   * @note   This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt()   
01052   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01053   *         the configuration information for CRYP module
01054   * @param  AuthTag Pointer to the authentication buffer
01055   * @param  Timeout Timeout duration
01056   * @retval HAL status
01057   */
01058 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout)
01059 {
01060   uint32_t tickstart = 0U;   
01061   uint32_t tagaddr = (uint32_t)AuthTag;
01062   uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch;
01063   uint32_t temptag[4U] = {0U}; /* Temporary TAG (MAC) */
01064   uint32_t loopcounter;
01065   
01066   /* Process Locked */
01067   __HAL_LOCK(hcryp);
01068   
01069   /* Change the CRYP peripheral state */
01070   hcryp->State = HAL_CRYP_STATE_BUSY;
01071   
01072   /* Check if initialization phase has already been performed */
01073   if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
01074   {
01075     /* Change the CRYP phase */
01076     hcryp->Phase = HAL_CRYP_PHASE_FINAL;
01077     
01078     /* Disable CRYP to start the final phase */
01079     __HAL_CRYP_DISABLE(hcryp);
01080     
01081     /* Select final phase */
01082     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
01083     
01084     /* Enable the CRYP peripheral */
01085     __HAL_CRYP_ENABLE(hcryp);
01086     
01087     /* Write the counter block in the IN FIFO */
01088     hcryp->Instance->DR = *(uint32_t*)ctraddr;
01089     ctraddr+=4U;
01090     hcryp->Instance->DR = *(uint32_t*)ctraddr;
01091     ctraddr+=4U;
01092     hcryp->Instance->DR = *(uint32_t*)ctraddr;
01093     ctraddr+=4U;
01094     hcryp->Instance->DR = *(uint32_t*)ctraddr;
01095     
01096     /* Get tick */
01097     tickstart = HAL_GetTick();
01098 
01099     while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
01100     {
01101       /* Check for the Timeout */
01102       if(Timeout != HAL_MAX_DELAY)
01103       {
01104         if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01105         {
01106           /* Change state */
01107           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01108           
01109           /* Process Unlocked */
01110           __HAL_UNLOCK(hcryp);
01111           
01112           return HAL_TIMEOUT;
01113         }
01114       }
01115     }
01116     
01117     /* Read the Auth TAG in the IN FIFO */
01118     temptag[0U] = hcryp->Instance->DOUT;
01119     temptag[1U] = hcryp->Instance->DOUT;
01120     temptag[2U] = hcryp->Instance->DOUT;
01121     temptag[3U] = hcryp->Instance->DOUT;
01122   }
01123   
01124   /* Copy temporary authentication TAG in user TAG buffer */
01125   for(loopcounter = 0U; loopcounter < hcryp->Init.TagSize ; loopcounter++)
01126   {
01127     /* Set the authentication TAG buffer */
01128     *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
01129   }
01130   
01131   /* Change the CRYP peripheral state */
01132   hcryp->State = HAL_CRYP_STATE_READY;
01133   
01134   /* Process Unlocked */
01135   __HAL_UNLOCK(hcryp);
01136   
01137   /* Return function status */
01138   return HAL_OK;
01139 }
01140 
01141 /**
01142   * @brief  Initializes the CRYP peripheral in AES CCM decryption mode then
01143   *         decrypted pCypherData. The cypher data are available in pPlainData.
01144   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01145   *         the configuration information for CRYP module
01146   * @param  pPlainData Pointer to the plaintext buffer
01147   * @param  Size Length of the plaintext buffer, must be a multiple of 16
01148   * @param  pCypherData Pointer to the cyphertext buffer
01149   * @param  Timeout Timeout duration
01150   * @retval HAL status
01151   */
01152 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
01153 {
01154   uint32_t tickstart = 0U;   
01155   uint32_t headersize = hcryp->Init.HeaderSize;
01156   uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
01157   uint32_t loopcounter = 0U;
01158   uint32_t bufferidx = 0U;
01159   uint8_t blockb0[16U] = {0};/* Block B0 */
01160   uint8_t ctr[16U] = {0}; /* Counter */
01161   uint32_t b0addr = (uint32_t)blockb0;
01162   
01163   /* Process Locked */
01164   __HAL_LOCK(hcryp);
01165   
01166   /* Change the CRYP peripheral state */
01167   hcryp->State = HAL_CRYP_STATE_BUSY;
01168   
01169   /* Check if initialization phase has already been performed */
01170   if(hcryp->Phase == HAL_CRYP_PHASE_READY)
01171   {
01172     /************************ Formatting the header block *********************/
01173     if(headersize != 0U)
01174     {
01175       /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
01176       if(headersize < 65280U)
01177       {
01178         hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
01179         hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
01180         headersize += 2U;
01181       }
01182       else
01183       {
01184         /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
01185         hcryp->Init.pScratch[bufferidx++] = 0xFFU;
01186         hcryp->Init.pScratch[bufferidx++] = 0xFEU;
01187         hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
01188         hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
01189         hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
01190         hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
01191         headersize += 6U;
01192       }
01193       /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
01194       for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
01195       {
01196         hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
01197       }
01198       /* Check if the header size is modulo 16 */
01199       if ((headersize % 16U) != 0U)
01200       {
01201         /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
01202         for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
01203         {
01204           hcryp->Init.pScratch[loopcounter] = 0U;
01205         }
01206         /* Set the header size to modulo 16 */
01207         headersize = ((headersize/16U) + 1U) * 16U;
01208       }
01209       /* Set the pointer headeraddr to hcryp->Init.pScratch */
01210       headeraddr = (uint32_t)hcryp->Init.pScratch;
01211     }
01212     /*********************** Formatting the block B0 **************************/
01213     if(headersize != 0U)
01214     {
01215       blockb0[0U] = 0x40U;
01216     }
01217     /* Flags byte */
01218     /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
01219     blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2U))) >> 1U) & (uint8_t)0x07U) << 3U);
01220     blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15U) - hcryp->Init.IVSize) - (uint8_t)1U) & (uint8_t)0x07U);
01221     
01222     for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
01223     {
01224       blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
01225     }
01226     for ( ; loopcounter < 13U; loopcounter++)
01227     {
01228       blockb0[loopcounter+1U] = 0U;
01229     }
01230     
01231     blockb0[14U] = (Size >> 8U);
01232     blockb0[15U] = (Size & 0xFFU);
01233     
01234     /************************* Formatting the initial counter *****************/
01235     /* Byte 0:
01236        Bits 7 and 6 are reserved and shall be set to 0
01237        Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
01238        blocks are distinct from B0
01239        Bits 0, 1, and 2 contain the same encoding of q as in B0
01240     */
01241     ctr[0U] = blockb0[0U] & 0x07U;
01242     /* byte 1 to NonceSize is the IV (Nonce) */
01243     for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
01244     {
01245       ctr[loopcounter] = blockb0[loopcounter];
01246     }
01247     /* Set the LSB to 1 */
01248     ctr[15U] |= 0x01U;
01249     
01250     /* Set the key */
01251     CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
01252     
01253     /* Set the CRYP peripheral in AES CCM mode */
01254     __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
01255     
01256     /* Set the Initialization Vector */
01257     CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
01258     
01259     /* Select init phase */
01260     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
01261     
01262     b0addr = (uint32_t)blockb0;
01263     /* Write the blockb0 block in the IN FIFO */
01264     hcryp->Instance->DR = *(uint32_t*)(b0addr);
01265     b0addr+=4U;
01266     hcryp->Instance->DR = *(uint32_t*)(b0addr);
01267     b0addr+=4U;
01268     hcryp->Instance->DR = *(uint32_t*)(b0addr);
01269     b0addr+=4U;
01270     hcryp->Instance->DR = *(uint32_t*)(b0addr);
01271     
01272     /* Enable the CRYP peripheral */
01273     __HAL_CRYP_ENABLE(hcryp);
01274     
01275     /* Get tick */
01276     tickstart = HAL_GetTick();
01277  
01278     while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
01279     {
01280       /* Check for the Timeout */
01281       if(Timeout != HAL_MAX_DELAY)
01282       {
01283         if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01284         {
01285           /* Change state */
01286           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01287           
01288           /* Process Unlocked */
01289           __HAL_UNLOCK(hcryp);
01290         
01291           return HAL_TIMEOUT;
01292         }
01293       }
01294     }
01295     /***************************** Header phase *******************************/
01296     if(headersize != 0U)
01297     {
01298       /* Select header phase */
01299       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
01300       
01301       /* Enable Crypto processor */
01302       __HAL_CRYP_ENABLE(hcryp);
01303       
01304       for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
01305       {
01306         /* Get tick */
01307         tickstart = HAL_GetTick();
01308 
01309         while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
01310         {
01311           /* Check for the Timeout */
01312           if(Timeout != HAL_MAX_DELAY)
01313           {
01314             if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01315             {
01316               /* Change state */
01317               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01318               
01319               /* Process Unlocked */
01320               __HAL_UNLOCK(hcryp);
01321               
01322               return HAL_TIMEOUT;
01323             }
01324           }
01325         }
01326         /* Write the header block in the IN FIFO */
01327         hcryp->Instance->DR = *(uint32_t*)(headeraddr);
01328         headeraddr+=4U;
01329         hcryp->Instance->DR = *(uint32_t*)(headeraddr);
01330         headeraddr+=4U;
01331         hcryp->Instance->DR = *(uint32_t*)(headeraddr);
01332         headeraddr+=4U;
01333         hcryp->Instance->DR = *(uint32_t*)(headeraddr);
01334         headeraddr+=4U;
01335       }
01336       
01337       /* Get tick */
01338       tickstart = HAL_GetTick();
01339 
01340       while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
01341       {
01342       /* Check for the Timeout */
01343         if(Timeout != HAL_MAX_DELAY)
01344         {
01345           if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
01346           {
01347             /* Change state */
01348             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01349             
01350             /* Process Unlocked */
01351             __HAL_UNLOCK(hcryp);
01352             
01353             return HAL_TIMEOUT;
01354           }
01355         }
01356       }
01357     }
01358     /* Save formatted counter into the scratch buffer pScratch */
01359     for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
01360     {
01361       hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
01362     }
01363     /* Reset bit 0 */
01364     hcryp->Init.pScratch[15U] &= 0xFEU;
01365     /* Select payload phase once the header phase is performed */
01366     __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
01367     
01368     /* Flush FIFO */
01369     __HAL_CRYP_FIFO_FLUSH(hcryp);
01370     
01371     /* Enable the CRYP peripheral */
01372     __HAL_CRYP_ENABLE(hcryp);
01373     
01374     /* Set the phase */
01375     hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
01376   }
01377   
01378   /* Write Plain Data and Get Cypher Data */
01379   if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
01380   {
01381     return HAL_TIMEOUT;
01382   }
01383   
01384   /* Change the CRYP peripheral state */
01385   hcryp->State = HAL_CRYP_STATE_READY;
01386   
01387   /* Process Unlocked */
01388   __HAL_UNLOCK(hcryp);
01389   
01390   /* Return function status */
01391   return HAL_OK;
01392 }
01393 
01394 /**
01395   * @brief  Initializes the CRYP peripheral in AES GCM encryption mode using IT.
01396   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01397   *         the configuration information for CRYP module
01398   * @param  pPlainData Pointer to the plaintext buffer
01399   * @param  Size Length of the plaintext buffer, must be a multiple of 16
01400   * @param  pCypherData Pointer to the cyphertext buffer
01401   * @retval HAL status
01402   */
01403 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
01404 {
01405   uint32_t tickstart = 0U;   
01406   uint32_t inputaddr;
01407   uint32_t outputaddr;
01408   
01409   if(hcryp->State == HAL_CRYP_STATE_READY)
01410   {
01411     /* Process Locked */
01412     __HAL_LOCK(hcryp);
01413     
01414     /* Get the buffer addresses and sizes */    
01415     hcryp->CrypInCount = Size;
01416     hcryp->pCrypInBuffPtr = pPlainData;
01417     hcryp->pCrypOutBuffPtr = pCypherData;
01418     hcryp->CrypOutCount = Size;
01419     
01420     /* Change the CRYP peripheral state */
01421     hcryp->State = HAL_CRYP_STATE_BUSY;
01422     
01423     /* Check if initialization phase has already been performed */
01424     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
01425     {
01426       /* Set the key */
01427       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
01428       
01429       /* Set the CRYP peripheral in AES GCM mode */
01430       __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
01431       
01432       /* Set the Initialization Vector */
01433       CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
01434       
01435       /* Flush FIFO */
01436       __HAL_CRYP_FIFO_FLUSH(hcryp);
01437       
01438       /* Enable CRYP to start the init phase */
01439       __HAL_CRYP_ENABLE(hcryp);
01440       
01441      /* Get tick */
01442      tickstart = HAL_GetTick();
01443 
01444       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
01445       {
01446         /* Check for the Timeout */
01447         
01448         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
01449         {
01450           /* Change state */
01451           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01452           
01453           /* Process Unlocked */
01454           __HAL_UNLOCK(hcryp);
01455           
01456           return HAL_TIMEOUT;
01457           
01458         }
01459       }
01460       
01461       /* Set the header phase */
01462       if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
01463       {
01464         return HAL_TIMEOUT;
01465       }
01466       /* Disable the CRYP peripheral */
01467       __HAL_CRYP_DISABLE(hcryp);
01468       
01469       /* Select payload phase once the header phase is performed */
01470       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
01471       
01472       /* Flush FIFO */
01473       __HAL_CRYP_FIFO_FLUSH(hcryp);
01474       
01475       /* Set the phase */
01476       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
01477     }
01478     
01479     if(Size != 0U)
01480     {
01481       /* Enable Interrupts */
01482       __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
01483       /* Enable the CRYP peripheral */
01484       __HAL_CRYP_ENABLE(hcryp);
01485     }
01486     else
01487     {
01488       /* Process Locked */
01489       __HAL_UNLOCK(hcryp);
01490       /* Change the CRYP state and phase */
01491       hcryp->State = HAL_CRYP_STATE_READY;
01492     }
01493     /* Return function status */
01494     return HAL_OK;
01495   }
01496   else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
01497   {
01498     inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
01499     /* Write the Input block in the IN FIFO */
01500     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01501     inputaddr+=4U;
01502     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01503     inputaddr+=4U;
01504     hcryp->Instance->DR  = *(uint32_t*)(inputaddr);
01505     inputaddr+=4U;
01506     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01507     hcryp->pCrypInBuffPtr += 16U;
01508     hcryp->CrypInCount -= 16U;
01509     if(hcryp->CrypInCount == 0U)
01510     {
01511       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
01512       /* Call the Input data transfer complete callback */
01513       HAL_CRYP_InCpltCallback(hcryp);
01514     }
01515   }
01516   else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
01517   {
01518     outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
01519     /* Read the Output block from the Output FIFO */
01520     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01521     outputaddr+=4U;
01522     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01523     outputaddr+=4U;
01524     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01525     outputaddr+=4U;
01526     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01527     hcryp->pCrypOutBuffPtr += 16U;
01528     hcryp->CrypOutCount -= 16U;
01529     if(hcryp->CrypOutCount == 0U)
01530     {
01531       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
01532       /* Process Unlocked */
01533       __HAL_UNLOCK(hcryp);
01534       /* Change the CRYP peripheral state */
01535       hcryp->State = HAL_CRYP_STATE_READY;
01536       /* Call Input transfer complete callback */
01537       HAL_CRYP_OutCpltCallback(hcryp);
01538     }
01539   }
01540   
01541   /* Return function status */
01542   return HAL_OK;
01543 }
01544 
01545 /**
01546   * @brief  Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
01547   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01548   *         the configuration information for CRYP module
01549   * @param  pPlainData Pointer to the plaintext buffer
01550   * @param  Size Length of the plaintext buffer, must be a multiple of 16
01551   * @param  pCypherData Pointer to the cyphertext buffer
01552   * @retval HAL status
01553   */
01554 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
01555 {
01556   uint32_t tickstart = 0U;   
01557   uint32_t inputaddr;
01558   uint32_t outputaddr;
01559   
01560   uint32_t headersize = hcryp->Init.HeaderSize;
01561   uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
01562   uint32_t loopcounter = 0U;
01563   uint32_t bufferidx = 0U;
01564   uint8_t blockb0[16U] = {0};/* Block B0 */
01565   uint8_t ctr[16U] = {0}; /* Counter */
01566   uint32_t b0addr = (uint32_t)blockb0;
01567   
01568   if(hcryp->State == HAL_CRYP_STATE_READY)
01569   {
01570     /* Process Locked */
01571     __HAL_LOCK(hcryp);
01572     
01573     hcryp->CrypInCount = Size;
01574     hcryp->pCrypInBuffPtr = pPlainData;
01575     hcryp->pCrypOutBuffPtr = pCypherData;
01576     hcryp->CrypOutCount = Size;
01577     
01578     /* Change the CRYP peripheral state */
01579     hcryp->State = HAL_CRYP_STATE_BUSY;
01580     
01581     /* Check if initialization phase has already been performed */
01582     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
01583     {    
01584       /************************ Formatting the header block *******************/
01585       if(headersize != 0U)
01586       {
01587         /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
01588         if(headersize < 65280U)
01589         {
01590           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
01591           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
01592           headersize += 2U;
01593         }
01594         else
01595         {
01596           /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
01597           hcryp->Init.pScratch[bufferidx++] = 0xFFU;
01598           hcryp->Init.pScratch[bufferidx++] = 0xFEU;
01599           hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
01600           hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
01601           hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
01602           hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
01603           headersize += 6U;
01604         }
01605         /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
01606         for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
01607         {
01608           hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
01609         }
01610         /* Check if the header size is modulo 16 */
01611         if ((headersize % 16U) != 0U)
01612         {
01613           /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
01614           for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
01615           {
01616             hcryp->Init.pScratch[loopcounter] = 0U;
01617           }
01618           /* Set the header size to modulo 16 */
01619           headersize = ((headersize/16U) + 1U) * 16U;
01620         }
01621         /* Set the pointer headeraddr to hcryp->Init.pScratch */
01622         headeraddr = (uint32_t)hcryp->Init.pScratch;
01623       }
01624       /*********************** Formatting the block B0 ************************/
01625       if(headersize != 0U)
01626       {
01627         blockb0[0U] = 0x40U;
01628       }
01629       /* Flags byte */
01630       /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
01631       blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
01632       blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
01633       
01634       for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
01635       {
01636         blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
01637       }
01638       for ( ; loopcounter < 13U; loopcounter++)
01639       {
01640         blockb0[loopcounter+1U] = 0U;
01641       }
01642       
01643       blockb0[14U] = (Size >> 8U);
01644       blockb0[15U] = (Size & 0xFFU);
01645       
01646       /************************* Formatting the initial counter ***************/
01647       /* Byte 0:
01648          Bits 7 and 6 are reserved and shall be set to 0
01649          Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
01650          blocks are distinct from B0
01651          Bits 0, 1, and 2 contain the same encoding of q as in B0
01652       */
01653       ctr[0U] = blockb0[0U] & 0x07U;
01654       /* byte 1 to NonceSize is the IV (Nonce) */
01655       for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
01656       {
01657         ctr[loopcounter] = blockb0[loopcounter];
01658       }
01659       /* Set the LSB to 1 */
01660       ctr[15U] |= 0x01U;
01661       
01662       /* Set the key */
01663       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
01664       
01665       /* Set the CRYP peripheral in AES CCM mode */
01666       __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
01667       
01668       /* Set the Initialization Vector */
01669       CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
01670       
01671       /* Select init phase */
01672       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
01673       
01674       b0addr = (uint32_t)blockb0;
01675       /* Write the blockb0 block in the IN FIFO */
01676       hcryp->Instance->DR = *(uint32_t*)(b0addr);
01677       b0addr+=4U;
01678       hcryp->Instance->DR = *(uint32_t*)(b0addr);
01679       b0addr+=4U;
01680       hcryp->Instance->DR = *(uint32_t*)(b0addr);
01681       b0addr+=4U;
01682       hcryp->Instance->DR = *(uint32_t*)(b0addr);
01683       
01684       /* Enable the CRYP peripheral */
01685       __HAL_CRYP_ENABLE(hcryp);
01686       
01687      /* Get tick */
01688      tickstart = HAL_GetTick();
01689 
01690       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
01691       {
01692         /* Check for the Timeout */
01693         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
01694         {
01695           /* Change state */
01696           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01697           
01698           /* Process Unlocked */
01699           __HAL_UNLOCK(hcryp);
01700           
01701           return HAL_TIMEOUT;
01702         }
01703       }
01704       /***************************** Header phase *****************************/
01705       if(headersize != 0U)
01706       {
01707         /* Select header phase */
01708         __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
01709         
01710         /* Enable Crypto processor */
01711         __HAL_CRYP_ENABLE(hcryp);
01712         
01713         for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
01714         {
01715          /* Get tick */
01716          tickstart = HAL_GetTick();
01717 
01718           while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
01719           {
01720             /* Check for the Timeout */
01721             if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
01722             {
01723               /* Change state */
01724               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01725               
01726               /* Process Unlocked */
01727               __HAL_UNLOCK(hcryp);
01728               
01729               return HAL_TIMEOUT;
01730             }
01731           }
01732           /* Write the header block in the IN FIFO */
01733           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
01734           headeraddr+=4U;
01735           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
01736           headeraddr+=4U;
01737           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
01738           headeraddr+=4U;
01739           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
01740           headeraddr+=4U;
01741         }
01742 
01743         /* Get tick */
01744         tickstart = HAL_GetTick();
01745 
01746         while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
01747         {
01748           /* Check for the Timeout */
01749           if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
01750           {
01751             /* Change state */
01752             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01753             
01754             /* Process Unlocked */
01755             __HAL_UNLOCK(hcryp);
01756             
01757             return HAL_TIMEOUT;
01758           }
01759         }
01760       }
01761       /* Save formatted counter into the scratch buffer pScratch */
01762       for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
01763       {
01764         hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
01765       }
01766       /* Reset bit 0 */
01767       hcryp->Init.pScratch[15U] &= 0xFEU;
01768       
01769       /* Select payload phase once the header phase is performed */
01770       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
01771       
01772       /* Flush FIFO */
01773       __HAL_CRYP_FIFO_FLUSH(hcryp);
01774       
01775       /* Set the phase */
01776       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
01777     }
01778     
01779     if(Size != 0U)
01780     {
01781       /* Enable Interrupts */
01782       __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
01783       /* Enable the CRYP peripheral */
01784       __HAL_CRYP_ENABLE(hcryp);
01785     }
01786     else
01787     {
01788       /* Change the CRYP state and phase */
01789       hcryp->State = HAL_CRYP_STATE_READY;
01790     }
01791     
01792     /* Return function status */
01793     return HAL_OK;
01794   }
01795   else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
01796   {
01797     inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
01798     /* Write the Input block in the IN FIFO */
01799     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01800     inputaddr+=4U;
01801     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01802     inputaddr+=4U;
01803     hcryp->Instance->DR  = *(uint32_t*)(inputaddr);
01804     inputaddr+=4U;
01805     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01806     hcryp->pCrypInBuffPtr += 16U;
01807     hcryp->CrypInCount -= 16U;
01808     if(hcryp->CrypInCount == 0U)
01809     {
01810       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
01811       /* Call Input transfer complete callback */
01812       HAL_CRYP_InCpltCallback(hcryp);
01813     }
01814   }
01815   else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
01816   {
01817     outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
01818     /* Read the Output block from the Output FIFO */
01819     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01820     outputaddr+=4U;
01821     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01822     outputaddr+=4U;
01823     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01824     outputaddr+=4U;
01825     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01826     hcryp->pCrypOutBuffPtr += 16U;
01827     hcryp->CrypOutCount -= 16U;
01828     if(hcryp->CrypOutCount == 0U)
01829     {
01830       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
01831       /* Process Unlocked */
01832       __HAL_UNLOCK(hcryp);
01833       /* Change the CRYP peripheral state */
01834       hcryp->State = HAL_CRYP_STATE_READY;
01835       /* Call Input transfer complete callback */
01836       HAL_CRYP_OutCpltCallback(hcryp);
01837     }
01838   }
01839   
01840   /* Return function status */
01841   return HAL_OK;
01842 }
01843 
01844 /**
01845   * @brief  Initializes the CRYP peripheral in AES GCM decryption mode using IT.
01846   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01847   *         the configuration information for CRYP module
01848   * @param  pCypherData Pointer to the cyphertext buffer
01849   * @param  Size Length of the cyphertext buffer, must be a multiple of 16
01850   * @param  pPlainData Pointer to the plaintext buffer
01851   * @retval HAL status
01852   */
01853 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
01854 {
01855   uint32_t tickstart = 0U;   
01856   uint32_t inputaddr;
01857   uint32_t outputaddr;
01858   
01859   if(hcryp->State == HAL_CRYP_STATE_READY)
01860   {
01861     /* Process Locked */
01862     __HAL_LOCK(hcryp);
01863     
01864     /* Get the buffer addresses and sizes */    
01865     hcryp->CrypInCount = Size;
01866     hcryp->pCrypInBuffPtr = pCypherData;
01867     hcryp->pCrypOutBuffPtr = pPlainData;
01868     hcryp->CrypOutCount = Size;
01869     
01870     /* Change the CRYP peripheral state */
01871     hcryp->State = HAL_CRYP_STATE_BUSY;
01872     
01873     /* Check if initialization phase has already been performed */
01874     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
01875     {
01876       /* Set the key */
01877       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
01878       
01879       /* Set the CRYP peripheral in AES GCM decryption mode */
01880       __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
01881       
01882       /* Set the Initialization Vector */
01883       CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
01884       
01885       /* Flush FIFO */
01886       __HAL_CRYP_FIFO_FLUSH(hcryp);
01887       
01888       /* Enable CRYP to start the init phase */
01889       __HAL_CRYP_ENABLE(hcryp);
01890 
01891         /* Get tick */
01892         tickstart = HAL_GetTick();
01893 
01894       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
01895       {
01896         /* Check for the Timeout */
01897         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
01898         {
01899           /* Change state */
01900           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
01901           
01902           /* Process Unlocked */
01903           __HAL_UNLOCK(hcryp);
01904           
01905           return HAL_TIMEOUT;
01906         }
01907       }
01908       
01909       /* Set the header phase */
01910       if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
01911       {
01912         return HAL_TIMEOUT;
01913       }
01914       /* Disable the CRYP peripheral */
01915       __HAL_CRYP_DISABLE(hcryp);
01916       
01917       /* Select payload phase once the header phase is performed */
01918       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
01919       
01920       /* Set the phase */
01921       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
01922     }
01923     
01924     if(Size != 0U)
01925     {
01926       /* Enable Interrupts */
01927       __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
01928       /* Enable the CRYP peripheral */
01929       __HAL_CRYP_ENABLE(hcryp);
01930     }
01931     else
01932     {
01933       /* Process Locked */
01934       __HAL_UNLOCK(hcryp);
01935       /* Change the CRYP state and phase */
01936       hcryp->State = HAL_CRYP_STATE_READY;
01937     }
01938     
01939     /* Return function status */
01940     return HAL_OK;
01941   }
01942   else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
01943   {
01944     inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
01945     /* Write the Input block in the IN FIFO */
01946     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01947     inputaddr+=4U;
01948     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01949     inputaddr+=4U;
01950     hcryp->Instance->DR  = *(uint32_t*)(inputaddr);
01951     inputaddr+=4U;
01952     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
01953     hcryp->pCrypInBuffPtr += 16U;
01954     hcryp->CrypInCount -= 16U;
01955     if(hcryp->CrypInCount == 0U)
01956     {
01957       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
01958       /* Call the Input data transfer complete callback */
01959       HAL_CRYP_InCpltCallback(hcryp);
01960     }
01961   }
01962   else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
01963   {
01964     outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
01965     /* Read the Output block from the Output FIFO */
01966     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01967     outputaddr+=4U;
01968     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01969     outputaddr+=4U;
01970     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01971     outputaddr+=4U;
01972     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
01973     hcryp->pCrypOutBuffPtr += 16U;
01974     hcryp->CrypOutCount -= 16U;
01975     if(hcryp->CrypOutCount == 0U)
01976     {
01977       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
01978       /* Process Unlocked */
01979       __HAL_UNLOCK(hcryp);
01980       /* Change the CRYP peripheral state */
01981       hcryp->State = HAL_CRYP_STATE_READY;
01982       /* Call Input transfer complete callback */
01983       HAL_CRYP_OutCpltCallback(hcryp);
01984     }
01985   }
01986   
01987   /* Return function status */
01988   return HAL_OK;
01989 }
01990 
01991 /**
01992   * @brief  Initializes the CRYP peripheral in AES CCM decryption mode using interrupt
01993   *         then decrypted pCypherData. The cypher data are available in pPlainData.
01994   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
01995   *         the configuration information for CRYP module
01996   * @param  pCypherData Pointer to the cyphertext buffer 
01997   * @param  Size Length of the plaintext buffer, must be a multiple of 16
01998   * @param  pPlainData Pointer to the plaintext buffer  
01999   * @retval HAL status
02000   */
02001 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
02002 {
02003   uint32_t inputaddr;
02004   uint32_t outputaddr;
02005   uint32_t tickstart = 0U;
02006   uint32_t headersize = hcryp->Init.HeaderSize;
02007   uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
02008   uint32_t loopcounter = 0U;
02009   uint32_t bufferidx = 0U;
02010   uint8_t blockb0[16U] = {0};/* Block B0 */
02011   uint8_t ctr[16U] = {0}; /* Counter */
02012   uint32_t b0addr = (uint32_t)blockb0;
02013   
02014   if(hcryp->State == HAL_CRYP_STATE_READY)
02015   {
02016     /* Process Locked */
02017     __HAL_LOCK(hcryp);
02018     
02019     hcryp->CrypInCount = Size;
02020     hcryp->pCrypInBuffPtr = pCypherData;
02021     hcryp->pCrypOutBuffPtr = pPlainData;
02022     hcryp->CrypOutCount = Size;
02023     
02024     /* Change the CRYP peripheral state */
02025     hcryp->State = HAL_CRYP_STATE_BUSY;
02026     
02027     /* Check if initialization phase has already been performed */
02028     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
02029     {
02030       /************************ Formatting the header block *******************/
02031       if(headersize != 0U)
02032       {
02033         /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
02034         if(headersize < 65280U)
02035         {
02036           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
02037           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
02038           headersize += 2U;
02039         }
02040         else
02041         {
02042           /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
02043           hcryp->Init.pScratch[bufferidx++] = 0xFFU;
02044           hcryp->Init.pScratch[bufferidx++] = 0xFEU;
02045           hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
02046           hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
02047           hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
02048           hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
02049           headersize += 6U;
02050         }
02051         /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
02052         for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
02053         {
02054           hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
02055         }
02056         /* Check if the header size is modulo 16 */
02057         if ((headersize % 16U) != 0U)
02058         {
02059           /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
02060           for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
02061           {
02062             hcryp->Init.pScratch[loopcounter] = 0U;
02063           }
02064           /* Set the header size to modulo 16 */
02065           headersize = ((headersize/16U) + 1U) * 16U;
02066         }
02067         /* Set the pointer headeraddr to hcryp->Init.pScratch */
02068         headeraddr = (uint32_t)hcryp->Init.pScratch;
02069       }
02070       /*********************** Formatting the block B0 ************************/
02071       if(headersize != 0U)
02072       {
02073         blockb0[0U] = 0x40U;
02074       }
02075       /* Flags byte */
02076       /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
02077       blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
02078       blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
02079       
02080       for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
02081       {
02082         blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
02083       }
02084       for ( ; loopcounter < 13U; loopcounter++)
02085       {
02086         blockb0[loopcounter+1U] = 0U;
02087       }
02088       
02089       blockb0[14U] = (Size >> 8U);
02090       blockb0[15U] = (Size & 0xFFU);
02091       
02092       /************************* Formatting the initial counter ***************/
02093       /* Byte 0:
02094          Bits 7 and 6 are reserved and shall be set to 0
02095          Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
02096          blocks are distinct from B0
02097          Bits 0, 1, and 2 contain the same encoding of q as in B0
02098       */
02099       ctr[0U] = blockb0[0U] & 0x07U;
02100       /* byte 1 to NonceSize is the IV (Nonce) */
02101       for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
02102       {
02103         ctr[loopcounter] = blockb0[loopcounter];
02104       }
02105       /* Set the LSB to 1 */
02106       ctr[15U] |= 0x01U;
02107       
02108       /* Set the key */
02109       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
02110       
02111       /* Set the CRYP peripheral in AES CCM mode */
02112       __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
02113       
02114       /* Set the Initialization Vector */
02115       CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
02116       
02117       /* Select init phase */
02118       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
02119       
02120       b0addr = (uint32_t)blockb0;
02121       /* Write the blockb0 block in the IN FIFO */
02122       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02123       b0addr+=4U;
02124       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02125       b0addr+=4U;
02126       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02127       b0addr+=4U;
02128       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02129       
02130       /* Enable the CRYP peripheral */
02131       __HAL_CRYP_ENABLE(hcryp);
02132 
02133       /* Get tick */
02134       tickstart = HAL_GetTick();
02135 
02136       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
02137       {
02138         /* Check for the Timeout */
02139         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02140         {
02141           /* Change state */
02142           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02143           
02144           /* Process Unlocked */
02145           __HAL_UNLOCK(hcryp);
02146           
02147           return HAL_TIMEOUT;
02148         }
02149       }
02150       /***************************** Header phase *****************************/
02151       if(headersize != 0U)
02152       {
02153         /* Select header phase */
02154         __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
02155         
02156         /* Enable Crypto processor */
02157         __HAL_CRYP_ENABLE(hcryp);
02158         
02159         for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
02160         {
02161          /* Get tick */
02162          tickstart = HAL_GetTick();
02163 
02164           while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
02165           {
02166             /* Check for the Timeout */
02167             if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02168             {
02169               /* Change state */
02170               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02171               
02172               /* Process Unlocked */
02173               __HAL_UNLOCK(hcryp);
02174               
02175               return HAL_TIMEOUT;
02176             }
02177           }
02178           /* Write the header block in the IN FIFO */
02179           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02180           headeraddr+=4U;
02181           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02182           headeraddr+=4U;
02183           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02184           headeraddr+=4U;
02185           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02186           headeraddr+=4U;
02187         }
02188 
02189         /* Get tick */
02190         tickstart = HAL_GetTick();
02191 
02192         while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
02193         {
02194           /* Check for the Timeout */
02195           if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02196           {
02197             /* Change state */
02198             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02199             
02200             /* Process Unlocked */
02201             __HAL_UNLOCK(hcryp);
02202             
02203             return HAL_TIMEOUT;
02204           }
02205         }
02206       }
02207       /* Save formatted counter into the scratch buffer pScratch */
02208       for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
02209       {
02210         hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
02211       }
02212       /* Reset bit 0 */
02213       hcryp->Init.pScratch[15U] &= 0xFEU;
02214       /* Select payload phase once the header phase is performed */
02215       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
02216       
02217       /* Flush FIFO */
02218       __HAL_CRYP_FIFO_FLUSH(hcryp);
02219       
02220       /* Set the phase */
02221       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
02222     }
02223     
02224     /* Enable Interrupts */
02225     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
02226     
02227     /* Enable the CRYP peripheral */
02228     __HAL_CRYP_ENABLE(hcryp);
02229     
02230     /* Return function status */
02231     return HAL_OK;
02232   }
02233   else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
02234   {
02235     inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
02236     /* Write the Input block in the IN FIFO */
02237     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
02238     inputaddr+=4U;
02239     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
02240     inputaddr+=4U;
02241     hcryp->Instance->DR  = *(uint32_t*)(inputaddr);
02242     inputaddr+=4U;
02243     hcryp->Instance->DR = *(uint32_t*)(inputaddr);
02244     hcryp->pCrypInBuffPtr += 16U;
02245     hcryp->CrypInCount -= 16U;
02246     if(hcryp->CrypInCount == 0U)
02247     {
02248       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
02249       /* Call the Input data transfer complete callback */
02250       HAL_CRYP_InCpltCallback(hcryp);
02251     }
02252   }
02253   else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
02254   {
02255     outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
02256     /* Read the Output block from the Output FIFO */
02257     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
02258     outputaddr+=4U;
02259     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
02260     outputaddr+=4U;
02261     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
02262     outputaddr+=4U;
02263     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
02264     hcryp->pCrypOutBuffPtr += 16U;
02265     hcryp->CrypOutCount -= 16U;
02266     if(hcryp->CrypOutCount == 0U)
02267     {
02268       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
02269       /* Process Unlocked */
02270       __HAL_UNLOCK(hcryp);
02271       /* Change the CRYP peripheral state */
02272       hcryp->State = HAL_CRYP_STATE_READY;
02273       /* Call Input transfer complete callback */
02274       HAL_CRYP_OutCpltCallback(hcryp);
02275     }
02276   }
02277   
02278   /* Return function status */
02279   return HAL_OK;
02280 }
02281 
02282 /**
02283   * @brief  Initializes the CRYP peripheral in AES GCM encryption mode using DMA.
02284   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02285   *         the configuration information for CRYP module
02286   * @param  pPlainData Pointer to the plaintext buffer
02287   * @param  Size Length of the plaintext buffer, must be a multiple of 16
02288   * @param  pCypherData Pointer to the cyphertext buffer
02289   * @retval HAL status
02290   */
02291 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
02292 {
02293   uint32_t tickstart = 0U;
02294   uint32_t inputaddr;
02295   uint32_t outputaddr;
02296   
02297   if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
02298   {
02299     /* Process Locked */
02300     __HAL_LOCK(hcryp);
02301     
02302     inputaddr  = (uint32_t)pPlainData;
02303     outputaddr = (uint32_t)pCypherData;
02304     
02305     /* Change the CRYP peripheral state */
02306     hcryp->State = HAL_CRYP_STATE_BUSY;
02307     
02308     /* Check if initialization phase has already been performed */
02309     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
02310     {
02311       /* Set the key */
02312       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
02313       
02314       /* Set the CRYP peripheral in AES GCM mode */
02315       __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
02316       
02317       /* Set the Initialization Vector */
02318       CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
02319       
02320       /* Flush FIFO */
02321       __HAL_CRYP_FIFO_FLUSH(hcryp);
02322       
02323       /* Enable CRYP to start the init phase */
02324       __HAL_CRYP_ENABLE(hcryp);
02325       
02326       /* Get tick */
02327       tickstart = HAL_GetTick();
02328 
02329       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
02330       {
02331         /* Check for the Timeout */
02332         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02333         {
02334           /* Change state */
02335           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02336           
02337           /* Process Unlocked */
02338           __HAL_UNLOCK(hcryp);
02339           
02340           return HAL_TIMEOUT;
02341         }
02342       }
02343       /* Flush FIFO */
02344       __HAL_CRYP_FIFO_FLUSH(hcryp);
02345       
02346       /* Set the header phase */
02347       if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
02348       {
02349         return HAL_TIMEOUT;
02350       }
02351       /* Disable the CRYP peripheral */
02352       __HAL_CRYP_DISABLE(hcryp);
02353       
02354       /* Select payload phase once the header phase is performed */
02355       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
02356       
02357       /* Flush FIFO */
02358       __HAL_CRYP_FIFO_FLUSH(hcryp);
02359       
02360       /* Set the phase */
02361       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
02362     }
02363     
02364     /* Set the input and output addresses and start DMA transfer */ 
02365     CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
02366     
02367     /* Unlock process */
02368     __HAL_UNLOCK(hcryp);
02369     
02370     /* Return function status */
02371     return HAL_OK;
02372   }
02373   else
02374   {
02375     return HAL_ERROR;   
02376   }
02377 }
02378 
02379 /**
02380   * @brief  Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
02381   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02382   *         the configuration information for CRYP module
02383   * @param  pPlainData Pointer to the plaintext buffer
02384   * @param  Size Length of the plaintext buffer, must be a multiple of 16
02385   * @param  pCypherData Pointer to the cyphertext buffer
02386   * @retval HAL status
02387   */
02388 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
02389 {
02390   uint32_t tickstart = 0U;   
02391   uint32_t inputaddr;
02392   uint32_t outputaddr;
02393   uint32_t headersize;
02394   uint32_t headeraddr;
02395   uint32_t loopcounter = 0U;
02396   uint32_t bufferidx = 0U;
02397   uint8_t blockb0[16U] = {0};/* Block B0 */
02398   uint8_t ctr[16U] = {0}; /* Counter */
02399   uint32_t b0addr = (uint32_t)blockb0;
02400   
02401   if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
02402   {
02403     /* Process Locked */
02404     __HAL_LOCK(hcryp);
02405     
02406     inputaddr  = (uint32_t)pPlainData;
02407     outputaddr = (uint32_t)pCypherData;
02408     
02409     headersize = hcryp->Init.HeaderSize;
02410     headeraddr = (uint32_t)hcryp->Init.Header;
02411     
02412     hcryp->CrypInCount = Size;
02413     hcryp->pCrypInBuffPtr = pPlainData;
02414     hcryp->pCrypOutBuffPtr = pCypherData;
02415     hcryp->CrypOutCount = Size;
02416     
02417     /* Change the CRYP peripheral state */
02418     hcryp->State = HAL_CRYP_STATE_BUSY;
02419     
02420     /* Check if initialization phase has already been performed */
02421     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
02422     {
02423       /************************ Formatting the header block *******************/
02424       if(headersize != 0U)
02425       {
02426         /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
02427         if(headersize < 65280U)
02428         {
02429           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
02430           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
02431           headersize += 2U;
02432         }
02433         else
02434         {
02435           /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
02436           hcryp->Init.pScratch[bufferidx++] = 0xFFU;
02437           hcryp->Init.pScratch[bufferidx++] = 0xFEU;
02438           hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
02439           hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
02440           hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
02441           hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
02442           headersize += 6U;
02443         }
02444         /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
02445         for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
02446         {
02447           hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
02448         }
02449         /* Check if the header size is modulo 16 */
02450         if ((headersize % 16U) != 0U)
02451         {
02452           /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
02453           for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
02454           {
02455             hcryp->Init.pScratch[loopcounter] = 0U;
02456           }
02457           /* Set the header size to modulo 16 */
02458           headersize = ((headersize/16U) + 1U) * 16U;
02459         }
02460         /* Set the pointer headeraddr to hcryp->Init.pScratch */
02461         headeraddr = (uint32_t)hcryp->Init.pScratch;
02462       }
02463       /*********************** Formatting the block B0 ************************/
02464       if(headersize != 0U)
02465       {
02466         blockb0[0U] = 0x40U;
02467       }
02468       /* Flags byte */
02469       /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
02470       blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07) << 3);
02471       blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
02472       
02473       for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
02474       {
02475         blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
02476       }
02477       for ( ; loopcounter < 13U; loopcounter++)
02478       {
02479         blockb0[loopcounter+1U] = 0U;
02480       }
02481       
02482       blockb0[14U] = (Size >> 8U);
02483       blockb0[15U] = (Size & 0xFFU);
02484       
02485       /************************* Formatting the initial counter ***************/
02486       /* Byte 0:
02487          Bits 7 and 6 are reserved and shall be set to 0
02488          Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
02489          blocks are distinct from B0
02490          Bits 0, 1, and 2 contain the same encoding of q as in B0
02491       */
02492       ctr[0U] = blockb0[0U] & 0x07U;
02493       /* byte 1 to NonceSize is the IV (Nonce) */
02494       for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
02495       {
02496         ctr[loopcounter] = blockb0[loopcounter];
02497       }
02498       /* Set the LSB to 1 */
02499       ctr[15U] |= 0x01U;
02500       
02501       /* Set the key */
02502       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
02503       
02504       /* Set the CRYP peripheral in AES CCM mode */
02505       __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
02506       
02507       /* Set the Initialization Vector */
02508       CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
02509       
02510       /* Select init phase */
02511       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
02512       
02513       b0addr = (uint32_t)blockb0;
02514       /* Write the blockb0 block in the IN FIFO */
02515       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02516       b0addr+=4U;
02517       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02518       b0addr+=4U;
02519       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02520       b0addr+=4U;
02521       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02522       
02523       /* Enable the CRYP peripheral */
02524       __HAL_CRYP_ENABLE(hcryp);
02525       
02526       /* Get tick */
02527       tickstart = HAL_GetTick();
02528  
02529       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
02530       {
02531         /* Check for the Timeout */
02532         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02533         {
02534           /* Change state */
02535           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02536           
02537           /* Process Unlocked */
02538           __HAL_UNLOCK(hcryp);
02539           
02540           return HAL_TIMEOUT;
02541         }
02542       }
02543       /***************************** Header phase *****************************/
02544       if(headersize != 0U)
02545       {
02546         /* Select header phase */
02547         __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
02548         
02549         /* Enable Crypto processor */
02550         __HAL_CRYP_ENABLE(hcryp);
02551         
02552         for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
02553         {
02554          /* Get tick */
02555          tickstart = HAL_GetTick();
02556 
02557           while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
02558           {
02559             /* Check for the Timeout */
02560             if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02561             {
02562               /* Change state */
02563               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02564               
02565               /* Process Unlocked */
02566               __HAL_UNLOCK(hcryp);
02567               
02568               return HAL_TIMEOUT;
02569             }
02570           }
02571           /* Write the header block in the IN FIFO */
02572           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02573           headeraddr+=4U;
02574           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02575           headeraddr+=4U;
02576           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02577           headeraddr+=4U;
02578           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02579           headeraddr+=4U;
02580         }
02581         
02582         /* Get tick */
02583         tickstart = HAL_GetTick();
02584 
02585         while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
02586         {
02587           /* Check for the Timeout */
02588           if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02589           {
02590             /* Change state */
02591             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02592             
02593             /* Process Unlocked */
02594             __HAL_UNLOCK(hcryp);
02595             
02596             return HAL_TIMEOUT;
02597           }
02598         }
02599       }
02600       /* Save formatted counter into the scratch buffer pScratch */
02601       for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
02602       {
02603         hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
02604       }
02605       /* Reset bit 0 */
02606       hcryp->Init.pScratch[15U] &= 0xFEU;
02607       
02608       /* Select payload phase once the header phase is performed */
02609       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
02610       
02611       /* Flush FIFO */
02612       __HAL_CRYP_FIFO_FLUSH(hcryp);
02613       
02614       /* Set the phase */
02615       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
02616     }
02617     
02618     /* Set the input and output addresses and start DMA transfer */ 
02619     CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
02620     
02621     /* Unlock process */
02622     __HAL_UNLOCK(hcryp);
02623     
02624     /* Return function status */
02625     return HAL_OK;
02626   }
02627   else
02628   {
02629     return HAL_ERROR;   
02630   }
02631 }
02632 
02633 /**
02634   * @brief  Initializes the CRYP peripheral in AES GCM decryption mode using DMA.
02635   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02636   *         the configuration information for CRYP module
02637   * @param  pCypherData Pointer to the cyphertext buffer.
02638   * @param  Size Length of the cyphertext buffer, must be a multiple of 16
02639   * @param  pPlainData Pointer to the plaintext buffer
02640   * @retval HAL status
02641   */
02642 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
02643 {
02644   uint32_t tickstart = 0U;   
02645   uint32_t inputaddr;
02646   uint32_t outputaddr;
02647   
02648   if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
02649   {
02650     /* Process Locked */
02651     __HAL_LOCK(hcryp);
02652     
02653     inputaddr  = (uint32_t)pCypherData;
02654     outputaddr = (uint32_t)pPlainData;
02655     
02656     /* Change the CRYP peripheral state */
02657     hcryp->State = HAL_CRYP_STATE_BUSY;
02658     
02659     /* Check if initialization phase has already been performed */
02660     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
02661     {
02662       /* Set the key */
02663       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
02664       
02665       /* Set the CRYP peripheral in AES GCM decryption mode */
02666       __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
02667       
02668       /* Set the Initialization Vector */
02669       CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
02670       
02671       /* Enable CRYP to start the init phase */
02672       __HAL_CRYP_ENABLE(hcryp);
02673       
02674       /* Get tick */
02675       tickstart = HAL_GetTick();
02676 
02677       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
02678       {
02679         /* Check for the Timeout */
02680         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02681         {
02682           /* Change state */
02683           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02684           
02685           /* Process Unlocked */
02686           __HAL_UNLOCK(hcryp);
02687           
02688           return HAL_TIMEOUT;
02689         }
02690       }
02691       
02692       /* Set the header phase */
02693       if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
02694       {
02695         return HAL_TIMEOUT;
02696       }
02697       /* Disable the CRYP peripheral */
02698       __HAL_CRYP_DISABLE(hcryp);
02699       
02700       /* Select payload phase once the header phase is performed */
02701       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
02702       
02703       /* Set the phase */
02704       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
02705     }
02706     
02707     /* Set the input and output addresses and start DMA transfer */ 
02708     CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
02709     
02710     /* Unlock process */
02711     __HAL_UNLOCK(hcryp);
02712     
02713     /* Return function status */
02714     return HAL_OK;
02715   }
02716   else
02717   {
02718     return HAL_ERROR;   
02719   }
02720 }
02721 
02722 /**
02723   * @brief  Initializes the CRYP peripheral in AES CCM decryption mode using DMA
02724   *         then decrypted pCypherData. The cypher data are available in pPlainData.
02725   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
02726   *         the configuration information for CRYP module
02727   * @param  pCypherData Pointer to the cyphertext buffer  
02728   * @param  Size Length of the plaintext buffer, must be a multiple of 16
02729   * @param  pPlainData Pointer to the plaintext buffer  
02730   * @retval HAL status
02731   */
02732 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
02733 {
02734   uint32_t tickstart = 0U;   
02735   uint32_t inputaddr;
02736   uint32_t outputaddr;
02737   uint32_t headersize;
02738   uint32_t headeraddr;
02739   uint32_t loopcounter = 0U;
02740   uint32_t bufferidx = 0U;
02741   uint8_t blockb0[16U] = {0};/* Block B0 */
02742   uint8_t ctr[16U] = {0}; /* Counter */
02743   uint32_t b0addr = (uint32_t)blockb0;
02744   
02745   if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
02746   {
02747     /* Process Locked */
02748     __HAL_LOCK(hcryp);
02749     
02750     inputaddr  = (uint32_t)pCypherData;
02751     outputaddr = (uint32_t)pPlainData;
02752     
02753     headersize = hcryp->Init.HeaderSize;
02754     headeraddr = (uint32_t)hcryp->Init.Header;
02755     
02756     hcryp->CrypInCount = Size;
02757     hcryp->pCrypInBuffPtr = pCypherData;
02758     hcryp->pCrypOutBuffPtr = pPlainData;
02759     hcryp->CrypOutCount = Size;
02760     
02761     /* Change the CRYP peripheral state */
02762     hcryp->State = HAL_CRYP_STATE_BUSY;
02763     
02764     /* Check if initialization phase has already been performed */
02765     if(hcryp->Phase == HAL_CRYP_PHASE_READY)
02766     {
02767       /************************ Formatting the header block *******************/
02768       if(headersize != 0U)
02769       {
02770         /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
02771         if(headersize < 65280U)
02772         {
02773           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
02774           hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
02775           headersize += 2U;
02776         }
02777         else
02778         {
02779           /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
02780           hcryp->Init.pScratch[bufferidx++] = 0xFFU;
02781           hcryp->Init.pScratch[bufferidx++] = 0xFEU;
02782           hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
02783           hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
02784           hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
02785           hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
02786           headersize += 6U;
02787         }
02788         /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
02789         for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
02790         {
02791           hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
02792         }
02793         /* Check if the header size is modulo 16 */
02794         if ((headersize % 16U) != 0U)
02795         {
02796           /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
02797           for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
02798           {
02799             hcryp->Init.pScratch[loopcounter] = 0U;
02800           }
02801           /* Set the header size to modulo 16 */
02802           headersize = ((headersize/16U) + 1U) * 16U;
02803         }
02804         /* Set the pointer headeraddr to hcryp->Init.pScratch */
02805         headeraddr = (uint32_t)hcryp->Init.pScratch;
02806       }
02807       /*********************** Formatting the block B0 ************************/
02808       if(headersize != 0U)
02809       {
02810         blockb0[0U] = 0x40U;
02811       }
02812       /* Flags byte */
02813       /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
02814       blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07) << 3);
02815       blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
02816       
02817       for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
02818       {
02819         blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
02820       }
02821       for ( ; loopcounter < 13U; loopcounter++)
02822       {
02823         blockb0[loopcounter+1U] = 0U;
02824       }
02825       
02826       blockb0[14U] = (Size >> 8U);
02827       blockb0[15U] = (Size & 0xFFU);
02828       
02829       /************************* Formatting the initial counter ***************/
02830       /* Byte 0:
02831          Bits 7 and 6 are reserved and shall be set to 0
02832          Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter 
02833          blocks are distinct from B0
02834          Bits 0, 1, and 2 contain the same encoding of q as in B0
02835       */
02836       ctr[0U] = blockb0[0U] & 0x07U;
02837       /* byte 1 to NonceSize is the IV (Nonce) */
02838       for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
02839       {
02840         ctr[loopcounter] = blockb0[loopcounter];
02841       }
02842       /* Set the LSB to 1 */
02843       ctr[15U] |= 0x01U;
02844       
02845       /* Set the key */
02846       CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
02847       
02848       /* Set the CRYP peripheral in AES CCM mode */
02849       __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
02850       
02851       /* Set the Initialization Vector */
02852       CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
02853       
02854       /* Select init phase */
02855       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
02856       
02857       b0addr = (uint32_t)blockb0;
02858       /* Write the blockb0 block in the IN FIFO */
02859       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02860       b0addr+=4U;
02861       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02862       b0addr+=4U;
02863       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02864       b0addr+=4U;
02865       hcryp->Instance->DR = *(uint32_t*)(b0addr);
02866       
02867       /* Enable the CRYP peripheral */
02868       __HAL_CRYP_ENABLE(hcryp);
02869       
02870       /* Get tick */
02871       tickstart = HAL_GetTick();
02872  
02873       while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
02874       {
02875         /* Check for the Timeout */
02876         
02877         if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02878         {
02879           /* Change state */
02880           hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02881           
02882           /* Process Unlocked */
02883           __HAL_UNLOCK(hcryp);
02884           
02885           return HAL_TIMEOUT;
02886           
02887         }
02888       }
02889       /***************************** Header phase *****************************/
02890       if(headersize != 0U)
02891       {
02892         /* Select header phase */
02893         __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
02894         
02895         /* Enable Crypto processor */
02896         __HAL_CRYP_ENABLE(hcryp);
02897         
02898         for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
02899         {
02900          /* Get tick */
02901          tickstart = HAL_GetTick();
02902  
02903           while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
02904           {
02905             /* Check for the Timeout */
02906             if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02907             {
02908               /* Change state */
02909               hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02910               
02911               /* Process Unlocked */
02912               __HAL_UNLOCK(hcryp);
02913               
02914               return HAL_TIMEOUT;
02915             }
02916           }
02917           /* Write the header block in the IN FIFO */
02918           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02919           headeraddr+=4U;
02920           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02921           headeraddr+=4U;
02922           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02923           headeraddr+=4U;
02924           hcryp->Instance->DR = *(uint32_t*)(headeraddr);
02925           headeraddr+=4U;
02926         }
02927         
02928         /* Get tick */
02929         tickstart = HAL_GetTick();
02930 
02931         while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
02932         {
02933           /* Check for the Timeout */
02934           if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
02935           {
02936             /* Change state */
02937             hcryp->State = HAL_CRYP_STATE_TIMEOUT;
02938             
02939             /* Process Unlocked */
02940             __HAL_UNLOCK(hcryp);
02941             
02942             return HAL_TIMEOUT;
02943           }
02944         }
02945       }
02946       /* Save formatted counter into the scratch buffer pScratch */
02947       for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
02948       {
02949         hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
02950       }
02951       /* Reset bit 0 */
02952       hcryp->Init.pScratch[15U] &= 0xFEU;
02953       /* Select payload phase once the header phase is performed */
02954       __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
02955       
02956       /* Flush FIFO */
02957       __HAL_CRYP_FIFO_FLUSH(hcryp);
02958       
02959       /* Set the phase */
02960       hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
02961     }
02962     /* Set the input and output addresses and start DMA transfer */ 
02963     CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
02964     
02965     /* Unlock process */
02966     __HAL_UNLOCK(hcryp);
02967     
02968     /* Return function status */
02969     return HAL_OK;
02970   }
02971   else
02972   {
02973     return HAL_ERROR;   
02974   }
02975 }
02976 
02977 /**
02978   * @}
02979   */
02980   
02981 /** @defgroup CRYPEx_Exported_Functions_Group2 CRYPEx IRQ handler management  
02982  *  @brief   CRYPEx IRQ handler.
02983  *
02984 @verbatim   
02985   ==============================================================================
02986                 ##### CRYPEx IRQ handler management #####
02987   ==============================================================================  
02988 [..]  This section provides CRYPEx IRQ handler function.
02989 
02990 @endverbatim
02991   * @{
02992   */
02993 
02994 /**
02995   * @brief  This function handles CRYPEx interrupt request.
02996   * @param  hcryp pointer to a CRYPEx_HandleTypeDef structure that contains
02997   *         the configuration information for CRYP module
02998   * @retval None
02999   */
03000 
03001 void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp)
03002 {
03003   switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION)
03004   {    
03005   case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT:
03006     HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, NULL, 0U, NULL);
03007     break;
03008     
03009   case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT:
03010     HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, NULL, 0U, NULL);
03011     break;
03012     
03013   case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT:
03014     HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, NULL, 0U, NULL);
03015     break;
03016     
03017   case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT:
03018     HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, NULL, 0U, NULL);
03019     break;
03020     
03021   default:
03022     break;
03023   }
03024 }
03025 
03026 /**
03027   * @}
03028   */
03029 
03030 /**
03031   * @}
03032   */
03033 #endif /* CRYP */
03034 
03035 #if defined (AES)
03036 
03037 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
03038   * @{
03039   */
03040 #define CRYP_CCF_TIMEOUTVALUE                      22000U  /*!< CCF flag raising time-out value */
03041 #define CRYP_BUSY_TIMEOUTVALUE                     22000U  /*!< BUSY flag reset time-out value  */
03042 
03043 #define CRYP_POLLING_OFF                           0x0U    /*!< No polling when padding */
03044 #define CRYP_POLLING_ON                            0x1U    /*!< Polling when padding    */
03045 /**
03046   * @}
03047   */
03048 
03049 /* Private macro -------------------------------------------------------------*/
03050 /* Private variables ---------------------------------------------------------*/
03051 /* Private function prototypes -----------------------------------------------*/
03052 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
03053  * @{
03054  */
03055 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
03056 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
03057 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
03058 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
03059 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma);
03060 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma);
03061 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma);
03062 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
03063 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
03064 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
03065 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
03066 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
03067 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
03068 /**
03069   * @}
03070   */
03071 
03072 /* Exported functions ---------------------------------------------------------*/
03073 
03074 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
03075   * @{
03076   */
03077 
03078 
03079 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function 
03080  *  @brief    Extended callback functions. 
03081  *
03082 @verbatim   
03083  ===============================================================================
03084                  ##### Extended callback functions #####
03085  =============================================================================== 
03086     [..]  This section provides callback function:
03087       (+) Computation completed.
03088 
03089 @endverbatim
03090   * @{
03091   */
03092 
03093 
03094 /**
03095   * @brief  Computation completed callbacks.
03096   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
03097   *         the configuration information for CRYP module
03098   * @retval None
03099   */
03100 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
03101 {
03102   /* Prevent unused argument(s) compilation warning */
03103   UNUSED(hcryp);
03104 
03105   /* NOTE : This function should not be modified; when the callback is needed,
03106             the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
03107    */ 
03108 }
03109 
03110 /**
03111   * @}
03112   */
03113 
03114 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions 
03115  *  @brief   Extended processing functions. 
03116  *
03117 @verbatim   
03118   ==============================================================================
03119                       ##### AES extended processing functions #####
03120   ==============================================================================  
03121     [..]  This section provides functions allowing to:
03122       (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
03123           Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
03124           based on the processing type. Three processing types are available:
03125           (++) Polling mode
03126           (++) Interrupt mode
03127           (++) DMA mode
03128       (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES 
03129           algorithm in different chaining modes.
03130           Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase 
03131           so that steps can be skipped if so required. Functions are only differentiated based on the processing type. 
03132           Three processing types are available:
03133           (++) Polling mode
03134           (++) Interrupt mode
03135           (++) DMA mode          
03136 
03137 @endverbatim
03138   * @{
03139   */
03140 
03141 /**
03142   * @brief  Carry out in polling mode the ciphering or deciphering operation according to
03143   *         hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and 
03144   *         chaining modes ECB, CBC and CTR are managed by this function in polling mode.
03145   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
03146   *         the configuration information for CRYP module
03147   * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
03148   *                     or key derivation+decryption.
03149   *                     Parameter is meaningless in case of key derivation.      
03150   * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
03151   *               Parameter is meaningless in case of key derivation.  
03152   * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of 
03153   *                     decryption/key derivation+decryption, or pointer to the derivative keys in
03154   *                     case of key derivation only.   
03155   * @param  Timeout Specify Timeout value 
03156   * @retval HAL status
03157   */
03158 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
03159 {
03160 
03161   if (hcryp->State == HAL_CRYP_STATE_READY)
03162   {
03163     /* Check parameters setting */
03164     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
03165     {
03166       if (pOutputData == NULL) 
03167       {
03168         return  HAL_ERROR;
03169       }
03170     }
03171     else
03172     {
03173       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
03174       {
03175         return  HAL_ERROR;
03176       }
03177     }
03178     
03179     /* Process Locked */
03180     __HAL_LOCK(hcryp);
03181   
03182     /* Change the CRYP state */
03183     hcryp->State = HAL_CRYP_STATE_BUSY;
03184   
03185     /* Call CRYP_ReadKey() API if the operating mode is set to
03186        key derivation, CRYP_ProcessData() otherwise  */
03187     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
03188     {
03189       if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
03190       {
03191         return HAL_TIMEOUT;
03192       }    
03193     }
03194     else
03195     {
03196       if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
03197       {
03198         return HAL_TIMEOUT;
03199       }
03200     }
03201   
03202     /* If the state has not been set to SUSPENDED, set it to
03203        READY, otherwise keep it as it is */
03204     if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
03205     {
03206       hcryp->State = HAL_CRYP_STATE_READY;
03207     }
03208   
03209     /* Process Unlocked */
03210     __HAL_UNLOCK(hcryp);
03211   
03212     return HAL_OK;
03213   }
03214   else
03215   {
03216     return HAL_BUSY;
03217   }
03218 }
03219 
03220 /**
03221   * @brief  Carry out in interrupt mode the ciphering or deciphering operation according to
03222   *         hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and 
03223   *         chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
03224   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
03225   *         the configuration information for CRYP module
03226   * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
03227   *                     or key derivation+decryption.
03228   *                     Parameter is meaningless in case of key derivation.      
03229   * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
03230   *               Parameter is meaningless in case of key derivation.  
03231   * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of 
03232   *                     decryption/key derivation+decryption, or pointer to the derivative keys in 
03233   *                     case of key derivation only.    
03234   * @retval HAL status
03235   */
03236 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp,  uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
03237 {
03238   uint32_t inputaddr = 0U;
03239   
03240   if(hcryp->State == HAL_CRYP_STATE_READY)
03241   {
03242     /* Check parameters setting */
03243     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
03244     {
03245       if (pOutputData == NULL) 
03246       {
03247         return  HAL_ERROR;
03248       }
03249     }
03250     else
03251     {
03252       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
03253       {
03254         return  HAL_ERROR;
03255       }
03256     }
03257     /* Process Locked */
03258     __HAL_LOCK(hcryp);
03259     
03260     /* If operating mode is not limited to key derivation only,
03261        get the buffers addresses and sizes */
03262     if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
03263     {
03264 
03265       hcryp->CrypInCount = Size;
03266       hcryp->pCrypInBuffPtr = pInputData;
03267       hcryp->pCrypOutBuffPtr = pOutputData;
03268       hcryp->CrypOutCount = Size;
03269     }
03270     
03271     /* Change the CRYP state */
03272     hcryp->State = HAL_CRYP_STATE_BUSY;
03273   
03274       /* Process Unlocked */
03275     __HAL_UNLOCK(hcryp);
03276     
03277     /* Enable Computation Complete Flag and Error Interrupts */
03278     __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
03279 
03280     /* If operating mode is key derivation only, the input data have 
03281        already been entered during the initialization process. For
03282        the other operating modes, they are fed to the CRYP hardware 
03283        block at this point. */
03284     if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
03285     {
03286       /* Initiate the processing under interrupt in entering 
03287          the first input data */
03288       inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
03289       /* Increment/decrement instance pointer/counter */
03290       hcryp->pCrypInBuffPtr += 16U;
03291       hcryp->CrypInCount -= 16U;
03292       /* Write the first input block in the Data Input register */
03293       hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03294       inputaddr+=4U;
03295       hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03296       inputaddr+=4U;
03297       hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
03298       inputaddr+=4U;
03299       hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03300     }
03301     
03302     /* Return function status */
03303     return HAL_OK;
03304   }
03305   else
03306   {
03307     return HAL_BUSY;   
03308   }
03309 }
03310 
03311 /**
03312   * @brief  Carry out in DMA mode the ciphering or deciphering operation according to
03313   *         hcryp->Init structure fields.
03314   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
03315   *         the configuration information for CRYP module
03316   * @param  pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
03317   *                     or key derivation+decryption.    
03318   * @param  Size Length of the input data buffer in bytes, must be a multiple of 16.
03319   * @param  pOutputData Pointer to the cipher text in case of encryption or plain text in case of 
03320   *                     decryption/key derivation+decryption.
03321   * @note   Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.   
03322   * @note   Supported operating modes are encryption, decryption and key derivation with decryption. 
03323   * @note   No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx 
03324   *         registers must be done by software.   
03325   * @note   This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx 
03326   *         registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
03327   * @note   pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.   
03328   * @retval HAL status
03329   */
03330 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp,  uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
03331 {
03332   uint32_t inputaddr = 0U;
03333   uint32_t outputaddr = 0U;
03334   
03335   if (hcryp->State == HAL_CRYP_STATE_READY)
03336   {
03337     /* Check parameters setting */
03338     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
03339     {
03340       /* no DMA channel is provided for key derivation operating mode, 
03341          access to AES_KEYRx registers must be done by software */
03342       return  HAL_ERROR;
03343     }
03344     else
03345     {
03346       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
03347       {
03348         return  HAL_ERROR;
03349       }
03350     }
03351 
03352     /* Process Locked */
03353     __HAL_LOCK(hcryp);
03354     
03355     inputaddr  = (uint32_t)pInputData;
03356     outputaddr = (uint32_t)pOutputData;
03357     
03358     /* Change the CRYP state */
03359     hcryp->State = HAL_CRYP_STATE_BUSY;
03360     
03361     /* Set the input and output addresses and start DMA transfer */ 
03362     CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
03363     
03364     /* Process Unlocked */
03365     __HAL_UNLOCK(hcryp);
03366     
03367     /* Return function status */
03368     return HAL_OK;
03369   }
03370   else
03371   {
03372     return HAL_BUSY;   
03373   }
03374 }
03375 
03376 /**
03377   * @brief  Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering 
03378   *         operation according to hcryp->Init structure fields. 
03379   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
03380   *         the configuration information for CRYP module
03381   * @param  pInputData 
03382   *         - pointer to payload data in GCM payload phase, 
03383   *         - pointer to B0 block in CMAC header phase,
03384   *         - pointer to C block in CMAC final phase. 
03385   *         - Parameter is meaningless in case of GCM/GMAC init, header and final phases.                                       
03386   * @param  Size 
03387   *         - length of the input payload data buffer in bytes,
03388   *         - length of B0 block (in bytes) in CMAC header phase,
03389   *         - length of C block (in bytes) in CMAC final phase.
03390   *         - Parameter is meaningless in case of GCM/GMAC init and header phases.                                
03391   * @param  pOutputData 
03392   *         - pointer to plain or cipher text in GCM payload phase, 
03393   *         - pointer to authentication tag in GCM/GMAC and CMAC final phases.
03394   *         - Parameter is meaningless in case of GCM/GMAC init and header phases
03395   *           and in case of CMAC header phase.  
03396   * @param  Timeout Specify Timeout value 
03397   * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable.
03398   * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 
03399   *         can be skipped by the user if so required.          
03400   * @retval HAL status
03401   */
03402 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
03403 {
03404   uint32_t index          = 0U;
03405   uint32_t inputaddr      = 0U;
03406   uint32_t outputaddr     = 0U;
03407   uint32_t tagaddr        = 0U;
03408   uint64_t headerlength   = 0U; 
03409   uint64_t inputlength    = 0U;
03410   uint64_t payloadlength  = 0U; 
03411   uint32_t difflength     = 0U;
03412   uint32_t addhoc_process = 0U;  
03413   
03414   if (hcryp->State == HAL_CRYP_STATE_READY)
03415   {
03416     /* input/output parameters check */
03417     if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
03418     {
03419       if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
03420       {
03421         return  HAL_ERROR;
03422       }
03423 #if defined(AES_CR_NPBLB)
03424       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
03425 #else      
03426       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
03427 #endif      
03428       {
03429         /* In case of CMAC (or CCM) header phase resumption, we can have pInputData = NULL and  Size = 0 */
03430         if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
03431         {
03432           return  HAL_ERROR;
03433         }
03434       }
03435     }
03436     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
03437     {   
03438       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
03439       {
03440         return  HAL_ERROR;
03441       }
03442     }
03443     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
03444     {
03445       if (pOutputData == NULL)
03446       {
03447         return  HAL_ERROR;
03448       }
03449 #if defined(AES_CR_NPBLB)  
03450       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
03451 #else    
03452       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
03453 #endif      
03454       {
03455         return  HAL_ERROR;
03456       }
03457     }
03458 
03459     /* Process Locked */
03460     __HAL_LOCK(hcryp);
03461   
03462     /* Change the CRYP state */
03463     hcryp->State = HAL_CRYP_STATE_BUSY;
03464   
03465     /*==============================================*/
03466     /* GCM/GMAC (or CCM when applicable) init phase */
03467     /*==============================================*/
03468     /* In case of init phase, the input data (Key and Initialization Vector) have 
03469        already been entered during the initialization process. Therefore, the
03470        API just waits for the CCF flag to be set. */
03471     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
03472     {
03473       /* just wait for hash computation */
03474       if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)  
03475       { 
03476         hcryp->State = HAL_CRYP_STATE_READY;        
03477         __HAL_UNLOCK(hcryp);
03478         return HAL_TIMEOUT;
03479       }
03480       
03481       /* Clear CCF Flag */
03482       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
03483       /* Mark that the initialization phase is over */
03484       hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
03485     }
03486     /*=====================================*/
03487     /* GCM/GMAC or (CCM/)CMAC header phase */
03488     /*=====================================*/
03489     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
03490     {      
03491       /* Set header phase; for GCM or GMAC, set data-byte at this point */
03492       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
03493       {
03494         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
03495       }
03496       else
03497       {
03498         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
03499       }
03500          
03501       /* Enable the Peripheral */
03502       __HAL_CRYP_ENABLE();
03503       
03504 #if !defined(AES_CR_NPBLB)       
03505       /* in case of CMAC, enter B0 block in header phase, before the header itself. */
03506       /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
03507          skip these steps and go directly to header buffer feeding to the HW */
03508       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U))
03509       {
03510         inputaddr = (uint32_t)pInputData; 
03511         
03512         for(index=0U; (index < Size); index += 16U)
03513         {
03514           /* Write the Input block in the Data Input register */
03515           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03516           inputaddr+=4U;
03517           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03518           inputaddr+=4U;
03519           hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
03520           inputaddr+=4U;
03521           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03522           inputaddr+=4U;
03523           
03524           if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)  
03525           { 
03526             hcryp->State = HAL_CRYP_STATE_READY;        
03527             __HAL_UNLOCK(hcryp);
03528             return HAL_TIMEOUT;
03529           }
03530           /* Clear CCF Flag */
03531           __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);           
03532 
03533           /* If the suspension flag has been raised and if the processing is not about
03534            to end, suspend processing */  
03535           if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Size))        
03536           {
03537             /* reset SuspendRequest */
03538             hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
03539             /* Change the CRYP state */
03540             hcryp->State = HAL_CRYP_STATE_SUSPENDED;
03541             /* Mark that the header phase is over */
03542             hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
03543             
03544            /* Save current reading and writing locations of Input and Output buffers */
03545            hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
03546            /* Save the total number of bytes (B blocks + header) that remain to be 
03547               processed at this point */
03548            hcryp->CrypInCount     =  hcryp->Init.HeaderSize + Size - (index+16U);
03549         
03550            /* Process Unlocked */
03551             __HAL_UNLOCK(hcryp);
03552         
03553             return HAL_OK;
03554           } 
03555         } /* for(index=0; (index < Size); index += 16) */             
03556       }
03557 #endif /* !defined(AES_CR_NPBLB) */      
03558       
03559       /* Enter header */  
03560       inputaddr = (uint32_t)hcryp->Init.Header; 
03561       /* Local variable headerlength is a number of bytes multiple of 128 bits,
03562          remaining header data (if any) are handled after this loop */
03563       headerlength =  (((hcryp->Init.HeaderSize)/16U)*16U) ; 
03564       if ((hcryp->Init.HeaderSize % 16U) != 0U)
03565       {
03566         difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);   
03567       }
03568       for(index=0U; index < headerlength; index += 16U)
03569       {
03570         /* Write the Input block in the Data Input register */
03571         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03572         inputaddr+=4U;
03573         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03574         inputaddr+=4U;
03575         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
03576         inputaddr+=4U;
03577         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03578         inputaddr+=4U;
03579         
03580         if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)  
03581         { 
03582           hcryp->State = HAL_CRYP_STATE_READY;        
03583           __HAL_UNLOCK(hcryp);
03584           return HAL_TIMEOUT;
03585         }
03586         /* Clear CCF Flag */
03587         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR); 
03588         
03589         /* If the suspension flag has been raised and if the processing is not about
03590          to end, suspend processing */  
03591         if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < headerlength))        
03592         {
03593           /* reset SuspendRequest */
03594           hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
03595           /* Change the CRYP state */
03596           hcryp->State = HAL_CRYP_STATE_SUSPENDED;
03597           /* Mark that the header phase is over */
03598           hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
03599           
03600          /* Save current reading and writing locations of Input and Output buffers */
03601          hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
03602          /* Save the total number of bytes that remain to be processed at this point */
03603           hcryp->CrypInCount =  hcryp->Init.HeaderSize - (index+16U);
03604       
03605          /* Process Unlocked */
03606           __HAL_UNLOCK(hcryp);
03607       
03608           return HAL_OK;
03609         }       
03610       }
03611       
03612       /* Case header length is not a multiple of 16 bytes */
03613       if (difflength != 0U)
03614       {
03615         hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
03616         CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);   
03617       }       
03618       
03619       /* Mark that the header phase is over */
03620       hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
03621     }
03622     /*============================================*/
03623     /* GCM (or CCM when applicable) payload phase */
03624     /*============================================*/
03625     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
03626     {
03627       
03628       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
03629       
03630       /* if the header phase has been bypassed, AES must be enabled again */
03631       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
03632       {
03633         __HAL_CRYP_ENABLE();  
03634       }
03635       
03636       inputaddr  = (uint32_t)pInputData;
03637       outputaddr = (uint32_t)pOutputData;
03638       
03639       /* Enter payload */
03640       /* Specific handling to manage payload last block size less than 128 bits */
03641       if ((Size % 16U) != 0U)
03642       {
03643         payloadlength = (Size/16U) * 16U;
03644         difflength = (uint32_t) (Size - payloadlength);
03645         addhoc_process = 1U;
03646       }
03647       else
03648       {
03649         payloadlength = Size;
03650         addhoc_process = 0U;      
03651       }
03652             
03653       /* Feed payload */  
03654       for(index=0U; index < payloadlength; index += 16U)
03655       {
03656         /* Write the Input block in the Data Input register */
03657         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03658         inputaddr+=4U;
03659         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03660         inputaddr+=4U;
03661         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
03662         inputaddr+=4U;
03663         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03664         inputaddr+=4U;
03665         
03666         if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)  
03667         { 
03668           hcryp->State = HAL_CRYP_STATE_READY;        
03669           __HAL_UNLOCK(hcryp);
03670           return HAL_TIMEOUT;
03671         }
03672           
03673         /* Clear CCF Flag */
03674         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
03675         
03676         /* Retrieve output data: read the output block 
03677            from the Data Output Register */
03678         *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
03679         outputaddr+=4U;
03680         *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
03681         outputaddr+=4U;
03682         *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
03683         outputaddr+=4U;
03684         *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
03685         outputaddr+=4U;
03686        
03687         /* If the suspension flag has been raised and if the processing is not about
03688          to end, suspend processing */  
03689         if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < payloadlength))
03690         {
03691           /* no flag waiting under IRQ handling */
03692           if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
03693           {
03694             /* Ensure that Busy flag is reset */
03695             if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)  
03696             {   
03697               hcryp->State = HAL_CRYP_STATE_READY;        
03698               __HAL_UNLOCK(hcryp);
03699               return HAL_TIMEOUT;
03700             }
03701           }               
03702           /* reset SuspendRequest */
03703           hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
03704           /* Change the CRYP state */
03705           hcryp->State = HAL_CRYP_STATE_SUSPENDED;
03706           /* Mark that the header phase is over */
03707           hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
03708           
03709           /* Save current reading and writing locations of Input and Output buffers */
03710           hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
03711           hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
03712           /* Save the number of bytes that remain to be processed at this point */
03713           hcryp->CrypInCount     =  Size - (index+16U);          
03714         
03715           /* Process Unlocked */
03716           __HAL_UNLOCK(hcryp);
03717         
03718           return HAL_OK;
03719         }            
03720         
03721       }
03722       
03723       /* Additional processing to manage GCM(/CCM) encryption and decryption cases when 
03724          payload last block size less than 128 bits */
03725       if (addhoc_process == 1U)
03726       {
03727         hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
03728         hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;        
03729         CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON); 
03730       } /* (addhoc_process == 1) */
03731          
03732       /* Mark that the payload phase is over */
03733       hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;         
03734     }
03735     /*====================================*/
03736     /* GCM/GMAC or (CCM/)CMAC final phase */
03737     /*====================================*/
03738     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
03739     {    
03740       tagaddr = (uint32_t)pOutputData;
03741       
03742 #if defined(AES_CR_NPBLB)   
03743      /* By default, clear NPBLB field */
03744       CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
03745 #endif        
03746       
03747       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
03748       
03749       /* if the header and payload phases have been bypassed, AES must be enabled again */
03750       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
03751       {
03752         __HAL_CRYP_ENABLE();  
03753       }
03754       
03755       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
03756       {
03757         headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
03758         inputlength = Size * 8U;                    /* input length in bits */ 
03759         
03760            
03761         if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
03762         {
03763           hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
03764           hcryp->Instance->DINR = __RBIT(headerlength);
03765           hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
03766           hcryp->Instance->DINR = __RBIT(inputlength);
03767         }
03768         else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
03769         {
03770           hcryp->Instance->DINR = __REV((headerlength)>>32U);
03771           hcryp->Instance->DINR = __REV(headerlength);
03772           hcryp->Instance->DINR = __REV((inputlength)>>32U);
03773           hcryp->Instance->DINR = __REV(inputlength);
03774         } 
03775         else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
03776         {
03777           hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
03778           hcryp->Instance->DINR = __ROR(headerlength, 16U);
03779           hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
03780           hcryp->Instance->DINR = __ROR(inputlength, 16U);          
03781         }
03782         else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
03783         {
03784           hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
03785           hcryp->Instance->DINR = (uint32_t)(headerlength);
03786           hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
03787           hcryp->Instance->DINR = (uint32_t)(inputlength);
03788         }
03789       }
03790 #if !defined(AES_CR_NPBLB)             
03791       else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)     
03792       {
03793         inputaddr  = (uint32_t)pInputData;
03794         /* Enter the last block made of a 128-bit value formatted
03795            from the original B0 packet. */
03796         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03797         inputaddr+=4U;
03798         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03799         inputaddr+=4U;
03800         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
03801         inputaddr+=4U;
03802         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
03803       }
03804 #endif       
03805       
03806       
03807       if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)  
03808       { 
03809           hcryp->State = HAL_CRYP_STATE_READY;        
03810           __HAL_UNLOCK(hcryp);
03811           return HAL_TIMEOUT;
03812       }
03813 
03814       /* Read the Auth TAG in the Data Out register */
03815       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
03816       tagaddr+=4U;
03817       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
03818       tagaddr+=4U;
03819       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
03820       tagaddr+=4U;
03821       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR; 
03822          
03823 
03824       /* Clear CCF Flag */
03825       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
03826       /* Mark that the final phase is over */
03827       hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
03828       /* Disable the Peripheral */
03829       __HAL_CRYP_DISABLE();
03830     }
03831     /*=================================================*/
03832     /* case incorrect hcryp->Init.GCMCMACPhase setting */
03833     /*=================================================*/
03834     else
03835     {
03836       hcryp->State = HAL_CRYP_STATE_ERROR; 
03837       __HAL_UNLOCK(hcryp); 
03838       return HAL_ERROR;
03839     }
03840  
03841     /* Change the CRYP state */
03842     hcryp->State = HAL_CRYP_STATE_READY;
03843   
03844     /* Process Unlocked */
03845     __HAL_UNLOCK(hcryp);
03846   
03847     return HAL_OK;
03848   }
03849   else
03850   {
03851     return HAL_BUSY;
03852   }
03853 }
03854 
03855 
03856 
03857 
03858 /**
03859   * @brief  Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering 
03860   *         operation according to hcryp->Init structure fields. 
03861   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
03862   *         the configuration information for CRYP module
03863   * @param  pInputData 
03864   *         - pointer to payload data in GCM payload phase,
03865   *         - pointer to B0 block in CMAC header phase,
03866   *         - pointer to C block in CMAC final phase.
03867   *         Parameter is meaningless in case of GCM/GMAC init, header and final phases.         
03868   * @param  Size 
03869   *         - length of the input payload data buffer in bytes,
03870   *         - length of B0 block (in bytes) in CMAC header phase,
03871   *         - length of C block (in bytes) in CMAC final phase.
03872   *         - Parameter is meaningless in case of GCM/GMAC init and header phases.             
03873   * @param  pOutputData 
03874   *         - pointer to plain or cipher text in GCM payload phase, 
03875   *         - pointer to authentication tag in GCM/GMAC and CMAC final phases.
03876   *         - Parameter is meaningless in case of GCM/GMAC init and header phases
03877   *           and in case of CMAC header phase.
03878   * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
03879   * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 
03880   *         can be skipped by the user if so required.                                 
03881   * @retval HAL status
03882   */
03883 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
03884 {
03885 
03886   uint32_t inputaddr      = 0U;
03887   uint64_t headerlength   = 0U;
03888   uint64_t inputlength    = 0U;
03889   uint32_t index          = 0U;
03890   uint32_t addhoc_process = 0U; 
03891   uint32_t difflength     = 0U;
03892   uint32_t difflengthmod4 = 0U;
03893   uint32_t mask[3U]       = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};     
03894  
03895 
03896   if (hcryp->State == HAL_CRYP_STATE_READY)
03897   {
03898     /* input/output parameters check */
03899     if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
03900     {
03901       if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
03902       {
03903         return  HAL_ERROR;
03904       }
03905 #if defined(AES_CR_NPBLB) 
03906       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
03907 #else       
03908       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
03909 #endif         
03910       {
03911         /* In case of CMAC header phase resumption, we can have pInputData = NULL and  Size = 0 */
03912         if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
03913         {
03914           return  HAL_ERROR;
03915         }
03916       }      
03917     }
03918     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
03919     {   
03920       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
03921       {
03922         return  HAL_ERROR;
03923       }
03924     }
03925     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
03926     {
03927       if (pOutputData == NULL)
03928       {
03929         return  HAL_ERROR;
03930       }
03931 #if defined(AES_CR_NPBLB)  
03932       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
03933 #else    
03934       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
03935 #endif 
03936       {
03937         return  HAL_ERROR;
03938       }
03939     }
03940     
03941     /* Process Locked */
03942     __HAL_LOCK(hcryp);
03943     
03944     /* Change the CRYP state */
03945     hcryp->State = HAL_CRYP_STATE_BUSY;
03946     
03947     /* Process Unlocked */
03948     __HAL_UNLOCK(hcryp);
03949                            
03950     /* Enable Computation Complete Flag and Error Interrupts */
03951     __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
03952 
03953     /*==============================================*/
03954     /* GCM/GMAC (or CCM when applicable) init phase */
03955     /*==============================================*/
03956     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
03957     {    
03958     /* In case of init phase, the input data (Key and Initialization Vector) have 
03959        already been entered during the initialization process. Therefore, the
03960        software just waits for the CCF interrupt to be raised and which will
03961        be handled by CRYP_AES_Auth_IT() API. */
03962     }
03963     /*=====================================*/
03964     /* GCM/GMAC or (CCM/)CMAC header phase */
03965     /*=====================================*/   
03966     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
03967     {
03968     
03969 #if defined(AES_CR_NPBLB)   
03970       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
03971 #else    
03972       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
03973 #endif      
03974       {
03975         /* In case of CMAC, B blocks are first entered, before the header.
03976            Therefore, B blocks and the header are entered back-to-back
03977            as if it was only one single block. 
03978            However, in case of resumption after suspension, if all the
03979            B blocks have been entered (in that case, Size = 0), only the
03980            remainder of the non-processed header bytes are entered. */
03981           if (Size != 0U)
03982           {
03983             hcryp->CrypInCount = Size + hcryp->Init.HeaderSize;
03984             hcryp->pCrypInBuffPtr = pInputData;
03985           }
03986           else
03987           {
03988             hcryp->CrypInCount = hcryp->Init.HeaderSize;
03989             hcryp->pCrypInBuffPtr = hcryp->Init.Header;
03990           }
03991       }
03992       else
03993       {
03994         /* Get the header addresses and sizes */
03995         hcryp->CrypInCount = hcryp->Init.HeaderSize;
03996         hcryp->pCrypInBuffPtr = hcryp->Init.Header;
03997       }    
03998     
03999       inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
04000       
04001       /* Set header phase; for GCM or GMAC, set data-byte at this point */
04002       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
04003       {
04004         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
04005       }
04006       else
04007       {
04008         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
04009       }
04010        
04011       /* Enable the Peripheral */
04012       __HAL_CRYP_ENABLE();
04013     
04014       /* Increment/decrement instance pointer/counter */
04015       if (hcryp->CrypInCount == 0U)
04016       {
04017         /* Case of no header */
04018         hcryp->State = HAL_CRYP_STATE_READY; 
04019         return HAL_OK;        
04020       }
04021       else if (hcryp->CrypInCount < 16U)
04022       {
04023         hcryp->CrypInCount = 0U;
04024         addhoc_process = 1U;  
04025         difflength = (uint32_t) (hcryp->Init.HeaderSize);
04026         difflengthmod4 = difflength%4U;              
04027       }
04028       else
04029       {
04030         hcryp->pCrypInBuffPtr += 16U;
04031         hcryp->CrypInCount -= 16U;
04032       }
04033 
04034 #if defined(AES_CR_NPBLB)    
04035       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
04036 #else     
04037       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
04038 #endif      
04039       { 
04040         if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
04041         {
04042           /* All B blocks will have been entered after the next
04043              four DINR writing, so point at header buffer for
04044              the next iteration */
04045           hcryp->pCrypInBuffPtr = hcryp->Init.Header;
04046         }
04047       }       
04048     
04049       /* Enter header first block to initiate the process
04050          in the Data Input register */
04051       if (addhoc_process == 0U)
04052       { 
04053         /* Header has size equal or larger than 128 bits */        
04054         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04055         inputaddr+=4U;
04056         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04057         inputaddr+=4U;
04058         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
04059         inputaddr+=4U;
04060         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04061       }
04062       else
04063       {
04064         /* Header has size less than 128 bits */ 
04065         /* Enter complete words when possible */
04066         for(index=0U; index < (difflength/4U); index ++)
04067         {
04068           /* Write the Input block in the Data Input register */
04069           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04070           inputaddr+=4U;
04071         }
04072         /* Enter incomplete word padded with zeroes if applicable 
04073           (case of header length not a multiple of 32-bits) */
04074         if (difflengthmod4 != 0U)
04075         {         
04076           hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
04077         }         
04078         /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
04079         for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)         
04080         {
04081           hcryp->Instance->DINR = 0U;
04082         }                 
04083       
04084       }
04085     }
04086     /*============================================*/
04087     /* GCM (or CCM when applicable) payload phase */
04088     /*============================================*/
04089     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
04090     {
04091       /* Get the buffer addresses and sizes */
04092       hcryp->CrypInCount = Size;
04093       hcryp->pCrypInBuffPtr = pInputData;
04094       hcryp->pCrypOutBuffPtr = pOutputData;
04095       hcryp->CrypOutCount = Size; 
04096     
04097       inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
04098       
04099       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCM_PAYLOAD_PHASE);
04100        
04101       /* if the header phase has been bypassed, AES must be enabled again */
04102       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
04103       {
04104         __HAL_CRYP_ENABLE();  
04105       }
04106     
04107      /* Specific handling to manage payload size less than 128 bits */
04108       if (Size < 16U)
04109       {
04110 #if defined(AES_CR_NPBLB)  
04111         /* In case of GCM encryption or CCM decryption, specify the number of padding
04112            bytes in last block of payload */
04113         if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
04114         {
04115           if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
04116                &&  (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))   
04117            ||  ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
04118                &&  (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
04119           {
04120             /* Set NPBLB field in writing the number of padding bytes 
04121                for the last block of payload */
04122             MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
04123           }
04124         }
04125 #else
04126         /* Software workaround applied to GCM encryption only */ 
04127         if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
04128         {
04129           /* Change the mode configured in CHMOD bits of CR register to select CTR mode */   
04130           __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
04131         } 
04132 #endif        
04133 
04134         /* Set hcryp->CrypInCount to 0 (no more data to enter) */ 
04135         hcryp->CrypInCount = 0U;  
04136 
04137         /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes, 
04138             to have a complete block of 128 bits */              
04139         difflength = (uint32_t) (Size);
04140         difflengthmod4 = difflength%4U;                 
04141         /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes 
04142             to have a complete block of 128 bits */
04143         for(index=0U; index < (difflength/4U); index ++)
04144         {
04145           /* Write the Input block in the Data Input register */
04146           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04147           inputaddr+=4U;
04148         }
04149         /* If required, manage input data size not multiple of 32 bits */
04150         if (difflengthmod4 != 0U)
04151         {         
04152           hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
04153         }         
04154         /* Wrap-up in padding with zero-words if applicable */
04155         for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)        
04156         {
04157           hcryp->Instance->DINR = 0U;
04158         }               
04159       }
04160       else
04161       {        
04162         /* Increment/decrement instance pointer/counter */
04163         hcryp->pCrypInBuffPtr += 16U;
04164         hcryp->CrypInCount -= 16U;
04165         
04166         /* Enter payload first block to initiate the process
04167            in the Data Input register */
04168         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04169         inputaddr+=4U;
04170         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04171         inputaddr+=4U;
04172         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
04173         inputaddr+=4U;
04174         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04175       }
04176     }
04177     /*====================================*/
04178     /* GCM/GMAC or (CCM/)CMAC final phase */
04179     /*====================================*/
04180     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
04181     {
04182        hcryp->pCrypOutBuffPtr = pOutputData;
04183        
04184 #if defined(AES_CR_NPBLB)   
04185      /* By default, clear NPBLB field */
04186       CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
04187 #endif         
04188        
04189        MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
04190        
04191       /* if the header and payload phases have been bypassed, AES must be enabled again */
04192       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
04193       {
04194         __HAL_CRYP_ENABLE();  
04195       }
04196       
04197       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
04198       {             
04199         headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
04200         inputlength = Size * 8U;                    /* Input length in bits */ 
04201         /* Write the number of bits in the header on 64 bits followed by the number
04202            of bits in the payload on 64 bits as well */
04203         if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
04204         {
04205           hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
04206           hcryp->Instance->DINR = __RBIT(headerlength);
04207           hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
04208           hcryp->Instance->DINR = __RBIT(inputlength);
04209         }
04210         else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
04211         {
04212           hcryp->Instance->DINR = __REV((headerlength)>>32U);
04213           hcryp->Instance->DINR = __REV(headerlength);
04214           hcryp->Instance->DINR = __REV((inputlength)>>32U);
04215           hcryp->Instance->DINR = __REV(inputlength);
04216         }
04217         else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
04218         {
04219           hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
04220           hcryp->Instance->DINR = __ROR(headerlength, 16U);
04221           hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
04222           hcryp->Instance->DINR = __ROR(inputlength, 16U);             
04223         }
04224         else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
04225         {
04226           hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
04227           hcryp->Instance->DINR = (uint32_t)(headerlength);
04228           hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
04229           hcryp->Instance->DINR = (uint32_t)(inputlength);
04230         }
04231       }
04232 #if !defined(AES_CR_NPBLB)         
04233       else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
04234       {
04235         inputaddr  = (uint32_t)pInputData;
04236         /* Enter the last block made of a 128-bit value formatted
04237            from the original B0 packet. */
04238         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04239         inputaddr+=4U;
04240         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04241         inputaddr+=4U;
04242         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
04243         inputaddr+=4U;
04244         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04245         inputaddr+=4U;
04246       }
04247 #endif      
04248     }
04249     /*=================================================*/
04250     /* case incorrect hcryp->Init.GCMCMACPhase setting */
04251     /*=================================================*/
04252     else
04253     {
04254       hcryp->State = HAL_CRYP_STATE_ERROR; 
04255       return HAL_ERROR;
04256     }
04257   
04258     return HAL_OK;
04259   }
04260   else
04261   {
04262     return HAL_BUSY;
04263   }
04264 }
04265 
04266 
04267 
04268 
04269 /**
04270   * @brief  Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering 
04271   *         operation according to hcryp->Init structure fields. 
04272   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04273   *         the configuration information for CRYP module
04274   * @param  pInputData 
04275   *         - pointer to payload data in GCM payload phase,
04276   *         - pointer to B0 block in CMAC header phase,
04277   *         - pointer to C block in CMAC final phase.
04278   *         - Parameter is meaningless in case of GCM/GMAC init, header and final phases.        
04279   * @param  Size 
04280   *         - length of the input payload data buffer in bytes,
04281   *         - length of B block (in bytes) in CMAC header phase,
04282   *         - length of C block (in bytes) in CMAC final phase.   
04283   *         - Parameter is meaningless in case of GCM/GMAC init and header phases.         
04284   * @param  pOutputData 
04285   *         - pointer to plain or cipher text in GCM payload phase,   
04286   *         - pointer to authentication tag in GCM/GMAC and CMAC final phases.
04287   *         - Parameter is meaningless in case of GCM/GMAC init and header phases
04288   *           and in case of CMAC header phase.
04289   * @note   Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
04290   * @note   Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes 
04291   *         can be skipped by the user if so required.
04292   * @note   pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.            
04293   * @retval HAL status
04294   */
04295 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
04296 {
04297   uint32_t inputaddr      = 0U;
04298   uint32_t outputaddr     = 0U;
04299   uint32_t tagaddr        = 0U;
04300   uint64_t headerlength   = 0U;
04301   uint64_t inputlength    = 0U;
04302   uint64_t payloadlength  = 0U;
04303        
04304   
04305   if (hcryp->State == HAL_CRYP_STATE_READY)
04306   {
04307     /* input/output parameters check */
04308     if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
04309     {
04310       if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
04311       {
04312         return  HAL_ERROR;
04313       }
04314 #if defined(AES_CR_NPBLB) 
04315       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
04316 #else       
04317       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
04318 #endif  
04319       {
04320         if ((pInputData == NULL) || (Size == 0U))
04321         {
04322           return  HAL_ERROR;
04323         }
04324       }      
04325     }
04326     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
04327     {   
04328       if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
04329       {
04330         return  HAL_ERROR;
04331       }
04332     }
04333     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
04334     {
04335       if (pOutputData == NULL)
04336       {
04337         return  HAL_ERROR;
04338       }
04339 #if defined(AES_CR_NPBLB)  
04340       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
04341 #else    
04342       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
04343 #endif 
04344       {
04345         return  HAL_ERROR;
04346       }
04347     }
04348 
04349     /* Process Locked */
04350     __HAL_LOCK(hcryp);
04351   
04352     /* Change the CRYP state */
04353     hcryp->State = HAL_CRYP_STATE_BUSY;
04354   
04355     /*==============================================*/
04356     /* GCM/GMAC (or CCM when applicable) init phase */
04357     /*==============================================*/
04358     /* In case of init phase, the input data (Key and Initialization Vector) have 
04359        already been entered during the initialization process. No DMA transfer is
04360        required at that point therefore, the software just waits for the CCF flag 
04361        to be raised. */
04362     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
04363     {
04364       /* just wait for hash computation */
04365       if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)  
04366       { 
04367         hcryp->State = HAL_CRYP_STATE_READY;        
04368         __HAL_UNLOCK(hcryp);
04369         return HAL_TIMEOUT;
04370       }
04371       
04372       /* Clear CCF Flag */
04373       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
04374       /* Mark that the initialization phase is over */
04375       hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
04376       hcryp->State = HAL_CRYP_STATE_READY;
04377     }
04378     /*===============================*/
04379     /* GCM/GMAC or CMAC header phase */
04380     /*===============================*/     
04381     else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
04382     {
04383       /* Set header phase; for GCM or GMAC, set data-byte at this point */
04384       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
04385       {
04386         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_GCMCMAC_HEADER_PHASE|hcryp->Init.DataType);
04387       }
04388       else
04389       {
04390         MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_HEADER_PHASE);
04391       }
04392       
04393 #if !defined(AES_CR_NPBLB)         
04394       /* enter first B0 block in polling mode (no DMA transfer for B0) */
04395       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
04396       {
04397          /* Enable the CRYP peripheral */
04398         __HAL_CRYP_ENABLE();
04399   
04400         inputaddr  = (uint32_t)pInputData;
04401         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04402         inputaddr+=4U;
04403         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04404         inputaddr+=4U;
04405         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
04406         inputaddr+=4U;
04407         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04408       
04409         if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)  
04410         { 
04411           hcryp->State = HAL_CRYP_STATE_READY;        
04412           __HAL_UNLOCK(hcryp);
04413           return HAL_TIMEOUT;
04414         }
04415         /* Clear CCF Flag */
04416         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
04417       }
04418 #endif      
04419       
04420       /* No header case */
04421       if (hcryp->Init.Header == NULL)
04422       {
04423         hcryp->State = HAL_CRYP_STATE_READY;   
04424         /* Mark that the header phase is over */
04425         hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER; 
04426         /* Process Unlocked */
04427         __HAL_UNLOCK(hcryp);
04428   
04429         return HAL_OK;             
04430       }
04431       
04432       inputaddr = (uint32_t)hcryp->Init.Header;
04433       if ((hcryp->Init.HeaderSize % 16U) != 0U)
04434       {
04435 
04436         if (hcryp->Init.HeaderSize < 16U)        
04437         {          
04438           CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);     
04439           
04440           hcryp->State = HAL_CRYP_STATE_READY;   
04441           /* Mark that the header phase is over */
04442           hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;  
04443           
04444           /* CCF flag indicating header phase AES processing completion 
04445              will be checked at the start of the next phase:
04446             - payload phase (GCM / CCM when applicable)
04447             - final phase (GMAC or CMAC).  */                     
04448         }
04449         else
04450         {
04451           /* Local variable headerlength is a number of bytes multiple of 128 bits,
04452             remaining header data (if any) are handled after this loop */
04453           headerlength =  (((hcryp->Init.HeaderSize)/16U)*16U) ;         
04454           /* Store the ending transfer point */
04455           hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
04456           hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */
04457         
04458           /* Set the input and output addresses and start DMA transfer */ 
04459           /* (incomplete DMA transfer, will be wrapped up after completion of
04460              the first one (initiated here) with data padding */
04461           CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, headerlength, 0U);
04462         }                          
04463       }
04464       else
04465       {
04466         hcryp->CrypInCount = 0U;
04467         /* Set the input address and start DMA transfer */ 
04468         CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, hcryp->Init.HeaderSize, 0U);            
04469       }
04470 
04471     }
04472     /*============================================*/
04473     /* GCM (or CCM when applicable) payload phase */
04474     /*============================================*/
04475     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
04476     {
04477       /* Coming from header phase, wait for CCF flag to be raised 
04478           if header present and fed to the IP in the previous phase */
04479       if (hcryp->Init.Header != NULL)
04480       {
04481         if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)  
04482         { 
04483           hcryp->State = HAL_CRYP_STATE_READY;        
04484           __HAL_UNLOCK(hcryp);
04485           return HAL_TIMEOUT;
04486         }
04487       }
04488       else
04489       {
04490         /* Enable the Peripheral since wasn't in header phase (no header case) */
04491         __HAL_CRYP_ENABLE();
04492       }
04493       /* Clear CCF Flag */
04494       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);     
04495     
04496       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
04497       
04498       /* Specific handling to manage payload size less than 128 bits */ 
04499       if ((Size % 16U) != 0U)
04500       {
04501         inputaddr  = (uint32_t)pInputData;
04502         outputaddr = (uint32_t)pOutputData;      
04503         if (Size < 16U)
04504         {
04505           /* Block is now entered in polling mode, no actual gain in resorting to DMA */
04506           hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
04507           hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
04508             
04509           CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON); 
04510           
04511           /* Change the CRYP state to ready */
04512           hcryp->State = HAL_CRYP_STATE_READY;
04513           /* Mark that the payload phase is over */
04514           hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 
04515   
04516           /* Call output data transfer complete callback */
04517           HAL_CRYP_OutCpltCallback(hcryp);
04518         }
04519         else
04520         {
04521           payloadlength = (Size/16U) * 16U;          
04522           
04523           /* Store the ending transfer points */
04524           hcryp->pCrypInBuffPtr = pInputData + payloadlength;
04525           hcryp->pCrypOutBuffPtr = pOutputData + payloadlength;
04526           hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */
04527         
04528           /* Set the input and output addresses and start DMA transfer */ 
04529           /* (incomplete DMA transfer, will be wrapped up with data padding  
04530              after completion of the one initiated here) */
04531           CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, payloadlength, outputaddr);                      
04532         }
04533       }
04534       else
04535       { 
04536         hcryp->CrypInCount = 0U;                          
04537         inputaddr  = (uint32_t)pInputData;
04538         outputaddr = (uint32_t)pOutputData;
04539         
04540         /* Set the input and output addresses and start DMA transfer */ 
04541         CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);         
04542       }  
04543     }
04544     /*====================================*/
04545     /* GCM/GMAC or (CCM/)CMAC final phase */
04546     /*====================================*/
04547     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
04548     {
04549       /* If coming from header phase (GMAC or CMAC case), 
04550          wait for CCF flag to be raised */
04551       if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE)
04552       {   
04553         if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)  
04554         { 
04555           hcryp->State = HAL_CRYP_STATE_READY;        
04556           __HAL_UNLOCK(hcryp);
04557           return HAL_TIMEOUT;
04558         }
04559         /* Clear CCF Flag */
04560         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
04561       }        
04562       
04563       tagaddr = (uint32_t)pOutputData;
04564       
04565       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
04566       
04567       /* if the header and payload phases have been bypassed, AES must be enabled again */
04568       if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
04569       {
04570         __HAL_CRYP_ENABLE();  
04571       }
04572       
04573       if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
04574       {
04575         headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
04576         inputlength = Size * 8U;  /* input length in bits */ 
04577         /* Write the number of bits in the header on 64 bits followed by the number
04578            of bits in the payload on 64 bits as well */
04579         if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
04580         {
04581           hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
04582           hcryp->Instance->DINR = __RBIT(headerlength);
04583           hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
04584           hcryp->Instance->DINR = __RBIT(inputlength);
04585         }
04586         else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
04587         {
04588           hcryp->Instance->DINR = __REV((headerlength)>>32U);
04589           hcryp->Instance->DINR = __REV(headerlength);
04590           hcryp->Instance->DINR = __REV((inputlength)>>32U);
04591           hcryp->Instance->DINR = __REV(inputlength);
04592         }
04593         else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
04594         {
04595           hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
04596           hcryp->Instance->DINR = __ROR(headerlength, 16U);
04597           hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
04598           hcryp->Instance->DINR = __ROR(inputlength, 16U);            
04599         }
04600         else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
04601         {
04602           hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
04603           hcryp->Instance->DINR = (uint32_t)(headerlength);
04604           hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
04605           hcryp->Instance->DINR = (uint32_t)(inputlength);
04606         }
04607       }
04608 #if !defined(AES_CR_NPBLB)           
04609       else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
04610       {
04611         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
04612         
04613         inputaddr  = (uint32_t)pInputData;
04614         /* Enter the last block made of a 128-bit value formatted
04615            from the original B0 packet. */
04616         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04617         inputaddr+=4U;
04618         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04619         inputaddr+=4U;
04620         hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
04621         inputaddr+=4U;
04622         hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
04623         inputaddr+=4U;
04624       }
04625 #endif      
04626       
04627       /* No DMA transfer is required at that point therefore, the software 
04628          just waits for the CCF flag to be raised. */
04629       if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)  
04630       { 
04631           hcryp->State = HAL_CRYP_STATE_READY;        
04632           __HAL_UNLOCK(hcryp);
04633           return HAL_TIMEOUT;
04634       }
04635       /* Clear CCF Flag */
04636       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
04637       /* Read the Auth TAG in the IN FIFO */
04638       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
04639       tagaddr+=4U;
04640       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
04641       tagaddr+=4U;
04642       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
04643       tagaddr+=4U;
04644       *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
04645   
04646       /* Mark that the final phase is over */
04647       hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
04648       hcryp->State = HAL_CRYP_STATE_READY;
04649       /* Disable the Peripheral */
04650       __HAL_CRYP_DISABLE();
04651     }
04652     /*=================================================*/
04653     /* case incorrect hcryp->Init.GCMCMACPhase setting */
04654     /*=================================================*/
04655     else
04656     {
04657       hcryp->State = HAL_CRYP_STATE_ERROR;
04658       __HAL_UNLOCK(hcryp); 
04659       return HAL_ERROR;
04660     }    
04661   
04662     /* Process Unlocked */
04663     __HAL_UNLOCK(hcryp);
04664   
04665     return HAL_OK;
04666   }
04667   else
04668   {
04669     return HAL_BUSY;
04670   }
04671 }
04672 
04673 /**
04674   * @}
04675   */
04676 
04677 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions 
04678  *  @brief   Extended processing functions. 
04679  *
04680 @verbatim   
04681   ==============================================================================
04682                     ##### AES extended suspension and resumption functions #####
04683   ==============================================================================  
04684     [..]  This section provides functions allowing to:
04685       (+) save in memory the Initialization Vector, the Key registers, the Control register or
04686           the Suspend registers when a process is suspended by a higher priority message
04687       (+) write back in CRYP hardware block the saved values listed above when the suspended
04688           lower priority message processing is resumed.     
04689 
04690 @endverbatim
04691   * @{
04692   */
04693 
04694 
04695 /**
04696   * @brief  In case of message processing suspension, read the Initialization Vector. 
04697   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04698   *         the configuration information for CRYP module.    
04699   * @param  Output Pointer to the buffer containing the saved Initialization Vector.
04700   * @note   This value has to be stored for reuse by writing the AES_IVRx registers
04701   *         as soon as the interrupted processing has to be resumed.
04702   *         Applicable to all chaining modes.    
04703   * @note   AES must be disabled when reading or resetting the IV values.   
04704   * @retval None
04705   */
04706 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
04707 {
04708   uint32_t outputaddr = (uint32_t)Output;
04709     
04710   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
04711   outputaddr+=4U;
04712   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
04713   outputaddr+=4U;
04714   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
04715   outputaddr+=4U;
04716   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
04717 }
04718 
04719 /**
04720   * @brief  In case of message processing resumption, rewrite the Initialization
04721   *         Vector in the AES_IVRx registers.
04722   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04723   *         the configuration information for CRYP module.      
04724   * @param  Input Pointer to the buffer containing the saved Initialization Vector to
04725   *         write back in the CRYP hardware block. 
04726   * @note   Applicable to all chaining modes.       
04727   * @note   AES must be disabled when reading or resetting the IV values.     
04728   * @retval None
04729   */
04730 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
04731 {
04732   uint32_t ivaddr = (uint32_t)Input;
04733   
04734   hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
04735   ivaddr+=4U;
04736   hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
04737   ivaddr+=4U;
04738   hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
04739   ivaddr+=4U;
04740   hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
04741 }
04742 
04743 
04744 /**
04745   * @brief  In case of message GCM/GMAC or CMAC processing suspension, read the Suspend Registers.
04746   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04747   *         the configuration information for CRYP module.  
04748   * @param  Output Pointer to the buffer containing the saved Suspend Registers.
04749   * @note   These values have to be stored for reuse by writing back the AES_SUSPxR registers
04750   *         as soon as the interrupted processing has to be resumed.       
04751   * @retval None
04752   */
04753 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
04754 {
04755   uint32_t outputaddr = (uint32_t)Output;
04756   
04757   /* In case of GCM payload phase encryption, check that suspension can be carried out */
04758   if (READ_BIT(hcryp->Instance->CR, (AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_GCM_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
04759   {
04760     /* Ensure that Busy flag is reset */
04761     if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)  
04762     { 
04763       hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
04764       hcryp->State = HAL_CRYP_STATE_ERROR;
04765               
04766       /* Process Unlocked */
04767       __HAL_UNLOCK(hcryp);  
04768     
04769       HAL_CRYP_ErrorCallback(hcryp);
04770       return ;
04771     }
04772   } 
04773     
04774   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
04775   outputaddr+=4U;
04776   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
04777   outputaddr+=4U;
04778   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
04779   outputaddr+=4U;
04780   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
04781   outputaddr+=4U;
04782   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
04783   outputaddr+=4U;
04784   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
04785   outputaddr+=4U;
04786   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R); 
04787   outputaddr+=4U;
04788   *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);   
04789 }
04790 
04791 /**
04792   * @brief  In case of message GCM/GMAC or CMAC processing resumption, rewrite the Suspend
04793   *         Registers in the AES_SUSPxR registers.
04794   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04795   *         the configuration information for CRYP module.    
04796   * @param  Input Pointer to the buffer containing the saved suspend registers to
04797   *         write back in the CRYP hardware block. 
04798   * @retval None
04799   */
04800 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
04801 {
04802   uint32_t ivaddr = (uint32_t)Input;
04803   
04804   hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
04805   ivaddr+=4U;
04806   hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
04807   ivaddr+=4U;
04808   hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
04809   ivaddr+=4U;
04810   hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
04811   ivaddr+=4U;
04812   hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
04813   ivaddr+=4U;
04814   hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
04815   ivaddr+=4U;
04816   hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
04817   ivaddr+=4U;
04818   hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));  
04819 }
04820 
04821 
04822 /**
04823   * @brief  In case of message GCM/GMAC or CMAC processing suspension, read the Key Registers.
04824   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04825   *         the configuration information for CRYP module.   
04826   * @param  Output Pointer to the buffer containing the saved Key Registers. 
04827   * @param  KeySize Indicates the key size (128 or 256 bits).
04828   * @note   These values have to be stored for reuse by writing back the AES_KEYRx registers
04829   *         as soon as the interrupted processing has to be resumed.           
04830   * @retval None
04831   */
04832 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
04833 {
04834   uint32_t keyaddr = (uint32_t)Output;
04835   
04836   if (KeySize == CRYP_KEYSIZE_256B)
04837   {
04838     *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
04839     keyaddr+=4U;
04840     *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
04841     keyaddr+=4U;
04842     *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
04843     keyaddr+=4U;
04844     *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
04845     keyaddr+=4U;                 
04846   }  
04847   
04848   *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
04849   keyaddr+=4U;
04850   *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
04851   keyaddr+=4U;
04852   *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
04853   keyaddr+=4U;
04854   *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0); 
04855 }
04856 
04857 /**
04858   * @brief  In case of message GCM/GMAC or CMAC processing resumption, rewrite the Key
04859   *         Registers in the AES_KEYRx registers.
04860   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04861   *         the configuration information for CRYP module.   
04862   * @param  Input Pointer to the buffer containing the saved key registers to
04863   *         write back in the CRYP hardware block. 
04864   * @param  KeySize Indicates the key size (128 or 256 bits)     
04865   * @retval None
04866   */
04867 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
04868 {  
04869   uint32_t keyaddr = (uint32_t)Input;
04870   
04871   if (KeySize == CRYP_KEYSIZE_256B)
04872   {
04873     hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
04874     keyaddr+=4U;
04875     hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
04876     keyaddr+=4U;
04877     hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
04878     keyaddr+=4U;
04879     hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
04880     keyaddr+=4U;      
04881   }  
04882   
04883     hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
04884     keyaddr+=4U;
04885     hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
04886     keyaddr+=4U;
04887     hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
04888     keyaddr+=4U;
04889     hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));    
04890 }
04891 
04892 
04893 /**
04894   * @brief  In case of message GCM/GMAC or CMAC processing suspension, read the Control Register.
04895   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04896   *         the configuration information for CRYP module.   
04897   * @param  Output Pointer to the buffer containing the saved Control Register.
04898   * @note   This values has to be stored for reuse by writing back the AES_CR register
04899   *         as soon as the interrupted processing has to be resumed.          
04900   * @retval None
04901   */
04902 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
04903 {
04904   *(uint32_t*)(Output) = hcryp->Instance->CR;    
04905 }
04906 
04907 /**
04908   * @brief  In case of message GCM/GMAC or CMAC processing resumption, rewrite the Control
04909   *         Registers in the AES_CR register.
04910   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04911   *         the configuration information for CRYP module.   
04912   * @param  Input Pointer to the buffer containing the saved Control Register to
04913   *         write back in the CRYP hardware block.   
04914   * @retval None
04915   */
04916 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
04917 {  
04918   hcryp->Instance->CR = *(uint32_t*)(Input);
04919   /* At the same time, set handle state back to READY to be able to resume the AES calculations 
04920      without the processing APIs returning HAL_BUSY when called. */
04921   hcryp->State        = HAL_CRYP_STATE_READY;
04922 }
04923 
04924 /**
04925   * @brief  Request CRYP processing suspension when in polling or interruption mode.
04926   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
04927   *         the configuration information for CRYP module. 
04928   * @note   Set the handle field SuspendRequest to the appropriate value so that 
04929   *         the on-going CRYP processing is suspended as soon as the required 
04930   *         conditions are met.
04931   * @note   It is advised not to suspend the CRYP processing when the DMA controller 
04932   *         is managing the data transfer     
04933   * @retval None
04934   */
04935 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)  
04936 {
04937   /* Set Handle Suspend Request field */
04938   hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
04939 }
04940 
04941 /**
04942   * @}
04943   */
04944 
04945 /**
04946   * @}
04947   */
04948 
04949 /** @addtogroup CRYPEx_Private_Functions
04950   * @{
04951   */
04952 
04953 /**
04954   * @brief  DMA CRYP Input Data process complete callback
04955   *         for GCM, GMAC or CMAC chainging modes.
04956   * @note   Specific setting of hcryp fields are required only
04957   *         in the case of header phase where no output data DMA
04958   *         transfer is on-going (only input data transfer is enabled
04959   *         in such a case).      
04960   * @param  hdma DMA handle.
04961   * @retval None
04962   */
04963 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma)  
04964 {
04965   uint32_t difflength = 0U;
04966   
04967   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
04968   
04969   /* Disable the DMA transfer for input request  */
04970   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
04971 
04972   if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
04973   { 
04974   
04975     if (hcryp->CrypInCount != 0U)
04976     {
04977       /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
04978       difflength = hcryp->CrypInCount;
04979       hcryp->CrypInCount = 0U;
04980       
04981       CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);      
04982     }
04983     hcryp->State = HAL_CRYP_STATE_READY;   
04984     /* Mark that the header phase is over */
04985     hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
04986   }
04987   /* CCF flag indicating header phase AES processing completion 
04988      will be checked at the start of the next phase:
04989      - payload phase (GCM or CCM when applicable)
04990      - final phase (GMAC or CMAC).
04991     This allows to avoid the Wait on Flag within the IRQ handling.  */
04992   
04993   /* Call input data transfer complete callback */
04994   HAL_CRYP_InCpltCallback(hcryp);
04995 }
04996 
04997 /**
04998   * @brief  DMA CRYP Output Data process complete callback
04999   *         for GCM, GMAC or CMAC chainging modes.
05000   * @note   This callback is called only in the payload phase.  
05001   * @param  hdma DMA handle.
05002   * @retval None
05003   */
05004 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma)
05005 {
05006   uint32_t difflength = 0U;
05007   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
05008   
05009   /* Disable the DMA transfer for output request */
05010   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
05011 
05012   /* Clear CCF Flag */
05013   __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05014   
05015   /* Initiate additional transfer to wrap-up data feeding to the IP */
05016   if (hcryp->CrypInCount != 0U)
05017   {
05018     /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
05019     difflength = hcryp->CrypInCount;
05020     hcryp->CrypInCount = 0U;
05021     
05022     CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON); 
05023   }  
05024   
05025   /* Change the CRYP state to ready */
05026   hcryp->State = HAL_CRYP_STATE_READY;
05027   /* Mark that the payload phase is over */
05028   hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER; 
05029   
05030   /* Call output data transfer complete callback */
05031   HAL_CRYP_OutCpltCallback(hcryp);
05032 }
05033 
05034 /**
05035   * @brief  DMA CRYP communication error callback
05036   *         for GCM, GMAC or CMAC chainging modes.
05037   * @param  hdma DMA handle
05038   * @retval None
05039   */
05040 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma)
05041 {
05042   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
05043   
05044   hcryp->State= HAL_CRYP_STATE_ERROR;
05045   hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
05046   HAL_CRYP_ErrorCallback(hcryp);
05047   /* Clear Error Flag */
05048   __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR);
05049 }
05050 
05051 /** 
05052   * @brief  Handle CRYP block input/output data handling under interruption
05053   *         for GCM, GMAC or CMAC chaining modes.  
05054   * @note   The function is called under interruption only, once
05055   *         interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().  
05056   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
05057   *         the configuration information for CRYP module
05058   * @retval HAL status
05059   */
05060 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
05061 {
05062   uint32_t inputaddr   = 0x0U;
05063   uint32_t outputaddr  = 0x0U; 
05064   uint32_t index       = 0x0U;
05065   uint32_t addhoc_process = 0U; 
05066   uint32_t difflength     = 0U;
05067   uint32_t difflengthmod4 = 0U;
05068   uint32_t mask[3]        = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
05069   uint32_t intermediate_data[4U] = {0U};        
05070   
05071   if(hcryp->State == HAL_CRYP_STATE_BUSY)
05072   {
05073     /*===========================*/
05074     /* GCM/GMAC(/CCM) init phase */
05075     /*===========================*/  
05076     if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
05077     {
05078       /* Clear Computation Complete Flag */
05079       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05080       /* Disable Computation Complete Flag and Errors Interrupts */
05081       __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
05082       /* Change the CRYP state */
05083       hcryp->State = HAL_CRYP_STATE_READY;
05084     
05085       /* Mark that the initialization phase is over */
05086       hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
05087           
05088       /* Process Unlocked */
05089       __HAL_UNLOCK(hcryp);
05090       /* Call computation complete callback */
05091       HAL_CRYPEx_ComputationCpltCallback(hcryp);
05092       return HAL_OK;
05093     }
05094     /*=====================================*/
05095     /* GCM/GMAC or (CCM/)CMAC header phase */
05096     /*=====================================*/   
05097     else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
05098     {
05099       /* Check if all input header data have been entered */
05100       if (hcryp->CrypInCount == 0U)
05101       {
05102         /* Clear Computation Complete Flag */
05103         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05104         /* Disable Computation Complete Flag and Errors Interrupts */
05105         __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
05106         /* Change the CRYP state */
05107         hcryp->State = HAL_CRYP_STATE_READY;
05108        /* Mark that the header phase is over */
05109         hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
05110       
05111        /* Process Unlocked */
05112         __HAL_UNLOCK(hcryp);
05113       
05114         /* Call computation complete callback */
05115         HAL_CRYPEx_ComputationCpltCallback(hcryp);
05116       
05117         return HAL_OK;
05118       }
05119       /* If suspension flag has been raised, suspend processing */
05120       else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
05121       {
05122         /* Clear CCF Flag */
05123         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05124        
05125         /* reset SuspendRequest */
05126         hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
05127         /* Disable Computation Complete Flag and Errors Interrupts */
05128         __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
05129         /* Change the CRYP state */
05130         hcryp->State = HAL_CRYP_STATE_SUSPENDED;
05131         /* Mark that the header phase is over */
05132         hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
05133       
05134        /* Process Unlocked */
05135         __HAL_UNLOCK(hcryp);
05136       
05137         return HAL_OK;
05138       }      
05139       else /* Carry on feeding input data to the CRYP hardware block */
05140       {
05141         /* Clear Computation Complete Flag */
05142         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05143         /* Get the last Input data address */
05144         inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
05145       
05146         /* Increment/decrement instance pointer/counter */
05147         if (hcryp->CrypInCount < 16U)
05148         {
05149           difflength = hcryp->CrypInCount;        
05150           hcryp->CrypInCount = 0U;
05151           addhoc_process = 1U;  
05152           difflengthmod4 = difflength%4U;              
05153         }
05154         else
05155         {
05156           hcryp->pCrypInBuffPtr += 16U;
05157           hcryp->CrypInCount -= 16U;
05158         }        
05159         
05160 #if defined(AES_CR_NPBLB)    
05161         if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
05162 #else     
05163         if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
05164 #endif         
05165         { 
05166           if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
05167           {
05168             /* All B blocks will have been entered after the next
05169               four DINR writing, so point at header buffer for
05170               the next iteration */
05171             hcryp->pCrypInBuffPtr = hcryp->Init.Header;
05172           }
05173         }           
05174       
05175         /* Write the Input block in the Data Input register */
05176         if (addhoc_process == 0U)
05177         {         
05178           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05179           inputaddr+=4U;
05180           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05181           inputaddr+=4U;
05182           hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
05183           inputaddr+=4U;
05184           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05185         }
05186         else
05187         {
05188           /* Header remainder has size less than 128 bits */ 
05189           /* Enter complete words when possible */
05190           for(index=0U; index < (difflength/4U); index ++)
05191           {
05192             /* Write the Input block in the Data Input register */
05193             hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05194             inputaddr+=4U;
05195           }
05196           /* Enter incomplete word padded with zeroes if applicable 
05197             (case of header length not a multiple of 32-bits) */
05198           if (difflengthmod4 != 0U)
05199           {         
05200             hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
05201           }         
05202           /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
05203           for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)         
05204           {
05205             hcryp->Instance->DINR = 0U;
05206           }          
05207         }
05208       
05209         return HAL_OK;      
05210       }
05211     }
05212     /*=======================*/
05213     /* GCM/CCM payload phase */
05214     /*=======================*/    
05215     else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
05216     {
05217       /* Get the last output data address */
05218       outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
05219       
05220      /* Specific handling to manage payload size less than 128 bits
05221         when GCM (or CCM when applicable) encryption or decryption is selected.
05222         Check here if the last block output data are read */
05223 #if defined(AES_CR_NPBLB)  
05224       if ((hcryp->CrypOutCount < 16U)                                && \
05225           (hcryp->CrypOutCount > 0U))
05226 #else    
05227       if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
05228           (hcryp->CrypOutCount < 16U)                                && \
05229           (hcryp->CrypOutCount > 0U))
05230 #endif          
05231       {
05232         addhoc_process = 1U;
05233         difflength = hcryp->CrypOutCount;
05234         difflengthmod4 = difflength%4U; 
05235         hcryp->CrypOutCount = 0U;   /* mark that no more output data will be needed */       
05236         /* Retrieve intermediate data */
05237         for(index=0U; index < 4U; index ++)
05238         {
05239           intermediate_data[index] = hcryp->Instance->DOUTR;                 
05240         } 
05241         /* Retrieve last words of cyphered data */
05242         /* First, retrieve complete output words */
05243         for(index=0U; index < (difflength/4U); index ++)
05244         {
05245           *(uint32_t*)(outputaddr) = intermediate_data[index];
05246           outputaddr+=4U; 
05247         } 
05248         /* Next, retrieve partial output word if applicable;
05249            at the same time, start masking intermediate data 
05250            with a mask of zeros of same size than the padding
05251            applied to the last block of payload */ 
05252         if (difflengthmod4 != 0U)
05253         {
05254           intermediate_data[difflength/4U] &= mask[difflengthmod4-1U];
05255           *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];            
05256         }           
05257    
05258 #if !defined(AES_CR_NPBLB)       
05259         if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
05260         { 
05261           /* Change again CHMOD configuration to GCM mode */
05262           __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC); 
05263         
05264           /* Select FINAL phase */
05265           MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);  
05266         
05267           /* Before inserting the intermediate data, carry on masking operation
05268              with a mask of zeros of same size than the padding applied to the last block of payload */
05269           for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)        
05270           {
05271             intermediate_data[(difflength+3U)/4U+index] = 0U;
05272           }  
05273         
05274           /* Insert intermediate data to trigger an additional DOUTR reading round */
05275           /* Clear Computation Complete Flag before entering new block */
05276           __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05277           for(index=0U; index < 4U; index ++)
05278           {
05279             hcryp->Instance->DINR = intermediate_data[index];          
05280           }
05281         }
05282         else
05283 #endif        
05284         {
05285           /* Payload phase is now over */
05286           /* Clear Computation Complete Flag */
05287           __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);        
05288           /* Disable Computation Complete Flag and Errors Interrupts */
05289           __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
05290           /* Change the CRYP state */
05291           hcryp->State = HAL_CRYP_STATE_READY;
05292           /* Mark that the payload phase is over */
05293           hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
05294       
05295           /* Process Unlocked */
05296           __HAL_UNLOCK(hcryp);
05297       
05298           /* Call computation complete callback */
05299           HAL_CRYPEx_ComputationCpltCallback(hcryp);
05300         }
05301         return HAL_OK;
05302       }
05303       else  
05304       { 
05305         if (hcryp->CrypOutCount != 0U)
05306         { 
05307           /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */ 
05308           /* Retrieve the last block available from the CRYP hardware block:
05309             read the output block from the Data Output Register */
05310           *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05311           outputaddr+=4U;
05312           *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05313           outputaddr+=4U;
05314           *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05315           outputaddr+=4U;
05316           *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05317           
05318           /* Increment/decrement instance pointer/counter */
05319           hcryp->pCrypOutBuffPtr += 16U;
05320           hcryp->CrypOutCount -= 16U;                    
05321         }
05322 #if !defined(AES_CR_NPBLB)          
05323         else
05324         {          
05325           /* Software work-around: additional DOUTR reading round to discard the data */
05326           for(index=0U; index < 4U; index ++)
05327           {
05328             intermediate_data[index] = hcryp->Instance->DOUTR;                 
05329           }          
05330         }
05331 #endif         
05332       }            
05333       
05334       /* Check if all output text has been retrieved */
05335       if (hcryp->CrypOutCount == 0U)
05336       {
05337 #if !defined(AES_CR_NPBLB)       
05338         /* Make sure that software-work around is not running before disabling
05339           the interruptions (indeed, if software work-around is running, the 
05340           interruptions must not be disabled to allow the additional DOUTR 
05341           reading round */
05342         if (addhoc_process == 0U)
05343 #endif        
05344         {
05345           /* Clear Computation Complete Flag */
05346           __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);        
05347           /* Disable Computation Complete Flag and Errors Interrupts */
05348           __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
05349           /* Change the CRYP state */
05350           hcryp->State = HAL_CRYP_STATE_READY;
05351          /* Mark that the payload phase is over */
05352           hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
05353       
05354          /* Process Unlocked */
05355           __HAL_UNLOCK(hcryp);
05356       
05357           /* Call computation complete callback */
05358           HAL_CRYPEx_ComputationCpltCallback(hcryp);
05359         }
05360       
05361         return HAL_OK;
05362       }
05363       /* If suspension flag has been raised, suspend processing */
05364       else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
05365       {     
05366         /* Clear CCF Flag */
05367         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05368        
05369         /* reset SuspendRequest */
05370         hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
05371         /* Disable Computation Complete Flag and Errors Interrupts */
05372         __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
05373         /* Change the CRYP state */
05374         hcryp->State = HAL_CRYP_STATE_SUSPENDED;
05375         /* Mark that the header phase is over */
05376         hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
05377       
05378        /* Process Unlocked */
05379         __HAL_UNLOCK(hcryp);
05380       
05381         return HAL_OK;
05382       }            
05383       else /* Output data are still expected, carry on feeding the CRYP
05384                hardware block with input data */
05385       {
05386         /* Clear Computation Complete Flag */
05387         __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);          
05388         /* Get the last Input data address */
05389         inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
05390       
05391         /* Usual input data feeding case */
05392         if (hcryp->CrypInCount < 16U)
05393         {
05394           difflength = (uint32_t) (hcryp->CrypInCount);
05395           difflengthmod4 = difflength%4U;
05396           hcryp->CrypInCount = 0U; 
05397           
05398 #if defined(AES_CR_NPBLB)  
05399           /* In case of GCM encryption or CCM decryption, specify the number of padding
05400              bytes in last block of payload */
05401                if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
05402                     &&  (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))   
05403                 ||  ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
05404                     &&  (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
05405                {
05406                  /* Set NPBLB field in writing the number of padding bytes 
05407                     for the last block of payload */
05408                  MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
05409                }
05410 #else          
05411           /* Software workaround applied to GCM encryption only */ 
05412           if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
05413           {
05414             /* Change the mode configured in CHMOD bits of CR register to select CTR mode */   
05415             __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
05416           }   
05417 #endif                   
05418           
05419           /*  Insert the last block (which size is inferior to 128 bits) padded with zeroes 
05420               to have a complete block of 128 bits */
05421           for(index=0U; index < (difflength/4U); index ++)
05422           {
05423             /* Write the Input block in the Data Input register */
05424             hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05425             inputaddr+=4U;
05426           }
05427           /* If required, manage input data size not multiple of 32 bits */
05428           if (difflengthmod4 != 0U)
05429           {         
05430             hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
05431           }         
05432           /* Wrap-up in padding with zero-words if applicable */
05433           for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)        
05434           {
05435             hcryp->Instance->DINR = 0U;
05436           }                                                               
05437         }
05438         else
05439         {
05440           hcryp->pCrypInBuffPtr += 16U;
05441           hcryp->CrypInCount -= 16U;
05442           
05443           /* Write the Input block in the Data Input register */
05444           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05445           inputaddr+=4U;
05446           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05447           inputaddr+=4U;
05448           hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
05449           inputaddr+=4U;
05450           hcryp->Instance->DINR = *(uint32_t*)(inputaddr);            
05451         }            
05452 
05453         return HAL_OK;      
05454       }
05455     }
05456     /*====================================*/
05457     /* GCM/GMAC or (CCM/)CMAC final phase */
05458     /*====================================*/  
05459     else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
05460     {
05461       /* Clear Computation Complete Flag */
05462       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);  
05463             
05464       /* Get the last output data address */
05465       outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
05466       
05467       /* Retrieve the last expected data from the CRYP hardware block:
05468          read the output block from the Data Output Register */
05469       *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05470       outputaddr+=4U;
05471       *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05472       outputaddr+=4U;
05473       *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05474       outputaddr+=4U;
05475       *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05476   
05477       /* Disable Computation Complete Flag and Errors Interrupts */
05478       __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
05479       /* Change the CRYP state */
05480       hcryp->State = HAL_CRYP_STATE_READY;
05481       /* Mark that the header phase is over */
05482       hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
05483       
05484       /* Disable the Peripheral */
05485       __HAL_CRYP_DISABLE();
05486       /* Process Unlocked */
05487        __HAL_UNLOCK(hcryp);
05488       
05489       /* Call computation complete callback */
05490       HAL_CRYPEx_ComputationCpltCallback(hcryp);
05491       
05492       return HAL_OK;
05493     }
05494     else
05495     {
05496       /* Clear Computation Complete Flag */
05497       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);       
05498       hcryp->State = HAL_CRYP_STATE_ERROR; 
05499       __HAL_UNLOCK(hcryp); 
05500       return HAL_ERROR; 
05501     }
05502   }
05503   else
05504   {
05505     return HAL_BUSY; 
05506   }  
05507 }
05508 
05509 /** 
05510   * @brief  Set the DMA configuration and start the DMA transfer
05511   *         for GCM, GMAC or CMAC chainging modes.   
05512   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
05513   *         the configuration information for CRYP module.
05514   * @param  inputaddr Address of the Input buffer.
05515   * @param  Size Size of the Input buffer un bytes, must be a multiple of 16.
05516   * @param  outputaddr Address of the Output buffer, null pointer when no output DMA stream
05517   *         has to be configured.  
05518   * @retval None
05519   */
05520 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
05521 {
05522 
05523   /* Set the input CRYP DMA transfer complete callback */
05524   hcryp->hdmain->XferCpltCallback = CRYP_GCMCMAC_DMAInCplt;
05525   /* Set the DMA error callback */
05526   hcryp->hdmain->XferErrorCallback = CRYP_GCMCMAC_DMAError;
05527   
05528   if (outputaddr != 0U) 
05529   { 
05530     /* Set the output CRYP DMA transfer complete callback */
05531     hcryp->hdmaout->XferCpltCallback = CRYP_GCMCMAC_DMAOutCplt;
05532     /* Set the DMA error callback */
05533     hcryp->hdmaout->XferErrorCallback = CRYP_GCMCMAC_DMAError;
05534   }
05535   
05536   /* Enable the CRYP peripheral */
05537   __HAL_CRYP_ENABLE();
05538   
05539   /* Enable the DMA input stream */
05540   HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4U);
05541   
05542   /* Enable the DMA input request */
05543   SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
05544 
05545   
05546   if (outputaddr != 0U) 
05547   {   
05548     /* Enable the DMA output stream */
05549     HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4U);
05550   
05551     /* Enable the DMA output request */
05552     SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
05553   }
05554 }  
05555 
05556 /**
05557   * @brief  Write/read input/output data in polling mode.
05558   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
05559   *         the configuration information for CRYP module.
05560   * @param  Input Pointer to the Input buffer.
05561   * @param  Ilength Length of the Input buffer in bytes, must be a multiple of 16.
05562   * @param  Output Pointer to the returned buffer.
05563   * @param  Timeout Specify Timeout value.  
05564   * @retval HAL status
05565   */
05566 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
05567 {
05568   uint32_t index = 0U;
05569   uint32_t inputaddr  = (uint32_t)Input;
05570   uint32_t outputaddr = (uint32_t)Output;
05571   
05572 
05573   for(index=0U; (index < Ilength); index += 16U)
05574   {
05575     /* Write the Input block in the Data Input register */
05576     hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05577     inputaddr+=4U;
05578     hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05579     inputaddr+=4U;
05580     hcryp->Instance->DINR  = *(uint32_t*)(inputaddr);
05581     inputaddr+=4U;
05582     hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05583     inputaddr+=4U;
05584     
05585     /* Wait for CCF flag to be raised */
05586     if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)  
05587     { 
05588       hcryp->State = HAL_CRYP_STATE_READY;        
05589       __HAL_UNLOCK(hcryp);
05590       return HAL_TIMEOUT;
05591     }
05592       
05593     /* Clear CCF Flag */
05594     __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05595     
05596     /* Read the Output block from the Data Output Register */
05597     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05598     outputaddr+=4U;
05599     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05600     outputaddr+=4U;
05601     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05602     outputaddr+=4U;
05603     *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
05604     outputaddr+=4U;
05605     
05606     /* If the suspension flag has been raised and if the processing is not about
05607        to end, suspend processing */
05608     if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength))
05609     {
05610       /* Reset SuspendRequest */
05611       hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
05612       
05613       /* Save current reading and writing locations of Input and Output buffers */
05614       hcryp->pCrypOutBuffPtr =  (uint8_t *)outputaddr;
05615       hcryp->pCrypInBuffPtr  =  (uint8_t *)inputaddr;
05616       /* Save the number of bytes that remain to be processed at this point */
05617       hcryp->CrypInCount     =  Ilength - (index+16U);
05618       
05619       /* Change the CRYP state */
05620       hcryp->State = HAL_CRYP_STATE_SUSPENDED;
05621       
05622       return HAL_OK;
05623     }
05624 
05625   }
05626   /* Return function status */
05627   return HAL_OK;
05628 
05629 }
05630 
05631 /**
05632   * @brief  Read derivative key in polling mode when CRYP hardware block is set
05633   *         in key derivation operating mode (mode 2).
05634   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
05635   *         the configuration information for CRYP module.
05636   * @param  Output Pointer to the returned buffer.
05637   * @param  Timeout Specify Timeout value.  
05638   * @retval HAL status
05639   */
05640 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
05641 {
05642   uint32_t outputaddr = (uint32_t)Output;
05643   
05644   /* Wait for CCF flag to be raised */  
05645   if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)  
05646   { 
05647     hcryp->State = HAL_CRYP_STATE_READY;        
05648     __HAL_UNLOCK(hcryp);
05649     return HAL_TIMEOUT;
05650   }
05651   /* Clear CCF Flag */
05652   __HAL_CRYP_CLEAR_FLAG( CRYP_CCF_CLEAR);
05653   
05654     /* Read the derivative key from the AES_KEYRx registers */
05655   if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
05656   {   
05657     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
05658     outputaddr+=4U;
05659     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
05660     outputaddr+=4U;
05661     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
05662     outputaddr+=4U;
05663     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
05664     outputaddr+=4U;
05665   }
05666   
05667     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
05668     outputaddr+=4U;
05669     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
05670     outputaddr+=4U;
05671     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
05672     outputaddr+=4U;
05673     *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);
05674 
05675   /* Return function status */
05676   return HAL_OK;
05677 }
05678 
05679 /**
05680   * @brief  Set the DMA configuration and start the DMA transfer.
05681   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
05682   *         the configuration information for CRYP module.
05683   * @param  inputaddr Address of the Input buffer.
05684   * @param  Size Size of the Input buffer in bytes, must be a multiple of 16.
05685   * @param  outputaddr Address of the Output buffer.
05686   * @retval None
05687   */
05688 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
05689 {
05690   /* Set the CRYP DMA transfer complete callback */
05691   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
05692   /* Set the DMA error callback */
05693   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
05694   
05695   /* Set the CRYP DMA transfer complete callback */
05696   hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
05697   /* Set the DMA error callback */
05698   hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
05699 
05700   /* Enable the DMA input stream */
05701   HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4U);
05702 
05703   /* Enable the DMA output stream */
05704   HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4U);
05705 
05706   /* Enable In and Out DMA requests */
05707   SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
05708   
05709   /* Enable the CRYP peripheral */
05710   __HAL_CRYP_ENABLE();
05711 }
05712 
05713 /**
05714   * @brief  Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
05715   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
05716   *         the configuration information for CRYP module.      
05717   * @param  Timeout Timeout duration.
05718   * @retval HAL status
05719   */
05720 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
05721 {
05722   uint32_t tickstart = 0U;
05723   
05724   /* Get timeout */
05725   tickstart = HAL_GetTick();
05726   
05727   while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
05728   {    
05729     /* Check for the Timeout */
05730     if(Timeout != HAL_MAX_DELAY)
05731     {
05732       if((HAL_GetTick() - tickstart ) > Timeout)
05733       {    
05734         return HAL_TIMEOUT;
05735       }
05736     }
05737   }
05738   return HAL_OK; 
05739 }
05740 
05741 /**
05742   * @brief  Wait for Busy Flag to be reset during a GCM payload encryption process suspension. 
05743   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
05744   *         the configuration information for CRYP module.         
05745   * @param  Timeout Timeout duration.
05746   * @retval HAL status
05747   */
05748 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
05749 {
05750   uint32_t tickstart = 0U;
05751   
05752   /* Get timeout */
05753   tickstart = HAL_GetTick();
05754   
05755   while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
05756   {    
05757     /* Check for the Timeout */
05758     if(Timeout != HAL_MAX_DELAY)
05759     {
05760       if((HAL_GetTick() - tickstart ) > Timeout)
05761       {    
05762         return HAL_TIMEOUT;
05763       }
05764     }
05765   }
05766   return HAL_OK; 
05767 }
05768 
05769 /**
05770   * @brief  DMA CRYP Input Data process complete callback.
05771   * @param  hdma DMA handle.
05772   * @retval None
05773   */
05774 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)  
05775 {
05776   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
05777   
05778   /* Disable the DMA transfer for input request  */
05779   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
05780   
05781   /* Call input data transfer complete callback */
05782   HAL_CRYP_InCpltCallback(hcryp);
05783 }
05784 
05785 /**
05786   * @brief  DMA CRYP Output Data process complete callback.
05787   * @param  hdma DMA handle.
05788   * @retval None
05789   */
05790 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
05791 {  
05792   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
05793   
05794   /* Disable the DMA transfer for output request */
05795   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
05796 
05797   /* Clear CCF Flag */
05798   __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05799   
05800   /* Disable CRYP */
05801   __HAL_CRYP_DISABLE();
05802   
05803   /* Change the CRYP state to ready */
05804   hcryp->State = HAL_CRYP_STATE_READY;
05805   
05806   /* Call output data transfer complete callback */
05807   HAL_CRYP_OutCpltCallback(hcryp);
05808 }
05809 
05810 /**
05811   * @brief  DMA CRYP communication error callback. 
05812   * @param  hdma DMA handle.
05813   * @retval None
05814   */
05815 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
05816 {
05817   CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
05818   
05819   hcryp->State= HAL_CRYP_STATE_ERROR;
05820   hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;  
05821   HAL_CRYP_ErrorCallback(hcryp);
05822   /* Clear Error Flag */
05823   __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR);
05824 }
05825 
05826 /**
05827   * @brief  Last header or payload block padding when size is not a multiple of 128 bits. 
05828   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
05829   *         the configuration information for CRYP module.         
05830   * @param  difflength size remainder after having fed all complete 128-bit blocks.
05831   * @param  polling specifies whether or not polling on CCF must be done after having
05832   *                  entered a complete block.     
05833   * @retval None
05834   */
05835 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
05836 {
05837   uint32_t index          = 0U;
05838   uint32_t difflengthmod4 = difflength%4U;
05839   uint32_t inputaddr      = (uint32_t)hcryp->pCrypInBuffPtr; 
05840   uint32_t outputaddr     = (uint32_t)hcryp->pCrypOutBuffPtr;   
05841   uint32_t mask[3U]       = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};  
05842   uint32_t intermediate_data[4U] = {0U};
05843   
05844 #if defined(AES_CR_NPBLB)  
05845   /* In case of GCM encryption or CCM decryption, specify the number of padding
05846      bytes in last block of payload */
05847      if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
05848      {
05849        if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
05850             &&  (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))   
05851         ||  ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
05852             &&  (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
05853        {
05854          /* Set NPBLB field in writing the number of padding bytes 
05855             for the last block of payload */
05856          MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
05857        }
05858      }
05859 #else
05860   /* Software workaround applied to GCM encryption only */
05861   if ((hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) &&           
05862       (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
05863   {
05864     /* Change the mode configured in CHMOD bits of CR register to select CTR mode */   
05865     __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
05866   }  
05867 #endif  
05868   
05869   /* Wrap-up entering header or payload data */
05870   /* Enter complete words when possible */
05871   for(index=0U; index < (difflength/4U); index ++)
05872   {
05873     /* Write the Input block in the Data Input register */
05874     hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
05875     inputaddr+=4U;
05876   }
05877   /* Enter incomplete word padded with zeroes if applicable 
05878     (case of header length not a multiple of 32-bits) */
05879   if (difflengthmod4 != 0U)
05880   {         
05881     hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
05882   }         
05883   /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
05884   for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)         
05885   {
05886     hcryp->Instance->DINR = 0U;
05887   } 
05888                 
05889   if (polling == CRYP_POLLING_ON)
05890   {
05891                 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)  
05892     { 
05893         hcryp->State = HAL_CRYP_STATE_READY;        
05894         __HAL_UNLOCK(hcryp);
05895        HAL_CRYP_ErrorCallback(hcryp);
05896       } 
05897 
05898     /* Clear CCF Flag */
05899     __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05900   }
05901                 
05902         /* if payload */
05903   if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
05904         {               
05905        
05906     /* Retrieve intermediate data */
05907     for(index=0U; index < 4U; index ++)
05908     {
05909       intermediate_data[index] = hcryp->Instance->DOUTR;                 
05910     }     
05911     /* Retrieve last words of cyphered data */
05912     /* First, retrieve complete output words */
05913     for(index=0U; index < (difflength/4U); index ++)
05914     {
05915       *(uint32_t*)(outputaddr) = intermediate_data[index];
05916       outputaddr+=4U; 
05917     } 
05918     /* Next, retrieve partial output word if applicable;
05919        at the same time, start masking intermediate data 
05920        with a mask of zeros of same size than the padding
05921        applied to the last block of payload */ 
05922     if (difflengthmod4 != 0U)
05923     {
05924       intermediate_data[difflength/4U] &= mask[difflengthmod4-1U];
05925       *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];            
05926     }
05927 
05928 #if !defined(AES_CR_NPBLB)      
05929     /* Software workaround applied to GCM encryption only,
05930        applicable for AES IP v2 version (where NPBLB is not defined) */           
05931     if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
05932     {
05933       /* Change again CHMOD configuration to GCM mode */
05934       __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC);  
05935       
05936       /* Select FINAL phase */
05937       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
05938       
05939       /* Before inserting the intermediate data, carry on masking operation
05940          with a mask of zeros of same size than the padding applied to the last block of payload */
05941       for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)        
05942       {
05943         intermediate_data[(difflength+3U)/4U+index] = 0U;
05944       }   
05945       /* Insert intermediate data */
05946       for(index=0U; index < 4U; index ++)
05947       {
05948         hcryp->Instance->DINR = intermediate_data[index];          
05949       } 
05950       
05951       /*  Wait for completion, and read data on DOUT. This data is to discard. */ 
05952       if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)  
05953       { 
05954         hcryp->State = HAL_CRYP_STATE_READY;        
05955         __HAL_UNLOCK(hcryp);
05956         HAL_CRYP_ErrorCallback(hcryp);
05957       } 
05958          
05959       /* Read data to discard */ 
05960       /* Clear CCF Flag */
05961       __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
05962       for(index=0U; index < 4U; index ++)
05963       {
05964         intermediate_data[index] = hcryp->Instance->DOUTR;        
05965       }  
05966                 
05967           } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
05968 #endif  /* !defined(AES_CR_NPBLB) */     
05969         }   /* if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) */
05970                 
05971 }
05972 
05973 /**
05974   * @}
05975   */
05976 
05977 #endif /* AES */
05978 
05979 #endif /* HAL_CRYP_MODULE_ENABLED */
05980 /**
05981   * @}
05982   */
05983 
05984 /**
05985   * @}
05986   */
05987 
05988 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/