Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:06

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_cryp.c
0004   * @author  MCD Application Team
0005   * @brief   CRYP HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Cryptography (CRYP) peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + AES processing functions
0010   *           + DES processing functions
0011   *           + TDES processing functions
0012   *           + DMA callback functions
0013   *           + CRYP IRQ handler management
0014   *           + Peripheral State functions
0015   *
0016   ******************************************************************************
0017   * @attention
0018   *
0019   * Copyright (c) 2017 STMicroelectronics.
0020   * All rights reserved.
0021   *
0022   * This software is licensed under terms that can be found in the LICENSE file
0023   * in the root directory of this software component.
0024   * If no LICENSE file comes with this software, it is provided AS-IS.
0025   *
0026   ******************************************************************************
0027   @verbatim
0028   ==============================================================================
0029                      ##### How to use this driver #####
0030   ==============================================================================
0031     [..]
0032       The CRYP HAL driver can be used in CRYP IP as follows:
0033 
0034       (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
0035          (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
0036          (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
0037              (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
0038              (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
0039              (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
0040          (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
0041              (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
0042              (+++) Configure and enable two DMA streams one for managing data transfer from
0043                  memory to peripheral (input stream) and another stream for managing data
0044                  transfer from peripheral to memory (output stream)
0045              (+++) Associate the initialized DMA handle to the CRYP DMA handle
0046                  using  __HAL_LINKDMA()
0047              (+++) Configure the priority and enable the NVIC for the transfer complete
0048                  interrupt on the two DMA Streams. The output stream should have higher
0049                  priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
0050 
0051       (#)Initialize the CRYP according to the specified parameters :
0052          (##) The data type: bit swap(1-bit data), byte swap(8-bit data), half word swap(16-bit data)
0053             or no swap(32-bit data).
0054          (##) The key size: 128, 192 or 256.
0055          (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM.
0056          (##) The initialization vector (counter). It is not used in ECB mode.
0057          (##) The key buffer used for encryption/decryption.
0058          (##) The Header used only in AES GCM and CCM Algorithm for authentication.
0059          (##) The HeaderSize The size of header buffer in word.
0060          (##) The B0 block is the first authentication block used only  in AES CCM mode.
0061 
0062       (#)Three processing (encryption/decryption) functions are available:
0063          (##) Polling mode: encryption and decryption APIs are blocking functions
0064               i.e. they process the data and wait till the processing is finished,
0065               e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
0066          (##) Interrupt mode: encryption and decryption APIs are not blocking functions
0067               i.e. they process the data under interrupt,
0068               e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
0069          (##) DMA mode: encryption and decryption APIs are not blocking functions
0070               i.e. the data transfer is ensured by DMA,
0071               e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
0072 
0073       (#)When the processing function is called at first time after HAL_CRYP_Init()
0074          the CRYP peripheral is configured and processes the buffer in input.
0075          At second call, no need to Initialize the CRYP, user have to get current configuration via
0076          HAL_CRYP_GetConfig() API, then only  HAL_CRYP_SetConfig() is requested to set
0077          new parametres, finally user can  start encryption/decryption.
0078 
0079        (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
0080 
0081        (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
0082           without having to configure again the Key or the Initialization Vector between each API call,
0083           the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
0084           Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
0085           or HAL_CRYP_Decrypt_DMA().
0086 
0087     [..]
0088       The cryptographic processor supports following standards:
0089       (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 IP:
0090          (##)64-bit data block processing
0091          (##) chaining modes supported :
0092              (+++)  Electronic Code Book(ECB)
0093              (+++)  Cipher Block Chaining (CBC)
0094          (##) keys length supported :64-bit, 128-bit and 192-bit.
0095       (#) The advanced encryption standard (AES) supported  by CRYP1:
0096          (##)128-bit data block processing
0097          (##) chaining modes supported :
0098              (+++)  Electronic Code Book(ECB)
0099              (+++)  Cipher Block Chaining (CBC)
0100              (+++)  Counter mode (CTR)
0101              (+++)  Galois/counter mode (GCM/GMAC)
0102              (+++)  Counter with Cipher Block Chaining-Message(CCM)
0103          (##) keys length Supported :
0104              (+++) for CRYP1 IP: 128-bit, 192-bit and 256-bit.
0105 
0106     [..]  This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 IP:
0107       (#)  Algorithm supported :
0108          (##) Galois/counter mode (GCM)
0109          (##) Galois message authentication code (GMAC) :is exactly the same as
0110               GCM algorithm composed only by an header.
0111       (#)  Four phases are performed in GCM :
0112          (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
0113          (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
0114           computation only.
0115          (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
0116           encryption + data XORing. It works in a similar way for ciphertext (C).
0117          (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
0118           HAL_CRYPEx_AESGCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond
0119           to the Tag. user should consider only part of this 4 words, if Tag length is less than 128 bits.
0120       (#)  structure of message construction in GCM is defined as below  :
0121          (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
0122          (##) The authenticated header A (also knows as Additional Authentication Data AAD)
0123           this part of the message is only authenticated, not encrypted.
0124          (##) The plaintext message P is both authenticated and encrypted as ciphertext.
0125           GCM standard specifies that ciphertext has same bit length as the plaintext.
0126          (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
0127           (on 64 bits)
0128 
0129     [..]  This section describe The AES Counter with Cipher Block Chaining-Message
0130           Authentication Code (CCM) supported by both CRYP1 IP:
0131       (#)  Specific parameters for CCM  :
0132 
0133          (##) B0 block  : According to NIST Special Publication 800-38C,
0134             The first block B0 is formatted as follows, where l(m) is encoded in
0135             most-significant-byte first order(see below table 3)
0136 
0137               (+++)  Q: a bit string representation of the octet length of P (plaintext)
0138               (+++)  q The octet length of the binary representation of the octet length of the payload
0139               (+++)  A nonce (N), n The octet length of the where n+q=15.
0140               (+++)  Flags: most significant octet containing four flags for control information,
0141               (+++)  t The octet length of the MAC.
0142          (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
0143               the associated data length expressed in bytes (a) defined as below:
0144             (+++)  If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
0145             (+++)  If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
0146             (+++)  If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
0147          (##) CTRx block  : control blocks
0148             (+++) Generation of CTR1 from first block B0 information :
0149               equal to B0 with first 5 bits zeroed and most significant bits storing octet
0150               length of P also zeroed, then incremented by one ( see below Table 4)
0151             (+++) Generation of CTR0: same as CTR1 with bit[0] set to zero.
0152 
0153       (#)  Four phases are performed in CCM for CRYP1 IP:
0154          (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
0155          (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
0156           computation only.
0157          (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
0158           encryption + data XORing. It works in a similar way for ciphertext (C).
0159          (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
0160          HAL_CRYPEx_AESCCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond to the Tag.
0161          user should consider only part of this 4 words, if Tag length is less than 128 bits
0162 
0163   *** Callback registration ***
0164   =============================
0165 
0166   [..]
0167   The compilation define  USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
0168   allows the user to configure dynamically the driver callbacks.
0169   Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
0170   to register an interrupt callback.
0171 
0172   [..]
0173   Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
0174     (+) InCpltCallback     :  Input FIFO transfer completed callback.
0175     (+) OutCpltCallback    : Output FIFO transfer completed callback.
0176     (+) ErrorCallback      : callback for error detection.
0177     (+) MspInitCallback    : CRYP MspInit.
0178     (+) MspDeInitCallback  : CRYP MspDeInit.
0179   This function takes as parameters the HAL peripheral handle, the Callback ID
0180   and a pointer to the user callback function.
0181 
0182   [..]
0183   Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
0184   weak function.
0185   @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
0186   and the Callback ID.
0187   This function allows to reset following callbacks:
0188     (+) InCpltCallback     :  Input FIFO transfer completed callback.
0189     (+) OutCpltCallback    : Output FIFO transfer completed callback.
0190     (+) ErrorCallback      : callback for error detection.
0191     (+) MspInitCallback    : CRYP MspInit.
0192     (+) MspDeInitCallback  : CRYP MspDeInit.
0193 
0194   [..]
0195   By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
0196   all callbacks are set to the corresponding weak functions :
0197   examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
0198   Exception done for MspInit and MspDeInit functions that are
0199   reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
0200   these callbacks are null (not registered beforehand).
0201   if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
0202   keep and use the user MspInit/MspDeInit functions (registered beforehand)
0203 
0204   [..]
0205   Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
0206   Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
0207   in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
0208   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
0209   In that case first register the MspInit/MspDeInit user callbacks
0210   using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
0211   or @ref HAL_CRYP_Init() function.
0212 
0213   [..]
0214   When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
0215   not defined, the callback registration feature is not available and all callbacks
0216   are set to the corresponding weak functions.
0217 
0218   @endverbatim
0219 
0220   Table 1. Initial Counter Block (ICB)
0221           +-------------------------------------------------------+
0222           |       Initialization vector (IV)      |  Counter      |
0223           |----------------|----------------|-----------|---------|
0224          127              95                63            31       0
0225 
0226 
0227               Bit Number    Register           Contents
0228               ----------   ---------------       -----------
0229               127 ...96    CRYP_IV1R[31:0]     ICB[127:96]
0230               95  ...64    CRYP_IV1L[31:0]     B0[95:64]
0231               63 ... 32    CRYP_IV0R[31:0]     ICB[63:32]
0232               31 ... 0     CRYP_IV0L[31:0]     ICB[31:0], where 32-bit counter= 0x2
0233 
0234   Table 2.  GCM last block definition
0235 
0236           +-------------------------------------------------------------------+
0237           |  Bit[0]   |  Bit[32]           |  Bit[64]  | Bit[96]              |
0238           |-----------|--------------------|-----------|----------------------|
0239           |   0x0     | Header length[31:0]|     0x0   | Payload length[31:0] |
0240           |-----------|--------------------|-----------|----------------------|
0241 
0242   Table 3. B0 block
0243                 Octet Number   Contents
0244                 ------------   ---------
0245                 0              Flags
0246                 1 ... 15-q     Nonce N
0247                 16-q ... 15    Q
0248 
0249             the Flags field is formatted as follows:
0250 
0251                 Bit Number   Contents
0252                 ----------   ----------------------
0253                 7            Reserved (always zero)
0254                 6            Adata
0255                 5 ... 3      (t-2)/2
0256                 2 ... 0      [q-1]3
0257 
0258  Table 4. CTRx block
0259                 Bit Number    Register           Contents
0260                 ----------   ---------------       -----------
0261                 127 ...96    CRYP_IV1R[31:0]     B0[127:96], where Q length bits are set to 0, except for
0262                                                  bit 0 that is set to 1
0263                 95  ...64    CRYP_IV1L[31:0]     B0[95:64]
0264                 63 ... 32    CRYP_IV0R[31:0]     B0[63:32]
0265                 31 ... 0     CRYP_IV0L[31:0]     B0[31:0], where flag bits set to 0
0266   */
0267 
0268 /* Includes ------------------------------------------------------------------*/
0269 #include "stm32h7xx_hal.h"
0270 
0271 /** @addtogroup STM32H7xx_HAL_Driver
0272   * @{
0273   */
0274 
0275 #if defined (CRYP)
0276 
0277 /** @defgroup CRYP CRYP
0278   * @ingroup RTEMSBSPsARMSTM32H7
0279   * @brief CRYP HAL module driver.
0280   * @{
0281   */
0282 
0283 
0284 #ifdef HAL_CRYP_MODULE_ENABLED
0285 
0286 /* Private typedef -----------------------------------------------------------*/
0287 /* Private define ------------------------------------------------------------*/
0288 /** @addtogroup CRYP_Private_Defines
0289   * @{
0290   */
0291 #define CRYP_TIMEOUT_KEYPREPARATION      82U         /*!<  The latency of key preparation operation is 82 clock cycles.*/
0292 #define CRYP_TIMEOUT_GCMCCMINITPHASE     299U        /*!<  The latency of  GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
0293 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE   290U        /*!<  The latency of  GCM/CCM header phase is 290 clock cycles.*/
0294 
0295 #define  CRYP_PHASE_READY                0x00000001U /*!< CRYP peripheral is ready for initialization. */
0296 #define  CRYP_PHASE_PROCESS              0x00000002U /*!< CRYP peripheral is in processing phase */
0297 
0298 #define CRYP_PHASE_INIT                  0x00000000U             /*!< GCM/GMAC (or CCM) init phase */
0299 #define CRYP_PHASE_HEADER                CRYP_CR_GCM_CCMPH_0     /*!< GCM/GMAC or CCM header phase */
0300 #define CRYP_PHASE_PAYLOAD               CRYP_CR_GCM_CCMPH_1     /*!< GCM(/CCM) payload phase      */
0301 #define CRYP_PHASE_FINAL                 CRYP_CR_GCM_CCMPH       /*!< GCM/GMAC or CCM  final phase */
0302 #define CRYP_OPERATINGMODE_ENCRYPT       0x00000000U             /*!< Encryption mode   */
0303 #define CRYP_OPERATINGMODE_DECRYPT       CRYP_CR_ALGODIR         /*!< Decryption        */
0304 
0305 
0306 /*  CTR1 information to use in CCM algorithm */
0307 #define CRYP_CCM_CTR1_0                  0x07FFFFFFU
0308 #define CRYP_CCM_CTR1_1                  0xFFFFFF00U
0309 #define CRYP_CCM_CTR1_2                  0x00000001U
0310 
0311 /**
0312   * @}
0313   */
0314 
0315 
0316 /* Private macro -------------------------------------------------------------*/
0317 /** @addtogroup CRYP_Private_Macros
0318   * @{
0319   */
0320 
0321 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__)  do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\
0322                                                         (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
0323                                                        }while(0)
0324 
0325 #define HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |=  CRYP_CR_FFLUSH)
0326 
0327 
0328 /**
0329   * @}
0330   */
0331 
0332 /* Private struct -------------------------------------------------------------*/
0333 /* Private variables ---------------------------------------------------------*/
0334 /* Private function prototypes -----------------------------------------------*/
0335 /** @addtogroup CRYP_Private_Functions_Prototypes
0336   * @{
0337   */
0338 
0339 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
0340 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
0341 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
0342 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
0343 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
0344 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
0345 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0346 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
0347 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
0348 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
0349 #if !defined (CRYP_VER_2_2)
0350 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0351 #endif /*End of not defined CRYP_VER_2_2*/
0352 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
0353 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
0354 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0355 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0356 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
0357 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
0358 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
0359 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0360 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0361 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
0362 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
0363 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
0364 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp);
0365 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0366 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0367 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0368 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
0369 
0370 /**
0371   * @}
0372   */
0373 
0374 /* Exported functions ---------------------------------------------------------*/
0375 
0376 /** @defgroup CRYP_Exported_Functions CRYP Exported Functions
0377   * @ingroup RTEMSBSPsARMSTM32H7
0378   * @{
0379   */
0380 
0381 
0382 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
0383   * @ingroup RTEMSBSPsARMSTM32H7
0384   *  @brief    CRYP  Initialization and Configuration functions.
0385   *
0386 @verbatim
0387   ========================================================================================
0388      ##### Initialization, de-initialization and Set and Get configuration functions #####
0389   ========================================================================================
0390     [..]  This section provides functions allowing to:
0391       (+) Initialize the CRYP
0392       (+) DeInitialize the CRYP
0393       (+) Initialize the CRYP MSP
0394       (+) DeInitialize the CRYP MSP
0395       (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
0396           Parameters which are configured in This section are :
0397           (++) Key size
0398           (++) Data Type : 32,16, 8 or 1bit
0399           (++) AlgoMode : for CRYP1 IP
0400                  ECB and CBC in DES/TDES Standard
0401                  ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
0402       (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
0403 
0404 
0405 @endverbatim
0406   * @{
0407   */
0408 
0409 
0410 /**
0411   * @brief  Initializes the CRYP according to the specified
0412   *         parameters in the CRYP_ConfigTypeDef and creates the associated handle.
0413   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
0414   *         the configuration information for CRYP module
0415   * @retval HAL status
0416   */
0417 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
0418 {
0419   /* Check the CRYP handle allocation */
0420   if (hcryp == NULL)
0421   {
0422     return HAL_ERROR;
0423   }
0424 
0425   /* Check parameters */
0426   assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
0427   assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
0428   assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
0429   assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
0430 
0431 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
0432   if (hcryp->State == HAL_CRYP_STATE_RESET)
0433   {
0434     /* Allocate lock resource and initialize it */
0435     hcryp->Lock = HAL_UNLOCKED;
0436 
0437     hcryp->InCpltCallback  = HAL_CRYP_InCpltCallback;  /* Legacy weak  InCpltCallback  */
0438     hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback  */
0439     hcryp->ErrorCallback   = HAL_CRYP_ErrorCallback;   /* Legacy weak ErrorCallback    */
0440 
0441     if (hcryp->MspInitCallback == NULL)
0442     {
0443       hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit  */
0444     }
0445 
0446     /* Init the low level hardware */
0447     hcryp->MspInitCallback(hcryp);
0448   }
0449 #else
0450   if (hcryp->State == HAL_CRYP_STATE_RESET)
0451   {
0452     /* Allocate lock resource and initialize it */
0453     hcryp->Lock = HAL_UNLOCKED;
0454 
0455     /* Init the low level hardware */
0456     HAL_CRYP_MspInit(hcryp);
0457   }
0458 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
0459 
0460   /* Set the key size(This bit field is don't care in the DES or TDES modes) data type and Algorithm */
0461   MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
0462              hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
0463 #if !defined (CRYP_VER_2_2)
0464   /* Read Device ID to indicate CRYP1 IP Version */
0465   hcryp->Version = HAL_GetREVID();
0466 #endif /*End of not defined CRYP_VER_2_2*/
0467   /* Reset Error Code field */
0468   hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
0469 
0470   /* Reset peripheral Key and IV configuration flag */
0471   hcryp->KeyIVConfig = 0U;
0472 
0473   /* Change the CRYP state */
0474   hcryp->State = HAL_CRYP_STATE_READY;
0475 
0476   /* Set the default CRYP phase */
0477   hcryp->Phase = CRYP_PHASE_READY;
0478 
0479   /* Return function status */
0480   return HAL_OK;
0481 }
0482 
0483 /**
0484   * @brief  De-Initializes the CRYP peripheral.
0485   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
0486   *         the configuration information for CRYP module
0487   * @retval HAL status
0488   */
0489 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
0490 {
0491   /* Check the CRYP handle allocation */
0492   if (hcryp == NULL)
0493   {
0494     return HAL_ERROR;
0495   }
0496 
0497   /* Set the default CRYP phase */
0498   hcryp->Phase = CRYP_PHASE_READY;
0499 
0500   /* Reset CrypInCount and CrypOutCount */
0501   hcryp->CrypInCount = 0;
0502   hcryp->CrypOutCount = 0;
0503   hcryp->CrypHeaderCount = 0;
0504 
0505   /* Disable the CRYP peripheral clock */
0506   __HAL_CRYP_DISABLE(hcryp);
0507 
0508 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
0509   if (hcryp->MspDeInitCallback == NULL)
0510   {
0511     hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit  */
0512   }
0513   /* DeInit the low level hardware */
0514   hcryp->MspDeInitCallback(hcryp);
0515 
0516 #else
0517   /* DeInit the low level hardware: CLOCK, NVIC.*/
0518   HAL_CRYP_MspDeInit(hcryp);
0519 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
0520 
0521   /* Change the CRYP state */
0522   hcryp->State = HAL_CRYP_STATE_RESET;
0523 
0524   /* Release Lock */
0525   __HAL_UNLOCK(hcryp);
0526 
0527   /* Return function status */
0528   return HAL_OK;
0529 }
0530 
0531 /**
0532   * @brief  Configure the CRYP according to the specified
0533   *         parameters in the CRYP_ConfigTypeDef
0534   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
0535   * @param  pConf: pointer to a CRYP_ConfigTypeDef structure that contains
0536   *         the configuration information for CRYP module
0537   * @retval HAL status
0538   */
0539 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
0540 {
0541   /* Check the CRYP handle allocation */
0542   if ((hcryp == NULL) || (pConf == NULL))
0543   {
0544     return HAL_ERROR;
0545   }
0546 
0547   /* Check parameters */
0548   assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
0549   assert_param(IS_CRYP_DATATYPE(pConf->DataType));
0550   assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
0551 
0552   if (hcryp->State == HAL_CRYP_STATE_READY)
0553   {
0554     /* Change the CRYP state */
0555     hcryp->State = HAL_CRYP_STATE_BUSY;
0556 
0557     /* Process locked */
0558     __HAL_LOCK(hcryp);
0559 
0560     /* Set  CRYP parameters  */
0561     hcryp->Init.DataType        = pConf->DataType;
0562     hcryp->Init.pKey            = pConf->pKey;
0563     hcryp->Init.Algorithm       = pConf->Algorithm;
0564     hcryp->Init.KeySize         = pConf->KeySize;
0565     hcryp->Init.pInitVect       = pConf->pInitVect;
0566     hcryp->Init.Header          = pConf->Header;
0567     hcryp->Init.HeaderSize      = pConf->HeaderSize;
0568     hcryp->Init.B0              = pConf->B0;
0569     hcryp->Init.DataWidthUnit   = pConf->DataWidthUnit;
0570     hcryp->Init.HeaderWidthUnit = pConf->HeaderWidthUnit;
0571     hcryp->Init.KeyIVConfigSkip = pConf->KeyIVConfigSkip;
0572 
0573     /* Set the key size(This bit field is don't care in the DES or TDES modes) data type, AlgoMode and operating mode*/
0574     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
0575                hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
0576 
0577     /* Process Unlocked */
0578     __HAL_UNLOCK(hcryp);
0579 
0580     /* Reset Error Code field */
0581     hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
0582 
0583     /* Change the CRYP state */
0584     hcryp->State = HAL_CRYP_STATE_READY;
0585 
0586     /* Set the default CRYP phase */
0587     hcryp->Phase = CRYP_PHASE_READY;
0588 
0589     /* Return function status */
0590     return HAL_OK;
0591   }
0592   else
0593   {
0594     /* Process Unlocked */
0595     __HAL_UNLOCK(hcryp);
0596 
0597     /* Busy error code field */
0598     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
0599     return HAL_ERROR;
0600   }
0601 }
0602 
0603 /**
0604   * @brief  Get CRYP Configuration parameters in associated handle.
0605   * @param  pConf: pointer to a CRYP_ConfigTypeDef structure
0606   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
0607   *         the configuration information for CRYP module
0608   * @retval HAL status
0609   */
0610 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
0611 {
0612   /* Check the CRYP handle allocation */
0613   if ((hcryp == NULL) || (pConf == NULL))
0614   {
0615     return HAL_ERROR;
0616   }
0617 
0618   if (hcryp->State == HAL_CRYP_STATE_READY)
0619   {
0620     /* Change the CRYP state */
0621     hcryp->State = HAL_CRYP_STATE_BUSY;
0622 
0623     /* Process locked */
0624     __HAL_LOCK(hcryp);
0625 
0626     /* Get  CRYP parameters  */
0627     pConf->DataType        = hcryp->Init.DataType;
0628     pConf->pKey            = hcryp->Init.pKey;
0629     pConf->Algorithm       = hcryp->Init.Algorithm;
0630     pConf->KeySize         = hcryp->Init.KeySize ;
0631     pConf->pInitVect       = hcryp->Init.pInitVect;
0632     pConf->Header          = hcryp->Init.Header ;
0633     pConf->HeaderSize      = hcryp->Init.HeaderSize;
0634     pConf->B0              = hcryp->Init.B0;
0635     pConf->DataWidthUnit   = hcryp->Init.DataWidthUnit;
0636     pConf->HeaderWidthUnit = hcryp->Init.HeaderWidthUnit;
0637     pConf->KeyIVConfigSkip = hcryp->Init.KeyIVConfigSkip;
0638 
0639     /* Process Unlocked */
0640     __HAL_UNLOCK(hcryp);
0641 
0642     /* Change the CRYP state */
0643     hcryp->State = HAL_CRYP_STATE_READY;
0644 
0645     /* Return function status */
0646     return HAL_OK;
0647   }
0648   else
0649   {
0650     /* Process Unlocked */
0651     __HAL_UNLOCK(hcryp);
0652 
0653     /* Busy error code field */
0654     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
0655     return HAL_ERROR;
0656   }
0657 }
0658 /**
0659   * @brief  Initializes the CRYP MSP.
0660   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
0661   *         the configuration information for CRYP module
0662   * @retval None
0663   */
0664 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
0665 {
0666   /* Prevent unused argument(s) compilation warning */
0667   UNUSED(hcryp);
0668 
0669   /* NOTE : This function Should not be modified, when the callback is needed,
0670             the HAL_CRYP_MspInit could be implemented in the user file
0671    */
0672 }
0673 
0674 /**
0675   * @brief  DeInitializes CRYP MSP.
0676   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
0677   *         the configuration information for CRYP module
0678   * @retval None
0679   */
0680 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
0681 {
0682   /* Prevent unused argument(s) compilation warning */
0683   UNUSED(hcryp);
0684 
0685   /* NOTE : This function Should not be modified, when the callback is needed,
0686             the HAL_CRYP_MspDeInit could be implemented in the user file
0687    */
0688 }
0689 
0690 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
0691 /**
0692   * @brief  Register a User CRYP Callback
0693   *         To be used instead of the weak predefined callback
0694   * @param hcryp cryp handle
0695   * @param CallbackID ID of the callback to be registered
0696   *        This parameter can be one of the following values:
0697   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
0698   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
0699   *          @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
0700   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
0701   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
0702   * @param pCallback pointer to the Callback function
0703   * @retval status
0704   */
0705 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID,
0706                                             pCRYP_CallbackTypeDef pCallback)
0707 {
0708   HAL_StatusTypeDef status = HAL_OK;
0709 
0710   if (pCallback == NULL)
0711   {
0712     /* Update the error code */
0713     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
0714 
0715     return HAL_ERROR;
0716   }
0717   /* Process locked */
0718   __HAL_LOCK(hcryp);
0719 
0720   if (hcryp->State == HAL_CRYP_STATE_READY)
0721   {
0722     switch (CallbackID)
0723     {
0724       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
0725         hcryp->InCpltCallback = pCallback;
0726         break;
0727 
0728       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
0729         hcryp->OutCpltCallback = pCallback;
0730         break;
0731 
0732       case HAL_CRYP_ERROR_CB_ID :
0733         hcryp->ErrorCallback = pCallback;
0734         break;
0735 
0736       case HAL_CRYP_MSPINIT_CB_ID :
0737         hcryp->MspInitCallback = pCallback;
0738         break;
0739 
0740       case HAL_CRYP_MSPDEINIT_CB_ID :
0741         hcryp->MspDeInitCallback = pCallback;
0742         break;
0743 
0744       default :
0745         /* Update the error code */
0746         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
0747         /* Return error status */
0748         status =  HAL_ERROR;
0749         break;
0750     }
0751   }
0752   else if (hcryp->State == HAL_CRYP_STATE_RESET)
0753   {
0754     switch (CallbackID)
0755     {
0756       case HAL_CRYP_MSPINIT_CB_ID :
0757         hcryp->MspInitCallback = pCallback;
0758         break;
0759 
0760       case HAL_CRYP_MSPDEINIT_CB_ID :
0761         hcryp->MspDeInitCallback = pCallback;
0762         break;
0763 
0764       default :
0765         /* Update the error code */
0766         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
0767         /* Return error status */
0768         status =  HAL_ERROR;
0769         break;
0770     }
0771   }
0772   else
0773   {
0774     /* Update the error code */
0775     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
0776     /* Return error status */
0777     status =  HAL_ERROR;
0778   }
0779 
0780   /* Release Lock */
0781   __HAL_UNLOCK(hcryp);
0782 
0783   return status;
0784 }
0785 
0786 /**
0787   * @brief  Unregister an CRYP Callback
0788   *         CRYP callback is redirected to the weak predefined callback
0789   * @param hcryp cryp handle
0790   * @param CallbackID ID of the callback to be unregistered
0791   *        This parameter can be one of the following values:
0792   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
0793   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
0794   *          @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
0795   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
0796   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
0797   * @retval status
0798   */
0799 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
0800 {
0801   HAL_StatusTypeDef status = HAL_OK;
0802 
0803   /* Process locked */
0804   __HAL_LOCK(hcryp);
0805 
0806   if (hcryp->State == HAL_CRYP_STATE_READY)
0807   {
0808     switch (CallbackID)
0809     {
0810       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
0811         hcryp->InCpltCallback = HAL_CRYP_InCpltCallback;  /* Legacy weak  InCpltCallback  */
0812         break;
0813 
0814       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
0815         hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback;         /* Legacy weak OutCpltCallback       */
0816         break;
0817 
0818       case HAL_CRYP_ERROR_CB_ID :
0819         hcryp->ErrorCallback = HAL_CRYP_ErrorCallback;           /* Legacy weak ErrorCallback        */
0820         break;
0821 
0822       case HAL_CRYP_MSPINIT_CB_ID :
0823         hcryp->MspInitCallback = HAL_CRYP_MspInit;
0824         break;
0825 
0826       case HAL_CRYP_MSPDEINIT_CB_ID :
0827         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
0828         break;
0829 
0830       default :
0831         /* Update the error code */
0832         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
0833         /* Return error status */
0834         status =  HAL_ERROR;
0835         break;
0836     }
0837   }
0838   else if (hcryp->State == HAL_CRYP_STATE_RESET)
0839   {
0840     switch (CallbackID)
0841     {
0842       case HAL_CRYP_MSPINIT_CB_ID :
0843         hcryp->MspInitCallback = HAL_CRYP_MspInit;
0844         break;
0845 
0846       case HAL_CRYP_MSPDEINIT_CB_ID :
0847         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
0848         break;
0849 
0850       default :
0851         /* Update the error code */
0852         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
0853         /* Return error status */
0854         status =  HAL_ERROR;
0855         break;
0856     }
0857   }
0858   else
0859   {
0860     /* Update the error code */
0861     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
0862     /* Return error status */
0863     status =  HAL_ERROR;
0864   }
0865 
0866   /* Release Lock */
0867   __HAL_UNLOCK(hcryp);
0868 
0869   return status;
0870 }
0871 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
0872 
0873 /**
0874   * @}
0875   */
0876 
0877 /** @defgroup CRYP_Exported_Functions_Group2  Encrypt Decrypt functions
0878   * @ingroup RTEMSBSPsARMSTM32H7
0879   *  @brief   CRYP processing functions.
0880   *
0881 @verbatim
0882   ==============================================================================
0883                       ##### Encrypt Decrypt  functions #####
0884   ==============================================================================
0885     [..]  This section provides API allowing to Encrypt/Decrypt Data following
0886           Standard DES/TDES or AES, and Algorithm configured by the user:
0887       (+) Standard DES/TDES only supported by CRYP1 IP, below list of Algorithm supported :
0888            (++)  Electronic Code Book(ECB)
0889            (++) Cipher Block Chaining (CBC)
0890       (+) Standard AES  supported by CRYP1 IP , list of Algorithm supported:
0891            (++) Electronic Code Book(ECB)
0892            (++) Cipher Block Chaining (CBC)
0893            (++) Counter mode (CTR)
0894            (++) Cipher Block Chaining (CBC)
0895            (++) Counter mode (CTR)
0896            (++) Galois/counter mode (GCM)
0897            (++) Counter with Cipher Block Chaining-Message(CCM)
0898     [..]  Three processing functions are available:
0899       (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
0900       (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
0901       (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
0902 
0903 @endverbatim
0904   * @{
0905   */
0906 
0907 
0908 /**
0909   * @brief  Encryption mode.
0910   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
0911   *         the configuration information for CRYP module
0912   * @param  Input: Pointer to the input buffer (plaintext)
0913   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit.
0914   * @param  Output: Pointer to the output buffer(ciphertext)
0915   * @param  Timeout: Specify Timeout value
0916   * @retval HAL status
0917   */
0918 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
0919                                    uint32_t Timeout)
0920 {
0921   uint32_t algo;
0922   HAL_StatusTypeDef status;
0923 
0924   if (hcryp->State == HAL_CRYP_STATE_READY)
0925   {
0926     /* Change state Busy */
0927     hcryp->State = HAL_CRYP_STATE_BUSY;
0928 
0929     /* Process locked */
0930     __HAL_LOCK(hcryp);
0931 
0932     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
0933     hcryp->CrypInCount = 0U;
0934     hcryp->CrypOutCount = 0U;
0935     hcryp->pCrypInBuffPtr = Input;
0936     hcryp->pCrypOutBuffPtr = Output;
0937 
0938     /*  Calculate Size parameter in Byte*/
0939     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
0940     {
0941       hcryp->Size = Size * 4U;
0942     }
0943     else
0944     {
0945       hcryp->Size = Size;
0946     }
0947 
0948     /* Set Encryption operating mode*/
0949     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
0950 
0951     /* algo get algorithm selected */
0952     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
0953 
0954     switch (algo)
0955     {
0956       case CRYP_DES_ECB:
0957       case CRYP_DES_CBC:
0958       case CRYP_TDES_ECB:
0959       case CRYP_TDES_CBC:
0960 
0961         /*Set Key */
0962         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
0963         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
0964         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
0965         {
0966           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
0967           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
0968           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
0969           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
0970         }
0971 
0972         /*Set Initialization Vector (IV)*/
0973         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
0974         {
0975           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
0976           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
0977         }
0978 
0979         /* Flush FIFO */
0980         HAL_CRYP_FIFO_FLUSH(hcryp);
0981 
0982         /* Set the phase */
0983         hcryp->Phase = CRYP_PHASE_PROCESS;
0984 
0985         /* Start DES/TDES encryption process */
0986         status = CRYP_TDES_Process(hcryp, Timeout);
0987         break;
0988 
0989       case CRYP_AES_ECB:
0990       case CRYP_AES_CBC:
0991       case CRYP_AES_CTR:
0992 
0993         /* AES encryption */
0994         status = CRYP_AES_Encrypt(hcryp, Timeout);
0995         break;
0996 
0997       case CRYP_AES_GCM:
0998 
0999         /* AES GCM encryption */
1000         status = CRYP_AESGCM_Process(hcryp, Timeout);
1001         break;
1002 
1003       case CRYP_AES_CCM:
1004 
1005         /* AES CCM encryption */
1006         status = CRYP_AESCCM_Process(hcryp, Timeout);
1007         break;
1008 
1009       default:
1010         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1011         status = HAL_ERROR;
1012         break;
1013     }
1014 
1015     if (status == HAL_OK)
1016     {
1017       /* Change the CRYP peripheral state */
1018       hcryp->State = HAL_CRYP_STATE_READY;
1019 
1020       /* Process unlocked */
1021       __HAL_UNLOCK(hcryp);
1022     }
1023   }
1024   else
1025   {
1026     /* Process unlocked */
1027     __HAL_UNLOCK(hcryp);
1028 
1029     /* Busy error code field */
1030     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1031     status = HAL_ERROR;
1032   }
1033 
1034   /* Return function status */
1035   return status ;
1036 }
1037 
1038 /**
1039   * @brief  Decryption mode.
1040   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1041   *         the configuration information for CRYP module
1042   * @param  Input: Pointer to the input buffer (ciphertext )
1043   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1044   * @param  Output: Pointer to the output buffer(plaintext)
1045   * @param  Timeout: Specify Timeout value
1046   * @retval HAL status
1047   */
1048 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
1049                                    uint32_t Timeout)
1050 {
1051   HAL_StatusTypeDef status;
1052   uint32_t algo;
1053 
1054   if (hcryp->State == HAL_CRYP_STATE_READY)
1055   {
1056     /* Change state Busy */
1057     hcryp->State = HAL_CRYP_STATE_BUSY;
1058 
1059     /* Process locked */
1060     __HAL_LOCK(hcryp);
1061 
1062     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1063     hcryp->CrypInCount = 0U;
1064     hcryp->CrypOutCount = 0U;
1065     hcryp->pCrypInBuffPtr = Input;
1066     hcryp->pCrypOutBuffPtr = Output;
1067 
1068     /*  Calculate Size parameter in Byte*/
1069     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1070     {
1071       hcryp->Size = Size * 4U;
1072     }
1073     else
1074     {
1075       hcryp->Size = Size;
1076     }
1077 
1078     /* Set Decryption operating mode*/
1079     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1080 
1081     /* algo get algorithm selected */
1082     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1083 
1084     switch (algo)
1085     {
1086       case CRYP_DES_ECB:
1087       case CRYP_DES_CBC:
1088       case CRYP_TDES_ECB:
1089       case CRYP_TDES_CBC:
1090 
1091         /*Set Key */
1092         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1093         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1094         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1095         {
1096           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1097           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1098           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1099           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1100         }
1101 
1102         /*Set Initialization Vector (IV)*/
1103         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1104         {
1105           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1106           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1107         }
1108 
1109         /* Flush FIFO */
1110         HAL_CRYP_FIFO_FLUSH(hcryp);
1111 
1112         /* Set the phase */
1113         hcryp->Phase = CRYP_PHASE_PROCESS;
1114 
1115         /* Start DES/TDES decryption process */
1116         status = CRYP_TDES_Process(hcryp, Timeout);
1117 
1118         break;
1119 
1120       case CRYP_AES_ECB:
1121       case CRYP_AES_CBC:
1122       case CRYP_AES_CTR:
1123 
1124         /* AES decryption */
1125         status = CRYP_AES_Decrypt(hcryp, Timeout);
1126         break;
1127 
1128       case CRYP_AES_GCM:
1129 
1130         /* AES GCM decryption */
1131         status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1132         break;
1133 
1134       case CRYP_AES_CCM:
1135 
1136         /* AES CCM decryption */
1137         status = CRYP_AESCCM_Process(hcryp, Timeout);
1138         break;
1139 
1140       default:
1141         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1142         status = HAL_ERROR;
1143         break;
1144     }
1145 
1146     if (status == HAL_OK)
1147     {
1148       /* Change the CRYP peripheral state */
1149       hcryp->State = HAL_CRYP_STATE_READY;
1150 
1151       /* Process unlocked */
1152       __HAL_UNLOCK(hcryp);
1153     }
1154   }
1155   else
1156   {
1157     /* Process unlocked */
1158     __HAL_UNLOCK(hcryp);
1159 
1160     /* Busy error code field */
1161     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1162     status = HAL_ERROR;
1163   }
1164 
1165   /* Return function status */
1166   return status;
1167 }
1168 
1169 /**
1170   * @brief  Encryption in interrupt mode.
1171   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1172   *         the configuration information for CRYP module
1173   * @param  Input: Pointer to the input buffer (plaintext)
1174   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1175   * @param  Output: Pointer to the output buffer(ciphertext)
1176   * @retval HAL status
1177   */
1178 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1179 {
1180   uint32_t algo;
1181   HAL_StatusTypeDef status;
1182 
1183   if (hcryp->State == HAL_CRYP_STATE_READY)
1184   {
1185     /* Change state Busy */
1186     hcryp->State = HAL_CRYP_STATE_BUSY;
1187 
1188     /* Process locked */
1189     __HAL_LOCK(hcryp);
1190 
1191     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1192     hcryp->CrypInCount = 0U;
1193     hcryp->CrypOutCount = 0U;
1194     hcryp->pCrypInBuffPtr = Input;
1195     hcryp->pCrypOutBuffPtr = Output;
1196 
1197     /*  Calculate Size parameter in Byte*/
1198     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1199     {
1200       hcryp->Size = Size * 4U;
1201     }
1202     else
1203     {
1204       hcryp->Size = Size;
1205     }
1206 
1207     /* Set encryption operating mode*/
1208     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1209 
1210     /* algo get algorithm selected */
1211     algo = (hcryp->Instance->CR & CRYP_CR_ALGOMODE);
1212 
1213     switch (algo)
1214     {
1215       case CRYP_DES_ECB:
1216       case CRYP_DES_CBC:
1217       case CRYP_TDES_ECB:
1218       case CRYP_TDES_CBC:
1219 
1220         /*Set Key */
1221         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1222         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1223         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1224         {
1225           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1226           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1227           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1228           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1229         }
1230         /* Set the Initialization Vector*/
1231         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1232         {
1233           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1234           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1235         }
1236 
1237         /* Flush FIFO */
1238         HAL_CRYP_FIFO_FLUSH(hcryp);
1239 
1240         /* Set the phase */
1241         hcryp->Phase = CRYP_PHASE_PROCESS;
1242 
1243         /* Enable interrupts */
1244         __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1245 
1246         /* Enable CRYP to start DES/TDES process*/
1247         __HAL_CRYP_ENABLE(hcryp);
1248 
1249         status = HAL_OK;
1250         break;
1251 
1252       case CRYP_AES_ECB:
1253       case CRYP_AES_CBC:
1254       case CRYP_AES_CTR:
1255 
1256         status = CRYP_AES_Encrypt_IT(hcryp);
1257         break;
1258 
1259       case CRYP_AES_GCM:
1260 
1261         status = CRYP_AESGCM_Process_IT(hcryp) ;
1262         break;
1263 
1264       case CRYP_AES_CCM:
1265 
1266         status = CRYP_AESCCM_Process_IT(hcryp);
1267         break;
1268 
1269       default:
1270         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1271         status =  HAL_ERROR;
1272         break;
1273     }
1274   }
1275   else
1276   {
1277     /* Busy error code field */
1278     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1279     status =  HAL_ERROR;
1280   }
1281 
1282   /* Return function status */
1283   return status ;
1284 }
1285 
1286 /**
1287   * @brief  Decryption in itnterrupt mode.
1288   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1289   *         the configuration information for CRYP module
1290   * @param  Input: Pointer to the input buffer (ciphertext )
1291   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1292   * @param  Output: Pointer to the output buffer(plaintext)
1293   * @retval HAL status
1294   */
1295 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1296 {
1297   uint32_t algo;
1298   HAL_StatusTypeDef status = HAL_OK;
1299 
1300   if (hcryp->State == HAL_CRYP_STATE_READY)
1301   {
1302     /* Change state Busy */
1303     hcryp->State = HAL_CRYP_STATE_BUSY;
1304 
1305     /* Process locked */
1306     __HAL_LOCK(hcryp);
1307 
1308     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1309     hcryp->CrypInCount = 0U;
1310     hcryp->CrypOutCount = 0U;
1311     hcryp->pCrypInBuffPtr = Input;
1312     hcryp->pCrypOutBuffPtr = Output;
1313 
1314     /*  Calculate Size parameter in Byte*/
1315     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1316     {
1317       hcryp->Size = Size * 4U;
1318     }
1319     else
1320     {
1321       hcryp->Size = Size;
1322     }
1323 
1324     /* Set decryption operating mode*/
1325     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1326 
1327     /* algo get algorithm selected */
1328     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1329 
1330     switch (algo)
1331     {
1332       case CRYP_DES_ECB:
1333       case CRYP_DES_CBC:
1334       case CRYP_TDES_ECB:
1335       case CRYP_TDES_CBC:
1336 
1337         /*Set Key */
1338         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1339         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1340         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1341         {
1342           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1343           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1344           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1345           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1346         }
1347 
1348         /* Set the Initialization Vector*/
1349         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1350         {
1351           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1352           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1353         }
1354         /* Flush FIFO */
1355         HAL_CRYP_FIFO_FLUSH(hcryp);
1356 
1357         /* Set the phase */
1358         hcryp->Phase = CRYP_PHASE_PROCESS;
1359 
1360         /* Enable interrupts */
1361         __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1362 
1363         /* Enable CRYP and start DES/TDES process*/
1364         __HAL_CRYP_ENABLE(hcryp);
1365 
1366         break;
1367 
1368       case CRYP_AES_ECB:
1369       case CRYP_AES_CBC:
1370       case CRYP_AES_CTR:
1371 
1372         /* AES decryption */
1373         status = CRYP_AES_Decrypt_IT(hcryp);
1374         break;
1375 
1376       case CRYP_AES_GCM:
1377 
1378         /* AES GCM decryption */
1379         status = CRYP_AESGCM_Process_IT(hcryp) ;
1380         break;
1381 
1382       case CRYP_AES_CCM:
1383 
1384         /* AES CCMdecryption */
1385         status = CRYP_AESCCM_Process_IT(hcryp);
1386         break;
1387 
1388       default:
1389         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1390         status = HAL_ERROR;
1391         break;
1392     }
1393   }
1394   else
1395   {
1396     /* Busy error code field */
1397     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1398     status = HAL_ERROR;
1399   }
1400 
1401   /* Return function status */
1402   return status;
1403 }
1404 
1405 /**
1406   * @brief  Encryption in DMA mode.
1407   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1408   *         the configuration information for CRYP module
1409   * @param  Input: Pointer to the input buffer (plaintext)
1410   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1411   * @param  Output: Pointer to the output buffer(ciphertext)
1412   * @retval HAL status
1413   */
1414 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1415 {
1416   HAL_StatusTypeDef status = HAL_OK;
1417   uint32_t algo;
1418   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1419 
1420   if (hcryp->State == HAL_CRYP_STATE_READY)
1421   {
1422     /* Change state Busy */
1423     hcryp->State = HAL_CRYP_STATE_BUSY;
1424 
1425     /* Process locked */
1426     __HAL_LOCK(hcryp);
1427 
1428     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1429     hcryp->CrypInCount = 0U;
1430     hcryp->CrypOutCount = 0U;
1431     hcryp->pCrypInBuffPtr = Input;
1432     hcryp->pCrypOutBuffPtr = Output;
1433 
1434     /*  Calculate Size parameter in Byte*/
1435     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1436     {
1437       hcryp->Size = Size * 4U;
1438     }
1439     else
1440     {
1441       hcryp->Size = Size;
1442     }
1443 
1444     /* Set encryption operating mode*/
1445     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1446 
1447     /* algo get algorithm selected */
1448     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1449 
1450     switch (algo)
1451     {
1452       case CRYP_DES_ECB:
1453       case CRYP_DES_CBC:
1454       case CRYP_TDES_ECB:
1455       case CRYP_TDES_CBC:
1456 
1457         /*Set Key */
1458         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1459         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1460         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1461         {
1462           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1463           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1464           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1465           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1466         }
1467 
1468         /* Set the Initialization Vector*/
1469         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1470         {
1471           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1472           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1473         }
1474 
1475         /* Flush FIFO */
1476         HAL_CRYP_FIFO_FLUSH(hcryp);
1477 
1478         /* Set the phase */
1479         hcryp->Phase = CRYP_PHASE_PROCESS;
1480 
1481         /* Start DMA process transfer for DES/TDES */
1482         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1483                           (uint32_t)(hcryp->pCrypOutBuffPtr));
1484 
1485         break;
1486 
1487       case CRYP_AES_ECB:
1488       case CRYP_AES_CBC:
1489       case CRYP_AES_CTR:
1490 
1491         if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1492         {
1493           if (hcryp->KeyIVConfig == 1U)
1494           {
1495             /* If the Key and IV configuration has to be done only once
1496                and if it has already been done, skip it */
1497             DoKeyIVConfig = 0U;
1498           }
1499           else
1500           {
1501             /* If the Key and IV configuration has to be done only once
1502                and if it has not been done already, do it and set KeyIVConfig
1503                to keep track it won't have to be done again next time */
1504             hcryp->KeyIVConfig = 1U;
1505           }
1506         }
1507 
1508         if (DoKeyIVConfig == 1U)
1509         {
1510           /*  Set the Key*/
1511           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1512 
1513           /* Set the Initialization Vector*/
1514           if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1515           {
1516             hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1517             hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
1518             hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
1519             hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
1520           }
1521         } /* if (DoKeyIVConfig == 1U) */
1522 
1523         /* Set the phase */
1524         hcryp->Phase = CRYP_PHASE_PROCESS;
1525 
1526         /* Start DMA process transfer for AES */
1527         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1528                           (uint32_t)(hcryp->pCrypOutBuffPtr));
1529         break;
1530 
1531       case CRYP_AES_GCM:
1532 
1533         /* AES GCM encryption */
1534         status = CRYP_AESGCM_Process_DMA(hcryp) ;
1535         break;
1536 
1537       case CRYP_AES_CCM:
1538 
1539         /* AES CCM encryption */
1540         status = CRYP_AESCCM_Process_DMA(hcryp);
1541         break;
1542 
1543       default:
1544         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1545         status =  HAL_ERROR;
1546         break;
1547     }
1548   }
1549   else
1550   {
1551     /* Busy error code field */
1552     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1553     status =  HAL_ERROR;
1554   }
1555 
1556   /* Return function status */
1557   return status;
1558 }
1559 
1560 /**
1561   * @brief  Decryption in DMA mode.
1562   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1563   *         the configuration information for CRYP module
1564   * @param  Input: Pointer to the input buffer (ciphertext )
1565   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1566   * @param  Output: Pointer to the output buffer(plaintext)
1567   * @retval HAL status
1568   */
1569 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1570 {
1571   uint32_t algo;
1572   HAL_StatusTypeDef status = HAL_OK;
1573 
1574   if (hcryp->State == HAL_CRYP_STATE_READY)
1575   {
1576     /* Change state Busy */
1577     hcryp->State = HAL_CRYP_STATE_BUSY;
1578 
1579     /* Process locked */
1580     __HAL_LOCK(hcryp);
1581 
1582     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1583     hcryp->CrypInCount = 0U;
1584     hcryp->CrypOutCount = 0U;
1585     hcryp->pCrypInBuffPtr = Input;
1586     hcryp->pCrypOutBuffPtr = Output;
1587 
1588     /*  Calculate Size parameter in Byte*/
1589     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1590     {
1591       hcryp->Size = Size * 4U;
1592     }
1593     else
1594     {
1595       hcryp->Size = Size;
1596     }
1597 
1598     /* Set decryption operating mode*/
1599     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1600 
1601     /* algo get algorithm selected */
1602     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1603 
1604     switch (algo)
1605     {
1606       case CRYP_DES_ECB:
1607       case CRYP_DES_CBC:
1608       case CRYP_TDES_ECB:
1609       case CRYP_TDES_CBC:
1610 
1611         /*Set Key */
1612         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1613         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1614         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1615         {
1616           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1617           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1618           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1619           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1620         }
1621 
1622         /* Set the Initialization Vector*/
1623         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1624         {
1625           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1626           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1627         }
1628 
1629         /* Flush FIFO */
1630         HAL_CRYP_FIFO_FLUSH(hcryp);
1631 
1632         /* Set the phase */
1633         hcryp->Phase = CRYP_PHASE_PROCESS;
1634 
1635         /* Start DMA process transfer for DES/TDES */
1636         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1637                           (uint32_t)(hcryp->pCrypOutBuffPtr));
1638         break;
1639 
1640       case CRYP_AES_ECB:
1641       case CRYP_AES_CBC:
1642       case CRYP_AES_CTR:
1643 
1644         /* AES decryption */
1645         status = CRYP_AES_Decrypt_DMA(hcryp);
1646         break;
1647 
1648       case CRYP_AES_GCM:
1649 
1650         /* AES GCM decryption */
1651         status = CRYP_AESGCM_Process_DMA(hcryp) ;
1652 
1653         break;
1654 
1655       case CRYP_AES_CCM:
1656 
1657         /* AES CCM decryption */
1658         status = CRYP_AESCCM_Process_DMA(hcryp);
1659         break;
1660 
1661       default:
1662         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1663         status =  HAL_ERROR;
1664         break;
1665     }
1666   }
1667   else
1668   {
1669     /* Busy error code field */
1670     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1671     status = HAL_ERROR;
1672   }
1673 
1674   /* Return function status */
1675   return status;
1676 }
1677 
1678 /**
1679   * @}
1680   */
1681 
1682 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1683   * @ingroup RTEMSBSPsARMSTM32H7
1684   *  @brief    CRYP IRQ handler.
1685   *
1686 @verbatim
1687   ==============================================================================
1688                 ##### CRYP IRQ handler management #####
1689   ==============================================================================
1690 [..]  This section provides CRYP IRQ handler and callback functions.
1691       (+) HAL_CRYP_IRQHandler CRYP interrupt request
1692       (+) HAL_CRYP_InCpltCallback input data transfer complete callback
1693       (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
1694       (+) HAL_CRYP_ErrorCallback  CRYP error callback
1695       (+) HAL_CRYP_GetState return the CRYP state
1696       (+) HAL_CRYP_GetError return the CRYP error code
1697 @endverbatim
1698   * @{
1699   */
1700 
1701 /**
1702   * @brief  This function handles cryptographic interrupt request.
1703   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1704   *         the configuration information for CRYP module
1705   * @retval None
1706   */
1707 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
1708 {
1709   uint32_t itstatus = hcryp->Instance->MISR;
1710 
1711   if ((itstatus & (CRYP_IT_INI | CRYP_IT_OUTI)) != 0U)
1712   {
1713     if ((hcryp->Init.Algorithm == CRYP_DES_ECB) || (hcryp->Init.Algorithm == CRYP_DES_CBC) ||
1714         (hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1715     {
1716       CRYP_TDES_IT(hcryp); /* DES or TDES*/
1717     }
1718     else if ((hcryp->Init.Algorithm == CRYP_AES_ECB) || (hcryp->Init.Algorithm == CRYP_AES_CBC) ||
1719              (hcryp->Init.Algorithm == CRYP_AES_CTR))
1720     {
1721       CRYP_AES_IT(hcryp); /*AES*/
1722     }
1723 
1724     else if ((hcryp->Init.Algorithm == CRYP_AES_GCM) || (hcryp->Init.Algorithm == CRYP_CR_ALGOMODE_AES_CCM))
1725     {
1726       /* if header phase */
1727       if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
1728       {
1729         CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
1730       }
1731       else  /* if payload phase */
1732       {
1733         CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
1734       }
1735     }
1736     else
1737     {
1738       /* Nothing to do */
1739     }
1740   }
1741 }
1742 
1743 /**
1744   * @brief  Return the CRYP error code.
1745   * @param  hcryp : pointer to a CRYP_HandleTypeDef structure that contains
1746   *                 the configuration information for the  CRYP IP
1747   * @retval CRYP error code
1748   */
1749 uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp)
1750 {
1751   return hcryp->ErrorCode;
1752 }
1753 
1754 /**
1755   * @brief  Returns the CRYP state.
1756   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1757   *         the configuration information for CRYP module.
1758   * @retval HAL state
1759   */
1760 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp)
1761 {
1762   return hcryp->State;
1763 }
1764 
1765 /**
1766   * @brief  Input FIFO transfer completed callback.
1767   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1768   *         the configuration information for CRYP module.
1769   * @retval None
1770   */
1771 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
1772 {
1773   /* Prevent unused argument(s) compilation warning */
1774   UNUSED(hcryp);
1775 
1776   /* NOTE : This function Should not be modified, when the callback is needed,
1777             the HAL_CRYP_InCpltCallback could be implemented in the user file
1778    */
1779 }
1780 
1781 /**
1782   * @brief  Output FIFO transfer completed callback.
1783   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1784   *         the configuration information for CRYP module.
1785   * @retval None
1786   */
1787 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
1788 {
1789   /* Prevent unused argument(s) compilation warning */
1790   UNUSED(hcryp);
1791 
1792   /* NOTE : This function Should not be modified, when the callback is needed,
1793             the HAL_CRYP_OutCpltCallback could be implemented in the user file
1794    */
1795 }
1796 
1797 /**
1798   * @brief  CRYP error callback.
1799   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1800   *         the configuration information for CRYP module.
1801   * @retval None
1802   */
1803 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
1804 {
1805   /* Prevent unused argument(s) compilation warning */
1806   UNUSED(hcryp);
1807 
1808   /* NOTE : This function Should not be modified, when the callback is needed,
1809             the HAL_CRYP_ErrorCallback could be implemented in the user file
1810    */
1811 }
1812 /**
1813   * @}
1814   */
1815 /**
1816   * @}
1817   */
1818 
1819 /* Private functions ---------------------------------------------------------*/
1820 /** @addtogroup CRYP_Private_Functions
1821   * @{
1822   */
1823 
1824 /**
1825   * @brief  Encryption in ECB/CBC Algorithm with DES/TDES standard.
1826   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1827   *         the configuration information for CRYP module
1828   * @param  Timeout: Timeout value
1829   * @retval HAL status
1830   */
1831 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
1832 {
1833 
1834   uint32_t temp;  /* Temporary CrypOutBuff */
1835   uint16_t incount; /* Temporary CrypInCount Value */
1836   uint16_t outcount;  /* Temporary CrypOutCount Value */
1837 
1838   /* Enable CRYP */
1839   __HAL_CRYP_ENABLE(hcryp);
1840   /*Temporary CrypOutCount Value*/
1841   outcount = hcryp->CrypOutCount;
1842 
1843   /*Start processing*/
1844   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
1845   {
1846     /* Temporary CrypInCount Value */
1847     incount = hcryp->CrypInCount;
1848     /* Write plain data and get cipher data */
1849     if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
1850     {
1851       /* Write the input block in the IN FIFO */
1852       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1853       hcryp->CrypInCount++;
1854       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1855       hcryp->CrypInCount++;
1856     }
1857 
1858     /* Wait for OFNE flag to be raised */
1859     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
1860     {
1861       /* Disable the CRYP peripheral clock */
1862       __HAL_CRYP_DISABLE(hcryp);
1863 
1864       /* Change state & errorCode*/
1865       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
1866       hcryp->State = HAL_CRYP_STATE_READY;
1867 
1868       /* Process unlocked */
1869       __HAL_UNLOCK(hcryp);
1870 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1871       /*Call registered error callback*/
1872       hcryp->ErrorCallback(hcryp);
1873 #else
1874       /*Call legacy weak error callback*/
1875       HAL_CRYP_ErrorCallback(hcryp);
1876 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1877     }
1878 
1879     /*Temporary CrypOutCount Value*/
1880     outcount = hcryp->CrypOutCount;
1881 
1882     if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
1883     {
1884       /* Read the output block from the Output FIFO and put them in temporary Buffer
1885        then get CrypOutBuff from temporary buffer  */
1886       temp = hcryp->Instance->DOUT;
1887       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1888       hcryp->CrypOutCount++;
1889       temp = hcryp->Instance->DOUT;
1890       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1891       hcryp->CrypOutCount++;
1892     }
1893     /*Temporary CrypOutCount Value*/
1894     outcount = hcryp->CrypOutCount;
1895   }
1896   /* Disable CRYP */
1897   __HAL_CRYP_DISABLE(hcryp);
1898   /* Change the CRYP state */
1899   hcryp->State = HAL_CRYP_STATE_READY;
1900 
1901   /* Return function status */
1902   return HAL_OK;
1903 }
1904 
1905 /**
1906   * @brief  CRYP block input/output data handling under interruption with DES/TDES standard.
1907   * @note   The function is called under interruption only, once
1908   *         interruptions have been enabled by CRYP_Decrypt_IT() and CRYP_Encrypt_IT().
1909   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1910   *         the configuration information for CRYP module.
1911   * @retval HAL status
1912   */
1913 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp)
1914 {
1915   uint32_t temp;  /* Temporary CrypOutBuff */
1916 
1917   if (hcryp->State == HAL_CRYP_STATE_BUSY)
1918   {
1919     if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI) != 0x0U)
1920     {
1921       if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_INRIS) != 0x0U)
1922       {
1923         /* Write input block in the IN FIFO */
1924         hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1925         hcryp->CrypInCount++;
1926         hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1927         hcryp->CrypInCount++;
1928 
1929         if (hcryp->CrypInCount == (hcryp->Size / 4U))
1930         {
1931           /* Disable interruption */
1932           __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1933 
1934           /* Call the input data transfer complete callback */
1935 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1936           /*Call registered Input complete callback*/
1937           hcryp->InCpltCallback(hcryp);
1938 #else
1939           /*Call legacy weak Input complete callback*/
1940           HAL_CRYP_InCpltCallback(hcryp);
1941 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1942         }
1943       }
1944     }
1945 
1946     if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI) != 0x0U)
1947     {
1948       if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_OUTRIS) != 0x0U)
1949       {
1950         /* Read the output block from the Output FIFO and put them in temporary Buffer
1951          then get CrypOutBuff from temporary buffer  */
1952         temp = hcryp->Instance->DOUT;
1953         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1954         hcryp->CrypOutCount++;
1955         temp = hcryp->Instance->DOUT;
1956         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1957         hcryp->CrypOutCount++;
1958         if (hcryp->CrypOutCount == (hcryp->Size / 4U))
1959         {
1960           /* Disable interruption */
1961           __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1962 
1963           /* Disable CRYP */
1964           __HAL_CRYP_DISABLE(hcryp);
1965 
1966           /* Process unlocked */
1967           __HAL_UNLOCK(hcryp);
1968 
1969           /* Change the CRYP state */
1970           hcryp->State = HAL_CRYP_STATE_READY;
1971 
1972           /* Call output transfer complete callback */
1973 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1974           /*Call registered Output complete callback*/
1975           hcryp->OutCpltCallback(hcryp);
1976 #else
1977           /*Call legacy weak Output complete callback*/
1978           HAL_CRYP_OutCpltCallback(hcryp);
1979 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1980 
1981         }
1982       }
1983     }
1984   }
1985   else
1986   {
1987     /* Process unlocked */
1988     __HAL_UNLOCK(hcryp);
1989     /* Busy error code field */
1990     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1991 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1992     /*Call registered error callback*/
1993     hcryp->ErrorCallback(hcryp);
1994 #else
1995     /*Call legacy weak error callback*/
1996     HAL_CRYP_ErrorCallback(hcryp);
1997 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1998   }
1999 }
2000 
2001 /**
2002   * @brief  Encryption in ECB/CBC & CTR Algorithm with AES Standard
2003   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
2004   * @param  Timeout: specify Timeout value
2005   * @retval HAL status
2006   */
2007 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2008 {
2009   uint16_t outcount;  /* Temporary CrypOutCount Value */
2010   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2011 
2012   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2013   {
2014     if (hcryp->KeyIVConfig == 1U)
2015     {
2016       /* If the Key and IV configuration has to be done only once
2017          and if it has already been done, skip it */
2018       DoKeyIVConfig = 0U;
2019     }
2020     else
2021     {
2022       /* If the Key and IV configuration has to be done only once
2023          and if it has not been done already, do it and set KeyIVConfig
2024          to keep track it won't have to be done again next time */
2025       hcryp->KeyIVConfig = 1U;
2026     }
2027   }
2028 
2029   if (DoKeyIVConfig == 1U)
2030   {
2031     /*  Set the Key*/
2032     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2033 
2034     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2035     {
2036       /* Set the Initialization Vector*/
2037       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2038       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2039       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2040       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2041     }
2042   } /* if (DoKeyIVConfig == 1U) */
2043 
2044   /* Set the phase */
2045   hcryp->Phase = CRYP_PHASE_PROCESS;
2046 
2047   /* Enable CRYP */
2048   __HAL_CRYP_ENABLE(hcryp);
2049   /*Temporary CrypOutCount Value*/
2050   outcount = hcryp->CrypOutCount;
2051 
2052   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2053   {
2054     /* Write plain Ddta and get cipher data */
2055     CRYP_AES_ProcessData(hcryp, Timeout);
2056     /*Temporary CrypOutCount Value*/
2057     outcount = hcryp->CrypOutCount;
2058   }
2059 
2060   /* Disable CRYP */
2061   __HAL_CRYP_DISABLE(hcryp);
2062 
2063   /* Change the CRYP state */
2064   hcryp->State = HAL_CRYP_STATE_READY;
2065 
2066   /* Return function status */
2067   return HAL_OK;
2068 }
2069 
2070 /**
2071   * @brief  Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2072   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2073   *         the configuration information for CRYP module
2074   * @retval HAL status
2075   */
2076 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
2077 {
2078   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2079 
2080   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2081   {
2082     if (hcryp->KeyIVConfig == 1U)
2083     {
2084       /* If the Key and IV configuration has to be done only once
2085          and if it has already been done, skip it */
2086       DoKeyIVConfig = 0U;
2087     }
2088     else
2089     {
2090       /* If the Key and IV configuration has to be done only once
2091          and if it has not been done already, do it and set KeyIVConfig
2092          to keep track it won't have to be done again next time */
2093       hcryp->KeyIVConfig = 1U;
2094     }
2095   }
2096 
2097   if (DoKeyIVConfig == 1U)
2098   {
2099     /*  Set the Key*/
2100     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2101 
2102     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2103     {
2104       /* Set the Initialization Vector*/
2105       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2106       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2107       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2108       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2109     }
2110   } /* if (DoKeyIVConfig == 1U) */
2111 
2112   /* Set the phase */
2113   hcryp->Phase = CRYP_PHASE_PROCESS;
2114 
2115   if (hcryp->Size != 0U)
2116   {
2117     /* Enable interrupts */
2118     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2119 
2120     /* Enable CRYP */
2121     __HAL_CRYP_ENABLE(hcryp);
2122   }
2123   else
2124   {
2125     /* Change the CRYP state */
2126     hcryp->State = HAL_CRYP_STATE_READY;
2127 
2128     /* Process unlocked */
2129     __HAL_UNLOCK(hcryp);
2130   }
2131 
2132   /* Return function status */
2133   return HAL_OK;
2134 }
2135 
2136 /**
2137   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard
2138   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
2139   * @param  Timeout: Specify Timeout value
2140   * @retval HAL status
2141   */
2142 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2143 {
2144   uint16_t outcount;  /* Temporary CrypOutCount Value */
2145   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2146 
2147   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2148   {
2149     if (hcryp->KeyIVConfig == 1U)
2150     {
2151       /* If the Key and IV configuration has to be done only once
2152          and if it has already been done, skip it */
2153       DoKeyIVConfig = 0U;
2154     }
2155     else
2156     {
2157       /* If the Key and IV configuration has to be done only once
2158          and if it has not been done already, do it and set KeyIVConfig
2159          to keep track it won't have to be done again next time */
2160       hcryp->KeyIVConfig = 1U;
2161     }
2162   }
2163 
2164   if (DoKeyIVConfig == 1U)
2165   {
2166     /*  Key preparation for ECB/CBC */
2167     if (hcryp->Init.Algorithm != CRYP_AES_CTR)   /*ECB or CBC*/
2168     {
2169       /* change ALGOMODE to key preparation for decryption*/
2170       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2171 
2172       /*  Set the Key*/
2173       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2174 
2175       /* Enable CRYP */
2176       __HAL_CRYP_ENABLE(hcryp);
2177 
2178       /* Wait for BUSY flag to be raised */
2179       if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
2180       {
2181         /* Disable the CRYP peripheral clock */
2182         __HAL_CRYP_DISABLE(hcryp);
2183 
2184         /* Change state */
2185         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2186         hcryp->State = HAL_CRYP_STATE_READY;
2187 
2188         /* Process unlocked */
2189         __HAL_UNLOCK(hcryp);
2190         return HAL_ERROR;
2191       }
2192       /* Turn back to ALGOMODE of the configuration */
2193       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2194     }
2195     else  /*Algorithm CTR */
2196     {
2197       /*  Set the Key*/
2198       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2199     }
2200 
2201     /* Set IV */
2202     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2203     {
2204       /* Set the Initialization Vector*/
2205       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2206       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2207       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2208       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2209     }
2210   } /* if (DoKeyIVConfig == 1U) */
2211 
2212   /* Set the phase */
2213   hcryp->Phase = CRYP_PHASE_PROCESS;
2214 
2215   /* Enable CRYP */
2216   __HAL_CRYP_ENABLE(hcryp);
2217 
2218   /*Temporary CrypOutCount Value*/
2219   outcount = hcryp->CrypOutCount;
2220 
2221   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2222   {
2223     /* Write plain data and get cipher data */
2224     CRYP_AES_ProcessData(hcryp, Timeout);
2225     /*Temporary CrypOutCount Value*/
2226     outcount = hcryp->CrypOutCount;
2227   }
2228 
2229   /* Disable CRYP */
2230   __HAL_CRYP_DISABLE(hcryp);
2231 
2232   /* Change the CRYP state */
2233   hcryp->State = HAL_CRYP_STATE_READY;
2234 
2235   /* Return function status */
2236   return HAL_OK;
2237 }
2238 /**
2239   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2240   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2241   *         the configuration information for CRYP module
2242   * @retval HAL status
2243   */
2244 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
2245 {
2246   __IO uint32_t count = 0U;
2247   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2248 
2249   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2250   {
2251     if (hcryp->KeyIVConfig == 1U)
2252     {
2253       /* If the Key and IV configuration has to be done only once
2254          and if it has already been done, skip it */
2255       DoKeyIVConfig = 0U;
2256     }
2257     else
2258     {
2259       /* If the Key and IV configuration has to be done only once
2260          and if it has not been done already, do it and set KeyIVConfig
2261          to keep track it won't have to be done again next time */
2262       hcryp->KeyIVConfig = 1U;
2263     }
2264   }
2265 
2266   if (DoKeyIVConfig == 1U)
2267   {
2268     /*  Key preparation for ECB/CBC */
2269     if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2270     {
2271       /* change ALGOMODE to key preparation for decryption*/
2272       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2273 
2274       /*  Set the Key*/
2275       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2276 
2277       /* Enable CRYP */
2278       __HAL_CRYP_ENABLE(hcryp);
2279 
2280       /* Wait for BUSY flag to be raised */
2281       count = CRYP_TIMEOUT_KEYPREPARATION;
2282       do
2283       {
2284         count-- ;
2285         if (count == 0U)
2286         {
2287           /* Change state */
2288           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2289           hcryp->State = HAL_CRYP_STATE_READY;
2290 
2291           /* Process unlocked */
2292           __HAL_UNLOCK(hcryp);
2293           return HAL_ERROR;
2294         }
2295       }
2296       while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2297 
2298       /* Turn back to ALGOMODE of the configuration */
2299       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2300     }
2301     else  /*Algorithm CTR */
2302     {
2303       /*  Set the Key*/
2304       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2305     }
2306 
2307     /* Set IV */
2308     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2309     {
2310       /* Set the Initialization Vector*/
2311       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2312       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2313       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2314       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2315     }
2316   } /* if (DoKeyIVConfig == 1U) */
2317 
2318   /* Set the phase */
2319   hcryp->Phase = CRYP_PHASE_PROCESS;
2320   if (hcryp->Size != 0U)
2321   {
2322     /* Enable interrupts */
2323     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2324 
2325     /* Enable CRYP */
2326     __HAL_CRYP_ENABLE(hcryp);
2327   }
2328   else
2329   {
2330     /* Process locked */
2331     __HAL_UNLOCK(hcryp);
2332 
2333     /* Change the CRYP state */
2334     hcryp->State = HAL_CRYP_STATE_READY;
2335   }
2336   /* Return function status */
2337   return HAL_OK;
2338 }
2339 /**
2340   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
2341   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2342   *         the configuration information for CRYP module
2343   * @retval HAL status
2344   */
2345 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
2346 {
2347   __IO uint32_t count = 0U;
2348   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2349 
2350   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2351   {
2352     if (hcryp->KeyIVConfig == 1U)
2353     {
2354       /* If the Key and IV configuration has to be done only once
2355          and if it has already been done, skip it */
2356       DoKeyIVConfig = 0U;
2357     }
2358     else
2359     {
2360       /* If the Key and IV configuration has to be done only once
2361          and if it has not been done already, do it and set KeyIVConfig
2362          to keep track it won't have to be done again next time */
2363       hcryp->KeyIVConfig = 1U;
2364     }
2365   }
2366 
2367   if (DoKeyIVConfig == 1U)
2368   {
2369     /*  Key preparation for ECB/CBC */
2370     if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2371     {
2372       /* change ALGOMODE to key preparation for decryption*/
2373       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2374 
2375       /*  Set the Key*/
2376       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2377 
2378       /* Enable CRYP */
2379       __HAL_CRYP_ENABLE(hcryp);
2380 
2381       /* Wait for BUSY flag to be raised */
2382       count = CRYP_TIMEOUT_KEYPREPARATION;
2383       do
2384       {
2385         count-- ;
2386         if (count == 0U)
2387         {
2388           /* Disable the CRYP peripheral clock */
2389           __HAL_CRYP_DISABLE(hcryp);
2390 
2391           /* Change state */
2392           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2393           hcryp->State = HAL_CRYP_STATE_READY;
2394 
2395           /* Process unlocked */
2396           __HAL_UNLOCK(hcryp);
2397           return HAL_ERROR;
2398         }
2399       }
2400       while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2401 
2402       /* Turn back to ALGOMODE of the configuration */
2403       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2404     }
2405     else  /*Algorithm CTR */
2406     {
2407       /*  Set the Key*/
2408       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2409     }
2410 
2411     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2412     {
2413       /* Set the Initialization Vector*/
2414       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2415       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2416       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2417       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2418     }
2419   } /* if (DoKeyIVConfig == 1U) */
2420 
2421   /* Set the phase */
2422   hcryp->Phase = CRYP_PHASE_PROCESS;
2423 
2424   if (hcryp->Size != 0U)
2425   {
2426     /* Set the input and output addresses and start DMA transfer */
2427     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
2428                       (uint32_t)(hcryp->pCrypOutBuffPtr));
2429   }
2430   else
2431   {
2432     /* Process unlocked */
2433     __HAL_UNLOCK(hcryp);
2434 
2435     /* Change the CRYP state */
2436     hcryp->State = HAL_CRYP_STATE_READY;
2437   }
2438 
2439   /* Return function status */
2440   return HAL_OK;
2441 }
2442 
2443 
2444 /**
2445   * @brief  DMA CRYP input data process complete callback.
2446   * @param  hdma: DMA handle
2447   * @retval None
2448   */
2449 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
2450 {
2451   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2452 
2453   /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit
2454   in the DMACR register */
2455   hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
2456 
2457   /* Call input data transfer complete callback */
2458 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2459   /*Call registered Input complete callback*/
2460   hcryp->InCpltCallback(hcryp);
2461 #else
2462   /*Call legacy weak Input complete callback*/
2463   HAL_CRYP_InCpltCallback(hcryp);
2464 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2465 }
2466 
2467 /**
2468   * @brief  DMA CRYP output data process complete callback.
2469   * @param  hdma: DMA handle
2470   * @retval None
2471   */
2472 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
2473 {
2474   uint32_t count;
2475   uint32_t npblb;
2476   uint32_t lastwordsize;
2477   uint32_t temp;  /* Temporary CrypOutBuff */
2478   uint32_t temp_cr_algodir;
2479   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2480 
2481 
2482   /* Disable the DMA transfer for output FIFO */
2483   hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
2484 
2485   /* Last block transfer in case of GCM or CCM with Size not %16*/
2486   if (((hcryp->Size) % 16U) != 0U)
2487   {
2488     /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA  */
2489     hcryp->CrypInCount = (hcryp->Size / 16U) * 4U ;
2490     hcryp->CrypOutCount = hcryp->CrypInCount;
2491 
2492     /* Compute the number of padding bytes in last block of payload */
2493     npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
2494 
2495 #if !defined (CRYP_VER_2_2)
2496     if (hcryp->Version >= REV_ID_B)
2497 #endif /*End of not defined CRYP_VER_2_2*/
2498     {
2499       /* Case of AES GCM payload encryption or AES CCM payload decryption to get right tag */
2500       temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
2501       if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
2502           ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
2503       {
2504         /* Disable the CRYP */
2505         __HAL_CRYP_DISABLE(hcryp);
2506 
2507         /* Specify the number of non-valid bytes using NPBLB register*/
2508         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
2509 
2510         /* Enable CRYP to start the final phase */
2511         __HAL_CRYP_ENABLE(hcryp);
2512       }
2513     }
2514 
2515     /* Number of valid words (lastwordsize) in last block */
2516     if ((npblb % 4U) == 0U)
2517     {
2518       lastwordsize = (16U - npblb) / 4U;
2519     }
2520     else
2521     {
2522       lastwordsize = ((16U - npblb) / 4U) + 1U;
2523     }
2524     /* Write the last input block in the IN FIFO */
2525     for (count = 0U; count < lastwordsize; count ++)
2526     {
2527       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2528       hcryp->CrypInCount++;
2529     }
2530     /* Pad the data with zeros to have a complete block */
2531     while (count < 4U)
2532     {
2533       hcryp->Instance->DIN  = 0U;
2534       count++;
2535     }
2536     /* Wait for OFNE flag to be raised */
2537     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
2538     do
2539     {
2540       count-- ;
2541       if (count == 0U)
2542       {
2543         /* Disable the CRYP peripheral clock */
2544         __HAL_CRYP_DISABLE(hcryp);
2545 
2546         /* Change state */
2547         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2548         hcryp->State = HAL_CRYP_STATE_READY;
2549 
2550         /* Process unlocked */
2551         __HAL_UNLOCK(hcryp);
2552 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2553         /*Call registered error callback*/
2554         hcryp->ErrorCallback(hcryp);
2555 #else
2556         /*Call legacy weak error callback*/
2557         HAL_CRYP_ErrorCallback(hcryp);
2558 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2559       }
2560     }
2561     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
2562 
2563     /*Read the output block from the output FIFO */
2564     for (count = 0U; count < 4U; count++)
2565     {
2566       /* Read the output block from the output FIFO and put them in temporary buffer
2567          then get CrypOutBuff from temporary buffer */
2568       temp = hcryp->Instance->DOUT;
2569 
2570       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2571       hcryp->CrypOutCount++;
2572     }
2573   } /*End of last block transfer in case of GCM or CCM */
2574 
2575   if ((hcryp->Init.Algorithm & CRYP_AES_GCM) != CRYP_AES_GCM)
2576   {
2577     /* Disable CRYP  (not allowed in  GCM)*/
2578     __HAL_CRYP_DISABLE(hcryp);
2579   }
2580 
2581   /* Change the CRYP state to ready */
2582   hcryp->State = HAL_CRYP_STATE_READY;
2583 
2584   /* Process unlocked */
2585   __HAL_UNLOCK(hcryp);
2586 
2587   /* Call output data transfer complete callback */
2588 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2589   /*Call registered Output complete callback*/
2590   hcryp->OutCpltCallback(hcryp);
2591 #else
2592   /*Call legacy weak Output complete callback*/
2593   HAL_CRYP_OutCpltCallback(hcryp);
2594 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2595 }
2596 
2597 /**
2598   * @brief  DMA CRYP communication error callback.
2599   * @param  hdma: DMA handle
2600   * @retval None
2601   */
2602 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
2603 {
2604   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2605 
2606   /* Change the CRYP peripheral state */
2607   hcryp->State = HAL_CRYP_STATE_READY;
2608 
2609   /* DMA error code field */
2610   hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2611 
2612   /* Call error callback */
2613 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2614   /*Call registered error callback*/
2615   hcryp->ErrorCallback(hcryp);
2616 #else
2617   /*Call legacy weak error callback*/
2618   HAL_CRYP_ErrorCallback(hcryp);
2619 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2620 }
2621 
2622 /**
2623   * @brief  Set the DMA configuration and start the DMA transfer
2624   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2625   *         the configuration information for CRYP module
2626   * @param  inputaddr: address of the input buffer
2627   * @param  Size: size of the input buffer, must be a multiple of 16.
2628   * @param  outputaddr: address of the output buffer
2629   * @retval None
2630   */
2631 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2632 {
2633   /* Set the CRYP DMA transfer complete callback */
2634   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2635 
2636   /* Set the DMA input error callback */
2637   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2638 
2639   /* Set the CRYP DMA transfer complete callback */
2640   hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2641 
2642   /* Set the DMA output error callback */
2643   hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2644 
2645   /* Enable CRYP */
2646   __HAL_CRYP_ENABLE(hcryp);
2647 
2648   /* Enable the input DMA Stream */
2649   if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DIN, Size) != HAL_OK)
2650   {
2651     /* DMA error code field */
2652     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2653 
2654     /* Call error callback */
2655 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2656     /*Call registered error callback*/
2657     hcryp->ErrorCallback(hcryp);
2658 #else
2659     /*Call legacy weak error callback*/
2660     HAL_CRYP_ErrorCallback(hcryp);
2661 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2662   }
2663 
2664   /* Enable the output DMA Stream */
2665   if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size) != HAL_OK)
2666   {
2667     /* DMA error code field */
2668     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2669 
2670     /* Call error callback */
2671 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2672     /*Call registered error callback*/
2673     hcryp->ErrorCallback(hcryp);
2674 #else
2675     /*Call legacy weak error callback*/
2676     HAL_CRYP_ErrorCallback(hcryp);
2677 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2678   }
2679   /* Enable In/Out DMA request */
2680   hcryp->Instance->DMACR = CRYP_DMACR_DOEN | CRYP_DMACR_DIEN;
2681 }
2682 
2683 /**
2684   * @brief  Process Data: Write Input data in polling mode and used in AES functions.
2685   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2686   *         the configuration information for CRYP module
2687   * @param  Timeout: Specify Timeout value
2688   * @retval None
2689   */
2690 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2691 {
2692 
2693   uint32_t temp[4];  /* Temporary CrypOutBuff */
2694   uint16_t incount;  /* Temporary CrypInCount Value */
2695   uint16_t outcount;  /* Temporary CrypOutCount Value */
2696   uint32_t i;
2697 
2698   /*Temporary CrypOutCount Value*/
2699   incount = hcryp->CrypInCount;
2700 
2701   if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < ((hcryp->Size) / 4U)))
2702   {
2703     /* Write the input block in the IN FIFO */
2704     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2705     hcryp->CrypInCount++;
2706     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2707     hcryp->CrypInCount++;
2708     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2709     hcryp->CrypInCount++;
2710     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2711     hcryp->CrypInCount++;
2712   }
2713 
2714   /* Wait for OFNE flag to be raised */
2715   if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
2716   {
2717     /* Disable the CRYP peripheral clock */
2718     __HAL_CRYP_DISABLE(hcryp);
2719 
2720     /* Change state & error code*/
2721     hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2722     hcryp->State = HAL_CRYP_STATE_READY;
2723 
2724     /* Process unlocked */
2725     __HAL_UNLOCK(hcryp);
2726 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2727     /*Call registered error callback*/
2728     hcryp->ErrorCallback(hcryp);
2729 #else
2730     /*Call legacy weak error callback*/
2731     HAL_CRYP_ErrorCallback(hcryp);
2732 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2733   }
2734   /*Temporary CrypOutCount Value*/
2735   outcount = hcryp->CrypOutCount;
2736 
2737   if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < ((hcryp->Size) / 4U)))
2738   {
2739     /* Read the output block from the Output FIFO and put them in temporary buffer
2740        then get CrypOutBuff from temporary buffer  */
2741     for (i = 0U; i < 4U; i++)
2742     {
2743       temp[i] = hcryp->Instance->DOUT;
2744     }
2745     i = 0U;
2746     while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
2747     {
2748       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2749       hcryp->CrypOutCount++;
2750       i++;
2751     }
2752   }
2753 }
2754 
2755 /**
2756   * @brief  Handle CRYP block input/output data handling under interruption.
2757   * @note   The function is called under interruption only, once
2758   *         interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
2759   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2760   *         the configuration information for CRYP module.
2761   * @retval HAL status
2762   */
2763 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
2764 {
2765   uint32_t temp[4];  /* Temporary CrypOutBuff */
2766   uint16_t incount; /* Temporary CrypInCount Value */
2767   uint16_t outcount;  /* Temporary CrypOutCount Value */
2768   uint32_t i;
2769 
2770   if (hcryp->State == HAL_CRYP_STATE_BUSY)
2771   {
2772     /*Temporary CrypOutCount Value*/
2773     incount = hcryp->CrypInCount;
2774 
2775     if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
2776     {
2777       /* Write the input block in the IN FIFO */
2778       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2779       hcryp->CrypInCount++;
2780       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2781       hcryp->CrypInCount++;
2782       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2783       hcryp->CrypInCount++;
2784       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2785       hcryp->CrypInCount++;
2786       if (hcryp->CrypInCount == (hcryp->Size / 4U))
2787       {
2788         /* Disable interrupts */
2789         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
2790 
2791         /* Call the input data transfer complete callback */
2792 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2793         /*Call registered Input complete callback*/
2794         hcryp->InCpltCallback(hcryp);
2795 #else
2796         /*Call legacy weak Input complete callback*/
2797         HAL_CRYP_InCpltCallback(hcryp);
2798 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2799       }
2800     }
2801 
2802     /*Temporary CrypOutCount Value*/
2803     outcount = hcryp->CrypOutCount;
2804 
2805     if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
2806     {
2807       /* Read the output block from the output FIFO and put them in temporary buffer
2808          then get CrypOutBuff from temporary buffer  */
2809       for (i = 0U; i < 4U; i++)
2810       {
2811         temp[i] = hcryp->Instance->DOUT;
2812       }
2813       i = 0U;
2814       while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
2815       {
2816         *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2817         hcryp->CrypOutCount++;
2818         i++;
2819       }
2820       if (hcryp->CrypOutCount == (hcryp->Size / 4U))
2821       {
2822         /* Disable interrupts */
2823         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
2824 
2825         /* Change the CRYP state */
2826         hcryp->State = HAL_CRYP_STATE_READY;
2827 
2828         /* Disable CRYP */
2829         __HAL_CRYP_DISABLE(hcryp);
2830 
2831         /* Process unlocked */
2832         __HAL_UNLOCK(hcryp);
2833 
2834         /* Call output transfer complete callback */
2835 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2836         /*Call registered Output complete callback*/
2837         hcryp->OutCpltCallback(hcryp);
2838 #else
2839         /*Call legacy weak Output complete callback*/
2840         HAL_CRYP_OutCpltCallback(hcryp);
2841 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2842       }
2843     }
2844   }
2845   else
2846   {
2847     /* Process unlocked */
2848     __HAL_UNLOCK(hcryp);
2849     /* Busy error code field */
2850     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
2851 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2852     /*Call registered error callback*/
2853     hcryp->ErrorCallback(hcryp);
2854 #else
2855     /*Call legacy weak error callback*/
2856     HAL_CRYP_ErrorCallback(hcryp);
2857 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2858   }
2859 }
2860 
2861 /**
2862   * @brief  Writes Key in Key registers.
2863   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2864   *         the configuration information for CRYP module
2865   * @param  KeySize: Size of Key
2866   * @retval None
2867   */
2868 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
2869 {
2870   switch (KeySize)
2871   {
2872     case CRYP_KEYSIZE_256B:
2873       hcryp->Instance->K0LR = *(uint32_t *)(hcryp->Init.pKey);
2874       hcryp->Instance->K0RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2875       hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2876       hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2877       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2878       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2879       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 6);
2880       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 7);
2881       break;
2882     case CRYP_KEYSIZE_192B:
2883       hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
2884       hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2885       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2886       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2887       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2888       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2889       break;
2890     case CRYP_KEYSIZE_128B:
2891       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey);
2892       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2893       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2894       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2895 
2896       break;
2897     default:
2898       break;
2899   }
2900 }
2901 
2902 /**
2903   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
2904   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2905   *         the configuration information for CRYP module
2906   * @param  Timeout: Timeout duration
2907   * @retval HAL status
2908   */
2909 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2910 {
2911   uint32_t tickstart;
2912   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
2913   uint32_t npblb ;
2914   uint32_t temp[4];  /* Temporary CrypOutBuff */
2915   uint32_t index ;
2916   uint32_t lastwordsize ;
2917   uint32_t nolastpaddingbytes;
2918   uint8_t *pval;
2919   uint16_t outcount;  /* Temporary CrypOutCount Value */
2920   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2921 
2922   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2923   {
2924     if (hcryp->KeyIVConfig == 1U)
2925     {
2926       /* If the Key and IV configuration has to be done only once
2927          and if it has already been done, skip it */
2928       DoKeyIVConfig = 0U;
2929       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
2930     }
2931     else
2932     {
2933       /* If the Key and IV configuration has to be done only once
2934          and if it has not been done already, do it and set KeyIVConfig
2935          to keep track it won't have to be done again next time */
2936       hcryp->KeyIVConfig = 1U;
2937       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
2938     }
2939   }
2940   else
2941   {
2942     hcryp->SizesSum = hcryp->Size;
2943   }
2944 
2945   if (DoKeyIVConfig == 1U)
2946   {
2947     /*  Reset CrypHeaderCount */
2948     hcryp->CrypHeaderCount = 0U;
2949 
2950     /****************************** Init phase **********************************/
2951 
2952     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2953 
2954     /* Set the key */
2955     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2956 
2957     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
2958     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2959     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2960     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2961     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2962 
2963     /* Enable the CRYP peripheral */
2964     __HAL_CRYP_ENABLE(hcryp);
2965 
2966     /* Get tick */
2967     tickstart = HAL_GetTick();
2968 
2969     /*Wait for the CRYPEN bit to be cleared*/
2970     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2971     {
2972       /* Check for the Timeout */
2973       if (Timeout != HAL_MAX_DELAY)
2974       {
2975         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2976         {
2977           /* Disable the CRYP peripheral clock */
2978           __HAL_CRYP_DISABLE(hcryp);
2979 
2980           /* Change state */
2981           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2982           hcryp->State = HAL_CRYP_STATE_READY;
2983 
2984           /* Process unlocked */
2985           __HAL_UNLOCK(hcryp);
2986           return HAL_ERROR;
2987         }
2988       }
2989     }
2990 
2991     /************************ Header phase *************************************/
2992 
2993     if (CRYP_GCMCCM_SetHeaderPhase(hcryp,  Timeout) != HAL_OK)
2994     {
2995       return HAL_ERROR;
2996     }
2997 
2998     /*************************Payload phase ************************************/
2999 
3000     /* Set the phase */
3001     hcryp->Phase = CRYP_PHASE_PROCESS;
3002 
3003     /* Disable the CRYP peripheral */
3004     __HAL_CRYP_DISABLE(hcryp);
3005 
3006 #if !defined (CRYP_VER_2_2)
3007     if (hcryp->Version >= REV_ID_B)
3008 #endif /*End of not defined CRYP_VER_2_2*/
3009     {
3010       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3011       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3012     }
3013 
3014     /* Select payload phase once the header phase is performed */
3015     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3016 
3017     /* Enable the CRYP peripheral */
3018     __HAL_CRYP_ENABLE(hcryp);
3019   } /* if (DoKeyIVConfig == 1U) */
3020 
3021   if ((hcryp->Size % 16U) != 0U)
3022   {
3023     /* recalculate  wordsize */
3024     wordsize = ((wordsize / 4U) * 4U) ;
3025   }
3026 
3027   /* Get tick */
3028   tickstart = HAL_GetTick();
3029   /*Temporary CrypOutCount Value*/
3030   outcount = hcryp->CrypOutCount;
3031 
3032   /* Write input data and get output Data */
3033   while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3034   {
3035     /* Write plain data and get cipher data */
3036     CRYP_AES_ProcessData(hcryp, Timeout);
3037 
3038     /*Temporary CrypOutCount Value*/
3039     outcount = hcryp->CrypOutCount;
3040 
3041     /* Check for the Timeout */
3042     if (Timeout != HAL_MAX_DELAY)
3043     {
3044       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3045       {
3046         /* Disable the CRYP peripheral clock */
3047         __HAL_CRYP_DISABLE(hcryp);
3048 
3049         /* Change state & error code */
3050         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3051         hcryp->State = HAL_CRYP_STATE_READY;
3052 
3053         /* Process unlocked */
3054         __HAL_UNLOCK(hcryp);
3055         return HAL_ERROR;
3056       }
3057     }
3058   }
3059 
3060   if ((hcryp->Size % 16U) != 0U)
3061   {
3062 
3063 #if !defined (CRYP_VER_2_2)
3064     if (hcryp->Version >= REV_ID_B)
3065 #endif /*End of not defined CRYP_VER_2_2*/
3066     {
3067       /* Compute the number of padding bytes in last block of payload */
3068       npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3069 
3070       /*  Set Npblb in case of AES GCM payload encryption to get right tag*/
3071       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3072       {
3073         /* Disable the CRYP */
3074         __HAL_CRYP_DISABLE(hcryp);
3075 
3076         /* Specify the number of non-valid bytes using NPBLB register*/
3077         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3078 
3079         /* Enable CRYP to start the final phase */
3080         __HAL_CRYP_ENABLE(hcryp);
3081       }
3082       /* Number of valid words (lastwordsize) in last block */
3083       if ((npblb % 4U) == 0U)
3084       {
3085         lastwordsize = (16U - npblb) / 4U;
3086       }
3087       else
3088       {
3089         lastwordsize = ((16U - npblb) / 4U) + 1U;
3090       }
3091 
3092       /* Write the last input block in the IN FIFO */
3093       for (index = 0U; index < lastwordsize; index ++)
3094       {
3095         hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3096         hcryp->CrypInCount++;
3097       }
3098 
3099       /* Pad the data with zeros to have a complete block */
3100       while (index < 4U)
3101       {
3102         hcryp->Instance->DIN  = 0U;
3103         index++;
3104       }
3105 
3106       /* Wait for OFNE flag to be raised */
3107       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3108       {
3109         /* Disable the CRYP peripheral clock */
3110         __HAL_CRYP_DISABLE(hcryp);
3111 
3112         /* Change state */
3113         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3114         hcryp->State = HAL_CRYP_STATE_READY;
3115 
3116         /* Process Unlocked */
3117         __HAL_UNLOCK(hcryp);
3118 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3119         /*Call registered error callback*/
3120         hcryp->ErrorCallback(hcryp);
3121 #else
3122         /*Call legacy weak error callback*/
3123         HAL_CRYP_ErrorCallback(hcryp);
3124 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3125       }
3126 
3127       /*Read the output block from the output FIFO */
3128       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3129       {
3130         for (index = 0U; index < 4U; index++)
3131         {
3132           /* Read the output block from the output FIFO and put them in temporary buffer
3133           then get CrypOutBuff from temporary buffer */
3134           temp[index] = hcryp->Instance->DOUT;
3135         }
3136 
3137         for (index = 0U; index < lastwordsize; index++)
3138         {
3139           pval = (uint8_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount));
3140 
3141           if (index == (lastwordsize - 1U))
3142           {
3143             nolastpaddingbytes = npblb % 4U;
3144 
3145             switch (nolastpaddingbytes)
3146             {
3147               case 1:
3148                 *(pval) = (uint8_t)(temp[index]);
3149                 pval++;
3150                 *(pval) = (uint8_t)(temp[index] >> 8U);
3151                 pval++;
3152                 *(pval) = (uint8_t)(temp[index] >> 16U);
3153                 break;
3154               case 2:
3155                 *(pval) = (uint8_t)(temp[index]);
3156                 pval++;
3157                 *(pval) = (uint8_t)(temp[index] >> 8U);
3158                 break;
3159               case 3:
3160                 *(pval) = (uint8_t)(temp[index]);
3161                 break;
3162               default:
3163                 *(pval) = (uint8_t)(temp[index]);
3164                 pval++;
3165                 *(pval) = (uint8_t)(temp[index] >> 8U);
3166                 pval++;
3167                 *(pval) = (uint8_t)(temp[index] >> 16U);
3168                 pval++;
3169                 *(pval) = (uint8_t)(temp[index] >> 24U);
3170                 break;
3171             }
3172           }
3173           else
3174           {
3175             *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
3176           }
3177 
3178           hcryp->CrypOutCount++;
3179         }
3180       }
3181     }
3182 #if !defined (CRYP_VER_2_2)
3183     else /*  Workaround to be used */
3184     {
3185       /*  Workaround 2 for STM32H7 below rev.B To generate correct TAG only when size of the last block of
3186       payload is inferior to 128 bits, in case of GCM encryption or CCM decryption*/
3187       CRYP_Workaround(hcryp, Timeout);
3188     } /* end of NPBLB or Workaround*/
3189 #endif /*End of not defined CRYP_VER_2_2*/
3190   }
3191 
3192   /* Return function status */
3193   return HAL_OK;
3194 }
3195 
3196 /**
3197   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
3198   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3199   *         the configuration information for CRYP module
3200   * @retval HAL status
3201   */
3202 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3203 {
3204   __IO uint32_t count = 0U;
3205   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3206 
3207   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3208   {
3209     if (hcryp->KeyIVConfig == 1U)
3210     {
3211       /* If the Key and IV configuration has to be done only once
3212       and if it has already been done, skip it */
3213       DoKeyIVConfig = 0U;
3214       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3215     }
3216     else
3217     {
3218       /* If the Key and IV configuration has to be done only once
3219       and if it has not been done already, do it and set KeyIVConfig
3220       to keep track it won't have to be done again next time */
3221       hcryp->KeyIVConfig = 1U;
3222       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3223     }
3224   }
3225   else
3226   {
3227     hcryp->SizesSum = hcryp->Size;
3228   }
3229 
3230   /* Configure Key, IV and process message (header and payload) */
3231   if (DoKeyIVConfig == 1U)
3232   {
3233     /*  Reset CrypHeaderCount */
3234     hcryp->CrypHeaderCount = 0U;
3235 
3236     /******************************* Init phase *********************************/
3237 
3238     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3239 
3240     /* Set the key */
3241     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3242 
3243     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3244     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3245     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3246     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3247     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3248 
3249     /* Enable the CRYP peripheral */
3250     __HAL_CRYP_ENABLE(hcryp);
3251 
3252     /*Wait for the CRYPEN bit to be cleared*/
3253     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3254     do
3255     {
3256       count-- ;
3257       if (count == 0U)
3258       {
3259         /* Disable the CRYP peripheral clock */
3260         __HAL_CRYP_DISABLE(hcryp);
3261 
3262         /* Change state */
3263         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3264         hcryp->State = HAL_CRYP_STATE_READY;
3265 
3266         /* Process unlocked */
3267         __HAL_UNLOCK(hcryp);
3268         return HAL_ERROR;
3269       }
3270     }
3271     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3272 
3273     /***************************** Header phase *********************************/
3274 
3275     /* Select header phase */
3276     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3277   } /* end of if (DoKeyIVConfig == 1U) */
3278   /* Enable interrupts */
3279   __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3280 
3281   /* Enable CRYP */
3282   __HAL_CRYP_ENABLE(hcryp);
3283 
3284   /* Return function status */
3285   return HAL_OK;
3286 }
3287 
3288 
3289 /**
3290   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
3291   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3292   *         the configuration information for CRYP module
3293   * @retval HAL status
3294   */
3295 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3296 {
3297   __IO uint32_t count = 0U;
3298   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3299   uint32_t index;
3300   uint32_t npblb;
3301   uint32_t lastwordsize;
3302   uint32_t temp[4];  /* Temporary CrypOutBuff */
3303   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3304 
3305   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3306   {
3307     if (hcryp->KeyIVConfig == 1U)
3308     {
3309       /* If the Key and IV configuration has to be done only once
3310          and if it has already been done, skip it */
3311       DoKeyIVConfig = 0U;
3312       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3313     }
3314     else
3315     {
3316       /* If the Key and IV configuration has to be done only once
3317          and if it has not been done already, do it and set KeyIVConfig
3318          to keep track it won't have to be done again next time */
3319       hcryp->KeyIVConfig = 1U;
3320       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3321     }
3322   }
3323   else
3324   {
3325     hcryp->SizesSum = hcryp->Size;
3326   }
3327 
3328   if (DoKeyIVConfig == 1U)
3329   {
3330     /*  Reset CrypHeaderCount */
3331     hcryp->CrypHeaderCount = 0U;
3332 
3333     /*************************** Init phase ************************************/
3334 
3335     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3336 
3337     /* Set the key */
3338     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3339 
3340     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3341     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3342     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3343     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3344     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3345 
3346     /* Enable the CRYP peripheral */
3347     __HAL_CRYP_ENABLE(hcryp);
3348 
3349     /*Wait for the CRYPEN bit to be cleared*/
3350     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3351     do
3352     {
3353       count-- ;
3354       if (count == 0U)
3355       {
3356         /* Disable the CRYP peripheral clock */
3357         __HAL_CRYP_DISABLE(hcryp);
3358 
3359         /* Change state */
3360         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3361         hcryp->State = HAL_CRYP_STATE_READY;
3362 
3363         /* Process unlocked */
3364         __HAL_UNLOCK(hcryp);
3365         return HAL_ERROR;
3366       }
3367     }
3368     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3369 
3370     /************************ Header phase *************************************/
3371 
3372     if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
3373     {
3374       return HAL_ERROR;
3375     }
3376 
3377     /************************ Payload phase ************************************/
3378 
3379     /* Set the phase */
3380     hcryp->Phase = CRYP_PHASE_PROCESS;
3381 
3382     /* Disable the CRYP peripheral */
3383     __HAL_CRYP_DISABLE(hcryp);
3384 
3385 #if !defined (CRYP_VER_2_2)
3386     if (hcryp->Version >= REV_ID_B)
3387 #endif /*End of not defined CRYP_VER_2_2*/
3388     {
3389       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3390       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3391     }
3392 
3393     /* Select payload phase once the header phase is performed */
3394     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3395 
3396   } /* if (DoKeyIVConfig == 1U) */
3397 
3398   if (hcryp->Size == 0U)
3399   {
3400     /* Process unLocked */
3401     __HAL_UNLOCK(hcryp);
3402 
3403     /* Change the CRYP state and phase */
3404     hcryp->State = HAL_CRYP_STATE_READY;
3405   }
3406   else if (hcryp->Size >= 16U)
3407   {
3408     /* for STM32H7 below rev.B : Size should be %4  otherwise Tag will  be incorrectly generated for GCM Encryption:
3409     Workaround is implemented in polling mode, so if last block of payload <128bit don't use DMA mode otherwise
3410     TAG is incorrectly generated */
3411 
3412     /*DMA transfer must not include the last block in case of Size is not %16 */
3413     wordsize = wordsize - (wordsize % 4U);
3414 
3415     /*DMA transfer */
3416     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)wordsize,
3417                       (uint32_t)(hcryp->pCrypOutBuffPtr));
3418   }
3419   else /* length of input data is < 16 */
3420   {
3421     /* Compute the number of padding bytes in last block of payload */
3422     npblb = 16U - (uint32_t)hcryp->Size;
3423 
3424 #if !defined (CRYP_VER_2_2)
3425     if (hcryp->Version >= REV_ID_B)
3426 #endif /*End of not defined CRYP_VER_2_2*/
3427     {
3428       /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3429       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3430       {
3431         /* Specify the number of non-valid bytes using NPBLB register*/
3432         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3433       }
3434     }
3435     /* Enable CRYP to start the final phase */
3436     __HAL_CRYP_ENABLE(hcryp);
3437 
3438     /* Number of valid words (lastwordsize) in last block */
3439     if ((npblb % 4U) == 0U)
3440     {
3441       lastwordsize = (16U - npblb) / 4U;
3442     }
3443     else
3444     {
3445       lastwordsize = ((16U - npblb) / 4U) + 1U;
3446     }
3447 
3448     /* Write the last input block in the IN FIFO */
3449     for (index = 0; index < lastwordsize; index ++)
3450     {
3451       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3452       hcryp->CrypInCount++;
3453     }
3454 
3455     /* Pad the data with zeros to have a complete block */
3456     while (index < 4U)
3457     {
3458       hcryp->Instance->DIN  = 0U;
3459       index++;
3460     }
3461 
3462     /* Wait for OFNE flag to be raised */
3463     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
3464     do
3465     {
3466       count-- ;
3467       if (count == 0U)
3468       {
3469         /* Disable the CRYP peripheral clock */
3470         __HAL_CRYP_DISABLE(hcryp);
3471 
3472         /* Change state */
3473         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3474         hcryp->State = HAL_CRYP_STATE_READY;
3475 
3476         /* Process unlocked */
3477         __HAL_UNLOCK(hcryp);
3478 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3479         /*Call registered error callback*/
3480         hcryp->ErrorCallback(hcryp);
3481 #else
3482         /*Call legacy weak error callback*/
3483         HAL_CRYP_ErrorCallback(hcryp);
3484 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3485       }
3486     }
3487     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
3488 
3489     /*Read the output block from the output FIFO */
3490     for (index = 0U; index < 4U; index++)
3491     {
3492       /* Read the output block from the output FIFO and put them in temporary buffer
3493       then get CrypOutBuff from temporary buffer */
3494       temp[index] = hcryp->Instance->DOUT;
3495     }
3496     for (index = 0; index < lastwordsize; index++)
3497     {
3498       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3499       hcryp->CrypOutCount++;
3500     }
3501 
3502     /* Change the CRYP state to ready */
3503     hcryp->State = HAL_CRYP_STATE_READY;
3504 
3505     /* Process unlocked */
3506     __HAL_UNLOCK(hcryp);
3507   }
3508 
3509   /* Return function status */
3510   return HAL_OK;
3511 }
3512 
3513 
3514 /**
3515   * @brief  AES CCM encryption/decryption processing in polling mode
3516   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3517   *         the configuration information for CRYP module
3518   * @param  Timeout: Timeout duration
3519   * @retval HAL status
3520   */
3521 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3522 {
3523   uint32_t tickstart;
3524   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
3525   uint32_t npblb ;
3526   uint32_t lastwordsize ;
3527   uint32_t temp[4] ;  /* Temporary CrypOutBuff */
3528   uint32_t index ;
3529   uint16_t outcount;  /* Temporary CrypOutCount Value */
3530   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3531 
3532   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3533   {
3534     if (hcryp->KeyIVConfig == 1U)
3535     {
3536       /* If the Key and IV configuration has to be done only once
3537       and if it has already been done, skip it */
3538       DoKeyIVConfig = 0U;
3539       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3540     }
3541     else
3542     {
3543       /* If the Key and IV configuration has to be done only once
3544       and if it has not been done already, do it and set KeyIVConfig
3545       to keep track it won't have to be done again next time */
3546       hcryp->KeyIVConfig = 1U;
3547       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3548     }
3549   }
3550   else
3551   {
3552     hcryp->SizesSum = hcryp->Size;
3553   }
3554 
3555   if (DoKeyIVConfig == 1U)
3556   {
3557     /*  Reset CrypHeaderCount */
3558     hcryp->CrypHeaderCount = 0U;
3559 
3560     /********************** Init phase ******************************************/
3561 
3562     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3563 
3564     /* Set the key */
3565     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3566 
3567     /* Set the initialization vector (IV) with CTR1 information */
3568     hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3569     hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3570     hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3571     hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
3572 
3573     /* Enable the CRYP peripheral */
3574     __HAL_CRYP_ENABLE(hcryp);
3575 
3576 #if defined (CRYP_VER_2_2)
3577     {
3578       /* for STM32H7 rev.B and above Write  B0 packet into CRYP_DR*/
3579       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3580       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3581       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3582       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3583     }
3584 #else
3585     if (hcryp->Version >= REV_ID_B)
3586     {
3587       /* for STM32H7 rev.B and above Write  B0 packet into CRYP_DR*/
3588       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3589       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3590       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3591       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3592     }
3593     else /* data has to be swapped according to the DATATYPE */
3594     {
3595       if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
3596       {
3597         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3598         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3599         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3600         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3601       }
3602       else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
3603       {
3604         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3605         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3606         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3607         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3608       }
3609       else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
3610       {
3611         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3612         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3613         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3614         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3615       }
3616       else
3617       {
3618         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3619         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3620         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3621         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3622       }
3623     }
3624 #endif /* CRYP_VER_2_2 */
3625     /* Get tick */
3626     tickstart = HAL_GetTick();
3627 
3628     /*Wait for the CRYPEN bit to be cleared*/
3629     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
3630     {
3631       /* Check for the Timeout */
3632       if (Timeout != HAL_MAX_DELAY)
3633       {
3634         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3635         {
3636           /* Disable the CRYP peripheral clock */
3637           __HAL_CRYP_DISABLE(hcryp);
3638 
3639           /* Change state */
3640           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3641           hcryp->State = HAL_CRYP_STATE_READY;
3642 
3643           /* Process unlocked */
3644           __HAL_UNLOCK(hcryp);
3645           return HAL_ERROR;
3646         }
3647       }
3648     }
3649 
3650     /************************* Header phase *************************************/
3651     /* Header block(B1) : associated data length expressed in bytes concatenated
3652     with Associated Data (A)*/
3653 
3654     if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
3655     {
3656       return HAL_ERROR;
3657     }
3658     /********************** Payload phase ***************************************/
3659 
3660     /* Set the phase */
3661     hcryp->Phase = CRYP_PHASE_PROCESS;
3662 
3663     /* Disable the CRYP peripheral */
3664     __HAL_CRYP_DISABLE(hcryp);
3665 #if !defined (CRYP_VER_2_2)
3666     if (hcryp->Version >= REV_ID_B)
3667 #endif /*End of not defined CRYP_VER_2_2*/
3668     {
3669       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3670       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3671     }
3672 
3673     /* Select payload phase once the header phase is performed */
3674     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3675 
3676     /* Enable the CRYP peripheral */
3677     __HAL_CRYP_ENABLE(hcryp);
3678 
3679   } /* if (DoKeyIVConfig == 1U) */
3680 
3681   if ((hcryp->Size % 16U) != 0U)
3682   {
3683     /* recalculate  wordsize */
3684     wordsize = ((wordsize / 4U) * 4U) ;
3685   }
3686   /* Get tick */
3687   tickstart = HAL_GetTick();
3688 
3689   /*Temporary CrypOutCount Value*/
3690   outcount = hcryp->CrypOutCount;
3691 
3692   /* Write input data and get output data */
3693   while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3694   {
3695     /* Write plain data and get cipher data */
3696     CRYP_AES_ProcessData(hcryp, Timeout);
3697 
3698     /*Temporary CrypOutCount Value*/
3699     outcount = hcryp->CrypOutCount;
3700 
3701     /* Check for the Timeout */
3702     if (Timeout != HAL_MAX_DELAY)
3703     {
3704       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3705       {
3706         /* Disable the CRYP peripheral clock */
3707         __HAL_CRYP_DISABLE(hcryp);
3708 
3709         /* Change state */
3710         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3711         hcryp->State = HAL_CRYP_STATE_READY;
3712 
3713         /* Process unlocked */
3714         __HAL_UNLOCK(hcryp);
3715         return HAL_ERROR;
3716       }
3717     }
3718   }
3719 
3720   if ((hcryp->Size % 16U) != 0U)
3721   {
3722 #if !defined (CRYP_VER_2_2)
3723     if (hcryp->Version >= REV_ID_B)
3724 #endif /*End of not defined CRYP_VER_2_2*/
3725     {
3726       /* Compute the number of padding bytes in last block of payload */
3727       npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3728 
3729       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
3730       {
3731         /* Disable the CRYP */
3732         __HAL_CRYP_DISABLE(hcryp);
3733 
3734         /* Set Npblb in case of AES CCM payload decryption to get right tag  */
3735         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3736 
3737         /* Enable CRYP to start the final phase */
3738         __HAL_CRYP_ENABLE(hcryp);
3739       }
3740 
3741       /* Number of valid words (lastwordsize) in last block */
3742       if ((npblb % 4U) == 0U)
3743       {
3744         lastwordsize = (16U - npblb) / 4U;
3745       }
3746       else
3747       {
3748         lastwordsize = ((16U - npblb) / 4U) + 1U;
3749       }
3750 
3751       /* Write the last input block in the IN FIFO */
3752       for (index = 0U; index < lastwordsize; index ++)
3753       {
3754         hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3755         hcryp->CrypInCount++;
3756       }
3757 
3758       /* Pad the data with zeros to have a complete block */
3759       while (index < 4U)
3760       {
3761         hcryp->Instance->DIN  = 0U;
3762         index++;
3763       }
3764 
3765       /* Wait for OFNE flag to be raised */
3766       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3767       {
3768         /* Disable the CRYP peripheral clock */
3769         __HAL_CRYP_DISABLE(hcryp);
3770 
3771         /* Change state */
3772         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3773         hcryp->State = HAL_CRYP_STATE_READY;
3774 
3775         /* Process Unlocked */
3776         __HAL_UNLOCK(hcryp);
3777 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3778         /*Call registered error callback*/
3779         hcryp->ErrorCallback(hcryp);
3780 #else
3781         /*Call legacy weak error callback*/
3782         HAL_CRYP_ErrorCallback(hcryp);
3783 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3784       }
3785 
3786       /*Read the output block from the output FIFO */
3787       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3788       {
3789         for (index = 0U; index < 4U; index++)
3790         {
3791           /* Read the output block from the output FIFO and put them in temporary buffer
3792           then get CrypOutBuff from temporary buffer */
3793           temp[index] = hcryp->Instance->DOUT;
3794         }
3795         for (index = 0; index < lastwordsize; index++)
3796         {
3797           *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3798           hcryp->CrypOutCount++;
3799         }
3800       }
3801     }
3802 #if !defined (CRYP_VER_2_2)
3803     else /* No NPBLB, Workaround to be used */
3804     {
3805       /* CRYP Workaround :  CRYP1 generates correct TAG  during CCM decryption only when ciphertext
3806       blocks size is multiple of 128 bits. If lthe size of the last block of payload is inferior to 128 bits,
3807       when CCM decryption is selected, then the TAG message will be wrong.*/
3808       CRYP_Workaround(hcryp, Timeout);
3809     }
3810 #endif /*End of not defined CRYP_VER_2_2*/
3811   }
3812 
3813   /* Return function status */
3814   return HAL_OK;
3815 }
3816 
3817 /**
3818   * @brief  AES CCM encryption/decryption process in interrupt mode
3819   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3820   *         the configuration information for CRYP module
3821   * @retval HAL status
3822   */
3823 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3824 {
3825   __IO uint32_t count = 0U;
3826   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3827 
3828   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3829   {
3830     if (hcryp->KeyIVConfig == 1U)
3831     {
3832       /* If the Key and IV configuration has to be done only once
3833       and if it has already been done, skip it */
3834       DoKeyIVConfig = 0U;
3835       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3836     }
3837     else
3838     {
3839       /* If the Key and IV configuration has to be done only once
3840       and if it has not been done already, do it and set KeyIVConfig
3841       to keep track it won't have to be done again next time */
3842       hcryp->KeyIVConfig = 1U;
3843       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3844     }
3845   }
3846   else
3847   {
3848     hcryp->SizesSum = hcryp->Size;
3849   }
3850 
3851   /* Configure Key, IV and process message (header and payload) */
3852   if (DoKeyIVConfig == 1U)
3853   {
3854     /*  Reset CrypHeaderCount */
3855     hcryp->CrypHeaderCount = 0U;
3856 
3857     /************ Init phase ************/
3858 
3859     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3860 
3861     /* Set the key */
3862     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3863 
3864     /* Set the initialization vector (IV) with CTR1 information */
3865     hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3866     hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3867     hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3868     hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
3869 
3870     /* Enable the CRYP peripheral */
3871     __HAL_CRYP_ENABLE(hcryp);
3872 
3873     /*Write the B0 packet into CRYP_DR*/
3874 #if !defined (CRYP_VER_2_2)
3875     if (hcryp->Version >= REV_ID_B)
3876 #endif /*End of not defined CRYP_VER_2_2*/
3877     {
3878       /* for STM32H7 rev.B and above data has not to be swapped */
3879       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3880       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3881       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3882       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3883     }
3884 #if !defined (CRYP_VER_2_2)
3885     else /* data has to be swapped according to the DATATYPE */
3886     {
3887       if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
3888       {
3889         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3890         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3891         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3892         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3893       }
3894       else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
3895       {
3896         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3897         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3898         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3899         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3900       }
3901       else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
3902       {
3903         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3904         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3905         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3906         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3907       }
3908       else
3909       {
3910         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3911         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3912         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3913         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3914       }
3915     }
3916 #endif /*End of not defined CRYP_VER_2_2*/
3917     /*Wait for the CRYPEN bit to be cleared*/
3918     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3919     do
3920     {
3921       count-- ;
3922       if (count == 0U)
3923       {
3924         /* Disable the CRYP peripheral clock */
3925         __HAL_CRYP_DISABLE(hcryp);
3926 
3927         /* Change state */
3928         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3929         hcryp->State = HAL_CRYP_STATE_READY;
3930 
3931         /* Process unlocked */
3932         __HAL_UNLOCK(hcryp);
3933         return HAL_ERROR;
3934       }
3935     }
3936     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3937 
3938     /* Select header phase */
3939     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3940   } /* end of if (DoKeyIVConfig == 1U) */
3941   /* Enable interrupts */
3942   __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3943 
3944   /* Enable CRYP */
3945   __HAL_CRYP_ENABLE(hcryp);
3946 
3947   /* Return function status */
3948   return HAL_OK;
3949 }
3950 /**
3951   * @brief  AES CCM encryption/decryption process in DMA mode
3952   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3953   *         the configuration information for CRYP module
3954   * @retval HAL status
3955   */
3956 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3957 {
3958   __IO uint32_t count    = 0U;
3959   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3960   uint32_t index;
3961   uint32_t npblb;
3962   uint32_t lastwordsize;
3963   uint32_t temp[4];  /* Temporary CrypOutBuff */
3964   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3965 
3966   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3967   {
3968     if (hcryp->KeyIVConfig == 1U)
3969     {
3970       /* If the Key and IV configuration has to be done only once
3971       and if it has already been done, skip it */
3972       DoKeyIVConfig = 0U;
3973       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3974     }
3975     else
3976     {
3977       /* If the Key and IV configuration has to be done only once
3978       and if it has not been done already, do it and set KeyIVConfig
3979       to keep track it won't have to be done again next time */
3980       hcryp->KeyIVConfig = 1U;
3981       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3982     }
3983   }
3984   else
3985   {
3986     hcryp->SizesSum = hcryp->Size;
3987   }
3988 
3989   if (DoKeyIVConfig == 1U)
3990   {
3991     /*  Reset CrypHeaderCount */
3992     hcryp->CrypHeaderCount = 0U;
3993 
3994     /************************** Init phase **************************************/
3995 
3996     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3997 
3998     /* Set the key */
3999     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4000 
4001     /* Set the initialization vector (IV) with CTR1 information */
4002     hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
4003     hcryp->Instance->IV0RR = hcryp->Init.B0[1];
4004     hcryp->Instance->IV1LR = hcryp->Init.B0[2];
4005     hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
4006 
4007     /* Enable the CRYP peripheral */
4008     __HAL_CRYP_ENABLE(hcryp);
4009 
4010     /*Write the B0 packet into CRYP_DR*/
4011 #if !defined (CRYP_VER_2_2)
4012     if (hcryp->Version >= REV_ID_B)
4013 #endif /*End of not defined CRYP_VER_2_2*/
4014     {
4015       /* for STM32H7 rev.B and above data has not to be swapped */
4016       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
4017       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
4018       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
4019       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
4020     }
4021 #if !defined (CRYP_VER_2_2)
4022     else /* data has to be swapped according to the DATATYPE */
4023     {
4024       if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
4025       {
4026         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
4027         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
4028         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
4029         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
4030       }
4031       else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
4032       {
4033         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
4034         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
4035         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
4036         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
4037       }
4038       else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
4039       {
4040         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
4041         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
4042         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
4043         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
4044       }
4045       else
4046       {
4047         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
4048         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
4049         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
4050         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
4051       }
4052     }
4053 #endif /*End of not defined CRYP_VER_2_2*/
4054     /*Wait for the CRYPEN bit to be cleared*/
4055     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
4056     do
4057     {
4058       count-- ;
4059       if (count == 0U)
4060       {
4061         /* Disable the CRYP peripheral clock */
4062         __HAL_CRYP_DISABLE(hcryp);
4063 
4064         /* Change state */
4065         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4066         hcryp->State = HAL_CRYP_STATE_READY;
4067 
4068         /* Process unlocked */
4069         __HAL_UNLOCK(hcryp);
4070         return HAL_ERROR;
4071       }
4072     }
4073     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
4074 
4075     /********************* Header phase *****************************************/
4076 
4077     if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
4078     {
4079       return HAL_ERROR;
4080     }
4081 
4082     /******************** Payload phase *****************************************/
4083 
4084     /* Set the phase */
4085     hcryp->Phase = CRYP_PHASE_PROCESS;
4086 
4087     /* Disable the CRYP peripheral */
4088     __HAL_CRYP_DISABLE(hcryp);
4089 #if !defined (CRYP_VER_2_2)
4090     if (hcryp->Version >= REV_ID_B)
4091 #endif /*End of not defined CRYP_VER_2_2*/
4092     {
4093       /* Set to 0 the number of non-valid bytes using NPBLB register*/
4094       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4095     }
4096 
4097     /* Select payload phase once the header phase is performed */
4098     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4099   } /* if (DoKeyIVConfig == 1U) */
4100 
4101   if (hcryp->Size == 0U)
4102   {
4103     /* Process unLocked */
4104     __HAL_UNLOCK(hcryp);
4105 
4106     /* Change the CRYP state and phase */
4107     hcryp->State = HAL_CRYP_STATE_READY;
4108   }
4109   else if (hcryp->Size >= 16U)
4110   {
4111     /* for STM32H7 below rev.B ::  Size should be %4  otherwise Tag will  be incorrectly generated for CCM Decryption,
4112     Workaround is implemented in polling mode*/
4113     /*DMA transfer must not include the last block in case of Size is not %16 */
4114     wordsize = wordsize - (wordsize % 4U);
4115 
4116     /*DMA transfer */
4117     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t) wordsize,
4118                       (uint32_t)(hcryp->pCrypOutBuffPtr));
4119   }
4120   else /* length of input data is  < 16U */
4121   {
4122     /* Compute the number of padding bytes in last block of payload */
4123     npblb = 16U - (uint32_t)(hcryp->Size);
4124 
4125 #if !defined (CRYP_VER_2_2)
4126     if (hcryp->Version >= REV_ID_B)
4127 #endif /*End of not defined CRYP_VER_2_2*/
4128     {
4129       /* Set Npblb in case of AES CCM payload decryption to get right tag*/
4130       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4131       {
4132         /* Specify the number of non-valid bytes using NPBLB register*/
4133         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4134       }
4135     }
4136     /* Enable CRYP to start the final phase */
4137     __HAL_CRYP_ENABLE(hcryp);
4138 
4139     /* Number of valid words (lastwordsize) in last block */
4140     if ((npblb % 4U) == 0U)
4141     {
4142       lastwordsize = (16U - npblb) / 4U;
4143     }
4144     else
4145     {
4146       lastwordsize = ((16U - npblb) / 4U) + 1U;
4147     }
4148 
4149     /* Write the last input block in the IN FIFO */
4150     for (index = 0U; index < lastwordsize; index ++)
4151     {
4152       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4153       hcryp->CrypInCount++;
4154     }
4155 
4156     /* Pad the data with zeros to have a complete block */
4157     while (index < 4U)
4158     {
4159       hcryp->Instance->DIN  = 0U;
4160       index++;
4161     }
4162 
4163     /* Wait for OFNE flag to be raised */
4164     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4165     do
4166     {
4167       count-- ;
4168       if (count == 0U)
4169       {
4170         /* Disable the CRYP peripheral clock */
4171         __HAL_CRYP_DISABLE(hcryp);
4172 
4173         /* Change state */
4174         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4175         hcryp->State = HAL_CRYP_STATE_READY;
4176 
4177         /* Process unlocked */
4178         __HAL_UNLOCK(hcryp);
4179 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4180         /*Call registered error callback*/
4181         hcryp->ErrorCallback(hcryp);
4182 #else
4183         /*Call legacy weak error callback*/
4184         HAL_CRYP_ErrorCallback(hcryp);
4185 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4186       }
4187     }
4188     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
4189 
4190     /*Read the output block from the output FIFO */
4191     for (index = 0U; index < 4U; index++)
4192     {
4193       /* Read the output block from the output FIFO and put them in temporary buffer
4194       then get CrypOutBuff from temporary buffer */
4195       temp[index] = hcryp->Instance->DOUT;
4196     }
4197     for (index = 0; index < lastwordsize; index++)
4198     {
4199       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
4200       hcryp->CrypOutCount++;
4201     }
4202 
4203     /* Change the CRYP state to ready */
4204     hcryp->State = HAL_CRYP_STATE_READY;
4205 
4206     /* Process unlocked */
4207     __HAL_UNLOCK(hcryp);
4208   }
4209 
4210   /* Return function status */
4211   return HAL_OK;
4212 }
4213 
4214 /**
4215   * @brief  Sets the payload phase in interrupt mode
4216   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4217   *         the configuration information for CRYP module
4218   * @retval state
4219   */
4220 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
4221 {
4222   uint32_t loopcounter;
4223   uint32_t temp[4];  /* Temporary CrypOutBuff */
4224   uint32_t lastwordsize;
4225   uint32_t npblb;
4226   uint32_t temp_cr_algodir;
4227   uint8_t negative = 0U;
4228   uint32_t i;
4229 
4230   /***************************** Payload phase *******************************/
4231 
4232   if ((hcryp->Size / 4U) < hcryp->CrypInCount)
4233   {
4234     negative = 1U;
4235   }
4236 
4237   if (hcryp->Size == 0U)
4238   {
4239     /* Disable interrupts */
4240     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4241 
4242     /* Process unlocked */
4243     __HAL_UNLOCK(hcryp);
4244 
4245     /* Change the CRYP state */
4246     hcryp->State = HAL_CRYP_STATE_READY;
4247   }
4248 
4249   else if ((((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) &&
4250            (negative == 0U))
4251   {
4252     if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM) != 0x0U)
4253     {
4254       /* Write the input block in the IN FIFO */
4255       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4256       hcryp->CrypInCount++;
4257       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4258       hcryp->CrypInCount++;
4259       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4260       hcryp->CrypInCount++;
4261       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4262       hcryp->CrypInCount++;
4263       if (((hcryp->Size / 4U) == hcryp->CrypInCount) && ((hcryp->Size % 16U) == 0U))
4264       {
4265         /* Disable interrupts */
4266         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4267         /* Call the input data transfer complete callback */
4268 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4269         /*Call registered Input complete callback*/
4270         hcryp->InCpltCallback(hcryp);
4271 #else
4272         /*Call legacy weak Input complete callback*/
4273         HAL_CRYP_InCpltCallback(hcryp);
4274 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4275       }
4276 
4277       if (hcryp->CrypOutCount < (hcryp->Size / 4U))
4278       {
4279         if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4280         {
4281           /* Read the output block from the Output FIFO and put them in temporary buffer
4282           then get CrypOutBuff from temporary buffer  */
4283           for (i = 0U; i < 4U; i++)
4284           {
4285             temp[i] = hcryp->Instance->DOUT;
4286           }
4287           i = 0U;
4288           while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
4289           {
4290             *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4291             hcryp->CrypOutCount++;
4292             i++;
4293           }
4294           if (((hcryp->Size / 4U) == hcryp->CrypOutCount) && ((hcryp->Size % 16U) == 0U))
4295           {
4296             /* Disable interrupts */
4297             __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
4298 
4299             /* Change the CRYP state */
4300             hcryp->State = HAL_CRYP_STATE_READY;
4301 
4302             /* Disable CRYP */
4303             __HAL_CRYP_DISABLE(hcryp);
4304 
4305             /* Process unlocked */
4306             __HAL_UNLOCK(hcryp);
4307 
4308             /* Call output transfer complete callback */
4309 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4310             /*Call registered Output complete callback*/
4311             hcryp->OutCpltCallback(hcryp);
4312 #else
4313             /*Call legacy weak Output complete callback*/
4314             HAL_CRYP_OutCpltCallback(hcryp);
4315 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4316           }
4317         }
4318       }
4319     }
4320   }
4321   else if ((hcryp->Size % 16U) != 0U)
4322   {
4323     /* Set padding only in case of input fifo interrupt */
4324     if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM) != 0x0U)
4325     {
4326       /* Compute the number of padding bytes in last block of payload */
4327       npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4328 
4329 #if !defined (CRYP_VER_2_2)
4330       if (hcryp->Version >= REV_ID_B)
4331 #endif /*End of not defined CRYP_VER_2_2*/
4332       {
4333         /* Set Npblb in case of AES GCM payload encryption and CCM decryption to get right tag */
4334         temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
4335 
4336         if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
4337             ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4338         {
4339           /* Disable the CRYP */
4340           __HAL_CRYP_DISABLE(hcryp);
4341 
4342           /* Specify the number of non-valid bytes using NPBLB register*/
4343           MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4344 
4345           /* Enable CRYP to start the final phase */
4346           __HAL_CRYP_ENABLE(hcryp);
4347         }
4348       }
4349 
4350       /* Number of valid words (lastwordsize) in last block */
4351       if ((npblb % 4U) == 0U)
4352       {
4353         lastwordsize = (16U - npblb) / 4U;
4354       }
4355       else
4356       {
4357         lastwordsize = ((16U - npblb) / 4U) + 1U;
4358       }
4359 
4360       /* Write the last input block in the IN FIFO */
4361       for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4362       {
4363         hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4364         hcryp->CrypInCount++;
4365       }
4366       /* Pad the data with zeros to have a complete block */
4367       while (loopcounter < 4U)
4368       {
4369         hcryp->Instance->DIN  = 0U;
4370         loopcounter++;
4371       }
4372 
4373       /* Disable the input FIFO Interrupt */
4374       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4375     }
4376 
4377     /*Read the output block from the output FIFO */
4378     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4379     {
4380       for (i = 0U; i < 4U; i++)
4381       {
4382         temp[i] = hcryp->Instance->DOUT;
4383       }
4384       if (((hcryp->Size) / 4U) == 0U)
4385       {
4386         for (i = 0U; (uint16_t)i < ((hcryp->Size) % 4U); i++)
4387         {
4388           *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4389           hcryp->CrypOutCount++;
4390         }
4391       }
4392       i = 0U;
4393       while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
4394       {
4395         *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4396         hcryp->CrypOutCount++;
4397         i++;
4398       }
4399     }
4400 
4401     /* Disable the output FIFO Interrupt */
4402     if (hcryp->CrypOutCount >= ((hcryp->Size) / 4U))
4403     {
4404       /* Disable interrupts */
4405       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI | CRYP_IT_INI);
4406 
4407       /* Change the CRYP peripheral state */
4408       hcryp->State = HAL_CRYP_STATE_READY;
4409 
4410       /* Process unlocked */
4411       __HAL_UNLOCK(hcryp);
4412 
4413       /* Call output transfer complete callback */
4414 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4415       /*Call registered Output complete callback*/
4416       hcryp->OutCpltCallback(hcryp);
4417 #else
4418       /*Call legacy weak Output complete callback*/
4419       HAL_CRYP_OutCpltCallback(hcryp);
4420 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4421     }
4422   }
4423   else
4424   {
4425     /* Nothing to do */
4426   }
4427 }
4428 
4429 
4430 /**
4431   * @brief  Sets the header phase in polling mode
4432   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4433   *         the configuration information for CRYP module(Header & HeaderSize)
4434   * @param  Timeout: Timeout value
4435   * @retval state
4436   */
4437 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4438 {
4439   uint32_t loopcounter;
4440   uint32_t size_in_bytes;
4441   uint32_t tmp;
4442   uint32_t mask[4] = {0x0U, 0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
4443 
4444   /***************************** Header phase for GCM/GMAC or CCM *********************************/
4445 
4446 
4447   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
4448   {
4449     size_in_bytes = hcryp->Init.HeaderSize * 4U;
4450   }
4451   else
4452   {
4453     size_in_bytes = hcryp->Init.HeaderSize;
4454   }
4455 
4456   if ((size_in_bytes != 0U))
4457   {
4458     /* Select header phase */
4459     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4460 
4461     /* Enable the CRYP peripheral */
4462     __HAL_CRYP_ENABLE(hcryp);
4463 
4464     /* If size_in_bytes is a multiple of blocks (a multiple of four 32-bits words ) */
4465     if ((size_in_bytes % 16U) == 0U)
4466     {
4467       /*  No padding */
4468       for (loopcounter = 0U; (loopcounter < (size_in_bytes / 4U)); loopcounter += 4U)
4469 
4470       {
4471         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4472         hcryp->CrypHeaderCount++ ;
4473         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4474         hcryp->CrypHeaderCount++ ;
4475         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4476         hcryp->CrypHeaderCount++ ;
4477         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4478         hcryp->CrypHeaderCount++ ;
4479 
4480         /* Wait for IFEM to be raised */
4481         if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4482         {
4483           /* Disable the CRYP peripheral clock */
4484           __HAL_CRYP_DISABLE(hcryp);
4485 
4486           /* Change state */
4487           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4488           hcryp->State = HAL_CRYP_STATE_READY;
4489 
4490           /* Process unlocked */
4491           __HAL_UNLOCK(hcryp);
4492           return HAL_ERROR;
4493         }
4494       }
4495     }
4496     else
4497     {
4498       /* Write header block in the IN FIFO without last block */
4499       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 16U) * 4U)); loopcounter += 4U)
4500       {
4501         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4502         hcryp->CrypHeaderCount++ ;
4503         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4504         hcryp->CrypHeaderCount++ ;
4505         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4506         hcryp->CrypHeaderCount++ ;
4507         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4508         hcryp->CrypHeaderCount++ ;
4509 
4510         /* Wait for IFEM to be raised */
4511         if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4512         {
4513           /* Disable the CRYP peripheral clock */
4514           __HAL_CRYP_DISABLE(hcryp);
4515 
4516           /* Change state */
4517           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4518           hcryp->State = HAL_CRYP_STATE_READY;
4519 
4520           /* Process unlocked */
4521           __HAL_UNLOCK(hcryp);
4522           return HAL_ERROR;
4523         }
4524       }
4525       /*  Last block optionally pad the data with zeros*/
4526       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 4U) % 4U)); loopcounter++)
4527       {
4528         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4529         hcryp->CrypHeaderCount++ ;
4530       }
4531       /* If the header size is a multiple of words */
4532       if ((size_in_bytes % 4U) == 0U)
4533       {
4534         /* Pad the data with zeros to have a complete block */
4535         while (loopcounter < 4U)
4536         {
4537           hcryp->Instance->DIN = 0x0U;
4538           loopcounter++;
4539         }
4540       }
4541       else
4542       {
4543         /* Enter last bytes, padded with zeroes */
4544         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4545         tmp &= mask[size_in_bytes % 4U];
4546         hcryp->Instance->DIN = tmp;
4547         loopcounter++;
4548         /* Pad the data with zeros to have a complete block */
4549         while (loopcounter < 4U)
4550         {
4551           hcryp->Instance->DIN = 0x0U;
4552           loopcounter++;
4553         }
4554       }
4555       /* Wait for CCF IFEM to be raised */
4556       if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4557       {
4558         /* Disable the CRYP peripheral clock */
4559         __HAL_CRYP_DISABLE(hcryp);
4560 
4561         /* Change state */
4562         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4563         hcryp->State = HAL_CRYP_STATE_READY;
4564 
4565         /* Process unlocked */
4566         __HAL_UNLOCK(hcryp);
4567         return HAL_ERROR;
4568       }
4569     }
4570     /* Wait until the complete message has been processed */
4571     if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
4572     {
4573       /* Disable the CRYP peripheral clock */
4574       __HAL_CRYP_DISABLE(hcryp);
4575 
4576       /* Change state */
4577       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4578       hcryp->State = HAL_CRYP_STATE_READY;
4579 
4580       /* Process unlocked & return error */
4581       __HAL_UNLOCK(hcryp);
4582       return HAL_ERROR;
4583     }
4584   }
4585   /* Return function status */
4586   return HAL_OK;
4587 }
4588 
4589 /**
4590   * @brief  Sets the header phase when using DMA in process
4591   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4592   *         the configuration information for CRYP module(Header & HeaderSize)
4593   * @retval None
4594   */
4595 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
4596 {
4597   __IO uint32_t count  = 0U;
4598   uint32_t loopcounter;
4599 
4600   /***************************** Header phase for GCM/GMAC or CCM *********************************/
4601   if ((hcryp->Init.HeaderSize != 0U))
4602   {
4603     /* Select header phase */
4604     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4605 
4606     /* Enable the CRYP peripheral */
4607     __HAL_CRYP_ENABLE(hcryp);
4608 
4609     if ((hcryp->Init.HeaderSize % 4U) == 0U)
4610     {
4611       /* HeaderSize %4, no padding */
4612       for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4613       {
4614         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4615         hcryp->CrypHeaderCount++ ;
4616         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4617         hcryp->CrypHeaderCount++ ;
4618         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4619         hcryp->CrypHeaderCount++ ;
4620         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4621         hcryp->CrypHeaderCount++ ;
4622 
4623         /* Wait for IFEM to be raised */
4624         count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4625         do
4626         {
4627           count-- ;
4628           if (count == 0U)
4629           {
4630             /* Disable the CRYP peripheral clock */
4631             __HAL_CRYP_DISABLE(hcryp);
4632 
4633             /* Change state */
4634             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4635             hcryp->State = HAL_CRYP_STATE_READY;
4636 
4637             /* Process unlocked */
4638             __HAL_UNLOCK(hcryp);
4639             return HAL_ERROR;
4640           }
4641         }
4642         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4643       }
4644     }
4645     else
4646     {
4647       /*Write header block in the IN FIFO without last block */
4648       for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U)));
4649            loopcounter += 4U)
4650       {
4651         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4652         hcryp->CrypHeaderCount++ ;
4653         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4654         hcryp->CrypHeaderCount++ ;
4655         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4656         hcryp->CrypHeaderCount++ ;
4657         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4658         hcryp->CrypHeaderCount++ ;
4659 
4660         /* Wait for IFEM to be raised */
4661         count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4662         do
4663         {
4664           count-- ;
4665           if (count == 0U)
4666           {
4667             /* Disable the CRYP peripheral clock */
4668             __HAL_CRYP_DISABLE(hcryp);
4669 
4670             /* Change state */
4671             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4672             hcryp->State = HAL_CRYP_STATE_READY;
4673 
4674             /* Process unlocked */
4675             __HAL_UNLOCK(hcryp);
4676             return HAL_ERROR;
4677           }
4678         }
4679         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4680       }
4681       /*  Last block optionally pad the data with zeros*/
4682       for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4683       {
4684         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4685         hcryp->CrypHeaderCount++ ;
4686       }
4687       while (loopcounter < 4U)
4688       {
4689         /* Pad the data with zeros to have a complete block */
4690         hcryp->Instance->DIN = 0x0U;
4691         loopcounter++;
4692       }
4693       /* Wait for IFEM to be raised */
4694       count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4695       do
4696       {
4697         count-- ;
4698         if (count == 0U)
4699         {
4700           /* Disable the CRYP peripheral clock */
4701           __HAL_CRYP_DISABLE(hcryp);
4702           /* Change state */
4703           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4704           hcryp->State = HAL_CRYP_STATE_READY;
4705           /* Process unlocked */
4706           __HAL_UNLOCK(hcryp);
4707           return HAL_ERROR;
4708         }
4709       }
4710       while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4711     }
4712     /* Wait until the complete message has been processed */
4713     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4714     do
4715     {
4716       count-- ;
4717       if (count == 0U)
4718       {
4719         /* Disable the CRYP peripheral clock */
4720         __HAL_CRYP_DISABLE(hcryp);
4721         /* Change state */
4722         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4723         hcryp->State = HAL_CRYP_STATE_READY;
4724         /* Process unlocked */
4725         __HAL_UNLOCK(hcryp);
4726         return HAL_ERROR;
4727       }
4728     }
4729     while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
4730   }
4731 
4732   /* Return function status */
4733   return HAL_OK;
4734 }
4735 
4736 /**
4737   * @brief  Sets the header phase in interrupt mode
4738   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4739   *         the configuration information for CRYP module(Header & HeaderSize)
4740   * @retval None
4741   */
4742 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
4743 {
4744   uint32_t loopcounter;
4745 
4746   /***************************** Header phase *********************************/
4747 
4748   if (hcryp->Init.HeaderSize ==  hcryp->CrypHeaderCount)
4749   {
4750     /* Disable interrupts */
4751     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4752 
4753     /* Disable the CRYP peripheral */
4754     __HAL_CRYP_DISABLE(hcryp);
4755 
4756 #if !defined (CRYP_VER_2_2)
4757     if (hcryp->Version >= REV_ID_B)
4758 #endif /*End of not defined CRYP_VER_2_2*/
4759     {
4760       /* Set to 0 the number of non-valid bytes using NPBLB register*/
4761       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4762     }
4763 
4764     /* Set the phase */
4765     hcryp->Phase = CRYP_PHASE_PROCESS;
4766 
4767     /* Select payload phase once the header phase is performed */
4768     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4769 
4770     /* Enable Interrupts */
4771     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4772 
4773     /* Enable the CRYP peripheral */
4774     __HAL_CRYP_ENABLE(hcryp);
4775   }
4776   else if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U)
4777 
4778   {
4779     /* HeaderSize %4, no padding */
4780     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4781     hcryp->CrypHeaderCount++ ;
4782     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4783     hcryp->CrypHeaderCount++  ;
4784     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4785     hcryp->CrypHeaderCount++ ;
4786     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4787     hcryp->CrypHeaderCount++ ;
4788   }
4789   else
4790   {
4791     /*  Last block optionally pad the data with zeros*/
4792     for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
4793     {
4794       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4795       hcryp->CrypHeaderCount++ ;
4796     }
4797     while (loopcounter < 4U)
4798     {
4799       /* Pad the data with zeros to have a complete block */
4800       hcryp->Instance->DIN = 0x0U;
4801       loopcounter++;
4802     }
4803   }
4804 }
4805 
4806 #if !defined (CRYP_VER_2_2)
4807 /**
4808   * @brief  Workaround used for GCM/CCM mode.
4809   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4810   *         the configuration information for CRYP module
4811   * @param  Timeout: Timeout value
4812   * @retval None
4813   */
4814 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4815 {
4816   uint32_t  iv1temp;
4817   uint32_t  temp[4] = {0};
4818   uint32_t  temp2[4] = {0};
4819   uint32_t intermediate_data[4] = {0};
4820   uint32_t index;
4821   uint32_t lastwordsize;
4822   uint32_t npblb;
4823 
4824   /* Compute the number of padding bytes in last block of payload */
4825   npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4826 
4827   /* Number of valid words (lastwordsize) in last block */
4828   if ((npblb % 4U) == 0U)
4829   {
4830     lastwordsize = (16U - npblb) / 4U;
4831   }
4832   else
4833   {
4834     lastwordsize = ((16U - npblb) / 4U) + 1U;
4835   }
4836 
4837   /* Workaround 2, case GCM encryption */
4838   if (hcryp->Init.Algorithm == CRYP_AES_GCM)
4839   {
4840     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4841     {
4842       /*Workaround in order to properly compute authentication tags while doing
4843        a GCM encryption with the last block of payload size inferior to 128 bits*/
4844       /* Disable CRYP to start the final phase */
4845       __HAL_CRYP_DISABLE(hcryp);
4846 
4847       /*Update CRYP_IV1R register and ALGOMODE*/
4848       hcryp->Instance->IV1RR = ((hcryp->Instance->CSGCMCCM7R) - 1U);
4849       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
4850 
4851       /* Enable CRYP to start the final phase */
4852       __HAL_CRYP_ENABLE(hcryp);
4853     }
4854 
4855     for (index = 0; index < lastwordsize ; index ++)
4856     {
4857       /* Write the last input block in the IN FIFO */
4858       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4859       hcryp->CrypInCount++;
4860     }
4861     while (index < 4U)
4862     {
4863       /* Pad the data with zeros to have a complete block */
4864       hcryp->Instance->DIN  = 0U;
4865       index++;
4866     }
4867     /* Wait for OFNE flag to be raised */
4868     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4869     {
4870       /* Disable the CRYP peripheral clock */
4871       __HAL_CRYP_DISABLE(hcryp);
4872 
4873       /* Change state */
4874       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4875       hcryp->State = HAL_CRYP_STATE_READY;
4876 
4877       /* Process Unlocked */
4878       __HAL_UNLOCK(hcryp);
4879 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4880       /*Call registered error callback*/
4881       hcryp->ErrorCallback(hcryp);
4882 #else
4883       /*Call legacy weak error callback*/
4884       HAL_CRYP_ErrorCallback(hcryp);
4885 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4886     }
4887     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4888     {
4889       for (index = 0U; index < 4U; index++)
4890       {
4891         /* Read the output block from the output FIFO */
4892         intermediate_data[index] = hcryp->Instance->DOUT;
4893 
4894         /* Intermediate data buffer to be used in for the workaround*/
4895         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
4896         hcryp->CrypOutCount++;
4897       }
4898     }
4899 
4900     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4901     {
4902       /*workaround in order to properly compute authentication tags while doing
4903       a GCM encryption with the last block of payload size inferior to 128 bits*/
4904       /* Change the AES mode to GCM mode and Select Final phase */
4905       /* configured  CHMOD GCM   */
4906       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_GCM);
4907 
4908       /* configured  final phase  */
4909       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
4910 
4911       if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_NO_SWAP)
4912       {
4913         if ((npblb % 4U) == 1U)
4914         {
4915           intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
4916         }
4917         if ((npblb % 4U) == 2U)
4918         {
4919           intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
4920         }
4921         if ((npblb % 4U) == 3U)
4922         {
4923           intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
4924         }
4925       }
4926       else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_BYTE_SWAP)
4927       {
4928         if ((npblb % 4U) == 1U)
4929         {
4930           intermediate_data[lastwordsize - 1U] &= __REV(0xFFFFFF00U);
4931         }
4932         if ((npblb % 4U) == 2U)
4933         {
4934           intermediate_data[lastwordsize - 1U] &= __REV(0xFFFF0000U);
4935         }
4936         if ((npblb % 4U) == 3U)
4937         {
4938           intermediate_data[lastwordsize - 1U] &= __REV(0xFF000000U);
4939         }
4940       }
4941       else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_HALFWORD_SWAP)
4942       {
4943         if ((npblb % 4U) == 1U)
4944         {
4945           intermediate_data[lastwordsize - 1U] &= __ROR((0xFFFFFF00U), 16);
4946         }
4947         if ((npblb % 4U) == 2U)
4948         {
4949           intermediate_data[lastwordsize - 1U] &= __ROR((0xFFFF0000U), 16);
4950         }
4951         if ((npblb % 4U) == 3U)
4952         {
4953           intermediate_data[lastwordsize - 1U] &= __ROR((0xFF000000U), 16);
4954         }
4955       }
4956       else /*CRYP_BIT_SWAP*/
4957       {
4958         if ((npblb % 4U) == 1U)
4959         {
4960           intermediate_data[lastwordsize - 1U] &= __RBIT(0xFFFFFF00U);
4961         }
4962         if ((npblb % 4U) == 2U)
4963         {
4964           intermediate_data[lastwordsize - 1U] &= __RBIT(0xFFFF0000U);
4965         }
4966         if ((npblb % 4U) == 3U)
4967         {
4968           intermediate_data[lastwordsize - 1U] &= __RBIT(0xFF000000U);
4969         }
4970       }
4971 
4972       for (index = 0U; index < lastwordsize ; index ++)
4973       {
4974         /*Write the intermediate_data in the IN FIFO */
4975         hcryp->Instance->DIN = intermediate_data[index];
4976       }
4977       while (index < 4U)
4978       {
4979         /* Pad the data with zeros to have a complete block */
4980         hcryp->Instance->DIN  = 0x0U;
4981         index++;
4982       }
4983       /* Wait for OFNE flag to be raised */
4984       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4985       {
4986         /* Disable the CRYP peripheral clock */
4987         __HAL_CRYP_DISABLE(hcryp);
4988 
4989         /* Change state */
4990         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4991         hcryp->State = HAL_CRYP_STATE_READY;
4992 
4993         /* Process unlocked */
4994         __HAL_UNLOCK(hcryp);
4995 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4996         /*Call registered error callback*/
4997         hcryp->ErrorCallback(hcryp);
4998 #else
4999         /*Call legacy weak error callback*/
5000         HAL_CRYP_ErrorCallback(hcryp);
5001 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5002       }
5003 
5004       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
5005       {
5006         for (index = 0U; index < 4U; index++)
5007         {
5008           intermediate_data[index] = hcryp->Instance->DOUT;
5009         }
5010       }
5011     }
5012   } /* End of GCM encryption */
5013   else
5014   {
5015     /* Workaround 2, case CCM decryption, in order to properly compute
5016       authentication tags while doing a CCM decryption with the last block
5017       of payload size inferior to 128 bits*/
5018 
5019     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
5020     {
5021       iv1temp = hcryp->Instance->CSGCMCCM7R;
5022 
5023       /* Disable CRYP to start the final phase */
5024       __HAL_CRYP_DISABLE(hcryp);
5025 
5026       temp[0] =  hcryp->Instance->CSGCMCCM0R;
5027       temp[1] =  hcryp->Instance->CSGCMCCM1R;
5028       temp[2] =  hcryp->Instance->CSGCMCCM2R;
5029       temp[3] =  hcryp->Instance->CSGCMCCM3R;
5030 
5031       hcryp->Instance->IV1RR = iv1temp;
5032 
5033       /* Configured  CHMOD CTR   */
5034       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
5035 
5036       /* Enable CRYP to start the final phase */
5037       __HAL_CRYP_ENABLE(hcryp);
5038     }
5039     /*  Last block optionally pad the data with zeros*/
5040     for (index = 0U; index < lastwordsize; index ++)
5041     {
5042       /* Write the last Input block in the IN FIFO */
5043       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5044       hcryp->CrypInCount++;
5045     }
5046     while (index < 4U)
5047     {
5048       /* Pad the data with zeros to have a complete block */
5049       hcryp->Instance->DIN  = 0U;
5050       index++;
5051     }
5052     /* Wait for OFNE flag to be raised */
5053     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
5054     {
5055       /* Disable the CRYP peripheral clock */
5056       __HAL_CRYP_DISABLE(hcryp);
5057 
5058       /* Change state */
5059       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5060       hcryp->State = HAL_CRYP_STATE_READY;
5061 
5062       /* Process Unlocked */
5063       __HAL_UNLOCK(hcryp);
5064 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5065       /*Call registered error callback*/
5066       hcryp->ErrorCallback(hcryp);
5067 #else
5068       /*Call legacy weak error callback*/
5069       HAL_CRYP_ErrorCallback(hcryp);
5070 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5071     }
5072 
5073     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
5074     {
5075       for (index = 0U; index < 4U; index++)
5076       {
5077         /* Read the Output block from the Output FIFO */
5078         intermediate_data[index] = hcryp->Instance->DOUT;
5079 
5080         /*intermediate data buffer to be used in for the workaround*/
5081         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
5082         hcryp->CrypOutCount++;
5083       }
5084     }
5085 
5086     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
5087     {
5088       temp2[0] =  hcryp->Instance->CSGCMCCM0R;
5089       temp2[1] =  hcryp->Instance->CSGCMCCM1R;
5090       temp2[2] =  hcryp->Instance->CSGCMCCM2R;
5091       temp2[3] =  hcryp->Instance->CSGCMCCM3R;
5092 
5093       /* configured  CHMOD CCM   */
5094       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CCM);
5095 
5096       /* configured  Header phase  */
5097       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_HEADER);
5098 
5099       /*set to zero the bits corresponding to the padded bits*/
5100       for (index = lastwordsize; index < 4U; index ++)
5101       {
5102         intermediate_data[index] = 0U;
5103       }
5104 
5105       if ((npblb % 4U) == 1U)
5106       {
5107         intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
5108       }
5109       if ((npblb % 4U) == 2U)
5110       {
5111         intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
5112       }
5113       if ((npblb % 4U) == 3U)
5114       {
5115         intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
5116       }
5117 
5118       for (index = 0U; index < 4U ; index ++)
5119       {
5120         intermediate_data[index] ^=  temp[index];
5121         intermediate_data[index] ^=  temp2[index];
5122       }
5123       for (index = 0U; index < 4U; index ++)
5124       {
5125         /* Write the last Input block in the IN FIFO */
5126         hcryp->Instance->DIN  = intermediate_data[index] ;
5127       }
5128 
5129       /* Wait for BUSY flag to be raised */
5130       if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
5131       {
5132         /* Disable the CRYP peripheral clock */
5133         __HAL_CRYP_DISABLE(hcryp);
5134 
5135         /* Change state */
5136         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5137         hcryp->State = HAL_CRYP_STATE_READY;
5138 
5139         /* Process Unlocked */
5140         __HAL_UNLOCK(hcryp);
5141 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5142         /*Call registered error callback*/
5143         hcryp->ErrorCallback(hcryp);
5144 #else
5145         /*Call legacy weak error callback*/
5146         HAL_CRYP_ErrorCallback(hcryp);
5147 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5148       }
5149     }
5150   } /* End of CCM WKA*/
5151 
5152   /* Process Unlocked */
5153   __HAL_UNLOCK(hcryp);
5154 }
5155 #endif /*End of not defined CRYP_VER_2_2*/
5156 
5157 /**
5158   * @brief  Handle CRYP hardware block Timeout when waiting for IFEM flag to be raised.
5159   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5160   *         the configuration information for CRYP module.
5161   * @param  Timeout: Timeout duration.
5162   * @retval HAL status
5163   */
5164 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5165 {
5166   uint32_t tickstart;
5167 
5168   /* Get timeout */
5169   tickstart = HAL_GetTick();
5170 
5171   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
5172   {
5173     /* Check for the Timeout */
5174     if (Timeout != HAL_MAX_DELAY)
5175     {
5176       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5177       {
5178         return HAL_ERROR;
5179       }
5180     }
5181   }
5182   return HAL_OK;
5183 }
5184 /**
5185   * @brief  Handle CRYP hardware block Timeout when waiting for BUSY flag to be raised.
5186   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5187   *         the configuration information for CRYP module.
5188   * @param  Timeout: Timeout duration.
5189   * @retval HAL status
5190   */
5191 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5192 {
5193   uint32_t tickstart;
5194 
5195   /* Get timeout */
5196   tickstart = HAL_GetTick();
5197 
5198   while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY))
5199   {
5200     /* Check for the Timeout */
5201     if (Timeout != HAL_MAX_DELAY)
5202     {
5203       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5204       {
5205         return HAL_ERROR;
5206       }
5207     }
5208   }
5209   return HAL_OK;
5210 }
5211 
5212 
5213 /**
5214   * @brief  Handle CRYP hardware block Timeout when waiting for OFNE flag to be raised.
5215   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5216   *         the configuration information for CRYP module.
5217   * @param  Timeout: Timeout duration.
5218   * @retval HAL status
5219   */
5220 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef  *hcryp, uint32_t Timeout)
5221 {
5222   uint32_t tickstart;
5223 
5224   /* Get timeout */
5225   tickstart = HAL_GetTick();
5226 
5227   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
5228   {
5229     /* Check for the Timeout */
5230     if (Timeout != HAL_MAX_DELAY)
5231     {
5232       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5233       {
5234         return HAL_ERROR;
5235       }
5236     }
5237   }
5238   return HAL_OK;
5239 }
5240 
5241 
5242 /**
5243   * @}
5244   */
5245 
5246 
5247 
5248 /**
5249   * @}
5250   */
5251 
5252 #endif /* HAL_CRYP_MODULE_ENABLED */
5253 
5254 
5255 /**
5256   * @}
5257   */
5258 #endif /* CRYP */
5259 /**
5260   * @}
5261   */
5262