STM32H735xx HAL User Manual
stm32h7xx_hal_cryp.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_cryp.c
00004   * @author  MCD Application Team
00005   * @brief   CRYP HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Cryptography (CRYP) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + AES processing functions
00010   *           + DES processing functions
00011   *           + TDES processing functions
00012   *           + DMA callback functions
00013   *           + CRYP IRQ handler management
00014   *           + Peripheral State functions
00015   *
00016   ******************************************************************************
00017   * @attention
00018   *
00019   * Copyright (c) 2017 STMicroelectronics.
00020   * All rights reserved.
00021   *
00022   * This software is licensed under terms that can be found in the LICENSE file
00023   * in the root directory of this software component.
00024   * If no LICENSE file comes with this software, it is provided AS-IS.
00025   *
00026   ******************************************************************************
00027   @verbatim
00028   ==============================================================================
00029                      ##### How to use this driver #####
00030   ==============================================================================
00031     [..]
00032       The CRYP HAL driver can be used in CRYP IP as follows:
00033 
00034       (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
00035          (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
00036          (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
00037              (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
00038              (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
00039              (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
00040          (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
00041              (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
00042              (+++) Configure and enable two DMA streams one for managing data transfer from
00043                  memory to peripheral (input stream) and another stream for managing data
00044                  transfer from peripheral to memory (output stream)
00045              (+++) Associate the initialized DMA handle to the CRYP DMA handle
00046                  using  __HAL_LINKDMA()
00047              (+++) Configure the priority and enable the NVIC for the transfer complete
00048                  interrupt on the two DMA Streams. The output stream should have higher
00049                  priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
00050 
00051       (#)Initialize the CRYP according to the specified parameters :
00052          (##) The data type: 1-bit, 8-bit, 16-bit or 32-bit.
00053          (##) The key size: 128, 192 or 256.
00054          (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM.
00055          (##) The initialization vector (counter). It is not used in ECB mode.
00056          (##) The key buffer used for encryption/decryption.
00057          (##) The Header used only in AES GCM and CCM Algorithm for authentication.
00058          (##) The HeaderSize The size of header buffer in word.
00059          (##) The B0 block is the first authentication block used only  in AES CCM mode.
00060 
00061       (#)Three processing (encryption/decryption) functions are available:
00062          (##) Polling mode: encryption and decryption APIs are blocking functions
00063               i.e. they process the data and wait till the processing is finished,
00064               e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
00065          (##) Interrupt mode: encryption and decryption APIs are not blocking functions
00066               i.e. they process the data under interrupt,
00067               e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
00068          (##) DMA mode: encryption and decryption APIs are not blocking functions
00069               i.e. the data transfer is ensured by DMA,
00070               e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
00071 
00072       (#)When the processing function is called at first time after HAL_CRYP_Init()
00073          the CRYP peripheral is configured and processes the buffer in input.
00074          At second call, no need to Initialize the CRYP, user have to get current configuration via
00075          HAL_CRYP_GetConfig() API, then only  HAL_CRYP_SetConfig() is requested to set
00076          new parametres, finally user can  start encryption/decryption.
00077 
00078        (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
00079        
00080        (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
00081           without having to configure again the Key or the Initialization Vector between each API call,
00082           the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
00083           Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
00084           or HAL_CRYP_Decrypt_DMA().
00085           
00086     [..]
00087       The cryptographic processor supports following standards:
00088       (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 IP:
00089          (##)64-bit data block processing
00090          (##) chaining modes supported :
00091              (+++)  Electronic Code Book(ECB)
00092              (+++)  Cipher Block Chaining (CBC)
00093          (##) keys length supported :64-bit, 128-bit and 192-bit.
00094       (#) The advanced encryption standard (AES) supported  by CRYP1:
00095          (##)128-bit data block processing
00096          (##) chaining modes supported :
00097              (+++)  Electronic Code Book(ECB)
00098              (+++)  Cipher Block Chaining (CBC)
00099              (+++)  Counter mode (CTR)
00100              (+++)  Galois/counter mode (GCM/GMAC)
00101              (+++)  Counter with Cipher Block Chaining-Message(CCM)
00102          (##) keys length Supported :
00103              (+++) for CRYP1 IP: 128-bit, 192-bit and 256-bit.
00104 
00105     [..]  This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 IP:
00106       (#)  Algorithm supported :
00107          (##) Galois/counter mode (GCM)
00108          (##) Galois message authentication code (GMAC) :is exactly the same as
00109               GCM algorithm composed only by an header.
00110       (#)  Four phases are performed in GCM :
00111          (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
00112          (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
00113           computation only.
00114          (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
00115           encryption + data XORing. It works in a similar way for ciphertext (C).
00116          (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
00117           HAL_CRYPEx_AESGCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond
00118           to the Tag. user should consider only part of this 4 words, if Tag length is less than 128 bits. 
00119       (#)  structure of message construction in GCM is defined as below  :
00120          (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
00121          (##) The authenticated header A (also knows as Additional Authentication Data AAD)
00122           this part of the message is only authenticated, not encrypted.
00123          (##) The plaintext message P is both authenticated and encrypted as ciphertext.
00124           GCM standard specifies that ciphertext has same bit length as the plaintext.
00125          (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
00126           (on 64 bits)
00127 
00128     [..]  This section describe The AES Counter with Cipher Block Chaining-Message
00129           Authentication Code (CCM) supported by both CRYP1 IP:
00130       (#)  Specific parameters for CCM  :
00131 
00132          (##) B0 block  : According to NIST Special Publication 800-38C,
00133             The first block B0 is formatted as follows, where l(m) is encoded in
00134             most-significant-byte first order(see below table 3)
00135 
00136               (+++)  Q: a bit string representation of the octet length of P (plaintext)
00137               (+++)  q The octet length of the binary representation of the octet length of the payload
00138               (+++)  A nonce (N), n The octet length of the where n+q=15.
00139               (+++)  Flags: most significant octet containing four flags for control information,
00140               (+++)  t The octet length of the MAC.
00141          (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
00142               the associated data length expressed in bytes (a) defined as below:
00143             (+++)  If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
00144             (+++)  If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
00145             (+++)  If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
00146          (##) CTRx block  : control blocks
00147             (+++) Generation of CTR1 from first block B0 information :
00148               equal to B0 with first 5 bits zeroed and most significant bits storing octet
00149               length of P also zeroed, then incremented by one ( see below Table 4)
00150             (+++) Generation of CTR0: same as CTR1 with bit[0] set to zero.
00151 
00152       (#)  Four phases are performed in CCM for CRYP1 IP:
00153          (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
00154          (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
00155           computation only.
00156          (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
00157           encryption + data XORing. It works in a similar way for ciphertext (C).
00158          (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
00159          HAL_CRYPEx_AESCCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond to the Tag.
00160          user should consider only part of this 4 words, if Tag length is less than 128 bits
00161 
00162   *** Callback registration ***
00163   =============================
00164 
00165   [..]
00166   The compilation define  USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
00167   allows the user to configure dynamically the driver callbacks.
00168   Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
00169   to register an interrupt callback.
00170 
00171   [..]
00172   Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
00173     (+) InCpltCallback     :  Input FIFO transfer completed callback.
00174     (+) OutCpltCallback    : Output FIFO transfer completed callback.
00175     (+) ErrorCallback      : callback for error detection.
00176     (+) MspInitCallback    : CRYP MspInit.
00177     (+) MspDeInitCallback  : CRYP MspDeInit.
00178   This function takes as parameters the HAL peripheral handle, the Callback ID
00179   and a pointer to the user callback function.
00180 
00181   [..]
00182   Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
00183   weak function.
00184   @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
00185   and the Callback ID.
00186   This function allows to reset following callbacks:
00187     (+) InCpltCallback     :  Input FIFO transfer completed callback.
00188     (+) OutCpltCallback    : Output FIFO transfer completed callback.
00189     (+) ErrorCallback      : callback for error detection.
00190     (+) MspInitCallback    : CRYP MspInit.
00191     (+) MspDeInitCallback  : CRYP MspDeInit.
00192 
00193   [..]
00194   By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
00195   all callbacks are set to the corresponding weak functions :
00196   examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
00197   Exception done for MspInit and MspDeInit functions that are
00198   reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
00199   these callbacks are null (not registered beforehand).
00200   if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
00201   keep and use the user MspInit/MspDeInit functions (registered beforehand)
00202 
00203   [..]
00204   Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
00205   Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
00206   in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
00207   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00208   In that case first register the MspInit/MspDeInit user callbacks
00209   using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
00210   or @ref HAL_CRYP_Init() function.
00211 
00212   [..]
00213   When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
00214   not defined, the callback registration feature is not available and all callbacks
00215   are set to the corresponding weak functions.
00216 
00217   @endverbatim
00218 
00219   Table 1. Initial Counter Block (ICB)
00220           +-------------------------------------------------------+
00221           |       Initialization vector (IV)      |  Counter      |
00222           |----------------|----------------|-----------|---------|
00223          127              95                63            31       0
00224 
00225 
00226               Bit Number    Register           Contents
00227               ----------   ---------------       -----------
00228               127 ...96    CRYP_IV1R[31:0]     ICB[127:96]
00229               95  ...64    CRYP_IV1L[31:0]     B0[95:64]
00230               63 ... 32    CRYP_IV0R[31:0]     ICB[63:32]
00231               31 ... 0     CRYP_IV0L[31:0]     ICB[31:0], where 32-bit counter= 0x2
00232 
00233   Table 2.  GCM last block definition
00234 
00235           +-------------------------------------------------------------------+
00236           |  Bit[0]   |  Bit[32]           |  Bit[64]  | Bit[96]              |
00237           |-----------|--------------------|-----------|----------------------|
00238           |   0x0     | Header length[31:0]|     0x0   | Payload length[31:0] |
00239           |-----------|--------------------|-----------|----------------------|
00240 
00241   Table 3. B0 block
00242                 Octet Number   Contents
00243                 ------------   ---------
00244                 0              Flags
00245                 1 ... 15-q     Nonce N
00246                 16-q ... 15    Q
00247 
00248             the Flags field is formatted as follows:
00249 
00250                 Bit Number   Contents
00251                 ----------   ----------------------
00252                 7            Reserved (always zero)
00253                 6            Adata
00254                 5 ... 3      (t-2)/2
00255                 2 ... 0      [q-1]3
00256 
00257  Table 4. CTRx block
00258                 Bit Number    Register           Contents
00259                 ----------   ---------------       -----------
00260                 127 ...96    CRYP_IV1R[31:0]     B0[127:96], where Q length bits are set to 0, except for
00261                                                  bit 0 that is set to 1
00262                 95  ...64    CRYP_IV1L[31:0]     B0[95:64]
00263                 63 ... 32    CRYP_IV0R[31:0]     B0[63:32]
00264                 31 ... 0     CRYP_IV0L[31:0]     B0[31:0], where flag bits set to 0
00265   */
00266 
00267 /* Includes ------------------------------------------------------------------*/
00268 #include "stm32h7xx_hal.h"
00269 
00270 /** @addtogroup STM32H7xx_HAL_Driver
00271   * @{
00272   */
00273 
00274 #if defined (CRYP)
00275 
00276 /** @defgroup CRYP CRYP
00277   * @brief CRYP HAL module driver.
00278   * @{
00279   */
00280 
00281 
00282 #ifdef HAL_CRYP_MODULE_ENABLED
00283 
00284 /* Private typedef -----------------------------------------------------------*/
00285 /* Private define ------------------------------------------------------------*/
00286 /** @addtogroup CRYP_Private_Defines
00287   * @{
00288   */
00289 #define CRYP_TIMEOUT_KEYPREPARATION      82U         /*The latency of key preparation operation is 82 clock cycles.*/
00290 #define CRYP_TIMEOUT_GCMCCMINITPHASE     299U        /*  The latency of  GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
00291 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE   290U        /*  The latency of  GCM/CCM header phase is 290 clock cycles.*/
00292 
00293 #define  CRYP_PHASE_READY                0x00000001U /*!< CRYP peripheral is ready for initialization. */
00294 #define  CRYP_PHASE_PROCESS              0x00000002U /*!< CRYP peripheral is in processing phase */
00295 
00296 #define CRYP_PHASE_INIT                  0x00000000U             /*!< GCM/GMAC (or CCM) init phase */
00297 #define CRYP_PHASE_HEADER                CRYP_CR_GCM_CCMPH_0     /*!< GCM/GMAC or CCM header phase */
00298 #define CRYP_PHASE_PAYLOAD               CRYP_CR_GCM_CCMPH_1     /*!< GCM(/CCM) payload phase      */
00299 #define CRYP_PHASE_FINAL                 CRYP_CR_GCM_CCMPH       /*!< GCM/GMAC or CCM  final phase */
00300 #define CRYP_OPERATINGMODE_ENCRYPT       0x00000000U             /*!< Encryption mode   */
00301 #define CRYP_OPERATINGMODE_DECRYPT       CRYP_CR_ALGODIR         /*!< Decryption        */
00302 
00303 
00304 /*  CTR1 information to use in CCM algorithm */
00305 #define CRYP_CCM_CTR1_0                  0x07FFFFFFU
00306 #define CRYP_CCM_CTR1_1                  0xFFFFFF00U
00307 #define CRYP_CCM_CTR1_2                  0x00000001U
00308 
00309 /**
00310   * @}
00311   */
00312 
00313 
00314 /* Private macro -------------------------------------------------------------*/
00315 /** @addtogroup CRYP_Private_Macros
00316   * @{
00317   */
00318 
00319 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__)  do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\
00320                                                         (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
00321                                                        }while(0)
00322 
00323 #define HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |=  CRYP_CR_FFLUSH)
00324 
00325 
00326 /**
00327   * @}
00328   */
00329 
00330 /* Private struct -------------------------------------------------------------*/
00331 /* Private variables ---------------------------------------------------------*/
00332 /* Private function prototypes -----------------------------------------------*/
00333 /** @addtogroup CRYP_Private_Functions_prototypes
00334   * @{
00335   */
00336 
00337 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
00338 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
00339 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
00340 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
00341 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
00342 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
00343 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00344 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
00345 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
00346 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
00347 #if !defined (CRYP_VER_2_2)
00348 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00349 #endif /*End of not defined CRYP_VER_2_2*/
00350 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
00351 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
00352 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00353 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00354 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
00355 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
00356 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
00357 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00358 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00359 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
00360 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
00361 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
00362 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp);
00363 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00364 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00365 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00366 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
00367 
00368 /**
00369   * @}
00370   */
00371 
00372 /* Exported functions ---------------------------------------------------------*/
00373 
00374 /** @defgroup CRYP_Exported_Functions CRYP Exported Functions
00375   * @{
00376   */
00377 
00378 
00379 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
00380   *  @brief    CRYP  Initialization and Configuration functions.
00381   *
00382 @verbatim
00383   ========================================================================================
00384      ##### Initialization, de-initialization and Set and Get configuration functions #####
00385   ========================================================================================
00386     [..]  This section provides functions allowing to:
00387       (+) Initialize the CRYP
00388       (+) DeInitialize the CRYP
00389       (+) Initialize the CRYP MSP
00390       (+) DeInitialize the CRYP MSP
00391       (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
00392           Parameters which are configured in This section are :
00393           (++) Key size
00394           (++) Data Type : 32,16, 8 or 1bit
00395           (++) AlgoMode : for CRYP1 IP
00396                  ECB and CBC in DES/TDES Standard
00397                  ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
00398       (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
00399 
00400 
00401 @endverbatim
00402   * @{
00403   */
00404 
00405 
00406 /**
00407   * @brief  Initializes the CRYP according to the specified
00408   *         parameters in the CRYP_ConfigTypeDef and creates the associated handle.
00409   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
00410   *         the configuration information for CRYP module
00411   * @retval HAL status
00412   */
00413 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
00414 {
00415   /* Check the CRYP handle allocation */
00416   if (hcryp == NULL)
00417   {
00418     return HAL_ERROR;
00419   }
00420 
00421   /* Check parameters */
00422   assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
00423   assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
00424   assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
00425   assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
00426 
00427 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
00428   if (hcryp->State == HAL_CRYP_STATE_RESET)
00429   {
00430     /* Allocate lock resource and initialize it */
00431     hcryp->Lock = HAL_UNLOCKED;
00432 
00433     hcryp->InCpltCallback  = HAL_CRYP_InCpltCallback;  /* Legacy weak  InCpltCallback  */
00434     hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback  */
00435     hcryp->ErrorCallback   = HAL_CRYP_ErrorCallback;   /* Legacy weak ErrorCallback    */
00436 
00437     if (hcryp->MspInitCallback == NULL)
00438     {
00439       hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit  */
00440     }
00441 
00442     /* Init the low level hardware */
00443     hcryp->MspInitCallback(hcryp);
00444   }
00445 #else
00446   if (hcryp->State == HAL_CRYP_STATE_RESET)
00447   {
00448     /* Allocate lock resource and initialize it */
00449     hcryp->Lock = HAL_UNLOCKED;
00450 
00451     /* Init the low level hardware */
00452     HAL_CRYP_MspInit(hcryp);
00453   }
00454 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
00455 
00456   /* Set the key size(This bit field is don't care in the DES or TDES modes) data type and Algorithm */
00457   MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
00458              hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
00459 #if !defined (CRYP_VER_2_2)
00460   /* Read Device ID to indicate CRYP1 IP Version */
00461   hcryp->Version = HAL_GetREVID();
00462 #endif /*End of not defined CRYP_VER_2_2*/
00463   /* Reset Error Code field */
00464   hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
00465 
00466   /* Reset peripheral Key and IV configuration flag */
00467   hcryp->KeyIVConfig = 0U;
00468   
00469   /* Change the CRYP state */
00470   hcryp->State = HAL_CRYP_STATE_READY;
00471 
00472   /* Set the default CRYP phase */
00473   hcryp->Phase = CRYP_PHASE_READY;
00474 
00475   /* Return function status */
00476   return HAL_OK;
00477 }
00478 
00479 /**
00480   * @brief  De-Initializes the CRYP peripheral.
00481   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
00482   *         the configuration information for CRYP module
00483   * @retval HAL status
00484   */
00485 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
00486 {
00487   /* Check the CRYP handle allocation */
00488   if (hcryp == NULL)
00489   {
00490     return HAL_ERROR;
00491   }
00492 
00493   /* Set the default CRYP phase */
00494   hcryp->Phase = CRYP_PHASE_READY;
00495 
00496   /* Reset CrypInCount and CrypOutCount */
00497   hcryp->CrypInCount = 0;
00498   hcryp->CrypOutCount = 0;
00499   hcryp->CrypHeaderCount = 0;
00500 
00501   /* Disable the CRYP peripheral clock */
00502   __HAL_CRYP_DISABLE(hcryp);
00503 
00504 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
00505   if (hcryp->MspDeInitCallback == NULL)
00506   {
00507     hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit  */
00508   }
00509   /* DeInit the low level hardware */
00510   hcryp->MspDeInitCallback(hcryp);
00511 
00512 #else
00513   /* DeInit the low level hardware: CLOCK, NVIC.*/
00514   HAL_CRYP_MspDeInit(hcryp);
00515 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
00516 
00517   /* Change the CRYP state */
00518   hcryp->State = HAL_CRYP_STATE_RESET;
00519 
00520   /* Release Lock */
00521   __HAL_UNLOCK(hcryp);
00522 
00523   /* Return function status */
00524   return HAL_OK;
00525 }
00526 
00527 /**
00528   * @brief  Configure the CRYP according to the specified
00529   *         parameters in the CRYP_ConfigTypeDef
00530   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
00531   * @param  pConf: pointer to a CRYP_ConfigTypeDef structure that contains
00532   *         the configuration information for CRYP module
00533   * @retval HAL status
00534   */
00535 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
00536 {
00537   /* Check the CRYP handle allocation */
00538   if ((hcryp == NULL) || (pConf == NULL))
00539   {
00540     return HAL_ERROR;
00541   }
00542 
00543   /* Check parameters */
00544   assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
00545   assert_param(IS_CRYP_DATATYPE(pConf->DataType));
00546   assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
00547 
00548   if (hcryp->State == HAL_CRYP_STATE_READY)
00549   {
00550     /* Change the CRYP state */
00551     hcryp->State = HAL_CRYP_STATE_BUSY;
00552 
00553     /* Process locked */
00554     __HAL_LOCK(hcryp);
00555 
00556     /* Set  CRYP parameters  */
00557     hcryp->Init.DataType     = pConf->DataType;
00558     hcryp->Init.pKey         = pConf->pKey;
00559     hcryp->Init.Algorithm    = pConf->Algorithm;
00560     hcryp->Init.KeySize      = pConf->KeySize;
00561     hcryp->Init.pInitVect    = pConf->pInitVect;
00562     hcryp->Init.Header       = pConf->Header;
00563     hcryp->Init.HeaderSize   = pConf->HeaderSize;
00564     hcryp->Init.B0           = pConf->B0;
00565     hcryp->Init.DataWidthUnit = pConf->DataWidthUnit;
00566 
00567     /* Set the key size(This bit field is don't care in the DES or TDES modes) data type, AlgoMode and operating mode*/
00568     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
00569                hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
00570 
00571     /* Process Unlocked */
00572     __HAL_UNLOCK(hcryp);
00573 
00574     /* Reset Error Code field */
00575     hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
00576 
00577     /* Change the CRYP state */
00578     hcryp->State = HAL_CRYP_STATE_READY;
00579 
00580     /* Set the default CRYP phase */
00581     hcryp->Phase = CRYP_PHASE_READY;
00582 
00583     /* Return function status */
00584     return HAL_OK;
00585   }
00586   else
00587   {
00588     /* Process Unlocked */
00589     __HAL_UNLOCK(hcryp);
00590 
00591     /* Busy error code field */
00592     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
00593     return HAL_ERROR;
00594   }
00595 }
00596 
00597 /**
00598   * @brief  Get CRYP Configuration parameters in associated handle.
00599   * @param  pConf: pointer to a CRYP_ConfigTypeDef structure
00600   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
00601   *         the configuration information for CRYP module
00602   * @retval HAL status
00603   */
00604 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
00605 {
00606   /* Check the CRYP handle allocation */
00607   if ((hcryp == NULL) || (pConf == NULL))
00608   {
00609     return HAL_ERROR;
00610   }
00611 
00612   if (hcryp->State == HAL_CRYP_STATE_READY)
00613   {
00614     /* Change the CRYP state */
00615     hcryp->State = HAL_CRYP_STATE_BUSY;
00616 
00617     /* Process locked */
00618     __HAL_LOCK(hcryp);
00619 
00620     /* Get  CRYP parameters  */
00621     pConf->DataType        = hcryp->Init.DataType;
00622     pConf->pKey            = hcryp->Init.pKey;
00623     pConf->Algorithm       = hcryp->Init.Algorithm;
00624     pConf->KeySize         = hcryp->Init.KeySize ;
00625     pConf->pInitVect       = hcryp->Init.pInitVect;
00626     pConf->Header          = hcryp->Init.Header ;
00627     pConf->HeaderSize      = hcryp->Init.HeaderSize;
00628     pConf->B0              = hcryp->Init.B0;
00629     pConf->DataWidthUnit    = hcryp->Init.DataWidthUnit;
00630 
00631     /* Process Unlocked */
00632     __HAL_UNLOCK(hcryp);
00633 
00634     /* Change the CRYP state */
00635     hcryp->State = HAL_CRYP_STATE_READY;
00636 
00637     /* Return function status */
00638     return HAL_OK;
00639   }
00640   else
00641   {
00642     /* Process Unlocked */
00643     __HAL_UNLOCK(hcryp);
00644 
00645     /* Busy error code field */
00646     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
00647     return HAL_ERROR;
00648   }
00649 }
00650 /**
00651   * @brief  Initializes the CRYP MSP.
00652   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
00653   *         the configuration information for CRYP module
00654   * @retval None
00655   */
00656 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
00657 {
00658   /* Prevent unused argument(s) compilation warning */
00659   UNUSED(hcryp);
00660 
00661   /* NOTE : This function Should not be modified, when the callback is needed,
00662             the HAL_CRYP_MspInit could be implemented in the user file
00663    */
00664 }
00665 
00666 /**
00667   * @brief  DeInitializes CRYP MSP.
00668   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
00669   *         the configuration information for CRYP module
00670   * @retval None
00671   */
00672 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
00673 {
00674   /* Prevent unused argument(s) compilation warning */
00675   UNUSED(hcryp);
00676 
00677   /* NOTE : This function Should not be modified, when the callback is needed,
00678             the HAL_CRYP_MspDeInit could be implemented in the user file
00679    */
00680 }
00681 
00682 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
00683 /**
00684   * @brief  Register a User CRYP Callback
00685   *         To be used instead of the weak predefined callback
00686   * @param hcryp cryp handle
00687   * @param CallbackID ID of the callback to be registered
00688   *        This parameter can be one of the following values:
00689   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
00690   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
00691   *          @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
00692   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
00693   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
00694   * @param pCallback pointer to the Callback function
00695   * @retval status
00696   */
00697 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID,
00698                                             pCRYP_CallbackTypeDef pCallback)
00699 {
00700   HAL_StatusTypeDef status = HAL_OK;
00701 
00702   if (pCallback == NULL)
00703   {
00704     /* Update the error code */
00705     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
00706 
00707     return HAL_ERROR;
00708   }
00709   /* Process locked */
00710   __HAL_LOCK(hcryp);
00711 
00712   if (hcryp->State == HAL_CRYP_STATE_READY)
00713   {
00714     switch (CallbackID)
00715     {
00716       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
00717         hcryp->InCpltCallback = pCallback;
00718         break;
00719 
00720       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
00721         hcryp->OutCpltCallback = pCallback;
00722         break;
00723 
00724       case HAL_CRYP_ERROR_CB_ID :
00725         hcryp->ErrorCallback = pCallback;
00726         break;
00727 
00728       case HAL_CRYP_MSPINIT_CB_ID :
00729         hcryp->MspInitCallback = pCallback;
00730         break;
00731 
00732       case HAL_CRYP_MSPDEINIT_CB_ID :
00733         hcryp->MspDeInitCallback = pCallback;
00734         break;
00735 
00736       default :
00737         /* Update the error code */
00738         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
00739         /* Return error status */
00740         status =  HAL_ERROR;
00741         break;
00742     }
00743   }
00744   else if (hcryp->State == HAL_CRYP_STATE_RESET)
00745   {
00746     switch (CallbackID)
00747     {
00748       case HAL_CRYP_MSPINIT_CB_ID :
00749         hcryp->MspInitCallback = pCallback;
00750         break;
00751 
00752       case HAL_CRYP_MSPDEINIT_CB_ID :
00753         hcryp->MspDeInitCallback = pCallback;
00754         break;
00755 
00756       default :
00757         /* Update the error code */
00758         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
00759         /* Return error status */
00760         status =  HAL_ERROR;
00761         break;
00762     }
00763   }
00764   else
00765   {
00766     /* Update the error code */
00767     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
00768     /* Return error status */
00769     status =  HAL_ERROR;
00770   }
00771 
00772   /* Release Lock */
00773   __HAL_UNLOCK(hcryp);
00774 
00775   return status;
00776 }
00777 
00778 /**
00779   * @brief  Unregister an CRYP Callback
00780   *         CRYP callabck is redirected to the weak predefined callback
00781   * @param hcryp cryp handle
00782   * @param CallbackID ID of the callback to be unregistered
00783   *        This parameter can be one of the following values:
00784   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
00785   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
00786   *          @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
00787   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
00788   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
00789   * @retval status
00790   */
00791 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
00792 {
00793   HAL_StatusTypeDef status = HAL_OK;
00794 
00795   /* Process locked */
00796   __HAL_LOCK(hcryp);
00797 
00798   if (hcryp->State == HAL_CRYP_STATE_READY)
00799   {
00800     switch (CallbackID)
00801     {
00802       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
00803         hcryp->InCpltCallback = HAL_CRYP_InCpltCallback;  /* Legacy weak  InCpltCallback  */
00804         break;
00805 
00806       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
00807         hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback;         /* Legacy weak OutCpltCallback       */
00808         break;
00809 
00810       case HAL_CRYP_ERROR_CB_ID :
00811         hcryp->ErrorCallback = HAL_CRYP_ErrorCallback;           /* Legacy weak ErrorCallback        */
00812         break;
00813 
00814       case HAL_CRYP_MSPINIT_CB_ID :
00815         hcryp->MspInitCallback = HAL_CRYP_MspInit;
00816         break;
00817 
00818       case HAL_CRYP_MSPDEINIT_CB_ID :
00819         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
00820         break;
00821 
00822       default :
00823         /* Update the error code */
00824         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
00825         /* Return error status */
00826         status =  HAL_ERROR;
00827         break;
00828     }
00829   }
00830   else if (hcryp->State == HAL_CRYP_STATE_RESET)
00831   {
00832     switch (CallbackID)
00833     {
00834       case HAL_CRYP_MSPINIT_CB_ID :
00835         hcryp->MspInitCallback = HAL_CRYP_MspInit;
00836         break;
00837 
00838       case HAL_CRYP_MSPDEINIT_CB_ID :
00839         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
00840         break;
00841 
00842       default :
00843         /* Update the error code */
00844         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
00845         /* Return error status */
00846         status =  HAL_ERROR;
00847         break;
00848     }
00849   }
00850   else
00851   {
00852     /* Update the error code */
00853     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
00854     /* Return error status */
00855     status =  HAL_ERROR;
00856   }
00857 
00858   /* Release Lock */
00859   __HAL_UNLOCK(hcryp);
00860 
00861   return status;
00862 }
00863 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
00864 
00865 /**
00866   * @}
00867   */
00868 
00869 /** @defgroup CRYP_Exported_Functions_Group2  Encrypt Decrypt functions
00870   *  @brief   CRYP processing functions.
00871   *
00872 @verbatim
00873   ==============================================================================
00874                       ##### Encrypt Decrypt  functions #####
00875   ==============================================================================
00876     [..]  This section provides API allowing to Encrypt/Decrypt Data following
00877           Standard DES/TDES or AES, and Algorithm configured by the user:
00878       (+) Standard DES/TDES only supported by CRYP1 IP, below list of Algorithm supported :
00879            (++)  Electronic Code Book(ECB)
00880            (++) Cipher Block Chaining (CBC)
00881       (+) Standard AES  supported by CRYP1 IP , list of Algorithm supported:
00882            (++) Electronic Code Book(ECB)
00883            (++) Cipher Block Chaining (CBC)
00884            (++) Counter mode (CTR)
00885            (++) Cipher Block Chaining (CBC)
00886            (++) Counter mode (CTR)
00887            (++) Galois/counter mode (GCM)
00888            (++) Counter with Cipher Block Chaining-Message(CCM)
00889     [..]  Three processing functions are available:
00890       (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
00891       (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
00892       (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
00893 
00894 @endverbatim
00895   * @{
00896   */
00897 
00898 
00899 /**
00900   * @brief  Encryption mode.
00901   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
00902   *         the configuration information for CRYP module
00903   * @param  Input: Pointer to the input buffer (plaintext)
00904   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit.
00905   * @param  Output: Pointer to the output buffer(ciphertext)
00906   * @param  Timeout: Specify Timeout value
00907   * @retval HAL status
00908   */
00909 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
00910                                    uint32_t Timeout)
00911 {
00912   uint32_t algo;
00913   HAL_StatusTypeDef status;
00914 
00915   if (hcryp->State == HAL_CRYP_STATE_READY)
00916   {
00917     /* Change state Busy */
00918     hcryp->State = HAL_CRYP_STATE_BUSY;
00919 
00920     /* Process locked */
00921     __HAL_LOCK(hcryp);
00922 
00923     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
00924     hcryp->CrypInCount = 0U;
00925     hcryp->CrypOutCount = 0U;
00926     hcryp->pCrypInBuffPtr = Input;
00927     hcryp->pCrypOutBuffPtr = Output;
00928 
00929     /*  Calculate Size parameter in Byte*/
00930     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
00931     {
00932       hcryp->Size = Size * 4U;
00933     }
00934     else
00935     {
00936       hcryp->Size = Size;
00937     }
00938 
00939     /* Set Encryption operating mode*/
00940     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
00941 
00942     /* algo get algorithm selected */
00943     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
00944 
00945     switch (algo)
00946     {
00947       case CRYP_DES_ECB:
00948       case CRYP_DES_CBC:
00949       case CRYP_TDES_ECB:
00950       case CRYP_TDES_CBC:
00951 
00952         /*Set Key */
00953         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
00954         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
00955         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
00956         {
00957           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
00958           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
00959           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
00960           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
00961         }
00962 
00963         /*Set Initialization Vector (IV)*/
00964         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
00965         {
00966           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
00967           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
00968         }
00969 
00970         /* Flush FIFO */
00971         HAL_CRYP_FIFO_FLUSH(hcryp);
00972 
00973         /* Set the phase */
00974         hcryp->Phase = CRYP_PHASE_PROCESS;
00975 
00976         /* Statrt DES/TDES encryption process */
00977         status = CRYP_TDES_Process(hcryp, Timeout);
00978         break;
00979 
00980       case CRYP_AES_ECB:
00981       case CRYP_AES_CBC:
00982       case CRYP_AES_CTR:
00983 
00984         /* AES encryption */
00985         status = CRYP_AES_Encrypt(hcryp, Timeout);
00986         break;
00987 
00988       case CRYP_AES_GCM:
00989 
00990         /* AES GCM encryption */
00991         status = CRYP_AESGCM_Process(hcryp, Timeout);
00992         break;
00993 
00994       case CRYP_AES_CCM:
00995 
00996         /* AES CCM encryption */
00997         status = CRYP_AESCCM_Process(hcryp, Timeout);
00998         break;
00999 
01000       default:
01001         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
01002         status = HAL_ERROR;
01003         break;
01004     }
01005 
01006     if (status == HAL_OK)
01007     {
01008       /* Change the CRYP peripheral state */
01009       hcryp->State = HAL_CRYP_STATE_READY;
01010 
01011       /* Process unlocked */
01012       __HAL_UNLOCK(hcryp);
01013     }
01014   }
01015   else
01016   {
01017     /* Process unlocked */
01018     __HAL_UNLOCK(hcryp);
01019 
01020     /* Busy error code field */
01021     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
01022     status = HAL_ERROR;
01023   }
01024 
01025   /* Return function status */
01026   return status ;
01027 }
01028 
01029 /**
01030   * @brief  Decryption mode.
01031   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01032   *         the configuration information for CRYP module
01033   * @param  Input: Pointer to the input buffer (ciphertext )
01034   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
01035   * @param  Output: Pointer to the output buffer(plaintext)
01036   * @param  Timeout: Specify Timeout value
01037   * @retval HAL status
01038   */
01039 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
01040                                    uint32_t Timeout)
01041 {
01042   HAL_StatusTypeDef status;
01043   uint32_t algo;
01044 
01045   if (hcryp->State == HAL_CRYP_STATE_READY)
01046   {
01047     /* Change state Busy */
01048     hcryp->State = HAL_CRYP_STATE_BUSY;
01049 
01050     /* Process locked */
01051     __HAL_LOCK(hcryp);
01052 
01053     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
01054     hcryp->CrypInCount = 0U;
01055     hcryp->CrypOutCount = 0U;
01056     hcryp->pCrypInBuffPtr = Input;
01057     hcryp->pCrypOutBuffPtr = Output;
01058 
01059     /*  Calculate Size parameter in Byte*/
01060     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
01061     {
01062       hcryp->Size = Size * 4U;
01063     }
01064     else
01065     {
01066       hcryp->Size = Size;
01067     }
01068 
01069     /* Set Decryption operating mode*/
01070     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
01071 
01072     /* algo get algorithm selected */
01073     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
01074 
01075     switch (algo)
01076     {
01077       case CRYP_DES_ECB:
01078       case CRYP_DES_CBC:
01079       case CRYP_TDES_ECB:
01080       case CRYP_TDES_CBC:
01081 
01082         /*Set Key */
01083         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
01084         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
01085         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01086         {
01087           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
01088           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
01089           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
01090           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
01091         }
01092 
01093         /*Set Initialization Vector (IV)*/
01094         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01095         {
01096           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
01097           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
01098         }
01099 
01100         /* Flush FIFO */
01101         HAL_CRYP_FIFO_FLUSH(hcryp);
01102 
01103         /* Set the phase */
01104         hcryp->Phase = CRYP_PHASE_PROCESS;
01105 
01106         /* Start DES/TDES decryption process */
01107         status = CRYP_TDES_Process(hcryp, Timeout);
01108 
01109         break;
01110 
01111       case CRYP_AES_ECB:
01112       case CRYP_AES_CBC:
01113       case CRYP_AES_CTR:
01114 
01115         /* AES decryption */
01116         status = CRYP_AES_Decrypt(hcryp, Timeout);
01117         break;
01118 
01119       case CRYP_AES_GCM:
01120 
01121         /* AES GCM decryption */
01122         status = CRYP_AESGCM_Process(hcryp, Timeout) ;
01123         break;
01124 
01125       case CRYP_AES_CCM:
01126 
01127         /* AES CCM decryption */
01128         status = CRYP_AESCCM_Process(hcryp, Timeout);
01129         break;
01130 
01131       default:
01132         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
01133         status = HAL_ERROR;
01134         break;
01135     }
01136 
01137     if (status == HAL_OK)
01138     {
01139       /* Change the CRYP peripheral state */
01140       hcryp->State = HAL_CRYP_STATE_READY;
01141 
01142       /* Process unlocked */
01143       __HAL_UNLOCK(hcryp);
01144     }
01145   }
01146   else
01147   {
01148     /* Process unlocked */
01149     __HAL_UNLOCK(hcryp);
01150 
01151     /* Busy error code field */
01152     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
01153     status = HAL_ERROR;
01154   }
01155 
01156   /* Return function status */
01157   return status;
01158 }
01159 
01160 /**
01161   * @brief  Encryption in interrupt mode.
01162   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01163   *         the configuration information for CRYP module
01164   * @param  Input: Pointer to the input buffer (plaintext)
01165   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
01166   * @param  Output: Pointer to the output buffer(ciphertext)
01167   * @retval HAL status
01168   */
01169 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
01170 {
01171   uint32_t algo;
01172   HAL_StatusTypeDef status;
01173 
01174   if (hcryp->State == HAL_CRYP_STATE_READY)
01175   {
01176     /* Change state Busy */
01177     hcryp->State = HAL_CRYP_STATE_BUSY;
01178 
01179     /* Process locked */
01180     __HAL_LOCK(hcryp);
01181 
01182     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
01183     hcryp->CrypInCount = 0U;
01184     hcryp->CrypOutCount = 0U;
01185     hcryp->pCrypInBuffPtr = Input;
01186     hcryp->pCrypOutBuffPtr = Output;
01187 
01188     /*  Calculate Size parameter in Byte*/
01189     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
01190     {
01191       hcryp->Size = Size * 4U;
01192     }
01193     else
01194     {
01195       hcryp->Size = Size;
01196     }
01197 
01198     /* Set encryption operating mode*/
01199     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
01200 
01201     /* algo get algorithm selected */
01202     algo = (hcryp->Instance->CR & CRYP_CR_ALGOMODE);
01203 
01204     switch (algo)
01205     {
01206       case CRYP_DES_ECB:
01207       case CRYP_DES_CBC:
01208       case CRYP_TDES_ECB:
01209       case CRYP_TDES_CBC:
01210 
01211         /*Set Key */
01212         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
01213         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
01214         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01215         {
01216           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
01217           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
01218           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
01219           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
01220         }
01221         /* Set the Initialization Vector*/
01222         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01223         {
01224           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
01225           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
01226         }
01227 
01228         /* Flush FIFO */
01229         HAL_CRYP_FIFO_FLUSH(hcryp);
01230 
01231         /* Set the phase */
01232         hcryp->Phase = CRYP_PHASE_PROCESS;
01233 
01234         /* Enable interrupts */
01235         __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
01236 
01237         /* Enable CRYP to start DES/TDES process*/
01238         __HAL_CRYP_ENABLE(hcryp);
01239         
01240         status = HAL_OK;
01241         break;
01242 
01243       case CRYP_AES_ECB:
01244       case CRYP_AES_CBC:
01245       case CRYP_AES_CTR:
01246 
01247         status = CRYP_AES_Encrypt_IT(hcryp);
01248         break;
01249 
01250       case CRYP_AES_GCM:
01251 
01252         status = CRYP_AESGCM_Process_IT(hcryp) ;
01253         break;
01254 
01255       case CRYP_AES_CCM:
01256 
01257         status = CRYP_AESCCM_Process_IT(hcryp);
01258         break;
01259 
01260       default:
01261         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
01262         status =  HAL_ERROR;
01263         break;
01264     }
01265   }
01266   else
01267   {
01268     /* Busy error code field */
01269     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
01270     status =  HAL_ERROR;
01271   }
01272 
01273   /* Return function status */
01274   return status ;
01275 }
01276 
01277 /**
01278   * @brief  Decryption in itnterrupt mode.
01279   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01280   *         the configuration information for CRYP module
01281   * @param  Input: Pointer to the input buffer (ciphertext )
01282   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
01283   * @param  Output: Pointer to the output buffer(plaintext)
01284   * @retval HAL status
01285   */
01286 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
01287 {
01288   uint32_t algo;
01289   HAL_StatusTypeDef status = HAL_OK;
01290 
01291   if (hcryp->State == HAL_CRYP_STATE_READY)
01292   {
01293     /* Change state Busy */
01294     hcryp->State = HAL_CRYP_STATE_BUSY;
01295 
01296     /* Process locked */
01297     __HAL_LOCK(hcryp);
01298 
01299     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
01300     hcryp->CrypInCount = 0U;
01301     hcryp->CrypOutCount = 0U;
01302     hcryp->pCrypInBuffPtr = Input;
01303     hcryp->pCrypOutBuffPtr = Output;
01304 
01305     /*  Calculate Size parameter in Byte*/
01306     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
01307     {
01308       hcryp->Size = Size * 4U;
01309     }
01310     else
01311     {
01312       hcryp->Size = Size;
01313     }
01314 
01315     /* Set decryption operating mode*/
01316     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
01317 
01318     /* algo get algorithm selected */
01319     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
01320 
01321     switch (algo)
01322     {
01323       case CRYP_DES_ECB:
01324       case CRYP_DES_CBC:
01325       case CRYP_TDES_ECB:
01326       case CRYP_TDES_CBC:
01327 
01328         /*Set Key */
01329         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
01330         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
01331         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01332         {
01333           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
01334           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
01335           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
01336           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
01337         }
01338 
01339         /* Set the Initialization Vector*/
01340         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01341         {
01342           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
01343           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
01344         }
01345         /* Flush FIFO */
01346         HAL_CRYP_FIFO_FLUSH(hcryp);
01347 
01348         /* Set the phase */
01349         hcryp->Phase = CRYP_PHASE_PROCESS;
01350 
01351         /* Enable interrupts */
01352         __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
01353 
01354         /* Enable CRYP and start DES/TDES process*/
01355         __HAL_CRYP_ENABLE(hcryp);
01356 
01357         break;
01358 
01359       case CRYP_AES_ECB:
01360       case CRYP_AES_CBC:
01361       case CRYP_AES_CTR:
01362 
01363         /* AES decryption */
01364         status = CRYP_AES_Decrypt_IT(hcryp);
01365         break;
01366 
01367       case CRYP_AES_GCM:
01368 
01369         /* AES GCM decryption */
01370         status = CRYP_AESGCM_Process_IT(hcryp) ;
01371         break;
01372 
01373       case CRYP_AES_CCM:
01374 
01375         /* AES CCMdecryption */
01376         status = CRYP_AESCCM_Process_IT(hcryp);
01377         break;
01378 
01379       default:
01380         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
01381         status = HAL_ERROR;
01382         break;
01383     }
01384   }
01385   else
01386   {
01387     /* Busy error code field */
01388     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
01389     status = HAL_ERROR;
01390   }
01391 
01392   /* Return function status */
01393   return status;
01394 }
01395 
01396 /**
01397   * @brief  Encryption in DMA mode.
01398   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01399   *         the configuration information for CRYP module
01400   * @param  Input: Pointer to the input buffer (plaintext)
01401   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
01402   * @param  Output: Pointer to the output buffer(ciphertext)
01403   * @retval HAL status
01404   */
01405 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
01406 {
01407   HAL_StatusTypeDef status = HAL_OK;
01408   uint32_t algo;
01409   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
01410 
01411   if (hcryp->State == HAL_CRYP_STATE_READY)
01412   {
01413     /* Change state Busy */
01414     hcryp->State = HAL_CRYP_STATE_BUSY;
01415 
01416     /* Process locked */
01417     __HAL_LOCK(hcryp);
01418 
01419     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
01420     hcryp->CrypInCount = 0U;
01421     hcryp->CrypOutCount = 0U;
01422     hcryp->pCrypInBuffPtr = Input;
01423     hcryp->pCrypOutBuffPtr = Output;
01424 
01425     /*  Calculate Size parameter in Byte*/
01426     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
01427     {
01428       hcryp->Size = Size * 4U;
01429     }
01430     else
01431     {
01432       hcryp->Size = Size;
01433     }
01434 
01435     /* Set encryption operating mode*/
01436     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
01437 
01438     /* algo get algorithm selected */
01439     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
01440 
01441     switch (algo)
01442     {
01443       case CRYP_DES_ECB:
01444       case CRYP_DES_CBC:
01445       case CRYP_TDES_ECB:
01446       case CRYP_TDES_CBC:
01447 
01448         /*Set Key */
01449         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
01450         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
01451         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01452         {
01453           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
01454           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
01455           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
01456           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
01457         }
01458 
01459         /* Set the Initialization Vector*/
01460         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01461         {
01462           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
01463           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
01464         }
01465 
01466         /* Flush FIFO */
01467         HAL_CRYP_FIFO_FLUSH(hcryp);
01468 
01469         /* Set the phase */
01470         hcryp->Phase = CRYP_PHASE_PROCESS;
01471 
01472         /* Start DMA process transfer for DES/TDES */
01473         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
01474 
01475         break;
01476 
01477       case CRYP_AES_ECB:
01478       case CRYP_AES_CBC:
01479       case CRYP_AES_CTR:
01480 
01481         if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
01482         {
01483           if (hcryp->KeyIVConfig == 1U)
01484           {
01485             /* If the Key and IV configuration has to be done only once
01486                and if it has already been done, skip it */
01487             DoKeyIVConfig = 0U;
01488           }
01489           else
01490           {
01491             /* If the Key and IV configuration has to be done only once
01492                and if it has not been done already, do it and set KeyIVConfig
01493                to keep track it won't have to be done again next time */
01494             hcryp->KeyIVConfig = 1U;
01495           }
01496         }
01497 
01498         if (DoKeyIVConfig == 1U)
01499         {
01500           /*  Set the Key*/
01501           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
01502 
01503           /* Set the Initialization Vector*/
01504           if (hcryp->Init.Algorithm != CRYP_AES_ECB)
01505           {
01506           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
01507           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
01508           hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
01509           hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
01510           }
01511         } /* if (DoKeyIVConfig == 1U) */
01512 
01513         /* Set the phase */
01514         hcryp->Phase = CRYP_PHASE_PROCESS;
01515 
01516         /* Start DMA process transfer for AES */
01517         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
01518         break;
01519 
01520       case CRYP_AES_GCM:
01521 
01522         /* AES GCM encryption */
01523         status = CRYP_AESGCM_Process_DMA(hcryp) ;
01524         break;
01525 
01526       case CRYP_AES_CCM:
01527 
01528         /* AES CCM encryption */
01529         status = CRYP_AESCCM_Process_DMA(hcryp);
01530         break;
01531 
01532       default:
01533         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
01534         status =  HAL_ERROR;
01535         break;
01536     }
01537   }
01538   else
01539   {
01540     /* Busy error code field */
01541     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
01542     status =  HAL_ERROR;
01543   }
01544 
01545   /* Return function status */
01546   return status;
01547 }
01548 
01549 /**
01550   * @brief  Decryption in DMA mode.
01551   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01552   *         the configuration information for CRYP module
01553   * @param  Input: Pointer to the input buffer (ciphertext )
01554   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
01555   * @param  Output: Pointer to the output buffer(plaintext)
01556   * @retval HAL status
01557   */
01558 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
01559 {
01560   uint32_t algo;
01561   HAL_StatusTypeDef status = HAL_OK;
01562 
01563   if (hcryp->State == HAL_CRYP_STATE_READY)
01564   {
01565     /* Change state Busy */
01566     hcryp->State = HAL_CRYP_STATE_BUSY;
01567 
01568     /* Process locked */
01569     __HAL_LOCK(hcryp);
01570 
01571     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
01572     hcryp->CrypInCount = 0U;
01573     hcryp->CrypOutCount = 0U;
01574     hcryp->pCrypInBuffPtr = Input;
01575     hcryp->pCrypOutBuffPtr = Output;
01576 
01577     /*  Calculate Size parameter in Byte*/
01578     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
01579     {
01580       hcryp->Size = Size * 4U;
01581     }
01582     else
01583     {
01584       hcryp->Size = Size;
01585     }
01586 
01587     /* Set decryption operating mode*/
01588     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
01589 
01590     /* algo get algorithm selected */
01591     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
01592 
01593     switch (algo)
01594     {
01595       case CRYP_DES_ECB:
01596       case CRYP_DES_CBC:
01597       case CRYP_TDES_ECB:
01598       case CRYP_TDES_CBC:
01599 
01600         /*Set Key */
01601         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
01602         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
01603         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01604         {
01605           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
01606           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
01607           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
01608           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
01609         }
01610 
01611         /* Set the Initialization Vector*/
01612         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01613         {
01614           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
01615           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
01616         }
01617 
01618         /* Flush FIFO */
01619         HAL_CRYP_FIFO_FLUSH(hcryp);
01620 
01621         /* Set the phase */
01622         hcryp->Phase = CRYP_PHASE_PROCESS;
01623 
01624         /* Start DMA process transfer for DES/TDES */
01625         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
01626         break;
01627 
01628       case CRYP_AES_ECB:
01629       case CRYP_AES_CBC:
01630       case CRYP_AES_CTR:
01631 
01632         /* AES decryption */
01633         status = CRYP_AES_Decrypt_DMA(hcryp);
01634         break;
01635 
01636       case CRYP_AES_GCM:
01637 
01638         /* AES GCM decryption */
01639         status = CRYP_AESGCM_Process_DMA(hcryp) ;
01640 
01641         break;
01642 
01643       case CRYP_AES_CCM:
01644 
01645         /* AES CCM decryption */
01646         status = CRYP_AESCCM_Process_DMA(hcryp);
01647         break;
01648 
01649       default:
01650         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
01651         status =  HAL_ERROR;
01652         break;
01653     }
01654   }
01655   else
01656   {
01657     /* Busy error code field */
01658     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
01659     status = HAL_ERROR;
01660   }
01661 
01662   /* Return function status */
01663   return status;
01664 }
01665 
01666 /**
01667   * @}
01668   */
01669 
01670 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
01671   *  @brief    CRYP IRQ handler.
01672   *
01673 @verbatim
01674   ==============================================================================
01675                 ##### CRYP IRQ handler management #####
01676   ==============================================================================
01677 [..]  This section provides CRYP IRQ handler and callback functions.
01678       (+) HAL_CRYP_IRQHandler CRYP interrupt request
01679       (+) HAL_CRYP_InCpltCallback input data transfer complete callback
01680       (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
01681       (+) HAL_CRYP_ErrorCallback  CRYP error callback
01682       (+) HAL_CRYP_GetState return the CRYP state
01683       (+) HAL_CRYP_GetError return the CRYP error code
01684 @endverbatim
01685   * @{
01686   */
01687 
01688 /**
01689   * @brief  This function handles cryptographic interrupt request.
01690   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01691   *         the configuration information for CRYP module
01692   * @retval None
01693   */
01694 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
01695 {
01696   uint32_t itstatus = hcryp->Instance->MISR;
01697 
01698   if ((itstatus & (CRYP_IT_INI | CRYP_IT_OUTI)) != 0U)
01699   {
01700     if ((hcryp->Init.Algorithm == CRYP_DES_ECB) || (hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
01701     {
01702       CRYP_TDES_IT(hcryp); /* DES or TDES*/
01703     }
01704     else if ((hcryp->Init.Algorithm == CRYP_AES_ECB) || (hcryp->Init.Algorithm == CRYP_AES_CBC) || (hcryp->Init.Algorithm == CRYP_AES_CTR))
01705     {
01706       CRYP_AES_IT(hcryp); /*AES*/
01707     }
01708 
01709     else if ((hcryp->Init.Algorithm == CRYP_AES_GCM) || (hcryp->Init.Algorithm == CRYP_CR_ALGOMODE_AES_CCM))
01710     {
01711       /* if header phase */
01712       if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
01713       {
01714         CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
01715       }
01716       else  /* if payload phase */
01717       {
01718         CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
01719       }
01720     }
01721     else
01722     {
01723       /* Nothing to do */
01724     }
01725   }
01726 }
01727 
01728 /**
01729   * @brief  Return the CRYP error code.
01730   * @param  hcryp : pointer to a CRYP_HandleTypeDef structure that contains
01731   *                 the configuration information for the  CRYP IP
01732   * @retval CRYP error code
01733   */
01734 uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp)
01735 {
01736   return hcryp->ErrorCode;
01737 }
01738 
01739 /**
01740   * @brief  Returns the CRYP state.
01741   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01742   *         the configuration information for CRYP module.
01743   * @retval HAL state
01744   */
01745 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp)
01746 {
01747   return hcryp->State;
01748 }
01749 
01750 /**
01751   * @brief  Input FIFO transfer completed callback.
01752   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01753   *         the configuration information for CRYP module.
01754   * @retval None
01755   */
01756 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
01757 {
01758   /* Prevent unused argument(s) compilation warning */
01759   UNUSED(hcryp);
01760 
01761   /* NOTE : This function Should not be modified, when the callback is needed,
01762             the HAL_CRYP_InCpltCallback could be implemented in the user file
01763    */
01764 }
01765 
01766 /**
01767   * @brief  Output FIFO transfer completed callback.
01768   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01769   *         the configuration information for CRYP module.
01770   * @retval None
01771   */
01772 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
01773 {
01774   /* Prevent unused argument(s) compilation warning */
01775   UNUSED(hcryp);
01776 
01777   /* NOTE : This function Should not be modified, when the callback is needed,
01778             the HAL_CRYP_OutCpltCallback could be implemented in the user file
01779    */
01780 }
01781 
01782 /**
01783   * @brief  CRYP error callback.
01784   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01785   *         the configuration information for CRYP module.
01786   * @retval None
01787   */
01788 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
01789 {
01790   /* Prevent unused argument(s) compilation warning */
01791   UNUSED(hcryp);
01792 
01793   /* NOTE : This function Should not be modified, when the callback is needed,
01794             the HAL_CRYP_ErrorCallback could be implemented in the user file
01795    */
01796 }
01797 /**
01798   * @}
01799   */
01800 
01801 /* Private functions ---------------------------------------------------------*/
01802 /** @addtogroup CRYP_Private_Functions
01803   * @{
01804   */
01805 
01806 /**
01807   * @brief  Encryption in ECB/CBC Algorithm with DES/TDES standard.
01808   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01809   *         the configuration information for CRYP module
01810   * @param  Timeout: Timeout value
01811   * @retval HAL status
01812   */
01813 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
01814 {
01815 
01816   uint32_t temp;  /* Temporary CrypOutBuff */
01817   uint16_t incount; /* Temporary CrypInCount Value */
01818   uint16_t outcount;  /* Temporary CrypOutCount Value */
01819 
01820   /* Enable CRYP */
01821   __HAL_CRYP_ENABLE(hcryp);
01822   /*Temporary CrypOutCount Value*/
01823   outcount = hcryp->CrypOutCount;
01824 
01825   /*Start processing*/
01826   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
01827   {
01828     /* Temporary CrypInCount Value */
01829     incount = hcryp->CrypInCount;
01830     /* Write plain data and get cipher data */
01831     if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
01832     {
01833       /* Write the input block in the IN FIFO */
01834       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
01835       hcryp->CrypInCount++;
01836       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
01837       hcryp->CrypInCount++;
01838     }
01839 
01840     /* Wait for OFNE flag to be raised */
01841     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
01842     {
01843       /* Disable the CRYP peripheral clock */
01844       __HAL_CRYP_DISABLE(hcryp);
01845 
01846       /* Change state & errorCode*/
01847       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
01848       hcryp->State = HAL_CRYP_STATE_READY;
01849 
01850       /* Process unlocked */
01851       __HAL_UNLOCK(hcryp);
01852 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
01853       /*Call registered error callback*/
01854       hcryp->ErrorCallback(hcryp);
01855 #else
01856       /*Call legacy weak error callback*/
01857       HAL_CRYP_ErrorCallback(hcryp);
01858 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
01859     }
01860 
01861     /*Temporary CrypOutCount Value*/
01862     outcount = hcryp->CrypOutCount;
01863 
01864     if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
01865     {
01866       /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer  */
01867       temp = hcryp->Instance->DOUT;
01868       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
01869       hcryp->CrypOutCount++;
01870       temp = hcryp->Instance->DOUT;
01871       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
01872       hcryp->CrypOutCount++;
01873     }
01874     /*Temporary CrypOutCount Value*/
01875     outcount = hcryp->CrypOutCount;
01876   }
01877   /* Disable CRYP */
01878   __HAL_CRYP_DISABLE(hcryp);
01879   /* Change the CRYP state */
01880   hcryp->State = HAL_CRYP_STATE_READY;
01881 
01882   /* Return function status */
01883   return HAL_OK;
01884 }
01885 
01886 /**
01887   * @brief  CRYP block input/output data handling under interruption with DES/TDES standard.
01888   * @note   The function is called under interruption only, once
01889   *         interruptions have been enabled by CRYP_Decrypt_IT() and CRYP_Encrypt_IT().
01890   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
01891   *         the configuration information for CRYP module.
01892   * @retval HAL status
01893   */
01894 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp)
01895 {
01896   uint32_t temp;  /* Temporary CrypOutBuff */
01897 
01898   if (hcryp->State == HAL_CRYP_STATE_BUSY)
01899   {
01900     if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI) != 0x0U)
01901     {
01902       if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_INRIS) != 0x0U)
01903       {
01904         /* Write input block in the IN FIFO */
01905         hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
01906         hcryp->CrypInCount++;
01907         hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
01908         hcryp->CrypInCount++;
01909         
01910         if (hcryp->CrypInCount == (hcryp->Size / 4U))
01911         {
01912           /* Disable interruption */
01913           __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
01914           
01915           /* Call the input data transfer complete callback */
01916 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
01917           /*Call registered Input complete callback*/
01918           hcryp->InCpltCallback(hcryp);
01919 #else
01920           /*Call legacy weak Input complete callback*/
01921           HAL_CRYP_InCpltCallback(hcryp);
01922 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
01923         }
01924       }
01925     }
01926 
01927     if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI) != 0x0U)
01928     {
01929       if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_OUTRIS) != 0x0U)
01930       {
01931         /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer  */
01932         temp = hcryp->Instance->DOUT;
01933         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
01934         hcryp->CrypOutCount++;
01935         temp = hcryp->Instance->DOUT;
01936         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
01937         hcryp->CrypOutCount++;
01938         if (hcryp->CrypOutCount == (hcryp->Size / 4U))
01939         {
01940           /* Disable interruption */
01941           __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
01942           
01943           /* Disable CRYP */
01944           __HAL_CRYP_DISABLE(hcryp);
01945           
01946           /* Process unlocked */
01947           __HAL_UNLOCK(hcryp);
01948           
01949           /* Change the CRYP state */
01950           hcryp->State = HAL_CRYP_STATE_READY;
01951           
01952           /* Call output transfer complete callback */
01953 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
01954           /*Call registered Output complete callback*/
01955           hcryp->OutCpltCallback(hcryp);
01956 #else
01957           /*Call legacy weak Output complete callback*/
01958           HAL_CRYP_OutCpltCallback(hcryp);
01959 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
01960           
01961         }
01962       }
01963     }
01964   }
01965   else
01966   {
01967     /* Process unlocked */
01968     __HAL_UNLOCK(hcryp);
01969     /* Busy error code field */
01970     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
01971 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
01972     /*Call registered error callback*/
01973     hcryp->ErrorCallback(hcryp);
01974 #else
01975     /*Call legacy weak error callback*/
01976     HAL_CRYP_ErrorCallback(hcryp);
01977 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
01978   }
01979 }
01980 
01981 /**
01982   * @brief  Encryption in ECB/CBC & CTR Algorithm with AES Standard
01983   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
01984   * @param  Timeout: specify Timeout value
01985   * @retval HAL status
01986   */
01987 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
01988 {
01989   uint16_t outcount;  /* Temporary CrypOutCount Value */
01990   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
01991 
01992   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
01993   {
01994     if (hcryp->KeyIVConfig == 1U)
01995     {
01996       /* If the Key and IV configuration has to be done only once
01997          and if it has already been done, skip it */
01998       DoKeyIVConfig = 0U;
01999     }
02000     else
02001     {
02002       /* If the Key and IV configuration has to be done only once
02003          and if it has not been done already, do it and set KeyIVConfig
02004          to keep track it won't have to be done again next time */
02005       hcryp->KeyIVConfig = 1U;
02006     }
02007   }
02008 
02009   if (DoKeyIVConfig == 1U)
02010   {
02011     /*  Set the Key*/
02012     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02013 
02014     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
02015     {
02016       /* Set the Initialization Vector*/
02017       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
02018       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
02019       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
02020       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
02021     }
02022   } /* if (DoKeyIVConfig == 1U) */
02023 
02024   /* Set the phase */
02025   hcryp->Phase = CRYP_PHASE_PROCESS;
02026 
02027   /* Enable CRYP */
02028   __HAL_CRYP_ENABLE(hcryp);
02029   /*Temporary CrypOutCount Value*/
02030   outcount = hcryp->CrypOutCount;
02031 
02032   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
02033   {
02034     /* Write plain Ddta and get cipher data */
02035     CRYP_AES_ProcessData(hcryp, Timeout);
02036     /*Temporary CrypOutCount Value*/
02037     outcount = hcryp->CrypOutCount;
02038   }
02039 
02040   /* Disable CRYP */
02041   __HAL_CRYP_DISABLE(hcryp);
02042 
02043   /* Change the CRYP state */
02044   hcryp->State = HAL_CRYP_STATE_READY;
02045 
02046   /* Return function status */
02047   return HAL_OK;
02048 }
02049 
02050 /**
02051   * @brief  Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
02052   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
02053   *         the configuration information for CRYP module
02054   * @retval HAL status
02055   */
02056 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
02057 {
02058   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
02059 
02060   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
02061   {
02062     if (hcryp->KeyIVConfig == 1U)
02063     {
02064       /* If the Key and IV configuration has to be done only once
02065          and if it has already been done, skip it */
02066       DoKeyIVConfig = 0U;
02067     }
02068     else
02069     {
02070       /* If the Key and IV configuration has to be done only once
02071          and if it has not been done already, do it and set KeyIVConfig
02072          to keep track it won't have to be done again next time */
02073       hcryp->KeyIVConfig = 1U;
02074     }
02075   }
02076 
02077   if (DoKeyIVConfig == 1U)
02078   {
02079     /*  Set the Key*/
02080     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02081 
02082     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
02083     {
02084       /* Set the Initialization Vector*/
02085       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
02086       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
02087       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
02088       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
02089     }
02090   } /* if (DoKeyIVConfig == 1U) */
02091 
02092   /* Set the phase */
02093   hcryp->Phase = CRYP_PHASE_PROCESS;
02094 
02095   if (hcryp->Size != 0U)
02096   {
02097     /* Enable interrupts */
02098     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
02099 
02100     /* Enable CRYP */
02101     __HAL_CRYP_ENABLE(hcryp);
02102   }
02103   else
02104   {
02105     /* Change the CRYP state */
02106     hcryp->State = HAL_CRYP_STATE_READY;
02107 
02108     /* Process unlocked */
02109     __HAL_UNLOCK(hcryp);
02110   }
02111 
02112   /* Return function status */
02113   return HAL_OK;
02114 }
02115 
02116 /**
02117   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard
02118   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
02119   * @param  Timeout: Specify Timeout value
02120   * @retval HAL status
02121   */
02122 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
02123 {
02124   uint16_t outcount;  /* Temporary CrypOutCount Value */
02125   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
02126 
02127   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
02128   {
02129     if (hcryp->KeyIVConfig == 1U)
02130     {
02131       /* If the Key and IV configuration has to be done only once
02132          and if it has already been done, skip it */
02133       DoKeyIVConfig = 0U;
02134     }
02135     else
02136     {
02137       /* If the Key and IV configuration has to be done only once
02138          and if it has not been done already, do it and set KeyIVConfig
02139          to keep track it won't have to be done again next time */
02140       hcryp->KeyIVConfig = 1U;
02141     }
02142   }
02143 
02144   if (DoKeyIVConfig == 1U)
02145   {
02146   /*  Key preparation for ECB/CBC */
02147   if (hcryp->Init.Algorithm != CRYP_AES_CTR)   /*ECB or CBC*/
02148   {
02149     /* change ALGOMODE to key preparation for decryption*/
02150     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
02151 
02152     /*  Set the Key*/
02153     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02154 
02155     /* Enable CRYP */
02156     __HAL_CRYP_ENABLE(hcryp);
02157 
02158     /* Wait for BUSY flag to be raised */
02159     if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
02160     {
02161       /* Disable the CRYP peripheral clock */
02162       __HAL_CRYP_DISABLE(hcryp);
02163 
02164       /* Change state */
02165       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
02166       hcryp->State = HAL_CRYP_STATE_READY;
02167 
02168       /* Process unlocked */
02169       __HAL_UNLOCK(hcryp);
02170       return HAL_ERROR;
02171     }
02172     /* Turn back to ALGOMODE of the configuration */
02173     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
02174   }
02175   else  /*Algorithm CTR */
02176   {
02177     /*  Set the Key*/
02178     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02179   }
02180 
02181   /* Set IV */
02182   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
02183   {
02184     /* Set the Initialization Vector*/
02185     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
02186     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
02187     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
02188     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
02189   }
02190 } /* if (DoKeyIVConfig == 1U) */
02191     
02192   /* Set the phase */
02193   hcryp->Phase = CRYP_PHASE_PROCESS;
02194 
02195   /* Enable CRYP */
02196   __HAL_CRYP_ENABLE(hcryp);
02197 
02198   /*Temporary CrypOutCount Value*/
02199   outcount = hcryp->CrypOutCount;
02200 
02201   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
02202   {
02203     /* Write plain data and get cipher data */
02204     CRYP_AES_ProcessData(hcryp, Timeout);
02205     /*Temporary CrypOutCount Value*/
02206     outcount = hcryp->CrypOutCount;
02207   }
02208 
02209   /* Disable CRYP */
02210   __HAL_CRYP_DISABLE(hcryp);
02211 
02212   /* Change the CRYP state */
02213   hcryp->State = HAL_CRYP_STATE_READY;
02214 
02215   /* Return function status */
02216   return HAL_OK;
02217 }
02218 /**
02219   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
02220   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
02221   *         the configuration information for CRYP module
02222   * @retval HAL status
02223   */
02224 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
02225 {
02226   __IO uint32_t count = 0U;
02227    uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
02228 
02229   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
02230   {
02231     if (hcryp->KeyIVConfig == 1U)
02232     {
02233       /* If the Key and IV configuration has to be done only once
02234          and if it has already been done, skip it */
02235       DoKeyIVConfig = 0U;
02236     }
02237     else
02238     {
02239       /* If the Key and IV configuration has to be done only once
02240          and if it has not been done already, do it and set KeyIVConfig
02241          to keep track it won't have to be done again next time */
02242       hcryp->KeyIVConfig = 1U;
02243     }
02244   }
02245 
02246   if (DoKeyIVConfig == 1U)
02247   {
02248   /*  Key preparation for ECB/CBC */
02249   if (hcryp->Init.Algorithm != CRYP_AES_CTR)
02250   {
02251     /* change ALGOMODE to key preparation for decryption*/
02252     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
02253 
02254     /*  Set the Key*/
02255     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02256 
02257     /* Enable CRYP */
02258     __HAL_CRYP_ENABLE(hcryp);
02259 
02260     /* Wait for BUSY flag to be raised */
02261     count = CRYP_TIMEOUT_KEYPREPARATION;
02262     do
02263     {
02264       count-- ;
02265       if (count == 0U)
02266       {
02267         /* Change state */
02268         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
02269         hcryp->State = HAL_CRYP_STATE_READY;
02270 
02271         /* Process unlocked */
02272         __HAL_UNLOCK(hcryp);
02273         return HAL_ERROR;
02274       }
02275     } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
02276 
02277     /* Turn back to ALGOMODE of the configuration */
02278     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
02279   }
02280   else  /*Algorithm CTR */
02281   {
02282     /*  Set the Key*/
02283     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02284   }
02285 
02286   /* Set IV */
02287   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
02288   {
02289     /* Set the Initialization Vector*/
02290     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
02291     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
02292     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
02293     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
02294   }
02295 } /* if (DoKeyIVConfig == 1U) */
02296     
02297   /* Set the phase */
02298   hcryp->Phase = CRYP_PHASE_PROCESS;
02299   if (hcryp->Size != 0U)
02300   {
02301     /* Enable interrupts */
02302     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
02303 
02304     /* Enable CRYP */
02305     __HAL_CRYP_ENABLE(hcryp);
02306   }
02307   else
02308   {
02309     /* Process locked */
02310     __HAL_UNLOCK(hcryp);
02311 
02312     /* Change the CRYP state */
02313     hcryp->State = HAL_CRYP_STATE_READY;
02314   }
02315   /* Return function status */
02316   return HAL_OK;
02317 }
02318 /**
02319   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
02320   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
02321   *         the configuration information for CRYP module
02322   * @retval HAL status
02323   */
02324 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
02325 {
02326   __IO uint32_t count = 0U;
02327   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
02328 
02329   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
02330   {
02331     if (hcryp->KeyIVConfig == 1U)
02332     {
02333       /* If the Key and IV configuration has to be done only once
02334          and if it has already been done, skip it */
02335       DoKeyIVConfig = 0U;
02336     }
02337     else
02338     {
02339       /* If the Key and IV configuration has to be done only once
02340          and if it has not been done already, do it and set KeyIVConfig
02341          to keep track it won't have to be done again next time */
02342       hcryp->KeyIVConfig = 1U;
02343     }
02344   }
02345 
02346   if (DoKeyIVConfig == 1U)
02347   {
02348   /*  Key preparation for ECB/CBC */
02349   if (hcryp->Init.Algorithm != CRYP_AES_CTR)
02350   {
02351     /* change ALGOMODE to key preparation for decryption*/
02352     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
02353 
02354     /*  Set the Key*/
02355     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02356 
02357     /* Enable CRYP */
02358     __HAL_CRYP_ENABLE(hcryp);
02359 
02360     /* Wait for BUSY flag to be raised */
02361     count = CRYP_TIMEOUT_KEYPREPARATION;
02362     do
02363     {
02364       count-- ;
02365       if (count == 0U)
02366       {
02367         /* Disable the CRYP peripheral clock */
02368         __HAL_CRYP_DISABLE(hcryp);
02369 
02370         /* Change state */
02371         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
02372         hcryp->State = HAL_CRYP_STATE_READY;
02373 
02374         /* Process unlocked */
02375         __HAL_UNLOCK(hcryp);
02376         return HAL_ERROR;
02377       }
02378     } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
02379 
02380     /* Turn back to ALGOMODE of the configuration */
02381     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
02382   }
02383   else  /*Algorithm CTR */
02384   {
02385     /*  Set the Key*/
02386     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02387   }
02388 
02389   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
02390   {
02391     /* Set the Initialization Vector*/
02392     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
02393     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
02394     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
02395     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
02396   }
02397 } /* if (DoKeyIVConfig == 1U) */
02398 
02399   /* Set the phase */
02400   hcryp->Phase = CRYP_PHASE_PROCESS;
02401 
02402   if (hcryp->Size != 0U)
02403   {
02404     /* Set the input and output addresses and start DMA transfer */
02405     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
02406   }
02407   else
02408   {
02409     /* Process unlocked */
02410     __HAL_UNLOCK(hcryp);
02411 
02412     /* Change the CRYP state */
02413     hcryp->State = HAL_CRYP_STATE_READY;
02414   }
02415 
02416   /* Return function status */
02417   return HAL_OK;
02418 }
02419 
02420 
02421 /**
02422   * @brief  DMA CRYP input data process complete callback.
02423   * @param  hdma: DMA handle
02424   * @retval None
02425   */
02426 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
02427 {
02428   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02429 
02430   /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit
02431   in the DMACR register */
02432   hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
02433 
02434   /* Call input data transfer complete callback */
02435 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02436   /*Call registered Input complete callback*/
02437   hcryp->InCpltCallback(hcryp);
02438 #else
02439   /*Call legacy weak Input complete callback*/
02440   HAL_CRYP_InCpltCallback(hcryp);
02441 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02442 }
02443 
02444 /**
02445   * @brief  DMA CRYP output data process complete callback.
02446   * @param  hdma: DMA handle
02447   * @retval None
02448   */
02449 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
02450 {
02451   uint32_t count;
02452   uint32_t npblb;
02453   uint32_t lastwordsize;
02454   uint32_t temp;  /* Temporary CrypOutBuff */
02455   uint32_t temp_cr_algodir;  
02456   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02457 
02458 
02459   /* Disable the DMA transfer for output FIFO */
02460   hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
02461   
02462   /* Last block transfer in case of GCM or CCM with Size not %16*/
02463   if (((hcryp->Size) % 16U) != 0U)
02464   {
02465     /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA  */
02466     hcryp->CrypInCount = (hcryp->Size / 16U) * 4U ;
02467     hcryp->CrypOutCount = hcryp->CrypInCount;
02468     
02469     /* Compute the number of padding bytes in last block of payload */
02470     npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
02471     
02472 #if !defined (CRYP_VER_2_2)
02473     if (hcryp->Version >= REV_ID_B)
02474 #endif /*End of not defined CRYP_VER_2_2*/
02475     {
02476     /* Case of AES GCM payload encryption or AES CCM payload decryption to get right tag */
02477       temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
02478       if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
02479           ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
02480       {
02481         /* Disable the CRYP */
02482         __HAL_CRYP_DISABLE(hcryp);
02483 
02484         /* Specify the number of non-valid bytes using NPBLB register*/
02485         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
02486 
02487         /* Enable CRYP to start the final phase */
02488         __HAL_CRYP_ENABLE(hcryp);
02489       }
02490     }
02491     
02492     /* Number of valid words (lastwordsize) in last block */
02493     if ((npblb % 4U) == 0U)
02494     {
02495       lastwordsize = (16U - npblb) / 4U;
02496     }
02497     else
02498     {
02499       lastwordsize = ((16U - npblb) / 4U) + 1U;
02500     }
02501     /* Write the last input block in the IN FIFO */
02502     for (count = 0U; count < lastwordsize; count ++)
02503     {
02504       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02505       hcryp->CrypInCount++;
02506     }
02507     /* Pad the data with zeros to have a complete block */
02508     while (count < 4U)
02509     {
02510       hcryp->Instance->DIN  = 0U;
02511       count++;
02512     }
02513     /* Wait for OFNE flag to be raised */
02514     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
02515     do
02516     {
02517       count-- ;
02518       if (count == 0U)
02519       {
02520         /* Disable the CRYP peripheral clock */
02521         __HAL_CRYP_DISABLE(hcryp);
02522 
02523         /* Change state */
02524         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
02525         hcryp->State = HAL_CRYP_STATE_READY;
02526 
02527         /* Process unlocked */
02528         __HAL_UNLOCK(hcryp);
02529 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02530         /*Call registered error callback*/
02531         hcryp->ErrorCallback(hcryp);
02532 #else
02533         /*Call legacy weak error callback*/
02534         HAL_CRYP_ErrorCallback(hcryp);
02535 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02536       }
02537     } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
02538 
02539     /*Read the output block from the output FIFO */
02540     for (count = 0U; count < 4U; count++)
02541     {
02542       /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
02543       temp = hcryp->Instance->DOUT;
02544 
02545       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
02546       hcryp->CrypOutCount++;
02547     }
02548   } /*End of last block transfer in case of GCM or CCM */
02549 
02550   if ((hcryp->Init.Algorithm & CRYP_AES_GCM) != CRYP_AES_GCM)
02551   {
02552     /* Disable CRYP  (not allowed in  GCM)*/
02553     __HAL_CRYP_DISABLE(hcryp);
02554   }
02555 
02556   /* Change the CRYP state to ready */
02557   hcryp->State = HAL_CRYP_STATE_READY;
02558 
02559   /* Process unlocked */
02560   __HAL_UNLOCK(hcryp);
02561 
02562   /* Call output data transfer complete callback */
02563 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02564   /*Call registered Output complete callback*/
02565   hcryp->OutCpltCallback(hcryp);
02566 #else
02567   /*Call legacy weak Output complete callback*/
02568   HAL_CRYP_OutCpltCallback(hcryp);
02569 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02570 }
02571 
02572 /**
02573   * @brief  DMA CRYP communication error callback.
02574   * @param  hdma: DMA handle
02575   * @retval None
02576   */
02577 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
02578 {
02579   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02580 
02581   /* Change the CRYP peripheral state */
02582   hcryp->State = HAL_CRYP_STATE_READY;
02583 
02584   /* DMA error code field */
02585   hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
02586 
02587   /* Call error callback */
02588 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02589   /*Call registered error callback*/
02590   hcryp->ErrorCallback(hcryp);
02591 #else
02592   /*Call legacy weak error callback*/
02593   HAL_CRYP_ErrorCallback(hcryp);
02594 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02595 }
02596 
02597 /**
02598   * @brief  Set the DMA configuration and start the DMA transfer
02599   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
02600   *         the configuration information for CRYP module
02601   * @param  inputaddr: address of the input buffer
02602   * @param  Size: size of the input buffer, must be a multiple of 16.
02603   * @param  outputaddr: address of the output buffer
02604   * @retval None
02605   */
02606 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
02607 {
02608   /* Set the CRYP DMA transfer complete callback */
02609   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
02610 
02611   /* Set the DMA input error callback */
02612   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
02613 
02614   /* Set the CRYP DMA transfer complete callback */
02615   hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
02616 
02617   /* Set the DMA output error callback */
02618   hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
02619 
02620   /* Enable CRYP */
02621   __HAL_CRYP_ENABLE(hcryp);
02622 
02623   /* Enable the input DMA Stream */
02624   if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DIN, Size) != HAL_OK)
02625   {
02626     /* DMA error code field */
02627     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
02628 
02629     /* Call error callback */
02630 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02631     /*Call registered error callback*/
02632     hcryp->ErrorCallback(hcryp);
02633 #else
02634     /*Call legacy weak error callback*/
02635     HAL_CRYP_ErrorCallback(hcryp);
02636 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02637   }
02638 
02639   /* Enable the output DMA Stream */
02640   if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size) != HAL_OK)
02641   {
02642     /* DMA error code field */
02643     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
02644 
02645     /* Call error callback */
02646 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02647     /*Call registered error callback*/
02648     hcryp->ErrorCallback(hcryp);
02649 #else
02650     /*Call legacy weak error callback*/
02651     HAL_CRYP_ErrorCallback(hcryp);
02652 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02653   }
02654   /* Enable In/Out DMA request */
02655   hcryp->Instance->DMACR = CRYP_DMACR_DOEN | CRYP_DMACR_DIEN;
02656 }
02657 
02658 /**
02659   * @brief  Process Data: Write Input data in polling mode and used in AES functions.
02660   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
02661   *         the configuration information for CRYP module
02662   * @param  Timeout: Specify Timeout value
02663   * @retval None
02664   */
02665 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
02666 {
02667 
02668   uint32_t temp[4];  /* Temporary CrypOutBuff */
02669   uint16_t incount;  /* Temporary CrypInCount Value */
02670   uint16_t outcount;  /* Temporary CrypOutCount Value */
02671   uint32_t i;
02672 
02673   /*Temporary CrypOutCount Value*/
02674   incount = hcryp->CrypInCount;
02675 
02676   if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < ((hcryp->Size) / 4U)))
02677   {
02678     /* Write the input block in the IN FIFO */
02679     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02680     hcryp->CrypInCount++;
02681     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02682     hcryp->CrypInCount++;
02683     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02684     hcryp->CrypInCount++;
02685     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02686     hcryp->CrypInCount++;
02687   }
02688 
02689   /* Wait for OFNE flag to be raised */
02690   if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
02691   {
02692     /* Disable the CRYP peripheral clock */
02693     __HAL_CRYP_DISABLE(hcryp);
02694 
02695     /* Change state & error code*/
02696     hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
02697     hcryp->State = HAL_CRYP_STATE_READY;
02698 
02699     /* Process unlocked */
02700     __HAL_UNLOCK(hcryp);
02701 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02702     /*Call registered error callback*/
02703     hcryp->ErrorCallback(hcryp);
02704 #else
02705     /*Call legacy weak error callback*/
02706     HAL_CRYP_ErrorCallback(hcryp);
02707 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02708   }
02709   /*Temporary CrypOutCount Value*/
02710   outcount = hcryp->CrypOutCount;
02711 
02712   if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < ((hcryp->Size) / 4U)))
02713   {
02714     /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer  */
02715     for (i = 0U; i < 4U; i++)
02716     {
02717       temp[i] = hcryp->Instance->DOUT;
02718     }
02719     i = 0U;
02720     while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
02721     {
02722       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
02723       hcryp->CrypOutCount++;
02724       i++;
02725     }
02726   }
02727 }
02728 
02729 /**
02730   * @brief  Handle CRYP block input/output data handling under interruption.
02731   * @note   The function is called under interruption only, once
02732   *         interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
02733   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
02734   *         the configuration information for CRYP module.
02735   * @retval HAL status
02736   */
02737 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
02738 {
02739   uint32_t temp[4];  /* Temporary CrypOutBuff */
02740   uint16_t incount; /* Temporary CrypInCount Value */
02741   uint16_t outcount;  /* Temporary CrypOutCount Value */
02742   uint32_t i;
02743 
02744   if (hcryp->State == HAL_CRYP_STATE_BUSY)
02745   {
02746     /*Temporary CrypOutCount Value*/
02747     incount = hcryp->CrypInCount;
02748 
02749     if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
02750     {
02751       /* Write the input block in the IN FIFO */
02752       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02753       hcryp->CrypInCount++;
02754       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02755       hcryp->CrypInCount++;
02756       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02757       hcryp->CrypInCount++;
02758       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
02759       hcryp->CrypInCount++;
02760       if (hcryp->CrypInCount == (hcryp->Size / 4U))
02761       {
02762         /* Disable interrupts */
02763         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
02764 
02765         /* Call the input data transfer complete callback */
02766 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02767         /*Call registered Input complete callback*/
02768         hcryp->InCpltCallback(hcryp);
02769 #else
02770         /*Call legacy weak Input complete callback*/
02771         HAL_CRYP_InCpltCallback(hcryp);
02772 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02773       }
02774     }
02775 
02776     /*Temporary CrypOutCount Value*/
02777     outcount = hcryp->CrypOutCount;
02778 
02779     if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
02780     {
02781       /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer  */
02782       for (i = 0U; i < 4U; i++)
02783       {
02784         temp[i] = hcryp->Instance->DOUT;
02785       }
02786       i = 0U;
02787       while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
02788       {
02789         *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
02790         hcryp->CrypOutCount++;
02791         i++;
02792       }
02793       if (hcryp->CrypOutCount == (hcryp->Size / 4U))
02794       {
02795         /* Disable interrupts */
02796         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
02797 
02798         /* Change the CRYP state */
02799         hcryp->State = HAL_CRYP_STATE_READY;
02800 
02801         /* Disable CRYP */
02802         __HAL_CRYP_DISABLE(hcryp);
02803 
02804         /* Process unlocked */
02805         __HAL_UNLOCK(hcryp);
02806 
02807         /* Call output transfer complete callback */
02808 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02809         /*Call registered Output complete callback*/
02810         hcryp->OutCpltCallback(hcryp);
02811 #else
02812         /*Call legacy weak Output complete callback*/
02813         HAL_CRYP_OutCpltCallback(hcryp);
02814 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02815       }
02816     }
02817   }
02818   else
02819   {
02820     /* Process unlocked */
02821     __HAL_UNLOCK(hcryp);
02822     /* Busy error code field */
02823     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
02824 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
02825     /*Call registered error callback*/
02826     hcryp->ErrorCallback(hcryp);
02827 #else
02828     /*Call legacy weak error callback*/
02829     HAL_CRYP_ErrorCallback(hcryp);
02830 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
02831   }
02832 }
02833 
02834 /**
02835   * @brief  Writes Key in Key registers.
02836   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
02837   *         the configuration information for CRYP module
02838   * @param  KeySize: Size of Key
02839   * @retval None
02840   */
02841 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
02842 {
02843   switch (KeySize)
02844   {
02845     case CRYP_KEYSIZE_256B:
02846       hcryp->Instance->K0LR = *(uint32_t *)(hcryp->Init.pKey);
02847       hcryp->Instance->K0RR = *(uint32_t *)(hcryp->Init.pKey + 1);
02848       hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey + 2);
02849       hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 3);
02850       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 4);
02851       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 5);
02852       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 6);
02853       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 7);
02854       break;
02855     case CRYP_KEYSIZE_192B:
02856       hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
02857       hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
02858       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
02859       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
02860       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
02861       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
02862       break;
02863     case CRYP_KEYSIZE_128B:
02864       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey);
02865       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 1);
02866       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 2);
02867       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 3);
02868 
02869       break;
02870     default:
02871       break;
02872   }
02873 }
02874 
02875 /**
02876   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
02877   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
02878   *         the configuration information for CRYP module
02879   * @param  Timeout: Timeout duration
02880   * @retval HAL status
02881   */
02882 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
02883 {
02884   uint32_t tickstart;
02885   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
02886   uint32_t npblb ;
02887   uint32_t temp[4];  /* Temporary CrypOutBuff */
02888   uint32_t index ;
02889   uint32_t lastwordsize ;
02890   uint16_t outcount;  /* Temporary CrypOutCount Value */
02891   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
02892 
02893   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
02894   {
02895     if (hcryp->KeyIVConfig == 1U)
02896     {
02897       /* If the Key and IV configuration has to be done only once
02898          and if it has already been done, skip it */
02899       DoKeyIVConfig = 0U;
02900       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
02901     }
02902     else
02903     {
02904       /* If the Key and IV configuration has to be done only once
02905          and if it has not been done already, do it and set KeyIVConfig
02906          to keep track it won't have to be done again next time */
02907       hcryp->KeyIVConfig = 1U;
02908       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
02909     }
02910   }
02911   else
02912   {
02913     hcryp->SizesSum = hcryp->Size;
02914   }
02915 
02916   if (DoKeyIVConfig == 1U)
02917   {
02918   /*  Reset CrypHeaderCount */
02919   hcryp->CrypHeaderCount = 0U;
02920 
02921   /****************************** Init phase **********************************/
02922 
02923   CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
02924 
02925   /* Set the key */
02926   CRYP_SetKey(hcryp, hcryp->Init.KeySize);
02927 
02928   /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
02929   hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
02930   hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
02931   hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
02932   hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
02933 
02934   /* Enable the CRYP peripheral */
02935   __HAL_CRYP_ENABLE(hcryp);
02936 
02937   /* Get tick */
02938   tickstart = HAL_GetTick();
02939 
02940   /*Wait for the CRYPEN bit to be cleared*/
02941   while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
02942   {
02943     /* Check for the Timeout */
02944     if (Timeout != HAL_MAX_DELAY)
02945     {
02946       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
02947       {
02948         /* Disable the CRYP peripheral clock */
02949         __HAL_CRYP_DISABLE(hcryp);
02950 
02951         /* Change state */
02952         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
02953         hcryp->State = HAL_CRYP_STATE_READY;
02954 
02955         /* Process unlocked */
02956         __HAL_UNLOCK(hcryp);
02957         return HAL_ERROR;
02958       }
02959     }
02960   }
02961 
02962   /************************ Header phase *************************************/
02963 
02964   if (CRYP_GCMCCM_SetHeaderPhase(hcryp,  Timeout) != HAL_OK)
02965   {
02966     return HAL_ERROR;
02967   }
02968 
02969   /*************************Payload phase ************************************/
02970 
02971   /* Set the phase */
02972   hcryp->Phase = CRYP_PHASE_PROCESS;
02973 
02974   /* Disable the CRYP peripheral */
02975   __HAL_CRYP_DISABLE(hcryp);
02976 
02977 #if !defined (CRYP_VER_2_2)
02978   if (hcryp->Version >= REV_ID_B)
02979 #endif /*End of not defined CRYP_VER_2_2*/
02980   {
02981     /* Set to 0 the number of non-valid bytes using NPBLB register*/
02982     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
02983   }
02984 
02985   /* Select payload phase once the header phase is performed */
02986   CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
02987 
02988   /* Enable the CRYP peripheral */
02989   __HAL_CRYP_ENABLE(hcryp);
02990 } /* if (DoKeyIVConfig == 1U) */
02991   
02992   if ((hcryp->Size % 16U) != 0U)
02993   {
02994     /* recalculate  wordsize */
02995     wordsize = ((wordsize / 4U) * 4U) ;
02996   }
02997 
02998   /* Get tick */
02999   tickstart = HAL_GetTick();
03000   /*Temporary CrypOutCount Value*/
03001   outcount = hcryp->CrypOutCount;
03002 
03003   /* Write input data and get output Data */
03004   while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
03005   {
03006     /* Write plain data and get cipher data */
03007     CRYP_AES_ProcessData(hcryp, Timeout);
03008 
03009     /*Temporary CrypOutCount Value*/
03010     outcount = hcryp->CrypOutCount;
03011 
03012     /* Check for the Timeout */
03013     if (Timeout != HAL_MAX_DELAY)
03014     {
03015       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
03016       {
03017         /* Disable the CRYP peripheral clock */
03018         __HAL_CRYP_DISABLE(hcryp);
03019 
03020         /* Change state & error code */
03021         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03022         hcryp->State = HAL_CRYP_STATE_READY;
03023 
03024         /* Process unlocked */
03025         __HAL_UNLOCK(hcryp);
03026         return HAL_ERROR;
03027       }
03028     }
03029   }
03030 
03031   if ((hcryp->Size % 16U) != 0U)
03032   {
03033 
03034 #if !defined (CRYP_VER_2_2)
03035     if (hcryp->Version >= REV_ID_B)
03036 #endif /*End of not defined CRYP_VER_2_2*/
03037     {
03038       /* Compute the number of padding bytes in last block of payload */
03039       npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
03040 
03041       /*  Set Npblb in case of AES GCM payload encryption to get right tag*/
03042       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
03043       {
03044         /* Disable the CRYP */
03045         __HAL_CRYP_DISABLE(hcryp);
03046 
03047         /* Specify the number of non-valid bytes using NPBLB register*/
03048         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
03049 
03050         /* Enable CRYP to start the final phase */
03051         __HAL_CRYP_ENABLE(hcryp);
03052       }
03053       /* Number of valid words (lastwordsize) in last block */
03054       if ((npblb % 4U) == 0U)
03055       {
03056         lastwordsize = (16U - npblb) / 4U;
03057       }
03058       else
03059       {
03060         lastwordsize = ((16U - npblb) / 4U) + 1U;
03061       }
03062 
03063       /* Write the last input block in the IN FIFO */
03064       for (index = 0U; index < lastwordsize; index ++)
03065       {
03066         hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
03067         hcryp->CrypInCount++;
03068       }
03069 
03070       /* Pad the data with zeros to have a complete block */
03071       while (index < 4U)
03072       {
03073         hcryp->Instance->DIN  = 0U;
03074         index++;
03075       }
03076 
03077       /* Wait for OFNE flag to be raised */
03078       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
03079       {
03080         /* Disable the CRYP peripheral clock */
03081         __HAL_CRYP_DISABLE(hcryp);
03082 
03083         /* Change state */
03084         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03085         hcryp->State = HAL_CRYP_STATE_READY;
03086 
03087         /* Process Unlocked */
03088         __HAL_UNLOCK(hcryp);
03089 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
03090         /*Call registered error callback*/
03091         hcryp->ErrorCallback(hcryp);
03092 #else
03093         /*Call legacy weak error callback*/
03094         HAL_CRYP_ErrorCallback(hcryp);
03095 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
03096       }
03097 
03098       /*Read the output block from the output FIFO */
03099       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
03100       {
03101         for (index = 0U; index < 4U; index++)
03102         {
03103           /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
03104           temp[index] = hcryp->Instance->DOUT;
03105         }
03106         for (index=0; index<lastwordsize; index++)
03107         {
03108           *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
03109           hcryp->CrypOutCount++;
03110         }
03111       }
03112     }
03113 #if !defined (CRYP_VER_2_2)
03114     else /*  Workaround to be used */
03115     {
03116       /*  Workaround 2 for STM32H7 below rev.B To generate correct TAG only when size of the last block of
03117       payload is inferior to 128 bits, in case of GCM encryption or CCM decryption*/
03118       CRYP_Workaround(hcryp, Timeout);
03119     } /* end of NPBLB or Workaround*/
03120 #endif /*End of not defined CRYP_VER_2_2*/
03121   }
03122 
03123   /* Return function status */
03124   return HAL_OK;
03125 }
03126 
03127 /**
03128   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
03129   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
03130   *         the configuration information for CRYP module
03131   * @retval HAL status
03132   */
03133 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
03134 {
03135   __IO uint32_t count = 0U;
03136   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
03137 
03138   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
03139   {
03140     if (hcryp->KeyIVConfig == 1U)
03141     {
03142       /* If the Key and IV configuration has to be done only once
03143       and if it has already been done, skip it */
03144       DoKeyIVConfig = 0U;
03145       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
03146     }
03147     else
03148     {
03149       /* If the Key and IV configuration has to be done only once
03150       and if it has not been done already, do it and set KeyIVConfig
03151       to keep track it won't have to be done again next time */
03152       hcryp->KeyIVConfig = 1U;
03153       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
03154     }
03155   }
03156   else
03157   {
03158     hcryp->SizesSum = hcryp->Size;
03159   }
03160 
03161   /* Configure Key, IV and process message (header and payload) */
03162   if (DoKeyIVConfig == 1U)
03163   {
03164   /*  Reset CrypHeaderCount */
03165   hcryp->CrypHeaderCount = 0U;
03166 
03167   /******************************* Init phase *********************************/
03168 
03169   CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
03170 
03171   /* Set the key */
03172   CRYP_SetKey(hcryp, hcryp->Init.KeySize);
03173 
03174   /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
03175   hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
03176   hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
03177   hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
03178   hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
03179 
03180   /* Enable the CRYP peripheral */
03181   __HAL_CRYP_ENABLE(hcryp);
03182 
03183   /*Wait for the CRYPEN bit to be cleared*/
03184   count = CRYP_TIMEOUT_GCMCCMINITPHASE;
03185   do
03186   {
03187     count-- ;
03188     if (count == 0U)
03189     {
03190       /* Disable the CRYP peripheral clock */
03191       __HAL_CRYP_DISABLE(hcryp);
03192 
03193       /* Change state */
03194       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03195       hcryp->State = HAL_CRYP_STATE_READY;
03196 
03197       /* Process unlocked */
03198       __HAL_UNLOCK(hcryp);
03199       return HAL_ERROR;
03200     }
03201   } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
03202 
03203   /***************************** Header phase *********************************/
03204 
03205   /* Select header phase */
03206   CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
03207   } /* end of if (DoKeyIVConfig == 1U) */
03208   /* Enable interrupts */
03209   __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
03210 
03211   /* Enable CRYP */
03212   __HAL_CRYP_ENABLE(hcryp);
03213 
03214   /* Return function status */
03215   return HAL_OK;
03216 }
03217 
03218 
03219 /**
03220   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
03221   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
03222   *         the configuration information for CRYP module
03223   * @retval HAL status
03224   */
03225 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
03226 {
03227   __IO uint32_t count = 0U;
03228   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
03229   uint32_t index;
03230   uint32_t npblb;
03231   uint32_t lastwordsize;
03232   uint32_t temp[4];  /* Temporary CrypOutBuff */
03233   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
03234 
03235   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
03236   {
03237     if (hcryp->KeyIVConfig == 1U)
03238     {
03239       /* If the Key and IV configuration has to be done only once
03240          and if it has already been done, skip it */
03241       DoKeyIVConfig = 0U;
03242       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
03243     }
03244     else
03245     {
03246       /* If the Key and IV configuration has to be done only once
03247          and if it has not been done already, do it and set KeyIVConfig
03248          to keep track it won't have to be done again next time */
03249       hcryp->KeyIVConfig = 1U;
03250       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
03251     }
03252   }
03253   else
03254   {
03255     hcryp->SizesSum = hcryp->Size;
03256   }
03257 
03258   if (DoKeyIVConfig == 1U)
03259   {
03260  /*  Reset CrypHeaderCount */
03261   hcryp->CrypHeaderCount = 0U;
03262 
03263   /*************************** Init phase ************************************/
03264 
03265   CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
03266 
03267   /* Set the key */
03268   CRYP_SetKey(hcryp, hcryp->Init.KeySize);
03269 
03270   /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
03271   hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
03272   hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
03273   hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
03274   hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
03275 
03276   /* Enable the CRYP peripheral */
03277   __HAL_CRYP_ENABLE(hcryp);
03278 
03279   /*Wait for the CRYPEN bit to be cleared*/
03280   count = CRYP_TIMEOUT_GCMCCMINITPHASE;
03281   do
03282   {
03283     count-- ;
03284     if (count == 0U)
03285     {
03286       /* Disable the CRYP peripheral clock */
03287       __HAL_CRYP_DISABLE(hcryp);
03288 
03289       /* Change state */
03290       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03291       hcryp->State = HAL_CRYP_STATE_READY;
03292 
03293       /* Process unlocked */
03294       __HAL_UNLOCK(hcryp);
03295       return HAL_ERROR;
03296     }
03297   } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
03298 
03299   /************************ Header phase *************************************/
03300 
03301   if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
03302   {
03303     return HAL_ERROR;
03304   }
03305 
03306   /************************ Payload phase ************************************/
03307 
03308   /* Set the phase */
03309   hcryp->Phase = CRYP_PHASE_PROCESS;
03310 
03311   /* Disable the CRYP peripheral */
03312   __HAL_CRYP_DISABLE(hcryp);
03313 
03314 #if !defined (CRYP_VER_2_2)
03315   if (hcryp->Version >= REV_ID_B)
03316 #endif /*End of not defined CRYP_VER_2_2*/
03317   {
03318     /* Set to 0 the number of non-valid bytes using NPBLB register*/
03319     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
03320   }
03321 
03322   /* Select payload phase once the header phase is performed */
03323   CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
03324 
03325 } /* if (DoKeyIVConfig == 1U) */
03326     
03327   if (hcryp->Size == 0U)
03328   {
03329     /* Process unLocked */
03330     __HAL_UNLOCK(hcryp);
03331 
03332     /* Change the CRYP state and phase */
03333     hcryp->State = HAL_CRYP_STATE_READY;
03334   }
03335   else if (hcryp->Size >= 16U)
03336   {
03337     /* for STM32H7 below rev.B : Size should be %4  otherwise Tag will  be incorrectly generated for GCM Encryption:
03338     Workaround is implemented in polling mode, so if last block of payload <128bit don't use DMA mode otherwise TAG is incorrectly generated */
03339 
03340     /*DMA transfer must not include the last block in case of Size is not %16 */
03341     wordsize = wordsize - (wordsize % 4U);
03342 
03343     /*DMA transfer */
03344     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
03345   }
03346   else /* length of input data is < 16 */
03347   {
03348     /* Compute the number of padding bytes in last block of payload */
03349     npblb = 16U - (uint32_t)hcryp->Size;
03350 
03351 #if !defined (CRYP_VER_2_2)
03352     if (hcryp->Version >= REV_ID_B)
03353 #endif /*End of not defined CRYP_VER_2_2*/
03354     {
03355       /* Set Npblb in case of AES GCM payload encryption to get right tag*/
03356       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
03357       {
03358         /* Specify the number of non-valid bytes using NPBLB register*/
03359         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
03360       }
03361     }
03362     /* Enable CRYP to start the final phase */
03363     __HAL_CRYP_ENABLE(hcryp);
03364 
03365     /* Number of valid words (lastwordsize) in last block */
03366     if ((npblb % 4U) == 0U)
03367     {
03368       lastwordsize = (16U - npblb) / 4U;
03369     }
03370     else
03371     {
03372       lastwordsize = ((16U - npblb) / 4U) + 1U;
03373     }
03374 
03375     /* Write the last input block in the IN FIFO */
03376     for (index = 0; index < lastwordsize; index ++)
03377     {
03378       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
03379       hcryp->CrypInCount++;
03380     }
03381 
03382     /* Pad the data with zeros to have a complete block */
03383     while (index < 4U)
03384     {
03385       hcryp->Instance->DIN  = 0U;
03386       index++;
03387     }
03388 
03389     /* Wait for OFNE flag to be raised */
03390     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
03391     do
03392     {
03393       count-- ;
03394       if (count == 0U)
03395       {
03396         /* Disable the CRYP peripheral clock */
03397         __HAL_CRYP_DISABLE(hcryp);
03398 
03399         /* Change state */
03400         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03401         hcryp->State = HAL_CRYP_STATE_READY;
03402 
03403         /* Process unlocked */
03404         __HAL_UNLOCK(hcryp);
03405 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
03406         /*Call registered error callback*/
03407         hcryp->ErrorCallback(hcryp);
03408 #else
03409         /*Call legacy weak error callback*/
03410         HAL_CRYP_ErrorCallback(hcryp);
03411 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
03412       }
03413     } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
03414 
03415     /*Read the output block from the output FIFO */
03416     for (index = 0U; index < 4U; index++)
03417     {
03418       /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
03419       temp[index] = hcryp->Instance->DOUT;
03420     }
03421     for (index=0; index<lastwordsize; index++)
03422     {
03423       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
03424       hcryp->CrypOutCount++;
03425     }
03426 
03427     /* Change the CRYP state to ready */
03428     hcryp->State = HAL_CRYP_STATE_READY;
03429 
03430     /* Process unlocked */
03431     __HAL_UNLOCK(hcryp);
03432   }
03433 
03434   /* Return function status */
03435   return HAL_OK;
03436 }
03437 
03438 
03439 /**
03440   * @brief  AES CCM encryption/decryption processing in polling mode
03441   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
03442   *         the configuration information for CRYP module
03443   * @param  Timeout: Timeout duration
03444   * @retval HAL status
03445   */
03446 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
03447 {
03448   uint32_t tickstart;
03449   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
03450   uint32_t npblb ;
03451   uint32_t lastwordsize ;
03452   uint32_t temp[4] ;  /* Temporary CrypOutBuff */
03453   uint32_t index ;
03454   uint16_t outcount;  /* Temporary CrypOutCount Value */
03455   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
03456 
03457   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
03458   {
03459     if (hcryp->KeyIVConfig == 1U)
03460     {
03461       /* If the Key and IV configuration has to be done only once
03462       and if it has already been done, skip it */
03463       DoKeyIVConfig = 0U;
03464       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
03465     }
03466     else
03467     {
03468       /* If the Key and IV configuration has to be done only once
03469       and if it has not been done already, do it and set KeyIVConfig
03470       to keep track it won't have to be done again next time */
03471       hcryp->KeyIVConfig = 1U;
03472       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
03473     }
03474   }
03475   else
03476   {
03477     hcryp->SizesSum = hcryp->Size;
03478   }
03479 
03480   if (DoKeyIVConfig == 1U)
03481   {
03482   /*  Reset CrypHeaderCount */
03483   hcryp->CrypHeaderCount = 0U;
03484 
03485   /********************** Init phase ******************************************/
03486 
03487   CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
03488 
03489   /* Set the key */
03490   CRYP_SetKey(hcryp, hcryp->Init.KeySize);
03491 
03492   /* Set the initialization vector (IV) with CTR1 information */
03493   hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
03494   hcryp->Instance->IV0RR = hcryp->Init.B0[1];
03495   hcryp->Instance->IV1LR = hcryp->Init.B0[2];
03496   hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
03497 
03498   /* Enable the CRYP peripheral */
03499   __HAL_CRYP_ENABLE(hcryp);
03500 
03501 #if defined (CRYP_VER_2_2)
03502   {
03503     /* for STM32H7 rev.B and above Write  B0 packet into CRYP_DR*/
03504     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
03505     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
03506     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
03507     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
03508   }
03509 #else
03510   if (hcryp->Version >= REV_ID_B)
03511   {
03512     /* for STM32H7 rev.B and above Write  B0 packet into CRYP_DR*/
03513     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
03514     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
03515     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
03516     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
03517   }
03518   else /* data has to be swapped according to the DATATYPE */
03519   {
03520     if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
03521     {
03522       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
03523       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
03524       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
03525       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
03526     }
03527     else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
03528     {
03529       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
03530       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
03531       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
03532       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
03533     }
03534     else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
03535     {
03536       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
03537       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
03538       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
03539       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
03540     }
03541     else
03542     {
03543       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
03544       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
03545       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
03546       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
03547     }
03548   }
03549 #endif
03550   /* Get tick */
03551   tickstart = HAL_GetTick();
03552 
03553   /*Wait for the CRYPEN bit to be cleared*/
03554   while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
03555   {
03556     /* Check for the Timeout */
03557     if (Timeout != HAL_MAX_DELAY)
03558     {
03559       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
03560       {
03561         /* Disable the CRYP peripheral clock */
03562         __HAL_CRYP_DISABLE(hcryp);
03563 
03564         /* Change state */
03565         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03566         hcryp->State = HAL_CRYP_STATE_READY;
03567 
03568         /* Process unlocked */
03569         __HAL_UNLOCK(hcryp);
03570         return HAL_ERROR;
03571       }
03572     }
03573   }
03574 
03575   /************************* Header phase *************************************/
03576   /* Header block(B1) : associated data length expressed in bytes concatenated
03577   with Associated Data (A)*/
03578 
03579   if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
03580   {
03581     return HAL_ERROR;
03582   }
03583   /********************** Payload phase ***************************************/
03584 
03585   /* Set the phase */
03586   hcryp->Phase = CRYP_PHASE_PROCESS;
03587 
03588   /* Disable the CRYP peripheral */
03589   __HAL_CRYP_DISABLE(hcryp);
03590 #if !defined (CRYP_VER_2_2)
03591   if (hcryp->Version >= REV_ID_B)
03592 #endif /*End of not defined CRYP_VER_2_2*/
03593   {
03594     /* Set to 0 the number of non-valid bytes using NPBLB register*/
03595     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
03596   }
03597 
03598   /* Select payload phase once the header phase is performed */
03599   CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
03600 
03601   /* Enable the CRYP peripheral */
03602   __HAL_CRYP_ENABLE(hcryp);
03603 
03604 } /* if (DoKeyIVConfig == 1U) */
03605    
03606   if ((hcryp->Size % 16U) != 0U)
03607   {
03608     /* recalculate  wordsize */
03609     wordsize = ((wordsize / 4U) * 4U) ;
03610   }
03611   /* Get tick */
03612   tickstart = HAL_GetTick();
03613 
03614   /*Temporary CrypOutCount Value*/
03615   outcount = hcryp->CrypOutCount;
03616 
03617   /* Write input data and get output data */
03618   while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
03619   {
03620     /* Write plain data and get cipher data */
03621     CRYP_AES_ProcessData(hcryp, Timeout);
03622 
03623     /*Temporary CrypOutCount Value*/
03624     outcount = hcryp->CrypOutCount;
03625 
03626     /* Check for the Timeout */
03627     if (Timeout != HAL_MAX_DELAY)
03628     {
03629       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
03630       {
03631         /* Disable the CRYP peripheral clock */
03632         __HAL_CRYP_DISABLE(hcryp);
03633 
03634         /* Change state */
03635         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03636         hcryp->State = HAL_CRYP_STATE_READY;
03637 
03638         /* Process unlocked */
03639         __HAL_UNLOCK(hcryp);
03640         return HAL_ERROR;
03641       }
03642     }
03643   }
03644 
03645   if ((hcryp->Size % 16U) != 0U)
03646   {
03647 #if !defined (CRYP_VER_2_2)
03648     if (hcryp->Version >= REV_ID_B)
03649 #endif /*End of not defined CRYP_VER_2_2*/
03650     {
03651       /* Compute the number of padding bytes in last block of payload */
03652       npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
03653 
03654       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
03655       {
03656         /* Disable the CRYP */
03657         __HAL_CRYP_DISABLE(hcryp);
03658 
03659         /* Set Npblb in case of AES CCM payload decryption to get right tag  */
03660         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
03661 
03662         /* Enable CRYP to start the final phase */
03663         __HAL_CRYP_ENABLE(hcryp);
03664       }
03665 
03666       /* Number of valid words (lastwordsize) in last block */
03667       if ((npblb % 4U) == 0U)
03668       {
03669         lastwordsize = (16U - npblb) / 4U;
03670       }
03671       else
03672       {
03673         lastwordsize = ((16U - npblb) / 4U) + 1U;
03674       }
03675 
03676       /* Write the last input block in the IN FIFO */
03677       for (index = 0U; index < lastwordsize; index ++)
03678       {
03679         hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
03680         hcryp->CrypInCount++;
03681       }
03682 
03683       /* Pad the data with zeros to have a complete block */
03684       while (index < 4U)
03685       {
03686         hcryp->Instance->DIN  = 0U;
03687         index++;
03688       }
03689 
03690       /* Wait for OFNE flag to be raised */
03691       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
03692       {
03693         /* Disable the CRYP peripheral clock */
03694         __HAL_CRYP_DISABLE(hcryp);
03695 
03696         /* Change state */
03697         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03698         hcryp->State = HAL_CRYP_STATE_READY;
03699 
03700         /* Process Unlocked */
03701         __HAL_UNLOCK(hcryp);
03702 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
03703         /*Call registered error callback*/
03704         hcryp->ErrorCallback(hcryp);
03705 #else
03706         /*Call legacy weak error callback*/
03707         HAL_CRYP_ErrorCallback(hcryp);
03708 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
03709       }
03710 
03711       /*Read the output block from the output FIFO */
03712       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
03713       {
03714         for (index = 0U; index < 4U; index++)
03715         {
03716           /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
03717           temp[index] = hcryp->Instance->DOUT;
03718         }
03719         for (index=0; index<lastwordsize; index++)
03720         {
03721           *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
03722           hcryp->CrypOutCount++;
03723         } 
03724       }
03725     }
03726 #if !defined (CRYP_VER_2_2)
03727     else /* No NPBLB, Workaround to be used */
03728     {
03729       /* CRYP Workaround :  CRYP1 generates correct TAG  during CCM decryption only when ciphertext blocks size is multiple of
03730       128 bits. If lthe size of the last block of payload is inferior to 128 bits, when CCM decryption
03731       is selected, then the TAG message will be wrong.*/
03732       CRYP_Workaround(hcryp, Timeout);
03733     }
03734 #endif /*End of not defined CRYP_VER_2_2*/
03735   }
03736 
03737   /* Return function status */
03738   return HAL_OK;
03739 }
03740 
03741 /**
03742   * @brief  AES CCM encryption/decryption process in interrupt mode
03743   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
03744   *         the configuration information for CRYP module
03745   * @retval HAL status
03746   */
03747 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
03748 {
03749   __IO uint32_t count = 0U;
03750   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
03751 
03752   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
03753   {
03754     if (hcryp->KeyIVConfig == 1U)
03755     {
03756       /* If the Key and IV configuration has to be done only once
03757       and if it has already been done, skip it */
03758       DoKeyIVConfig = 0U;
03759       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
03760     }
03761     else
03762     {
03763       /* If the Key and IV configuration has to be done only once
03764       and if it has not been done already, do it and set KeyIVConfig
03765       to keep track it won't have to be done again next time */
03766       hcryp->KeyIVConfig = 1U;
03767       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
03768     }
03769   }
03770   else
03771   {
03772     hcryp->SizesSum = hcryp->Size;
03773   }
03774 
03775   /* Configure Key, IV and process message (header and payload) */
03776   if (DoKeyIVConfig == 1U)
03777   {
03778   /*  Reset CrypHeaderCount */
03779   hcryp->CrypHeaderCount = 0U;
03780 
03781   /************ Init phase ************/
03782 
03783   CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
03784 
03785   /* Set the key */
03786   CRYP_SetKey(hcryp, hcryp->Init.KeySize);
03787 
03788   /* Set the initialization vector (IV) with CTR1 information */
03789   hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
03790   hcryp->Instance->IV0RR = hcryp->Init.B0[1];
03791   hcryp->Instance->IV1LR = hcryp->Init.B0[2];
03792   hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
03793 
03794   /* Enable the CRYP peripheral */
03795   __HAL_CRYP_ENABLE(hcryp);
03796 
03797   /*Write the B0 packet into CRYP_DR*/
03798 #if !defined (CRYP_VER_2_2)
03799   if (hcryp->Version >= REV_ID_B)
03800 #endif /*End of not defined CRYP_VER_2_2*/
03801   {
03802     /* for STM32H7 rev.B and above data has not to be swapped */
03803     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
03804     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
03805     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
03806     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
03807   }
03808 #if !defined (CRYP_VER_2_2)
03809   else /* data has to be swapped according to the DATATYPE */
03810   {
03811     if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
03812     {
03813       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
03814       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
03815       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
03816       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
03817     }
03818     else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
03819     {
03820       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
03821       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
03822       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
03823       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
03824     }
03825     else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
03826     {
03827       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
03828       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
03829       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
03830       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
03831     }
03832     else
03833     {
03834       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
03835       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
03836       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
03837       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
03838     }
03839   }
03840 #endif /*End of not defined CRYP_VER_2_2*/
03841   /*Wait for the CRYPEN bit to be cleared*/
03842   count = CRYP_TIMEOUT_GCMCCMINITPHASE;
03843   do
03844   {
03845     count-- ;
03846     if (count == 0U)
03847     {
03848       /* Disable the CRYP peripheral clock */
03849       __HAL_CRYP_DISABLE(hcryp);
03850 
03851       /* Change state */
03852       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03853       hcryp->State = HAL_CRYP_STATE_READY;
03854 
03855       /* Process unlocked */
03856       __HAL_UNLOCK(hcryp);
03857       return HAL_ERROR;
03858     }
03859   } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
03860 
03861   /* Select header phase */
03862   CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
03863 } /* end of if (DoKeyIVConfig == 1U) */
03864   /* Enable interrupts */
03865   __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
03866 
03867   /* Enable CRYP */
03868   __HAL_CRYP_ENABLE(hcryp);
03869 
03870   /* Return function status */
03871   return HAL_OK;
03872 }
03873 /**
03874   * @brief  AES CCM encryption/decryption process in DMA mode
03875   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
03876   *         the configuration information for CRYP module
03877   * @retval HAL status
03878   */
03879 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
03880 {
03881   __IO uint32_t count    = 0U;
03882   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
03883   uint32_t index;
03884   uint32_t npblb;
03885   uint32_t lastwordsize;
03886   uint32_t temp[4];  /* Temporary CrypOutBuff */
03887   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
03888 
03889   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
03890   {
03891     if (hcryp->KeyIVConfig == 1U)
03892     {
03893       /* If the Key and IV configuration has to be done only once
03894       and if it has already been done, skip it */
03895       DoKeyIVConfig = 0U;
03896       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
03897     }
03898     else
03899     {
03900       /* If the Key and IV configuration has to be done only once
03901       and if it has not been done already, do it and set KeyIVConfig
03902       to keep track it won't have to be done again next time */
03903       hcryp->KeyIVConfig = 1U;
03904       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
03905     }
03906   }
03907   else
03908   {
03909     hcryp->SizesSum = hcryp->Size;
03910   }
03911 
03912   if (DoKeyIVConfig == 1U)
03913   {
03914   /*  Reset CrypHeaderCount */
03915   hcryp->CrypHeaderCount = 0U;
03916 
03917   /************************** Init phase **************************************/
03918 
03919   CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
03920 
03921   /* Set the key */
03922   CRYP_SetKey(hcryp, hcryp->Init.KeySize);
03923 
03924   /* Set the initialization vector (IV) with CTR1 information */
03925   hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
03926   hcryp->Instance->IV0RR = hcryp->Init.B0[1];
03927   hcryp->Instance->IV1LR = hcryp->Init.B0[2];
03928   hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
03929 
03930   /* Enable the CRYP peripheral */
03931   __HAL_CRYP_ENABLE(hcryp);
03932 
03933   /*Write the B0 packet into CRYP_DR*/
03934 #if !defined (CRYP_VER_2_2)
03935   if (hcryp->Version >= REV_ID_B)
03936 #endif /*End of not defined CRYP_VER_2_2*/
03937   {
03938     /* for STM32H7 rev.B and above data has not to be swapped */
03939     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
03940     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
03941     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
03942     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
03943   }
03944 #if !defined (CRYP_VER_2_2)
03945   else /* data has to be swapped according to the DATATYPE */
03946   {
03947     if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
03948     {
03949       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
03950       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
03951       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
03952       hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
03953     }
03954     else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
03955     {
03956       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
03957       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
03958       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
03959       hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
03960     }
03961     else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
03962     {
03963       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
03964       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
03965       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
03966       hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
03967     }
03968     else
03969     {
03970       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
03971       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
03972       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
03973       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
03974     }
03975   }
03976 #endif /*End of not defined CRYP_VER_2_2*/
03977   /*Wait for the CRYPEN bit to be cleared*/
03978   count = CRYP_TIMEOUT_GCMCCMINITPHASE;
03979   do
03980   {
03981     count-- ;
03982     if (count == 0U)
03983     {
03984       /* Disable the CRYP peripheral clock */
03985       __HAL_CRYP_DISABLE(hcryp);
03986 
03987       /* Change state */
03988       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
03989       hcryp->State = HAL_CRYP_STATE_READY;
03990 
03991       /* Process unlocked */
03992       __HAL_UNLOCK(hcryp);
03993       return HAL_ERROR;
03994     }
03995   } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
03996 
03997   /********************* Header phase *****************************************/
03998 
03999   if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
04000   {
04001     return HAL_ERROR;
04002   }
04003 
04004   /******************** Payload phase *****************************************/
04005 
04006   /* Set the phase */
04007   hcryp->Phase = CRYP_PHASE_PROCESS;
04008 
04009   /* Disable the CRYP peripheral */
04010   __HAL_CRYP_DISABLE(hcryp);
04011 #if !defined (CRYP_VER_2_2)
04012   if (hcryp->Version >= REV_ID_B)
04013 #endif /*End of not defined CRYP_VER_2_2*/
04014   {
04015     /* Set to 0 the number of non-valid bytes using NPBLB register*/
04016     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
04017   }
04018 
04019   /* Select payload phase once the header phase is performed */
04020   CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
04021   } /* if (DoKeyIVConfig == 1U) */
04022 
04023   if (hcryp->Size == 0U)
04024   {
04025     /* Process unLocked */
04026     __HAL_UNLOCK(hcryp);
04027 
04028     /* Change the CRYP state and phase */
04029     hcryp->State = HAL_CRYP_STATE_READY;
04030   }
04031   else if (hcryp->Size >= 16U)
04032   {
04033     /* for STM32H7 below rev.B ::  Size should be %4  otherwise Tag will  be incorrectly generated for CCM Decryption, Workaround is implemented in polling mode*/
04034     /*DMA transfer must not include the last block in case of Size is not %16 */
04035     wordsize = wordsize - (wordsize % 4U);
04036 
04037     /*DMA transfer */
04038     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t) wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
04039   }
04040   else /* length of input data is  < 16U */
04041   {
04042     /* Compute the number of padding bytes in last block of payload */
04043     npblb = 16U - (uint32_t)(hcryp->Size);
04044 
04045 #if !defined (CRYP_VER_2_2)
04046     if (hcryp->Version >= REV_ID_B)
04047 #endif /*End of not defined CRYP_VER_2_2*/
04048     {
04049       /* Set Npblb in case of AES CCM payload decryption to get right tag*/
04050       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
04051       {
04052         /* Specify the number of non-valid bytes using NPBLB register*/
04053         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
04054       }
04055     }
04056     /* Enable CRYP to start the final phase */
04057     __HAL_CRYP_ENABLE(hcryp);
04058 
04059     /* Number of valid words (lastwordsize) in last block */
04060     if ((npblb % 4U) == 0U)
04061     {
04062       lastwordsize = (16U - npblb) / 4U;
04063     }
04064     else
04065     {
04066       lastwordsize = ((16U - npblb) / 4U) + 1U;
04067     }
04068 
04069     /* Write the last input block in the IN FIFO */
04070     for (index = 0U; index < lastwordsize; index ++)
04071     {
04072       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
04073       hcryp->CrypInCount++;
04074     }
04075 
04076     /* Pad the data with zeros to have a complete block */
04077     while (index < 4U)
04078     {
04079       hcryp->Instance->DIN  = 0U;
04080       index++;
04081     }
04082 
04083     /* Wait for OFNE flag to be raised */
04084     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
04085     do
04086     {
04087       count-- ;
04088       if (count == 0U)
04089       {
04090         /* Disable the CRYP peripheral clock */
04091         __HAL_CRYP_DISABLE(hcryp);
04092 
04093         /* Change state */
04094         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04095         hcryp->State = HAL_CRYP_STATE_READY;
04096 
04097         /* Process unlocked */
04098         __HAL_UNLOCK(hcryp);
04099 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
04100         /*Call registered error callback*/
04101         hcryp->ErrorCallback(hcryp);
04102 #else
04103         /*Call legacy weak error callback*/
04104         HAL_CRYP_ErrorCallback(hcryp);
04105 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
04106       }
04107     } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
04108 
04109     /*Read the output block from the output FIFO */
04110     for (index = 0U; index < 4U; index++)
04111     {
04112       /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
04113       temp[index] = hcryp->Instance->DOUT;
04114     }
04115     for (index=0; index<lastwordsize; index++)
04116     {
04117       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
04118       hcryp->CrypOutCount++;
04119     }
04120 
04121     /* Change the CRYP state to ready */
04122     hcryp->State = HAL_CRYP_STATE_READY;
04123 
04124     /* Process unlocked */
04125     __HAL_UNLOCK(hcryp);
04126   }
04127 
04128   /* Return function status */
04129   return HAL_OK;
04130 }
04131 
04132 /**
04133   * @brief  Sets the payload phase in interrupt mode
04134   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
04135   *         the configuration information for CRYP module
04136   * @retval state
04137   */
04138 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
04139 {
04140   uint32_t loopcounter;
04141   uint32_t temp[4];  /* Temporary CrypOutBuff */
04142   uint32_t lastwordsize;
04143   uint32_t npblb;
04144   uint32_t temp_cr_algodir;
04145   uint8_t negative = 0U;
04146   uint32_t i;
04147 
04148   /***************************** Payload phase *******************************/
04149 
04150   if ((hcryp->Size / 4U) < hcryp->CrypInCount)
04151   {
04152     negative = 1U;
04153   }
04154 
04155   if (hcryp->Size == 0U)
04156   {
04157     /* Disable interrupts */
04158     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
04159 
04160     /* Process unlocked */
04161     __HAL_UNLOCK(hcryp);
04162 
04163     /* Change the CRYP state */
04164     hcryp->State = HAL_CRYP_STATE_READY;
04165   }
04166   
04167   else if ((((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) &&
04168            (negative == 0U))
04169   {
04170     if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM)!= 0x0U)
04171     {
04172       /* Write the input block in the IN FIFO */
04173       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
04174       hcryp->CrypInCount++;
04175       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
04176       hcryp->CrypInCount++;
04177       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
04178       hcryp->CrypInCount++;
04179       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
04180       hcryp->CrypInCount++;
04181       if (((hcryp->Size / 4U) == hcryp->CrypInCount) && ((hcryp->Size % 16U) == 0U))
04182       {
04183         /* Disable interrupts */
04184         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
04185         /* Call the input data transfer complete callback */
04186 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
04187         /*Call registered Input complete callback*/
04188         hcryp->InCpltCallback(hcryp);
04189 #else
04190         /*Call legacy weak Input complete callback*/
04191         HAL_CRYP_InCpltCallback(hcryp);
04192 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
04193       }
04194       
04195       if (hcryp->CrypOutCount < (hcryp->Size / 4U))     
04196       {
04197         if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
04198         {
04199           /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer  */
04200           for (i = 0U; i < 4U; i++)
04201           {
04202             temp[i] = hcryp->Instance->DOUT;
04203           }
04204           i = 0U;
04205           while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
04206           {
04207             *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
04208             hcryp->CrypOutCount++;
04209             i++;
04210           }
04211           if (((hcryp->Size / 4U) == hcryp->CrypOutCount) && ((hcryp->Size % 16U) == 0U))
04212           {
04213             /* Disable interrupts */
04214             __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
04215 
04216             /* Change the CRYP state */
04217             hcryp->State = HAL_CRYP_STATE_READY;
04218             
04219             /* Disable CRYP */
04220             __HAL_CRYP_DISABLE(hcryp);
04221             
04222             /* Process unlocked */
04223             __HAL_UNLOCK(hcryp);
04224             
04225             /* Call output transfer complete callback */
04226 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
04227         /*Call registered Output complete callback*/
04228         hcryp->OutCpltCallback(hcryp);
04229 #else
04230         /*Call legacy weak Output complete callback*/
04231         HAL_CRYP_OutCpltCallback(hcryp);
04232 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
04233           }
04234         }
04235       }
04236     }
04237   }
04238   else if ((hcryp->Size % 16U) != 0U)
04239   {
04240         /* Set padding only in case of input fifo interrupt */
04241         if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM)!= 0x0U)
04242  {
04243     /* Compute the number of padding bytes in last block of payload */
04244     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
04245     
04246 #if !defined (CRYP_VER_2_2)
04247     if (hcryp->Version >= REV_ID_B)
04248 #endif /*End of not defined CRYP_VER_2_2*/
04249     {
04250       /* Set Npblb in case of AES GCM payload encryption and CCM decryption to get right tag */
04251       temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
04252 
04253       if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
04254           ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
04255       {
04256         /* Disable the CRYP */
04257         __HAL_CRYP_DISABLE(hcryp);
04258 
04259         /* Specify the number of non-valid bytes using NPBLB register*/
04260         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
04261 
04262         /* Enable CRYP to start the final phase */
04263         __HAL_CRYP_ENABLE(hcryp);
04264       }
04265     }
04266 
04267     /* Number of valid words (lastwordsize) in last block */
04268     if ((npblb % 4U) == 0U)
04269     {
04270       lastwordsize = (16U - npblb) / 4U;
04271     }
04272     else
04273     {
04274       lastwordsize = ((16U - npblb) / 4U) + 1U;
04275     }
04276 
04277     /* Write the last input block in the IN FIFO */
04278     for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
04279     {
04280       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
04281       hcryp->CrypInCount++;
04282     }
04283     /* Pad the data with zeros to have a complete block */
04284     while (loopcounter < 4U)
04285     {
04286       hcryp->Instance->DIN  = 0U;
04287       loopcounter++;
04288     }
04289 
04290     /* Disable the input FIFO Interrupt */
04291     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
04292         }
04293 
04294     /*Read the output block from the output FIFO */
04295     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
04296     {
04297       for (i = 0U; i < 4U; i++)
04298       {
04299         temp[i] = hcryp->Instance->DOUT;
04300       }
04301       if (( (hcryp->Size)/4U)==0U)
04302       {
04303         for (i = 0U; (uint16_t)i<((hcryp->Size)%4U); i++)
04304         {
04305           *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
04306           hcryp->CrypOutCount++;
04307         }     
04308       }
04309       i = 0U;
04310       while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
04311       {
04312         *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
04313         hcryp->CrypOutCount++;
04314         i++;
04315       }
04316     }
04317 
04318     /* Disable the output FIFO Interrupt */
04319     if (hcryp->CrypOutCount >= ((hcryp->Size) / 4U))
04320     {
04321       /* Disable interrupts */
04322       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI | CRYP_IT_INI);
04323 
04324       /* Change the CRYP peripheral state */
04325       hcryp->State = HAL_CRYP_STATE_READY;
04326 
04327       /* Process unlocked */
04328       __HAL_UNLOCK(hcryp);
04329 
04330       /* Call output transfer complete callback */
04331 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
04332       /*Call registered Output complete callback*/
04333       hcryp->OutCpltCallback(hcryp);
04334 #else
04335       /*Call legacy weak Output complete callback*/
04336       HAL_CRYP_OutCpltCallback(hcryp);
04337 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
04338     }
04339   }
04340   else
04341   {
04342     /* Nothing to do */
04343   }
04344 }
04345 
04346 
04347 /**
04348   * @brief  Sets the header phase in polling mode
04349   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
04350   *         the configuration information for CRYP module(Header & HeaderSize)
04351   * @param  Timeout: Timeout value
04352   * @retval state
04353   */
04354 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
04355 {
04356   uint32_t loopcounter;
04357   uint32_t size_in_bytes;
04358   uint32_t tmp;
04359   uint32_t mask[4] = {0x0U, 0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
04360 
04361   /***************************** Header phase for GCM/GMAC or CCM *********************************/
04362 
04363 
04364   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
04365   {
04366     size_in_bytes = hcryp->Init.HeaderSize * 4U;
04367   }
04368   else
04369   {
04370     size_in_bytes = hcryp->Init.HeaderSize;
04371   }
04372 
04373   if ((size_in_bytes != 0U))
04374   {
04375     /* Select header phase */
04376     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
04377 
04378     /* Enable the CRYP peripheral */
04379     __HAL_CRYP_ENABLE(hcryp);
04380 
04381     /* If size_in_bytes is a multiple of blocks (a multiple of four 32-bits words ) */
04382     if ((size_in_bytes % 16U) == 0U)
04383     {
04384       /*  No padding */
04385       for (loopcounter = 0U; (loopcounter < (size_in_bytes / 4U)); loopcounter += 4U)
04386       
04387       {
04388         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04389         hcryp->CrypHeaderCount++ ;
04390         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04391         hcryp->CrypHeaderCount++ ;
04392         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04393         hcryp->CrypHeaderCount++ ;
04394         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04395         hcryp->CrypHeaderCount++ ;
04396 
04397         /* Wait for IFEM to be raised */
04398         if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
04399         {
04400           /* Disable the CRYP peripheral clock */
04401           __HAL_CRYP_DISABLE(hcryp);
04402 
04403           /* Change state */
04404           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04405           hcryp->State = HAL_CRYP_STATE_READY;
04406 
04407           /* Process unlocked */
04408           __HAL_UNLOCK(hcryp);
04409           return HAL_ERROR;
04410         }
04411       }
04412     }
04413     else
04414     {
04415       /* Write header block in the IN FIFO without last block */
04416       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 16U) * 4U)); loopcounter += 4U)
04417       {
04418         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04419         hcryp->CrypHeaderCount++ ;
04420         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04421         hcryp->CrypHeaderCount++ ;
04422         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04423         hcryp->CrypHeaderCount++ ;
04424         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04425         hcryp->CrypHeaderCount++ ;
04426 
04427         /* Wait for IFEM to be raised */
04428         if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
04429         {
04430           /* Disable the CRYP peripheral clock */
04431           __HAL_CRYP_DISABLE(hcryp);
04432 
04433           /* Change state */
04434           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04435           hcryp->State = HAL_CRYP_STATE_READY;
04436 
04437           /* Process unlocked */
04438           __HAL_UNLOCK(hcryp);
04439           return HAL_ERROR;
04440         }
04441       }
04442       /*  Last block optionally pad the data with zeros*/
04443       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 4U) % 4U)); loopcounter++)
04444       {
04445         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04446         hcryp->CrypHeaderCount++ ;
04447       }
04448       /* If the header size is a multiple of words */
04449       if ((size_in_bytes % 4U) == 0U)
04450       {
04451         /* Pad the data with zeros to have a complete block */
04452         while (loopcounter < 4U)
04453         {
04454           hcryp->Instance->DIN = 0x0U;
04455           loopcounter++;
04456         }
04457       }
04458       else
04459       {
04460          /* Enter last bytes, padded with zeroes */
04461          tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04462          tmp &= mask[size_in_bytes % 4U];
04463          hcryp->Instance->DIN = tmp;
04464          loopcounter++;
04465          /* Pad the data with zeros to have a complete block */
04466          while (loopcounter < 4U)
04467          {
04468            hcryp->Instance->DIN = 0x0U;
04469            loopcounter++;
04470          }
04471       }
04472       /* Wait for CCF IFEM to be raised */
04473       if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
04474       {
04475         /* Disable the CRYP peripheral clock */
04476         __HAL_CRYP_DISABLE(hcryp);
04477 
04478         /* Change state */
04479         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04480         hcryp->State = HAL_CRYP_STATE_READY;
04481 
04482         /* Process unlocked */
04483         __HAL_UNLOCK(hcryp);
04484         return HAL_ERROR;
04485       }
04486     }
04487     /* Wait until the complete message has been processed */
04488     if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
04489     {
04490       /* Disable the CRYP peripheral clock */
04491       __HAL_CRYP_DISABLE(hcryp);
04492 
04493       /* Change state */
04494       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04495       hcryp->State = HAL_CRYP_STATE_READY;
04496 
04497       /* Process unlocked & return error */
04498       __HAL_UNLOCK(hcryp);
04499       return HAL_ERROR;
04500     }
04501   }
04502   /* Return function status */
04503   return HAL_OK;
04504 }
04505 
04506 /**
04507   * @brief  Sets the header phase when using DMA in process
04508   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
04509   *         the configuration information for CRYP module(Header & HeaderSize)
04510   * @retval None
04511   */
04512 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
04513 {
04514   __IO uint32_t count  = 0U;
04515   uint32_t loopcounter;
04516 
04517   /***************************** Header phase for GCM/GMAC or CCM *********************************/
04518   if ((hcryp->Init.HeaderSize != 0U))
04519   {
04520     /* Select header phase */
04521     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
04522 
04523     /* Enable the CRYP peripheral */
04524     __HAL_CRYP_ENABLE(hcryp);
04525 
04526     if ((hcryp->Init.HeaderSize % 4U) == 0U)
04527     {
04528       /* HeaderSize %4, no padding */
04529       for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
04530       {
04531         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04532         hcryp->CrypHeaderCount++ ;
04533         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04534         hcryp->CrypHeaderCount++ ;
04535         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04536         hcryp->CrypHeaderCount++ ;
04537         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04538         hcryp->CrypHeaderCount++ ;
04539 
04540         /* Wait for IFEM to be raised */
04541         count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
04542         do
04543         {
04544           count-- ;
04545           if (count == 0U)
04546           {
04547             /* Disable the CRYP peripheral clock */
04548             __HAL_CRYP_DISABLE(hcryp);
04549 
04550             /* Change state */
04551             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04552             hcryp->State = HAL_CRYP_STATE_READY;
04553 
04554             /* Process unlocked */
04555             __HAL_UNLOCK(hcryp);
04556             return HAL_ERROR;
04557           }
04558         } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
04559       }
04560     }
04561     else
04562     {
04563       /*Write header block in the IN FIFO without last block */
04564       for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U))); loopcounter += 4U)
04565       {
04566         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04567         hcryp->CrypHeaderCount++ ;
04568         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04569         hcryp->CrypHeaderCount++ ;
04570         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04571         hcryp->CrypHeaderCount++ ;
04572         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04573         hcryp->CrypHeaderCount++ ;
04574 
04575         /* Wait for IFEM to be raised */
04576         count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
04577         do
04578         {
04579           count-- ;
04580           if (count == 0U)
04581           {
04582             /* Disable the CRYP peripheral clock */
04583             __HAL_CRYP_DISABLE(hcryp);
04584 
04585             /* Change state */
04586             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04587             hcryp->State = HAL_CRYP_STATE_READY;
04588 
04589             /* Process unlocked */
04590             __HAL_UNLOCK(hcryp);
04591             return HAL_ERROR;
04592           }
04593         } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
04594       }
04595       /*  Last block optionally pad the data with zeros*/
04596       for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
04597       {
04598         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04599         hcryp->CrypHeaderCount++ ;
04600       }
04601       while (loopcounter < 4U)
04602       {
04603         /* Pad the data with zeros to have a complete block */
04604         hcryp->Instance->DIN = 0x0U;
04605         loopcounter++;
04606       }
04607       /* Wait for IFEM to be raised */
04608       count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
04609       do
04610       {
04611         count-- ;
04612         if (count == 0U)
04613         {
04614           /* Disable the CRYP peripheral clock */
04615           __HAL_CRYP_DISABLE(hcryp);
04616           /* Change state */
04617           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04618           hcryp->State = HAL_CRYP_STATE_READY;
04619           /* Process unlocked */
04620           __HAL_UNLOCK(hcryp);
04621           return HAL_ERROR;
04622         }
04623       } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
04624     }
04625     /* Wait until the complete message has been processed */
04626     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
04627     do
04628     {
04629       count-- ;
04630       if (count == 0U)
04631       {
04632         /* Disable the CRYP peripheral clock */
04633         __HAL_CRYP_DISABLE(hcryp);
04634         /* Change state */
04635         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04636         hcryp->State = HAL_CRYP_STATE_READY;
04637         /* Process unlocked */
04638         __HAL_UNLOCK(hcryp);
04639         return HAL_ERROR;
04640       }
04641     } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
04642   }
04643 
04644   /* Return function status */
04645   return HAL_OK;
04646 }
04647 
04648 /**
04649   * @brief  Sets the header phase in interrupt mode
04650   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
04651   *         the configuration information for CRYP module(Header & HeaderSize)
04652   * @retval None
04653   */
04654 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
04655 {
04656   uint32_t loopcounter;
04657 
04658   /***************************** Header phase *********************************/
04659 
04660   if (hcryp->Init.HeaderSize ==  hcryp->CrypHeaderCount)
04661   {
04662     /* Disable interrupts */
04663     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
04664 
04665     /* Disable the CRYP peripheral */
04666     __HAL_CRYP_DISABLE(hcryp);
04667 
04668 #if !defined (CRYP_VER_2_2)
04669     if (hcryp->Version >= REV_ID_B)
04670 #endif /*End of not defined CRYP_VER_2_2*/
04671     {
04672       /* Set to 0 the number of non-valid bytes using NPBLB register*/
04673       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
04674     }
04675 
04676     /* Set the phase */
04677     hcryp->Phase = CRYP_PHASE_PROCESS;
04678 
04679     /* Select payload phase once the header phase is performed */
04680     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
04681 
04682     /* Enable Interrupts */
04683     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
04684 
04685     /* Enable the CRYP peripheral */
04686     __HAL_CRYP_ENABLE(hcryp);
04687   }
04688   else if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U)
04689 
04690   {
04691     /* HeaderSize %4, no padding */
04692     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04693     hcryp->CrypHeaderCount++ ;
04694     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04695     hcryp->CrypHeaderCount++  ;
04696     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04697     hcryp->CrypHeaderCount++ ;
04698     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04699     hcryp->CrypHeaderCount++ ;
04700   }
04701   else
04702   {
04703     /*  Last block optionally pad the data with zeros*/
04704     for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
04705     {
04706       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
04707       hcryp->CrypHeaderCount++ ;
04708     }
04709     while (loopcounter < 4U)
04710     {
04711       /* Pad the data with zeros to have a complete block */
04712       hcryp->Instance->DIN = 0x0U;
04713       loopcounter++;
04714     }
04715   }
04716 }
04717 
04718 #if !defined (CRYP_VER_2_2)
04719 /**
04720   * @brief  Workaround used for GCM/CCM mode.
04721   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
04722   *         the configuration information for CRYP module
04723   * @param  Timeout: Timeout value
04724   * @retval None
04725   */
04726 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
04727 {
04728   uint32_t  iv1temp;
04729   uint32_t  temp[4] = {0};
04730   uint32_t  temp2[4] = {0};
04731   uint32_t intermediate_data[4] = {0};
04732   uint32_t index;
04733   uint32_t lastwordsize;
04734   uint32_t npblb;
04735 
04736   /* Compute the number of padding bytes in last block of payload */
04737   npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
04738 
04739   /* Number of valid words (lastwordsize) in last block */
04740   if ((npblb % 4U) == 0U)
04741   {
04742     lastwordsize = (16U - npblb) / 4U;
04743   }
04744   else
04745   {
04746     lastwordsize = ((16U - npblb) / 4U) + 1U;
04747   }
04748 
04749   /* Workaround 2, case GCM encryption */
04750   if (hcryp->Init.Algorithm == CRYP_AES_GCM)
04751   {
04752     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
04753     {
04754       /*Workaround in order to properly compute authentication tags while doing
04755        a GCM encryption with the last block of payload size inferior to 128 bits*/
04756       /* Disable CRYP to start the final phase */
04757       __HAL_CRYP_DISABLE(hcryp);
04758 
04759       /*Update CRYP_IV1R register and ALGOMODE*/
04760       hcryp->Instance->IV1RR = ((hcryp->Instance->CSGCMCCM7R)-1U);
04761       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
04762 
04763       /* Enable CRYP to start the final phase */
04764       __HAL_CRYP_ENABLE(hcryp);
04765     }
04766 
04767     for (index = 0; index < lastwordsize ; index ++)
04768     {
04769       /* Write the last input block in the IN FIFO */
04770       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
04771       hcryp->CrypInCount++;
04772     }
04773     while (index < 4U)
04774     {
04775       /* Pad the data with zeros to have a complete block */
04776       hcryp->Instance->DIN  = 0U;
04777       index++;
04778     }
04779     /* Wait for OFNE flag to be raised */
04780     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
04781     {
04782       /* Disable the CRYP peripheral clock */
04783       __HAL_CRYP_DISABLE(hcryp);
04784 
04785       /* Change state */
04786       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04787       hcryp->State = HAL_CRYP_STATE_READY;
04788 
04789       /* Process Unlocked */
04790       __HAL_UNLOCK(hcryp);
04791 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
04792       /*Call registered error callback*/
04793       hcryp->ErrorCallback(hcryp);
04794 #else
04795       /*Call legacy weak error callback*/
04796       HAL_CRYP_ErrorCallback(hcryp);
04797 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
04798     }
04799     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
04800     {
04801       for (index = 0U; index < 4U; index++)
04802       {
04803         /* Read the output block from the output FIFO */
04804         intermediate_data[index] = hcryp->Instance->DOUT;
04805 
04806         /* Intermediate data buffer to be used in for the workaround*/
04807         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
04808         hcryp->CrypOutCount++;
04809       }
04810     }
04811 
04812     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
04813     {
04814       /*workaround in order to properly compute authentication tags while doing
04815       a GCM encryption with the last block of payload size inferior to 128 bits*/
04816       /* Change the AES mode to GCM mode and Select Final phase */
04817       /* configured  CHMOD GCM   */
04818       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_GCM);
04819 
04820       /* configured  final phase  */
04821       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
04822 
04823       if ( (hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_32B)
04824       {
04825         if ((npblb %4U)==1U)
04826         {
04827           intermediate_data[lastwordsize-1U] &= 0xFFFFFF00U;
04828         }
04829         if ((npblb %4U)==2U)
04830         {
04831           intermediate_data[lastwordsize-1U] &= 0xFFFF0000U;
04832         }
04833         if ((npblb %4U)==3U)
04834         {
04835           intermediate_data[lastwordsize-1U] &= 0xFF000000U;
04836         }
04837       }
04838       else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_8B)
04839       {
04840         if ((npblb %4U)==1U)
04841         {
04842           intermediate_data[lastwordsize-1U] &= __REV(0xFFFFFF00U);
04843         }
04844         if ((npblb %4U)==2U)
04845         {
04846           intermediate_data[lastwordsize-1U] &= __REV(0xFFFF0000U);
04847         }
04848         if ((npblb %4U)==3U)
04849         {
04850           intermediate_data[lastwordsize-1U] &= __REV(0xFF000000U);
04851         }
04852       }
04853       else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_16B)
04854       {
04855         if ((npblb %4U)==1U)
04856         {
04857           intermediate_data[lastwordsize-1U] &= __ROR((0xFFFFFF00U), 16);
04858         }
04859         if ((npblb %4U)==2U)
04860         {
04861           intermediate_data[lastwordsize-1U] &= __ROR((0xFFFF0000U), 16);
04862         }
04863         if ((npblb %4U)==3U)
04864         {
04865           intermediate_data[lastwordsize-1U] &= __ROR((0xFF000000U), 16);
04866         }
04867       }
04868       else /*CRYP_DATATYPE_1B*/
04869       {
04870         if ((npblb %4U)==1U)
04871         {
04872           intermediate_data[lastwordsize-1U] &= __RBIT(0xFFFFFF00U);
04873         }
04874         if ((npblb %4U)==2U)
04875         {
04876           intermediate_data[lastwordsize-1U] &= __RBIT(0xFFFF0000U);
04877         }
04878         if ((npblb %4U)==3U)
04879         {
04880           intermediate_data[lastwordsize-1U] &= __RBIT(0xFF000000U);
04881         }
04882       }
04883       
04884       for (index = 0U; index < lastwordsize ; index ++)
04885       {
04886         /*Write the intermediate_data in the IN FIFO */
04887         hcryp->Instance->DIN = intermediate_data[index];
04888       }
04889       while (index < 4U)
04890       {
04891         /* Pad the data with zeros to have a complete block */
04892         hcryp->Instance->DIN  = 0x0U;
04893         index++;
04894       }
04895       /* Wait for OFNE flag to be raised */
04896       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
04897       {
04898         /* Disable the CRYP peripheral clock */
04899         __HAL_CRYP_DISABLE(hcryp);
04900 
04901         /* Change state */
04902         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04903         hcryp->State = HAL_CRYP_STATE_READY;
04904 
04905         /* Process unlocked */
04906         __HAL_UNLOCK(hcryp);
04907 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
04908         /*Call registered error callback*/
04909         hcryp->ErrorCallback(hcryp);
04910 #else
04911         /*Call legacy weak error callback*/
04912         HAL_CRYP_ErrorCallback(hcryp);
04913 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
04914       }
04915 
04916       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
04917       {
04918         for (index = 0U; index < 4U; index++)
04919         {
04920           intermediate_data[index] = hcryp->Instance->DOUT;
04921         }
04922       }
04923     }
04924   } /* End of GCM encryption */
04925   else
04926   {
04927     /* Workaround 2, case CCM decryption, in order to properly compute
04928       authentication tags while doing a CCM decryption with the last block
04929       of payload size inferior to 128 bits*/
04930 
04931     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
04932     {
04933       iv1temp = hcryp->Instance->CSGCMCCM7R;
04934 
04935       /* Disable CRYP to start the final phase */
04936       __HAL_CRYP_DISABLE(hcryp);
04937 
04938       temp[0] =  hcryp->Instance->CSGCMCCM0R;
04939       temp[1] =  hcryp->Instance->CSGCMCCM1R;
04940       temp[2] =  hcryp->Instance->CSGCMCCM2R;
04941       temp[3] =  hcryp->Instance->CSGCMCCM3R;
04942 
04943       hcryp->Instance->IV1RR = iv1temp;
04944 
04945       /* Configured  CHMOD CTR   */
04946       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
04947 
04948       /* Enable CRYP to start the final phase */
04949       __HAL_CRYP_ENABLE(hcryp);
04950     }
04951     /*  Last block optionally pad the data with zeros*/
04952     for (index = 0U; index < lastwordsize; index ++)
04953     {
04954       /* Write the last Input block in the IN FIFO */
04955       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
04956       hcryp->CrypInCount++;
04957     }
04958     while (index < 4U)
04959     {
04960       /* Pad the data with zeros to have a complete block */
04961       hcryp->Instance->DIN  = 0U;
04962       index++;
04963     }
04964     /* Wait for OFNE flag to be raised */
04965     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
04966     {
04967       /* Disable the CRYP peripheral clock */
04968       __HAL_CRYP_DISABLE(hcryp);
04969 
04970       /* Change state */
04971       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
04972       hcryp->State = HAL_CRYP_STATE_READY;
04973 
04974       /* Process Unlocked */
04975       __HAL_UNLOCK(hcryp);
04976 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
04977       /*Call registered error callback*/
04978       hcryp->ErrorCallback(hcryp);
04979 #else
04980       /*Call legacy weak error callback*/
04981       HAL_CRYP_ErrorCallback(hcryp);
04982 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
04983     }
04984 
04985     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
04986     {
04987       for (index = 0U; index < 4U; index++)
04988       {
04989         /* Read the Output block from the Output FIFO */
04990         intermediate_data[index] = hcryp->Instance->DOUT;
04991 
04992         /*intermediate data buffer to be used in for the workaround*/
04993         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
04994         hcryp->CrypOutCount++;
04995       }
04996     }
04997 
04998     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
04999     {
05000       temp2[0] =  hcryp->Instance->CSGCMCCM0R;
05001       temp2[1] =  hcryp->Instance->CSGCMCCM1R;
05002       temp2[2] =  hcryp->Instance->CSGCMCCM2R;
05003       temp2[3] =  hcryp->Instance->CSGCMCCM3R;
05004 
05005       /* configured  CHMOD CCM   */
05006       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CCM);
05007 
05008       /* configured  Header phase  */
05009       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_HEADER);
05010 
05011       /*set to zero the bits corresponding to the padded bits*/
05012       for (index = lastwordsize; index < 4U; index ++)
05013       {
05014         intermediate_data[index] = 0U;
05015       }
05016 
05017       if ((npblb % 4U) == 1U)
05018       {
05019         intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
05020       }
05021       if ((npblb % 4U) == 2U)
05022       {
05023         intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
05024       }
05025       if ((npblb % 4U) == 3U)
05026       {
05027         intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
05028       }
05029 
05030       for (index = 0U; index < 4U ; index ++)
05031       {
05032         intermediate_data[index] ^=  temp[index];
05033         intermediate_data[index] ^=  temp2[index];
05034       }
05035       for (index = 0U; index < 4U; index ++)
05036       {
05037         /* Write the last Input block in the IN FIFO */
05038         hcryp->Instance->DIN  = intermediate_data[index] ;
05039       }
05040 
05041       /* Wait for BUSY flag to be raised */
05042       if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
05043       {
05044         /* Disable the CRYP peripheral clock */
05045         __HAL_CRYP_DISABLE(hcryp);
05046 
05047         /* Change state */
05048         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
05049         hcryp->State = HAL_CRYP_STATE_READY;
05050 
05051         /* Process Unlocked */
05052         __HAL_UNLOCK(hcryp);
05053 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
05054         /*Call registered error callback*/
05055         hcryp->ErrorCallback(hcryp);
05056 #else
05057         /*Call legacy weak error callback*/
05058         HAL_CRYP_ErrorCallback(hcryp);
05059 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
05060       }
05061     }
05062   } /* End of CCM WKA*/
05063 
05064   /* Process Unlocked */
05065   __HAL_UNLOCK(hcryp);
05066 }
05067 #endif /*End of not defined CRYP_VER_2_2*/
05068 
05069 /**
05070   * @brief  Handle CRYP hardware block Timeout when waiting for IFEM flag to be raised.
05071   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
05072   *         the configuration information for CRYP module.
05073   * @param  Timeout: Timeout duration.
05074   * @retval HAL status
05075   */
05076 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
05077 {
05078   uint32_t tickstart;
05079 
05080   /* Get timeout */
05081   tickstart = HAL_GetTick();
05082 
05083   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
05084   {
05085     /* Check for the Timeout */
05086     if (Timeout != HAL_MAX_DELAY)
05087     {
05088       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
05089       {
05090         return HAL_ERROR;
05091       }
05092     }
05093   }
05094   return HAL_OK;
05095 }
05096 /**
05097   * @brief  Handle CRYP hardware block Timeout when waiting for BUSY flag to be raised.
05098   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
05099   *         the configuration information for CRYP module.
05100   * @param  Timeout: Timeout duration.
05101   * @retval HAL status
05102   */
05103 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
05104 {
05105   uint32_t tickstart;
05106 
05107   /* Get timeout */
05108   tickstart = HAL_GetTick();
05109 
05110   while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY))
05111   {
05112     /* Check for the Timeout */
05113     if (Timeout != HAL_MAX_DELAY)
05114     {
05115       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
05116       {
05117         return HAL_ERROR;
05118       }
05119     }
05120   }
05121   return HAL_OK;
05122 }
05123 
05124 
05125 /**
05126   * @brief  Handle CRYP hardware block Timeout when waiting for OFNE flag to be raised.
05127   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
05128   *         the configuration information for CRYP module.
05129   * @param  Timeout: Timeout duration.
05130   * @retval HAL status
05131   */
05132 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef  *hcryp, uint32_t Timeout)
05133 {
05134   uint32_t tickstart;
05135 
05136   /* Get timeout */
05137   tickstart = HAL_GetTick();
05138 
05139   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
05140   {
05141     /* Check for the Timeout */
05142     if (Timeout != HAL_MAX_DELAY)
05143     {
05144       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
05145       {
05146         return HAL_ERROR;
05147       }
05148     }
05149   }
05150   return HAL_OK;
05151 }
05152 
05153 
05154 /**
05155   * @}
05156   */
05157 
05158 
05159 
05160 /**
05161   * @}
05162   */
05163 
05164 /**
05165   * @}
05166   */
05167 
05168 #endif /* HAL_CRYP_MODULE_ENABLED */
05169 
05170 
05171 /**
05172   * @}
05173   */
05174 #endif /* CRYP */
05175 /**
05176   * @}
05177   */
05178