1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_cryp.c
4   * @author  MCD Application Team
5   * @brief   CRYP HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Cryptography (CRYP) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + AES processing functions
10   *           + DES processing functions
11   *           + TDES processing functions
12   *           + DMA callback functions
13   *           + CRYP IRQ handler management
14   *           + Peripheral State functions
15   *
16   ******************************************************************************
17   * @attention
18   *
19   * Copyright (c) 2017 STMicroelectronics.
20   * All rights reserved.
21   *
22   * This software is licensed under terms that can be found in the LICENSE file
23   * in the root directory of this software component.
24   * If no LICENSE file comes with this software, it is provided AS-IS.
25   *
26   ******************************************************************************
27   @verbatim
28   ==============================================================================
29                      ##### How to use this driver #####
30   ==============================================================================
31     [..]
32       The CRYP HAL driver can be used in CRYP IP as follows:
33 
34       (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
35          (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
36          (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
37              (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
38              (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
39              (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
40          (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
41              (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
42              (+++) Configure and enable two DMA streams one for managing data transfer from
43                  memory to peripheral (input stream) and another stream for managing data
44                  transfer from peripheral to memory (output stream)
45              (+++) Associate the initialized DMA handle to the CRYP DMA handle
46                  using  __HAL_LINKDMA()
47              (+++) Configure the priority and enable the NVIC for the transfer complete
48                  interrupt on the two DMA Streams. The output stream should have higher
49                  priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
50 
51       (#)Initialize the CRYP according to the specified parameters :
52          (##) The data type: bit swap(1-bit data), byte swap(8-bit data), half word swap(16-bit data)
53             or no swap(32-bit data).
54          (##) The key size: 128, 192 or 256.
55          (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM.
56          (##) The initialization vector (counter). It is not used in ECB mode.
57          (##) The key buffer used for encryption/decryption.
58          (##) The Header used only in AES GCM and CCM Algorithm for authentication.
59          (##) The HeaderSize The size of header buffer in word.
60          (##) The B0 block is the first authentication block used only  in AES CCM mode.
61 
62       (#)Three processing (encryption/decryption) functions are available:
63          (##) Polling mode: encryption and decryption APIs are blocking functions
64               i.e. they process the data and wait till the processing is finished,
65               e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
66          (##) Interrupt mode: encryption and decryption APIs are not blocking functions
67               i.e. they process the data under interrupt,
68               e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
69          (##) DMA mode: encryption and decryption APIs are not blocking functions
70               i.e. the data transfer is ensured by DMA,
71               e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
72 
73       (#)When the processing function is called at first time after HAL_CRYP_Init()
74          the CRYP peripheral is configured and processes the buffer in input.
75          At second call, no need to Initialize the CRYP, user have to get current configuration via
76          HAL_CRYP_GetConfig() API, then only  HAL_CRYP_SetConfig() is requested to set
77          new parameters, finally user can  start encryption/decryption.
78 
79        (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
80 
81        (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
82           without having to configure again the Key or the Initialization Vector between each API call,
83           the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
84           Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
85           or HAL_CRYP_Decrypt_DMA().
86 
87     [..]
88       The cryptographic processor supports following standards:
89       (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 IP:
90          (##)64-bit data block processing
91          (##) chaining modes supported :
92              (+++)  Electronic Code Book(ECB)
93              (+++)  Cipher Block Chaining (CBC)
94          (##) keys length supported :64-bit, 128-bit and 192-bit.
95       (#) The advanced encryption standard (AES) supported  by CRYP1:
96          (##)128-bit data block processing
97          (##) chaining modes supported :
98              (+++)  Electronic Code Book(ECB)
99              (+++)  Cipher Block Chaining (CBC)
100              (+++)  Counter mode (CTR)
101              (+++)  Galois/counter mode (GCM/GMAC)
102              (+++)  Counter with Cipher Block Chaining-Message(CCM)
103          (##) keys length Supported :
104              (+++) for CRYP1 IP: 128-bit, 192-bit and 256-bit.
105 
106     [..]  This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 IP:
107       (#)  Algorithm supported :
108          (##) Galois/counter mode (GCM)
109          (##) Galois message authentication code (GMAC) :is exactly the same as
110               GCM algorithm composed only by an header.
111       (#)  Four phases are performed in GCM :
112          (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
113          (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
114           computation only.
115          (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
116           encryption + data XORing. It works in a similar way for ciphertext (C).
117          (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
118           HAL_CRYPEx_AESGCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond
119           to the Tag. user should consider only part of this 4 words, if Tag length is less than 128 bits.
120       (#)  structure of message construction in GCM is defined as below  :
121          (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
122          (##) The authenticated header A (also knows as Additional Authentication Data AAD)
123           this part of the message is only authenticated, not encrypted.
124          (##) The plaintext message P is both authenticated and encrypted as ciphertext.
125           GCM standard specifies that ciphertext has same bit length as the plaintext.
126          (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
127           (on 64 bits)
128 
129     [..]  This section describe The AES Counter with Cipher Block Chaining-Message
130           Authentication Code (CCM) supported by both CRYP1 IP:
131       (#)  Specific parameters for CCM  :
132 
133          (##) B0 block  : According to NIST Special Publication 800-38C,
134             The first block B0 is formatted as follows, where l(m) is encoded in
135             most-significant-byte first order(see below table 3)
136 
137               (+++)  Q: a bit string representation of the octet length of P (plaintext)
138               (+++)  q The octet length of the binary representation of the octet length of the payload
139               (+++)  A nonce (N), n The octet length of the where n+q=15.
140               (+++)  Flags: most significant octet containing four flags for control information,
141               (+++)  t The octet length of the MAC.
142          (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
143               the associated data length expressed in bytes (a) defined as below:
144             (+++)  If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
145             (+++)  If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
146             (+++)  If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
147          (##) CTRx block  : control blocks
148             (+++) Generation of CTR1 from first block B0 information :
149               equal to B0 with first 5 bits zeroed and most significant bits storing octet
150               length of P also zeroed, then incremented by one ( see below Table 4)
151             (+++) Generation of CTR0: same as CTR1 with bit[0] set to zero.
152 
153       (#)  Four phases are performed in CCM for CRYP1 IP:
154          (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
155          (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
156           computation only.
157          (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
158           encryption + data XORing. It works in a similar way for ciphertext (C).
159          (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
160          HAL_CRYPEx_AESCCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond to the Tag.
161          user should consider only part of this 4 words, if Tag length is less than 128 bits
162 
163   *** Callback registration ***
164   =============================
165 
166   [..]
167   The compilation define  USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
168   allows the user to configure dynamically the driver callbacks.
169   Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
170   to register an interrupt callback.
171 
172   [..]
173   Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
174     (+) InCpltCallback     :  Input FIFO transfer completed callback.
175     (+) OutCpltCallback    : Output FIFO transfer completed callback.
176     (+) ErrorCallback      : callback for error detection.
177     (+) MspInitCallback    : CRYP MspInit.
178     (+) MspDeInitCallback  : CRYP MspDeInit.
179   This function takes as parameters the HAL peripheral handle, the Callback ID
180   and a pointer to the user callback function.
181 
182   [..]
183   Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
184   weak function.
185   @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
186   and the Callback ID.
187   This function allows to reset following callbacks:
188     (+) InCpltCallback     :  Input FIFO transfer completed callback.
189     (+) OutCpltCallback    : Output FIFO transfer completed callback.
190     (+) ErrorCallback      : callback for error detection.
191     (+) MspInitCallback    : CRYP MspInit.
192     (+) MspDeInitCallback  : CRYP MspDeInit.
193 
194   [..]
195   By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
196   all callbacks are set to the corresponding weak functions :
197   examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
198   Exception done for MspInit and MspDeInit functions that are
199   reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
200   these callbacks are null (not registered beforehand).
201   if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
202   keep and use the user MspInit/MspDeInit functions (registered beforehand)
203 
204   [..]
205   Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
206   Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
207   in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
208   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
209   In that case first register the MspInit/MspDeInit user callbacks
210   using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
211   or @ref HAL_CRYP_Init() function.
212 
213   [..]
214   When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
215   not defined, the callback registration feature is not available and all callbacks
216   are set to the corresponding weak functions.
217 
218   @endverbatim
219 
220   Table 1. Initial Counter Block (ICB)
221           +-------------------------------------------------------+
222           |       Initialization vector (IV)      |  Counter      |
223           |----------------|----------------|-----------|---------|
224          127              95                63            31       0
225 
226 
227               Bit Number    Register           Contents
228               ----------   ---------------       -----------
229               127 ...96    CRYP_IV1R[31:0]     ICB[127:96]
230               95  ...64    CRYP_IV1L[31:0]     B0[95:64]
231               63 ... 32    CRYP_IV0R[31:0]     ICB[63:32]
232               31 ... 0     CRYP_IV0L[31:0]     ICB[31:0], where 32-bit counter= 0x2
233 
234   Table 2.  GCM last block definition
235 
236           +-------------------------------------------------------------------+
237           |  Bit[0]   |  Bit[32]           |  Bit[64]  | Bit[96]              |
238           |-----------|--------------------|-----------|----------------------|
239           |   0x0     | Header length[31:0]|     0x0   | Payload length[31:0] |
240           |-----------|--------------------|-----------|----------------------|
241 
242   Table 3. B0 block
243                 Octet Number   Contents
244                 ------------   ---------
245                 0              Flags
246                 1 ... 15-q     Nonce N
247                 16-q ... 15    Q
248 
249             the Flags field is formatted as follows:
250 
251                 Bit Number   Contents
252                 ----------   ----------------------
253                 7            Reserved (always zero)
254                 6            Adata
255                 5 ... 3      (t-2)/2
256                 2 ... 0      [q-1]3
257 
258  Table 4. CTRx block
259                 Bit Number    Register           Contents
260                 ----------   ---------------       -----------
261                 127 ...96    CRYP_IV1R[31:0]     B0[127:96], where Q length bits are set to 0, except for
262                                                  bit 0 that is set to 1
263                 95  ...64    CRYP_IV1L[31:0]     B0[95:64]
264                 63 ... 32    CRYP_IV0R[31:0]     B0[63:32]
265                 31 ... 0     CRYP_IV0L[31:0]     B0[31:0], where flag bits set to 0
266   */
267 
268 /* Includes ------------------------------------------------------------------*/
269 #include "stm32h7xx_hal.h"
270 
271 /** @addtogroup STM32H7xx_HAL_Driver
272   * @{
273   */
274 
275 #if defined (CRYP)
276 
277 /** @defgroup CRYP CRYP
278   * @brief CRYP HAL module driver.
279   * @{
280   */
281 
282 
283 #ifdef HAL_CRYP_MODULE_ENABLED
284 
285 /* Private typedef -----------------------------------------------------------*/
286 /* Private define ------------------------------------------------------------*/
287 /** @addtogroup CRYP_Private_Defines
288   * @{
289   */
290 #define CRYP_TIMEOUT_KEYPREPARATION      82U         /*!<  The latency of key preparation operation is 82 clock cycles.*/
291 #define CRYP_TIMEOUT_GCMCCMINITPHASE     299U        /*!<  The latency of  GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
292 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE   290U        /*!<  The latency of  GCM/CCM header phase is 290 clock cycles.*/
293 
294 #define  CRYP_PHASE_READY                0x00000001U /*!< CRYP peripheral is ready for initialization. */
295 #define  CRYP_PHASE_PROCESS              0x00000002U /*!< CRYP peripheral is in processing phase */
296 
297 #define CRYP_PHASE_INIT                  0x00000000U             /*!< GCM/GMAC (or CCM) init phase */
298 #define CRYP_PHASE_HEADER                CRYP_CR_GCM_CCMPH_0     /*!< GCM/GMAC or CCM header phase */
299 #define CRYP_PHASE_PAYLOAD               CRYP_CR_GCM_CCMPH_1     /*!< GCM(/CCM) payload phase      */
300 #define CRYP_PHASE_FINAL                 CRYP_CR_GCM_CCMPH       /*!< GCM/GMAC or CCM  final phase */
301 #define CRYP_OPERATINGMODE_ENCRYPT       0x00000000U             /*!< Encryption mode   */
302 #define CRYP_OPERATINGMODE_DECRYPT       CRYP_CR_ALGODIR         /*!< Decryption        */
303 
304 
305 /*  CTR1 information to use in CCM algorithm */
306 #define CRYP_CCM_CTR1_0                  0x07FFFFFFU
307 #define CRYP_CCM_CTR1_1                  0xFFFFFF00U
308 #define CRYP_CCM_CTR1_2                  0x00000001U
309 
310 /**
311   * @}
312   */
313 
314 
315 /* Private macro -------------------------------------------------------------*/
316 /** @addtogroup CRYP_Private_Macros
317   * @{
318   */
319 
320 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__)  do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\
321                                                         (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
322                                                        }while(0)
323 
324 #define HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |=  CRYP_CR_FFLUSH)
325 
326 
327 /**
328   * @}
329   */
330 
331 /* Private struct -------------------------------------------------------------*/
332 /* Private variables ---------------------------------------------------------*/
333 /* Private function prototypes -----------------------------------------------*/
334 /** @addtogroup CRYP_Private_Functions_Prototypes
335   * @{
336   */
337 
338 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
339 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
340 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
341 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
342 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
343 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
344 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
345 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
346 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
347 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
348 #if !defined (CRYP_VER_2_2)
349 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
350 #endif /*End of not defined CRYP_VER_2_2*/
351 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
352 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
353 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
354 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
355 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
356 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
357 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
358 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
359 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
360 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
361 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
362 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
363 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp);
364 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
365 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
366 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
367 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
368 
369 /**
370   * @}
371   */
372 
373 /* Exported functions ---------------------------------------------------------*/
374 
375 /** @defgroup CRYP_Exported_Functions CRYP Exported Functions
376   * @{
377   */
378 
379 
380 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
381   *  @brief    CRYP  Initialization and Configuration functions.
382   *
383 @verbatim
384   ========================================================================================
385      ##### Initialization, de-initialization and Set and Get configuration functions #####
386   ========================================================================================
387     [..]  This section provides functions allowing to:
388       (+) Initialize the CRYP
389       (+) DeInitialize the CRYP
390       (+) Initialize the CRYP MSP
391       (+) DeInitialize the CRYP MSP
392       (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
393           Parameters which are configured in This section are :
394           (++) Key size
395           (++) Data Type : 32,16, 8 or 1bit
396           (++) AlgoMode : for CRYP1 IP
397                  ECB and CBC in DES/TDES Standard
398                  ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
399       (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
400 
401 
402 @endverbatim
403   * @{
404   */
405 
406 
407 /**
408   * @brief  Initializes the CRYP according to the specified
409   *         parameters in the CRYP_ConfigTypeDef and creates the associated handle.
410   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
411   *         the configuration information for CRYP module
412   * @retval HAL status
413   */
HAL_CRYP_Init(CRYP_HandleTypeDef * hcryp)414 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
415 {
416   /* Check the CRYP handle allocation */
417   if (hcryp == NULL)
418   {
419     return HAL_ERROR;
420   }
421 
422   /* Check parameters */
423   assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
424   assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
425   assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
426   assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
427 
428 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
429   if (hcryp->State == HAL_CRYP_STATE_RESET)
430   {
431     /* Allocate lock resource and initialize it */
432     hcryp->Lock = HAL_UNLOCKED;
433 
434     hcryp->InCpltCallback  = HAL_CRYP_InCpltCallback;  /* Legacy weak  InCpltCallback  */
435     hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback  */
436     hcryp->ErrorCallback   = HAL_CRYP_ErrorCallback;   /* Legacy weak ErrorCallback    */
437 
438     if (hcryp->MspInitCallback == NULL)
439     {
440       hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit  */
441     }
442 
443     /* Init the low level hardware */
444     hcryp->MspInitCallback(hcryp);
445   }
446 #else
447   if (hcryp->State == HAL_CRYP_STATE_RESET)
448   {
449     /* Allocate lock resource and initialize it */
450     hcryp->Lock = HAL_UNLOCKED;
451 
452     /* Init the low level hardware */
453     HAL_CRYP_MspInit(hcryp);
454   }
455 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
456 
457   /* Set the key size(This bit field is don't care in the DES or TDES modes) data type and Algorithm */
458   MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
459              hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
460 #if !defined (CRYP_VER_2_2)
461   /* Read Device ID to indicate CRYP1 IP Version */
462   hcryp->Version = HAL_GetREVID();
463 #endif /*End of not defined CRYP_VER_2_2*/
464   /* Reset Error Code field */
465   hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
466 
467   /* Reset peripheral Key and IV configuration flag */
468   hcryp->KeyIVConfig = 0U;
469 
470   /* Change the CRYP state */
471   hcryp->State = HAL_CRYP_STATE_READY;
472 
473   /* Set the default CRYP phase */
474   hcryp->Phase = CRYP_PHASE_READY;
475 
476   /* Return function status */
477   return HAL_OK;
478 }
479 
480 /**
481   * @brief  De-Initializes the CRYP peripheral.
482   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
483   *         the configuration information for CRYP module
484   * @retval HAL status
485   */
HAL_CRYP_DeInit(CRYP_HandleTypeDef * hcryp)486 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
487 {
488   /* Check the CRYP handle allocation */
489   if (hcryp == NULL)
490   {
491     return HAL_ERROR;
492   }
493 
494   /* Set the default CRYP phase */
495   hcryp->Phase = CRYP_PHASE_READY;
496 
497   /* Reset CrypInCount and CrypOutCount */
498   hcryp->CrypInCount = 0;
499   hcryp->CrypOutCount = 0;
500   hcryp->CrypHeaderCount = 0;
501 
502   /* Disable the CRYP peripheral clock */
503   __HAL_CRYP_DISABLE(hcryp);
504 
505 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
506   if (hcryp->MspDeInitCallback == NULL)
507   {
508     hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit  */
509   }
510   /* DeInit the low level hardware */
511   hcryp->MspDeInitCallback(hcryp);
512 
513 #else
514   /* DeInit the low level hardware: CLOCK, NVIC.*/
515   HAL_CRYP_MspDeInit(hcryp);
516 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
517 
518   /* Change the CRYP state */
519   hcryp->State = HAL_CRYP_STATE_RESET;
520 
521   /* Release Lock */
522   __HAL_UNLOCK(hcryp);
523 
524   /* Return function status */
525   return HAL_OK;
526 }
527 
528 /**
529   * @brief  Configure the CRYP according to the specified
530   *         parameters in the CRYP_ConfigTypeDef
531   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
532   * @param  pConf: pointer to a CRYP_ConfigTypeDef structure that contains
533   *         the configuration information for CRYP module
534   * @retval HAL status
535   */
HAL_CRYP_SetConfig(CRYP_HandleTypeDef * hcryp,CRYP_ConfigTypeDef * pConf)536 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
537 {
538   /* Check the CRYP handle allocation */
539   if ((hcryp == NULL) || (pConf == NULL))
540   {
541     return HAL_ERROR;
542   }
543 
544   /* Check parameters */
545   assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
546   assert_param(IS_CRYP_DATATYPE(pConf->DataType));
547   assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
548 
549   if (hcryp->State == HAL_CRYP_STATE_READY)
550   {
551     /* Change the CRYP state */
552     hcryp->State = HAL_CRYP_STATE_BUSY;
553 
554     /* Process locked */
555     __HAL_LOCK(hcryp);
556 
557     /* Set  CRYP parameters  */
558     hcryp->Init.DataType        = pConf->DataType;
559     hcryp->Init.pKey            = pConf->pKey;
560     hcryp->Init.Algorithm       = pConf->Algorithm;
561     hcryp->Init.KeySize         = pConf->KeySize;
562     hcryp->Init.pInitVect       = pConf->pInitVect;
563     hcryp->Init.Header          = pConf->Header;
564     hcryp->Init.HeaderSize      = pConf->HeaderSize;
565     hcryp->Init.B0              = pConf->B0;
566     hcryp->Init.DataWidthUnit   = pConf->DataWidthUnit;
567     hcryp->Init.HeaderWidthUnit = pConf->HeaderWidthUnit;
568     hcryp->Init.KeyIVConfigSkip = pConf->KeyIVConfigSkip;
569 
570     /* Set the key size(This bit field is don't care in the DES or TDES modes) data type, AlgoMode and operating mode*/
571     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
572                hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
573 
574     /* Process Unlocked */
575     __HAL_UNLOCK(hcryp);
576 
577     /* Reset Error Code field */
578     hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
579 
580     /* Change the CRYP state */
581     hcryp->State = HAL_CRYP_STATE_READY;
582 
583     /* Set the default CRYP phase */
584     hcryp->Phase = CRYP_PHASE_READY;
585 
586     /* Return function status */
587     return HAL_OK;
588   }
589   else
590   {
591     /* Process Unlocked */
592     __HAL_UNLOCK(hcryp);
593 
594     /* Busy error code field */
595     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
596     return HAL_ERROR;
597   }
598 }
599 
600 /**
601   * @brief  Get CRYP Configuration parameters in associated handle.
602   * @param  pConf: pointer to a CRYP_ConfigTypeDef structure
603   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
604   *         the configuration information for CRYP module
605   * @retval HAL status
606   */
HAL_CRYP_GetConfig(CRYP_HandleTypeDef * hcryp,CRYP_ConfigTypeDef * pConf)607 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
608 {
609   /* Check the CRYP handle allocation */
610   if ((hcryp == NULL) || (pConf == NULL))
611   {
612     return HAL_ERROR;
613   }
614 
615   if (hcryp->State == HAL_CRYP_STATE_READY)
616   {
617     /* Change the CRYP state */
618     hcryp->State = HAL_CRYP_STATE_BUSY;
619 
620     /* Process locked */
621     __HAL_LOCK(hcryp);
622 
623     /* Get  CRYP parameters  */
624     pConf->DataType        = hcryp->Init.DataType;
625     pConf->pKey            = hcryp->Init.pKey;
626     pConf->Algorithm       = hcryp->Init.Algorithm;
627     pConf->KeySize         = hcryp->Init.KeySize ;
628     pConf->pInitVect       = hcryp->Init.pInitVect;
629     pConf->Header          = hcryp->Init.Header ;
630     pConf->HeaderSize      = hcryp->Init.HeaderSize;
631     pConf->B0              = hcryp->Init.B0;
632     pConf->DataWidthUnit   = hcryp->Init.DataWidthUnit;
633     pConf->HeaderWidthUnit = hcryp->Init.HeaderWidthUnit;
634     pConf->KeyIVConfigSkip = hcryp->Init.KeyIVConfigSkip;
635 
636     /* Process Unlocked */
637     __HAL_UNLOCK(hcryp);
638 
639     /* Change the CRYP state */
640     hcryp->State = HAL_CRYP_STATE_READY;
641 
642     /* Return function status */
643     return HAL_OK;
644   }
645   else
646   {
647     /* Process Unlocked */
648     __HAL_UNLOCK(hcryp);
649 
650     /* Busy error code field */
651     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
652     return HAL_ERROR;
653   }
654 }
655 /**
656   * @brief  Initializes the CRYP MSP.
657   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
658   *         the configuration information for CRYP module
659   * @retval None
660   */
HAL_CRYP_MspInit(CRYP_HandleTypeDef * hcryp)661 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
662 {
663   /* Prevent unused argument(s) compilation warning */
664   UNUSED(hcryp);
665 
666   /* NOTE : This function Should not be modified, when the callback is needed,
667             the HAL_CRYP_MspInit could be implemented in the user file
668    */
669 }
670 
671 /**
672   * @brief  DeInitializes CRYP MSP.
673   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
674   *         the configuration information for CRYP module
675   * @retval None
676   */
HAL_CRYP_MspDeInit(CRYP_HandleTypeDef * hcryp)677 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
678 {
679   /* Prevent unused argument(s) compilation warning */
680   UNUSED(hcryp);
681 
682   /* NOTE : This function Should not be modified, when the callback is needed,
683             the HAL_CRYP_MspDeInit could be implemented in the user file
684    */
685 }
686 
687 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
688 /**
689   * @brief  Register a User CRYP Callback
690   *         To be used instead of the weak predefined callback
691   * @param hcryp cryp handle
692   * @param CallbackID ID of the callback to be registered
693   *        This parameter can be one of the following values:
694   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
695   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
696   *          @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
697   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
698   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
699   * @param pCallback pointer to the Callback function
700   * @retval status
701   */
HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef * hcryp,HAL_CRYP_CallbackIDTypeDef CallbackID,pCRYP_CallbackTypeDef pCallback)702 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID,
703                                             pCRYP_CallbackTypeDef pCallback)
704 {
705   HAL_StatusTypeDef status = HAL_OK;
706 
707   if (pCallback == NULL)
708   {
709     /* Update the error code */
710     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
711 
712     return HAL_ERROR;
713   }
714   /* Process locked */
715   __HAL_LOCK(hcryp);
716 
717   if (hcryp->State == HAL_CRYP_STATE_READY)
718   {
719     switch (CallbackID)
720     {
721       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
722         hcryp->InCpltCallback = pCallback;
723         break;
724 
725       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
726         hcryp->OutCpltCallback = pCallback;
727         break;
728 
729       case HAL_CRYP_ERROR_CB_ID :
730         hcryp->ErrorCallback = pCallback;
731         break;
732 
733       case HAL_CRYP_MSPINIT_CB_ID :
734         hcryp->MspInitCallback = pCallback;
735         break;
736 
737       case HAL_CRYP_MSPDEINIT_CB_ID :
738         hcryp->MspDeInitCallback = pCallback;
739         break;
740 
741       default :
742         /* Update the error code */
743         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
744         /* Return error status */
745         status =  HAL_ERROR;
746         break;
747     }
748   }
749   else if (hcryp->State == HAL_CRYP_STATE_RESET)
750   {
751     switch (CallbackID)
752     {
753       case HAL_CRYP_MSPINIT_CB_ID :
754         hcryp->MspInitCallback = pCallback;
755         break;
756 
757       case HAL_CRYP_MSPDEINIT_CB_ID :
758         hcryp->MspDeInitCallback = pCallback;
759         break;
760 
761       default :
762         /* Update the error code */
763         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
764         /* Return error status */
765         status =  HAL_ERROR;
766         break;
767     }
768   }
769   else
770   {
771     /* Update the error code */
772     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
773     /* Return error status */
774     status =  HAL_ERROR;
775   }
776 
777   /* Release Lock */
778   __HAL_UNLOCK(hcryp);
779 
780   return status;
781 }
782 
783 /**
784   * @brief  Unregister an CRYP Callback
785   *         CRYP callback is redirected to the weak predefined callback
786   * @param hcryp cryp handle
787   * @param CallbackID ID of the callback to be unregistered
788   *        This parameter can be one of the following values:
789   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
790   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
791   *          @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
792   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
793   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
794   * @retval status
795   */
HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef * hcryp,HAL_CRYP_CallbackIDTypeDef CallbackID)796 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
797 {
798   HAL_StatusTypeDef status = HAL_OK;
799 
800   /* Process locked */
801   __HAL_LOCK(hcryp);
802 
803   if (hcryp->State == HAL_CRYP_STATE_READY)
804   {
805     switch (CallbackID)
806     {
807       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
808         hcryp->InCpltCallback = HAL_CRYP_InCpltCallback;  /* Legacy weak  InCpltCallback  */
809         break;
810 
811       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
812         hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback;         /* Legacy weak OutCpltCallback       */
813         break;
814 
815       case HAL_CRYP_ERROR_CB_ID :
816         hcryp->ErrorCallback = HAL_CRYP_ErrorCallback;           /* Legacy weak ErrorCallback        */
817         break;
818 
819       case HAL_CRYP_MSPINIT_CB_ID :
820         hcryp->MspInitCallback = HAL_CRYP_MspInit;
821         break;
822 
823       case HAL_CRYP_MSPDEINIT_CB_ID :
824         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
825         break;
826 
827       default :
828         /* Update the error code */
829         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
830         /* Return error status */
831         status =  HAL_ERROR;
832         break;
833     }
834   }
835   else if (hcryp->State == HAL_CRYP_STATE_RESET)
836   {
837     switch (CallbackID)
838     {
839       case HAL_CRYP_MSPINIT_CB_ID :
840         hcryp->MspInitCallback = HAL_CRYP_MspInit;
841         break;
842 
843       case HAL_CRYP_MSPDEINIT_CB_ID :
844         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
845         break;
846 
847       default :
848         /* Update the error code */
849         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
850         /* Return error status */
851         status =  HAL_ERROR;
852         break;
853     }
854   }
855   else
856   {
857     /* Update the error code */
858     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
859     /* Return error status */
860     status =  HAL_ERROR;
861   }
862 
863   /* Release Lock */
864   __HAL_UNLOCK(hcryp);
865 
866   return status;
867 }
868 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
869 
870 /**
871   * @}
872   */
873 
874 /** @defgroup CRYP_Exported_Functions_Group2  Encrypt Decrypt functions
875   *  @brief   CRYP processing functions.
876   *
877 @verbatim
878   ==============================================================================
879                       ##### Encrypt Decrypt  functions #####
880   ==============================================================================
881     [..]  This section provides API allowing to Encrypt/Decrypt Data following
882           Standard DES/TDES or AES, and Algorithm configured by the user:
883       (+) Standard DES/TDES only supported by CRYP1 IP, below list of Algorithm supported :
884            (++)  Electronic Code Book(ECB)
885            (++) Cipher Block Chaining (CBC)
886       (+) Standard AES  supported by CRYP1 IP , list of Algorithm supported:
887            (++) Electronic Code Book(ECB)
888            (++) Cipher Block Chaining (CBC)
889            (++) Counter mode (CTR)
890            (++) Cipher Block Chaining (CBC)
891            (++) Counter mode (CTR)
892            (++) Galois/counter mode (GCM)
893            (++) Counter with Cipher Block Chaining-Message(CCM)
894     [..]  Three processing functions are available:
895       (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
896       (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
897       (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
898 
899 @endverbatim
900   * @{
901   */
902 
903 
904 /**
905   * @brief  Encryption mode.
906   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
907   *         the configuration information for CRYP module
908   * @param  Input: Pointer to the input buffer (plaintext)
909   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit.
910   * @param  Output: Pointer to the output buffer(ciphertext)
911   * @param  Timeout: Specify Timeout value
912   * @retval HAL status
913   */
HAL_CRYP_Encrypt(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output,uint32_t Timeout)914 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
915                                    uint32_t Timeout)
916 {
917   uint32_t algo;
918   HAL_StatusTypeDef status;
919 
920   if (hcryp->State == HAL_CRYP_STATE_READY)
921   {
922     /* Change state Busy */
923     hcryp->State = HAL_CRYP_STATE_BUSY;
924 
925     /* Process locked */
926     __HAL_LOCK(hcryp);
927 
928     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
929     hcryp->CrypInCount = 0U;
930     hcryp->CrypOutCount = 0U;
931     hcryp->pCrypInBuffPtr = Input;
932     hcryp->pCrypOutBuffPtr = Output;
933 
934     /*  Calculate Size parameter in Byte*/
935     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
936     {
937       hcryp->Size = Size * 4U;
938     }
939     else
940     {
941       hcryp->Size = Size;
942     }
943 
944     /* Set Encryption operating mode*/
945     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
946 
947     /* algo get algorithm selected */
948     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
949 
950     switch (algo)
951     {
952       case CRYP_DES_ECB:
953       case CRYP_DES_CBC:
954       case CRYP_TDES_ECB:
955       case CRYP_TDES_CBC:
956 
957         /*Set Key */
958         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
959         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
960         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
961         {
962           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
963           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
964           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
965           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
966         }
967 
968         /*Set Initialization Vector (IV)*/
969         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
970         {
971           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
972           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
973         }
974 
975         /* Flush FIFO */
976         HAL_CRYP_FIFO_FLUSH(hcryp);
977 
978         /* Set the phase */
979         hcryp->Phase = CRYP_PHASE_PROCESS;
980 
981         /* Start DES/TDES encryption process */
982         status = CRYP_TDES_Process(hcryp, Timeout);
983         break;
984 
985       case CRYP_AES_ECB:
986       case CRYP_AES_CBC:
987       case CRYP_AES_CTR:
988 
989         /* AES encryption */
990         status = CRYP_AES_Encrypt(hcryp, Timeout);
991         break;
992 
993       case CRYP_AES_GCM:
994 
995         /* AES GCM encryption */
996         status = CRYP_AESGCM_Process(hcryp, Timeout);
997         break;
998 
999       case CRYP_AES_CCM:
1000 
1001         /* AES CCM encryption */
1002         status = CRYP_AESCCM_Process(hcryp, Timeout);
1003         break;
1004 
1005       default:
1006         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1007         status = HAL_ERROR;
1008         break;
1009     }
1010 
1011     if (status == HAL_OK)
1012     {
1013       /* Change the CRYP peripheral state */
1014       hcryp->State = HAL_CRYP_STATE_READY;
1015 
1016       /* Process unlocked */
1017       __HAL_UNLOCK(hcryp);
1018     }
1019   }
1020   else
1021   {
1022     /* Process unlocked */
1023     __HAL_UNLOCK(hcryp);
1024 
1025     /* Busy error code field */
1026     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1027     status = HAL_ERROR;
1028   }
1029 
1030   /* Return function status */
1031   return status ;
1032 }
1033 
1034 /**
1035   * @brief  Decryption mode.
1036   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1037   *         the configuration information for CRYP module
1038   * @param  Input: Pointer to the input buffer (ciphertext )
1039   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1040   * @param  Output: Pointer to the output buffer(plaintext)
1041   * @param  Timeout: Specify Timeout value
1042   * @retval HAL status
1043   */
HAL_CRYP_Decrypt(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output,uint32_t Timeout)1044 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
1045                                    uint32_t Timeout)
1046 {
1047   HAL_StatusTypeDef status;
1048   uint32_t algo;
1049 
1050   if (hcryp->State == HAL_CRYP_STATE_READY)
1051   {
1052     /* Change state Busy */
1053     hcryp->State = HAL_CRYP_STATE_BUSY;
1054 
1055     /* Process locked */
1056     __HAL_LOCK(hcryp);
1057 
1058     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1059     hcryp->CrypInCount = 0U;
1060     hcryp->CrypOutCount = 0U;
1061     hcryp->pCrypInBuffPtr = Input;
1062     hcryp->pCrypOutBuffPtr = Output;
1063 
1064     /*  Calculate Size parameter in Byte*/
1065     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1066     {
1067       hcryp->Size = Size * 4U;
1068     }
1069     else
1070     {
1071       hcryp->Size = Size;
1072     }
1073 
1074     /* Set Decryption operating mode*/
1075     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1076 
1077     /* algo get algorithm selected */
1078     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1079 
1080     switch (algo)
1081     {
1082       case CRYP_DES_ECB:
1083       case CRYP_DES_CBC:
1084       case CRYP_TDES_ECB:
1085       case CRYP_TDES_CBC:
1086 
1087         /*Set Key */
1088         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1089         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1090         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1091         {
1092           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1093           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1094           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1095           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1096         }
1097 
1098         /*Set Initialization Vector (IV)*/
1099         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1100         {
1101           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1102           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1103         }
1104 
1105         /* Flush FIFO */
1106         HAL_CRYP_FIFO_FLUSH(hcryp);
1107 
1108         /* Set the phase */
1109         hcryp->Phase = CRYP_PHASE_PROCESS;
1110 
1111         /* Start DES/TDES decryption process */
1112         status = CRYP_TDES_Process(hcryp, Timeout);
1113 
1114         break;
1115 
1116       case CRYP_AES_ECB:
1117       case CRYP_AES_CBC:
1118       case CRYP_AES_CTR:
1119 
1120         /* AES decryption */
1121         status = CRYP_AES_Decrypt(hcryp, Timeout);
1122         break;
1123 
1124       case CRYP_AES_GCM:
1125 
1126         /* AES GCM decryption */
1127         status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1128         break;
1129 
1130       case CRYP_AES_CCM:
1131 
1132         /* AES CCM decryption */
1133         status = CRYP_AESCCM_Process(hcryp, Timeout);
1134         break;
1135 
1136       default:
1137         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1138         status = HAL_ERROR;
1139         break;
1140     }
1141 
1142     if (status == HAL_OK)
1143     {
1144       /* Change the CRYP peripheral state */
1145       hcryp->State = HAL_CRYP_STATE_READY;
1146 
1147       /* Process unlocked */
1148       __HAL_UNLOCK(hcryp);
1149     }
1150   }
1151   else
1152   {
1153     /* Process unlocked */
1154     __HAL_UNLOCK(hcryp);
1155 
1156     /* Busy error code field */
1157     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1158     status = HAL_ERROR;
1159   }
1160 
1161   /* Return function status */
1162   return status;
1163 }
1164 
1165 /**
1166   * @brief  Encryption in interrupt mode.
1167   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1168   *         the configuration information for CRYP module
1169   * @param  Input: Pointer to the input buffer (plaintext)
1170   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1171   * @param  Output: Pointer to the output buffer(ciphertext)
1172   * @retval HAL status
1173   */
HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1174 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1175 {
1176   uint32_t algo;
1177   HAL_StatusTypeDef status;
1178 
1179   if (hcryp->State == HAL_CRYP_STATE_READY)
1180   {
1181     /* Change state Busy */
1182     hcryp->State = HAL_CRYP_STATE_BUSY;
1183 
1184     /* Process locked */
1185     __HAL_LOCK(hcryp);
1186 
1187     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1188     hcryp->CrypInCount = 0U;
1189     hcryp->CrypOutCount = 0U;
1190     hcryp->pCrypInBuffPtr = Input;
1191     hcryp->pCrypOutBuffPtr = Output;
1192 
1193     /*  Calculate Size parameter in Byte*/
1194     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1195     {
1196       hcryp->Size = Size * 4U;
1197     }
1198     else
1199     {
1200       hcryp->Size = Size;
1201     }
1202 
1203     /* Set encryption operating mode*/
1204     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1205 
1206     /* algo get algorithm selected */
1207     algo = (hcryp->Instance->CR & CRYP_CR_ALGOMODE);
1208 
1209     switch (algo)
1210     {
1211       case CRYP_DES_ECB:
1212       case CRYP_DES_CBC:
1213       case CRYP_TDES_ECB:
1214       case CRYP_TDES_CBC:
1215 
1216         /*Set Key */
1217         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1218         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1219         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1220         {
1221           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1222           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1223           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1224           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1225         }
1226         /* Set the Initialization Vector*/
1227         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1228         {
1229           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1230           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1231         }
1232 
1233         /* Flush FIFO */
1234         HAL_CRYP_FIFO_FLUSH(hcryp);
1235 
1236         /* Set the phase */
1237         hcryp->Phase = CRYP_PHASE_PROCESS;
1238 
1239         /* Enable interrupts */
1240         __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1241 
1242         /* Enable CRYP to start DES/TDES process*/
1243         __HAL_CRYP_ENABLE(hcryp);
1244 
1245         status = HAL_OK;
1246         break;
1247 
1248       case CRYP_AES_ECB:
1249       case CRYP_AES_CBC:
1250       case CRYP_AES_CTR:
1251 
1252         status = CRYP_AES_Encrypt_IT(hcryp);
1253         break;
1254 
1255       case CRYP_AES_GCM:
1256 
1257         status = CRYP_AESGCM_Process_IT(hcryp) ;
1258         break;
1259 
1260       case CRYP_AES_CCM:
1261 
1262         status = CRYP_AESCCM_Process_IT(hcryp);
1263         break;
1264 
1265       default:
1266         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1267         status =  HAL_ERROR;
1268         break;
1269     }
1270   }
1271   else
1272   {
1273     /* Busy error code field */
1274     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1275     status =  HAL_ERROR;
1276   }
1277 
1278   /* Return function status */
1279   return status ;
1280 }
1281 
1282 /**
1283   * @brief  Decryption in itnterrupt mode.
1284   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1285   *         the configuration information for CRYP module
1286   * @param  Input: Pointer to the input buffer (ciphertext )
1287   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1288   * @param  Output: Pointer to the output buffer(plaintext)
1289   * @retval HAL status
1290   */
HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1291 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1292 {
1293   uint32_t algo;
1294   HAL_StatusTypeDef status = HAL_OK;
1295 
1296   if (hcryp->State == HAL_CRYP_STATE_READY)
1297   {
1298     /* Change state Busy */
1299     hcryp->State = HAL_CRYP_STATE_BUSY;
1300 
1301     /* Process locked */
1302     __HAL_LOCK(hcryp);
1303 
1304     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1305     hcryp->CrypInCount = 0U;
1306     hcryp->CrypOutCount = 0U;
1307     hcryp->pCrypInBuffPtr = Input;
1308     hcryp->pCrypOutBuffPtr = Output;
1309 
1310     /*  Calculate Size parameter in Byte*/
1311     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1312     {
1313       hcryp->Size = Size * 4U;
1314     }
1315     else
1316     {
1317       hcryp->Size = Size;
1318     }
1319 
1320     /* Set decryption operating mode*/
1321     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1322 
1323     /* algo get algorithm selected */
1324     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1325 
1326     switch (algo)
1327     {
1328       case CRYP_DES_ECB:
1329       case CRYP_DES_CBC:
1330       case CRYP_TDES_ECB:
1331       case CRYP_TDES_CBC:
1332 
1333         /*Set Key */
1334         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1335         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1336         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1337         {
1338           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1339           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1340           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1341           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1342         }
1343 
1344         /* Set the Initialization Vector*/
1345         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1346         {
1347           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1348           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1349         }
1350         /* Flush FIFO */
1351         HAL_CRYP_FIFO_FLUSH(hcryp);
1352 
1353         /* Set the phase */
1354         hcryp->Phase = CRYP_PHASE_PROCESS;
1355 
1356         /* Enable interrupts */
1357         __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1358 
1359         /* Enable CRYP and start DES/TDES process*/
1360         __HAL_CRYP_ENABLE(hcryp);
1361 
1362         break;
1363 
1364       case CRYP_AES_ECB:
1365       case CRYP_AES_CBC:
1366       case CRYP_AES_CTR:
1367 
1368         /* AES decryption */
1369         status = CRYP_AES_Decrypt_IT(hcryp);
1370         break;
1371 
1372       case CRYP_AES_GCM:
1373 
1374         /* AES GCM decryption */
1375         status = CRYP_AESGCM_Process_IT(hcryp) ;
1376         break;
1377 
1378       case CRYP_AES_CCM:
1379 
1380         /* AES CCMdecryption */
1381         status = CRYP_AESCCM_Process_IT(hcryp);
1382         break;
1383 
1384       default:
1385         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1386         status = HAL_ERROR;
1387         break;
1388     }
1389   }
1390   else
1391   {
1392     /* Busy error code field */
1393     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1394     status = HAL_ERROR;
1395   }
1396 
1397   /* Return function status */
1398   return status;
1399 }
1400 
1401 /**
1402   * @brief  Encryption in DMA mode.
1403   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1404   *         the configuration information for CRYP module
1405   * @param  Input: Pointer to the input buffer (plaintext)
1406   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1407   * @param  Output: Pointer to the output buffer(ciphertext)
1408   * @retval HAL status
1409   */
HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1410 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1411 {
1412   HAL_StatusTypeDef status = HAL_OK;
1413   uint32_t algo;
1414   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1415 
1416   if (hcryp->State == HAL_CRYP_STATE_READY)
1417   {
1418     /* Change state Busy */
1419     hcryp->State = HAL_CRYP_STATE_BUSY;
1420 
1421     /* Process locked */
1422     __HAL_LOCK(hcryp);
1423 
1424     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1425     hcryp->CrypInCount = 0U;
1426     hcryp->CrypOutCount = 0U;
1427     hcryp->pCrypInBuffPtr = Input;
1428     hcryp->pCrypOutBuffPtr = Output;
1429 
1430     /*  Calculate Size parameter in Byte*/
1431     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1432     {
1433       hcryp->Size = Size * 4U;
1434     }
1435     else
1436     {
1437       hcryp->Size = Size;
1438     }
1439 
1440     /* Set encryption operating mode*/
1441     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1442 
1443     /* algo get algorithm selected */
1444     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1445 
1446     switch (algo)
1447     {
1448       case CRYP_DES_ECB:
1449       case CRYP_DES_CBC:
1450       case CRYP_TDES_ECB:
1451       case CRYP_TDES_CBC:
1452 
1453         /*Set Key */
1454         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1455         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1456         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1457         {
1458           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1459           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1460           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1461           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1462         }
1463 
1464         /* Set the Initialization Vector*/
1465         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1466         {
1467           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1468           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1469         }
1470 
1471         /* Flush FIFO */
1472         HAL_CRYP_FIFO_FLUSH(hcryp);
1473 
1474         /* Set the phase */
1475         hcryp->Phase = CRYP_PHASE_PROCESS;
1476 
1477         /* Start DMA process transfer for DES/TDES */
1478         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1479                           (uint32_t)(hcryp->pCrypOutBuffPtr));
1480 
1481         break;
1482 
1483       case CRYP_AES_ECB:
1484       case CRYP_AES_CBC:
1485       case CRYP_AES_CTR:
1486 
1487         if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1488         {
1489           if (hcryp->KeyIVConfig == 1U)
1490           {
1491             /* If the Key and IV configuration has to be done only once
1492                and if it has already been done, skip it */
1493             DoKeyIVConfig = 0U;
1494           }
1495           else
1496           {
1497             /* If the Key and IV configuration has to be done only once
1498                and if it has not been done already, do it and set KeyIVConfig
1499                to keep track it won't have to be done again next time */
1500             hcryp->KeyIVConfig = 1U;
1501           }
1502         }
1503 
1504         if (DoKeyIVConfig == 1U)
1505         {
1506           /*  Set the Key*/
1507           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1508 
1509           /* Set the Initialization Vector*/
1510           if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1511           {
1512             hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1513             hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
1514             hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
1515             hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
1516           }
1517         } /* if (DoKeyIVConfig == 1U) */
1518 
1519         /* Set the phase */
1520         hcryp->Phase = CRYP_PHASE_PROCESS;
1521 
1522         /* Start DMA process transfer for AES */
1523         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1524                           (uint32_t)(hcryp->pCrypOutBuffPtr));
1525         break;
1526 
1527       case CRYP_AES_GCM:
1528 
1529         /* AES GCM encryption */
1530         status = CRYP_AESGCM_Process_DMA(hcryp) ;
1531         break;
1532 
1533       case CRYP_AES_CCM:
1534 
1535         /* AES CCM encryption */
1536         status = CRYP_AESCCM_Process_DMA(hcryp);
1537         break;
1538 
1539       default:
1540         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1541         status =  HAL_ERROR;
1542         break;
1543     }
1544   }
1545   else
1546   {
1547     /* Busy error code field */
1548     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1549     status =  HAL_ERROR;
1550   }
1551 
1552   /* Return function status */
1553   return status;
1554 }
1555 
1556 /**
1557   * @brief  Decryption in DMA mode.
1558   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1559   *         the configuration information for CRYP module
1560   * @param  Input: Pointer to the input buffer (ciphertext )
1561   * @param  Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1562   * @param  Output: Pointer to the output buffer(plaintext)
1563   * @retval HAL status
1564   */
HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1565 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1566 {
1567   uint32_t algo;
1568   HAL_StatusTypeDef status = HAL_OK;
1569 
1570   if (hcryp->State == HAL_CRYP_STATE_READY)
1571   {
1572     /* Change state Busy */
1573     hcryp->State = HAL_CRYP_STATE_BUSY;
1574 
1575     /* Process locked */
1576     __HAL_LOCK(hcryp);
1577 
1578     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1579     hcryp->CrypInCount = 0U;
1580     hcryp->CrypOutCount = 0U;
1581     hcryp->pCrypInBuffPtr = Input;
1582     hcryp->pCrypOutBuffPtr = Output;
1583 
1584     /*  Calculate Size parameter in Byte*/
1585     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1586     {
1587       hcryp->Size = Size * 4U;
1588     }
1589     else
1590     {
1591       hcryp->Size = Size;
1592     }
1593 
1594     /* Set decryption operating mode*/
1595     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1596 
1597     /* algo get algorithm selected */
1598     algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1599 
1600     switch (algo)
1601     {
1602       case CRYP_DES_ECB:
1603       case CRYP_DES_CBC:
1604       case CRYP_TDES_ECB:
1605       case CRYP_TDES_CBC:
1606 
1607         /*Set Key */
1608         hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1609         hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1610         if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1611         {
1612           hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1613           hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1614           hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1615           hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1616         }
1617 
1618         /* Set the Initialization Vector*/
1619         if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1620         {
1621           hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1622           hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1623         }
1624 
1625         /* Flush FIFO */
1626         HAL_CRYP_FIFO_FLUSH(hcryp);
1627 
1628         /* Set the phase */
1629         hcryp->Phase = CRYP_PHASE_PROCESS;
1630 
1631         /* Start DMA process transfer for DES/TDES */
1632         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1633                           (uint32_t)(hcryp->pCrypOutBuffPtr));
1634         break;
1635 
1636       case CRYP_AES_ECB:
1637       case CRYP_AES_CBC:
1638       case CRYP_AES_CTR:
1639 
1640         /* AES decryption */
1641         status = CRYP_AES_Decrypt_DMA(hcryp);
1642         break;
1643 
1644       case CRYP_AES_GCM:
1645 
1646         /* AES GCM decryption */
1647         status = CRYP_AESGCM_Process_DMA(hcryp) ;
1648 
1649         break;
1650 
1651       case CRYP_AES_CCM:
1652 
1653         /* AES CCM decryption */
1654         status = CRYP_AESCCM_Process_DMA(hcryp);
1655         break;
1656 
1657       default:
1658         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1659         status =  HAL_ERROR;
1660         break;
1661     }
1662   }
1663   else
1664   {
1665     /* Busy error code field */
1666     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1667     status = HAL_ERROR;
1668   }
1669 
1670   /* Return function status */
1671   return status;
1672 }
1673 
1674 /**
1675   * @}
1676   */
1677 
1678 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1679   *  @brief    CRYP IRQ handler.
1680   *
1681 @verbatim
1682   ==============================================================================
1683                 ##### CRYP IRQ handler management #####
1684   ==============================================================================
1685 [..]  This section provides CRYP IRQ handler and callback functions.
1686       (+) HAL_CRYP_IRQHandler CRYP interrupt request
1687       (+) HAL_CRYP_InCpltCallback input data transfer complete callback
1688       (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
1689       (+) HAL_CRYP_ErrorCallback  CRYP error callback
1690       (+) HAL_CRYP_GetState return the CRYP state
1691       (+) HAL_CRYP_GetError return the CRYP error code
1692 @endverbatim
1693   * @{
1694   */
1695 
1696 /**
1697   * @brief  This function handles cryptographic interrupt request.
1698   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1699   *         the configuration information for CRYP module
1700   * @retval None
1701   */
HAL_CRYP_IRQHandler(CRYP_HandleTypeDef * hcryp)1702 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
1703 {
1704   uint32_t itstatus = hcryp->Instance->MISR;
1705 
1706   if ((itstatus & (CRYP_IT_INI | CRYP_IT_OUTI)) != 0U)
1707   {
1708     if ((hcryp->Init.Algorithm == CRYP_DES_ECB) || (hcryp->Init.Algorithm == CRYP_DES_CBC) ||
1709         (hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1710     {
1711       CRYP_TDES_IT(hcryp); /* DES or TDES*/
1712     }
1713     else if ((hcryp->Init.Algorithm == CRYP_AES_ECB) || (hcryp->Init.Algorithm == CRYP_AES_CBC) ||
1714              (hcryp->Init.Algorithm == CRYP_AES_CTR))
1715     {
1716       CRYP_AES_IT(hcryp); /*AES*/
1717     }
1718 
1719     else if ((hcryp->Init.Algorithm == CRYP_AES_GCM) || (hcryp->Init.Algorithm == CRYP_CR_ALGOMODE_AES_CCM))
1720     {
1721       /* if header phase */
1722       if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
1723       {
1724         CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
1725       }
1726       else  /* if payload phase */
1727       {
1728         CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
1729       }
1730     }
1731     else
1732     {
1733       /* Nothing to do */
1734     }
1735   }
1736 }
1737 
1738 /**
1739   * @brief  Return the CRYP error code.
1740   * @param  hcryp : pointer to a CRYP_HandleTypeDef structure that contains
1741   *                 the configuration information for the  CRYP IP
1742   * @retval CRYP error code
1743   */
HAL_CRYP_GetError(const CRYP_HandleTypeDef * hcryp)1744 uint32_t HAL_CRYP_GetError(const CRYP_HandleTypeDef *hcryp)
1745 {
1746   return hcryp->ErrorCode;
1747 }
1748 
1749 /**
1750   * @brief  Returns the CRYP state.
1751   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1752   *         the configuration information for CRYP module.
1753   * @retval HAL state
1754   */
HAL_CRYP_GetState(const CRYP_HandleTypeDef * hcryp)1755 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(const CRYP_HandleTypeDef *hcryp)
1756 {
1757   return hcryp->State;
1758 }
1759 
1760 /**
1761   * @brief  Input FIFO transfer completed callback.
1762   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1763   *         the configuration information for CRYP module.
1764   * @retval None
1765   */
HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef * hcryp)1766 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
1767 {
1768   /* Prevent unused argument(s) compilation warning */
1769   UNUSED(hcryp);
1770 
1771   /* NOTE : This function Should not be modified, when the callback is needed,
1772             the HAL_CRYP_InCpltCallback could be implemented in the user file
1773    */
1774 }
1775 
1776 /**
1777   * @brief  Output FIFO transfer completed callback.
1778   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1779   *         the configuration information for CRYP module.
1780   * @retval None
1781   */
HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef * hcryp)1782 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
1783 {
1784   /* Prevent unused argument(s) compilation warning */
1785   UNUSED(hcryp);
1786 
1787   /* NOTE : This function Should not be modified, when the callback is needed,
1788             the HAL_CRYP_OutCpltCallback could be implemented in the user file
1789    */
1790 }
1791 
1792 /**
1793   * @brief  CRYP error callback.
1794   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1795   *         the configuration information for CRYP module.
1796   * @retval None
1797   */
HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef * hcryp)1798 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
1799 {
1800   /* Prevent unused argument(s) compilation warning */
1801   UNUSED(hcryp);
1802 
1803   /* NOTE : This function Should not be modified, when the callback is needed,
1804             the HAL_CRYP_ErrorCallback could be implemented in the user file
1805    */
1806 }
1807 /**
1808   * @}
1809   */
1810 /**
1811   * @}
1812   */
1813 
1814 /* Private functions ---------------------------------------------------------*/
1815 /** @addtogroup CRYP_Private_Functions
1816   * @{
1817   */
1818 
1819 /**
1820   * @brief  Encryption in ECB/CBC Algorithm with DES/TDES standard.
1821   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1822   *         the configuration information for CRYP module
1823   * @param  Timeout: Timeout value
1824   * @retval HAL status
1825   */
CRYP_TDES_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)1826 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
1827 {
1828 
1829   uint32_t temp;  /* Temporary CrypOutBuff */
1830   uint16_t incount; /* Temporary CrypInCount Value */
1831   uint16_t outcount;  /* Temporary CrypOutCount Value */
1832 
1833   /* Enable CRYP */
1834   __HAL_CRYP_ENABLE(hcryp);
1835   /*Temporary CrypOutCount Value*/
1836   outcount = hcryp->CrypOutCount;
1837 
1838   /*Start processing*/
1839   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
1840   {
1841     /* Temporary CrypInCount Value */
1842     incount = hcryp->CrypInCount;
1843     /* Write plain data and get cipher data */
1844     if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
1845     {
1846       /* Write the input block in the IN FIFO */
1847       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1848       hcryp->CrypInCount++;
1849       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1850       hcryp->CrypInCount++;
1851     }
1852 
1853     /* Wait for OFNE flag to be raised */
1854     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
1855     {
1856       /* Disable the CRYP peripheral clock */
1857       __HAL_CRYP_DISABLE(hcryp);
1858 
1859       /* Change state & errorCode*/
1860       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
1861       hcryp->State = HAL_CRYP_STATE_READY;
1862 
1863       /* Process unlocked */
1864       __HAL_UNLOCK(hcryp);
1865 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1866       /*Call registered error callback*/
1867       hcryp->ErrorCallback(hcryp);
1868 #else
1869       /*Call legacy weak error callback*/
1870       HAL_CRYP_ErrorCallback(hcryp);
1871 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1872     }
1873 
1874     /*Temporary CrypOutCount Value*/
1875     outcount = hcryp->CrypOutCount;
1876 
1877     if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
1878     {
1879       /* Read the output block from the Output FIFO and put them in temporary Buffer
1880        then get CrypOutBuff from temporary buffer  */
1881       temp = hcryp->Instance->DOUT;
1882       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1883       hcryp->CrypOutCount++;
1884       temp = hcryp->Instance->DOUT;
1885       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1886       hcryp->CrypOutCount++;
1887     }
1888     /*Temporary CrypOutCount Value*/
1889     outcount = hcryp->CrypOutCount;
1890   }
1891   /* Disable CRYP */
1892   __HAL_CRYP_DISABLE(hcryp);
1893   /* Change the CRYP state */
1894   hcryp->State = HAL_CRYP_STATE_READY;
1895 
1896   /* Return function status */
1897   return HAL_OK;
1898 }
1899 
1900 /**
1901   * @brief  CRYP block input/output data handling under interruption with DES/TDES standard.
1902   * @note   The function is called under interruption only, once
1903   *         interruptions have been enabled by CRYP_Decrypt_IT() and CRYP_Encrypt_IT().
1904   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1905   *         the configuration information for CRYP module.
1906   * @retval HAL status
1907   */
CRYP_TDES_IT(CRYP_HandleTypeDef * hcryp)1908 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp)
1909 {
1910   uint32_t temp;  /* Temporary CrypOutBuff */
1911 
1912   if (hcryp->State == HAL_CRYP_STATE_BUSY)
1913   {
1914     if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI) != 0x0U)
1915     {
1916       if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_INRIS) != 0x0U)
1917       {
1918         /* Write input block in the IN FIFO */
1919         hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1920         hcryp->CrypInCount++;
1921         hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1922         hcryp->CrypInCount++;
1923 
1924         if (hcryp->CrypInCount == (hcryp->Size / 4U))
1925         {
1926           /* Disable interruption */
1927           __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1928 
1929           /* Call the input data transfer complete callback */
1930 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1931           /*Call registered Input complete callback*/
1932           hcryp->InCpltCallback(hcryp);
1933 #else
1934           /*Call legacy weak Input complete callback*/
1935           HAL_CRYP_InCpltCallback(hcryp);
1936 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1937         }
1938       }
1939     }
1940 
1941     if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI) != 0x0U)
1942     {
1943       if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_OUTRIS) != 0x0U)
1944       {
1945         /* Read the output block from the Output FIFO and put them in temporary Buffer
1946          then get CrypOutBuff from temporary buffer  */
1947         temp = hcryp->Instance->DOUT;
1948         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1949         hcryp->CrypOutCount++;
1950         temp = hcryp->Instance->DOUT;
1951         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1952         hcryp->CrypOutCount++;
1953         if (hcryp->CrypOutCount == (hcryp->Size / 4U))
1954         {
1955           /* Disable interruption */
1956           __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1957 
1958           /* Disable CRYP */
1959           __HAL_CRYP_DISABLE(hcryp);
1960 
1961           /* Process unlocked */
1962           __HAL_UNLOCK(hcryp);
1963 
1964           /* Change the CRYP state */
1965           hcryp->State = HAL_CRYP_STATE_READY;
1966 
1967           /* Call output transfer complete callback */
1968 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1969           /*Call registered Output complete callback*/
1970           hcryp->OutCpltCallback(hcryp);
1971 #else
1972           /*Call legacy weak Output complete callback*/
1973           HAL_CRYP_OutCpltCallback(hcryp);
1974 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1975 
1976         }
1977       }
1978     }
1979   }
1980   else
1981   {
1982     /* Process unlocked */
1983     __HAL_UNLOCK(hcryp);
1984     /* Busy error code field */
1985     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1986 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1987     /*Call registered error callback*/
1988     hcryp->ErrorCallback(hcryp);
1989 #else
1990     /*Call legacy weak error callback*/
1991     HAL_CRYP_ErrorCallback(hcryp);
1992 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1993   }
1994 }
1995 
1996 /**
1997   * @brief  Encryption in ECB/CBC & CTR Algorithm with AES Standard
1998   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
1999   * @param  Timeout: specify Timeout value
2000   * @retval HAL status
2001   */
CRYP_AES_Encrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2002 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2003 {
2004   uint16_t outcount;  /* Temporary CrypOutCount Value */
2005   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2006 
2007   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2008   {
2009     if (hcryp->KeyIVConfig == 1U)
2010     {
2011       /* If the Key and IV configuration has to be done only once
2012          and if it has already been done, skip it */
2013       DoKeyIVConfig = 0U;
2014     }
2015     else
2016     {
2017       /* If the Key and IV configuration has to be done only once
2018          and if it has not been done already, do it and set KeyIVConfig
2019          to keep track it won't have to be done again next time */
2020       hcryp->KeyIVConfig = 1U;
2021     }
2022   }
2023 
2024   if (DoKeyIVConfig == 1U)
2025   {
2026     /*  Set the Key*/
2027     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2028 
2029     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2030     {
2031       /* Set the Initialization Vector*/
2032       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2033       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2034       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2035       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2036     }
2037   } /* if (DoKeyIVConfig == 1U) */
2038 
2039   /* Set the phase */
2040   hcryp->Phase = CRYP_PHASE_PROCESS;
2041 
2042   /* Enable CRYP */
2043   __HAL_CRYP_ENABLE(hcryp);
2044   /*Temporary CrypOutCount Value*/
2045   outcount = hcryp->CrypOutCount;
2046 
2047   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2048   {
2049     /* Write plain Ddta and get cipher data */
2050     CRYP_AES_ProcessData(hcryp, Timeout);
2051     /*Temporary CrypOutCount Value*/
2052     outcount = hcryp->CrypOutCount;
2053   }
2054 
2055   /* Disable CRYP */
2056   __HAL_CRYP_DISABLE(hcryp);
2057 
2058   /* Change the CRYP state */
2059   hcryp->State = HAL_CRYP_STATE_READY;
2060 
2061   /* Return function status */
2062   return HAL_OK;
2063 }
2064 
2065 /**
2066   * @brief  Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2067   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2068   *         the configuration information for CRYP module
2069   * @retval HAL status
2070   */
CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef * hcryp)2071 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
2072 {
2073   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2074 
2075   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2076   {
2077     if (hcryp->KeyIVConfig == 1U)
2078     {
2079       /* If the Key and IV configuration has to be done only once
2080          and if it has already been done, skip it */
2081       DoKeyIVConfig = 0U;
2082     }
2083     else
2084     {
2085       /* If the Key and IV configuration has to be done only once
2086          and if it has not been done already, do it and set KeyIVConfig
2087          to keep track it won't have to be done again next time */
2088       hcryp->KeyIVConfig = 1U;
2089     }
2090   }
2091 
2092   if (DoKeyIVConfig == 1U)
2093   {
2094     /*  Set the Key*/
2095     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2096 
2097     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2098     {
2099       /* Set the Initialization Vector*/
2100       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2101       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2102       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2103       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2104     }
2105   } /* if (DoKeyIVConfig == 1U) */
2106 
2107   /* Set the phase */
2108   hcryp->Phase = CRYP_PHASE_PROCESS;
2109 
2110   if (hcryp->Size != 0U)
2111   {
2112     /* Enable interrupts */
2113     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2114 
2115     /* Enable CRYP */
2116     __HAL_CRYP_ENABLE(hcryp);
2117   }
2118   else
2119   {
2120     /* Change the CRYP state */
2121     hcryp->State = HAL_CRYP_STATE_READY;
2122 
2123     /* Process unlocked */
2124     __HAL_UNLOCK(hcryp);
2125   }
2126 
2127   /* Return function status */
2128   return HAL_OK;
2129 }
2130 
2131 /**
2132   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard
2133   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure
2134   * @param  Timeout: Specify Timeout value
2135   * @retval HAL status
2136   */
CRYP_AES_Decrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2137 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2138 {
2139   uint16_t outcount;  /* Temporary CrypOutCount Value */
2140   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2141 
2142   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2143   {
2144     if (hcryp->KeyIVConfig == 1U)
2145     {
2146       /* If the Key and IV configuration has to be done only once
2147          and if it has already been done, skip it */
2148       DoKeyIVConfig = 0U;
2149     }
2150     else
2151     {
2152       /* If the Key and IV configuration has to be done only once
2153          and if it has not been done already, do it and set KeyIVConfig
2154          to keep track it won't have to be done again next time */
2155       hcryp->KeyIVConfig = 1U;
2156     }
2157   }
2158 
2159   if (DoKeyIVConfig == 1U)
2160   {
2161     /*  Key preparation for ECB/CBC */
2162     if (hcryp->Init.Algorithm != CRYP_AES_CTR)   /*ECB or CBC*/
2163     {
2164       /* change ALGOMODE to key preparation for decryption*/
2165       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2166 
2167       /*  Set the Key*/
2168       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2169 
2170       /* Enable CRYP */
2171       __HAL_CRYP_ENABLE(hcryp);
2172 
2173       /* Wait for BUSY flag to be raised */
2174       if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
2175       {
2176         /* Disable the CRYP peripheral clock */
2177         __HAL_CRYP_DISABLE(hcryp);
2178 
2179         /* Change state */
2180         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2181         hcryp->State = HAL_CRYP_STATE_READY;
2182 
2183         /* Process unlocked */
2184         __HAL_UNLOCK(hcryp);
2185         return HAL_ERROR;
2186       }
2187       /* Turn back to ALGOMODE of the configuration */
2188       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2189     }
2190     else  /*Algorithm CTR */
2191     {
2192       /*  Set the Key*/
2193       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2194     }
2195 
2196     /* Set IV */
2197     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2198     {
2199       /* Set the Initialization Vector*/
2200       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2201       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2202       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2203       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2204     }
2205   } /* if (DoKeyIVConfig == 1U) */
2206 
2207   /* Set the phase */
2208   hcryp->Phase = CRYP_PHASE_PROCESS;
2209 
2210   /* Enable CRYP */
2211   __HAL_CRYP_ENABLE(hcryp);
2212 
2213   /*Temporary CrypOutCount Value*/
2214   outcount = hcryp->CrypOutCount;
2215 
2216   while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2217   {
2218     /* Write plain data and get cipher data */
2219     CRYP_AES_ProcessData(hcryp, Timeout);
2220     /*Temporary CrypOutCount Value*/
2221     outcount = hcryp->CrypOutCount;
2222   }
2223 
2224   /* Disable CRYP */
2225   __HAL_CRYP_DISABLE(hcryp);
2226 
2227   /* Change the CRYP state */
2228   hcryp->State = HAL_CRYP_STATE_READY;
2229 
2230   /* Return function status */
2231   return HAL_OK;
2232 }
2233 /**
2234   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2235   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2236   *         the configuration information for CRYP module
2237   * @retval HAL status
2238   */
CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef * hcryp)2239 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
2240 {
2241   __IO uint32_t count = 0U;
2242   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2243 
2244   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2245   {
2246     if (hcryp->KeyIVConfig == 1U)
2247     {
2248       /* If the Key and IV configuration has to be done only once
2249          and if it has already been done, skip it */
2250       DoKeyIVConfig = 0U;
2251     }
2252     else
2253     {
2254       /* If the Key and IV configuration has to be done only once
2255          and if it has not been done already, do it and set KeyIVConfig
2256          to keep track it won't have to be done again next time */
2257       hcryp->KeyIVConfig = 1U;
2258     }
2259   }
2260 
2261   if (DoKeyIVConfig == 1U)
2262   {
2263     /*  Key preparation for ECB/CBC */
2264     if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2265     {
2266       /* change ALGOMODE to key preparation for decryption*/
2267       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2268 
2269       /*  Set the Key*/
2270       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2271 
2272       /* Enable CRYP */
2273       __HAL_CRYP_ENABLE(hcryp);
2274 
2275       /* Wait for BUSY flag to be raised */
2276       count = CRYP_TIMEOUT_KEYPREPARATION;
2277       do
2278       {
2279         count-- ;
2280         if (count == 0U)
2281         {
2282           /* Change state */
2283           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2284           hcryp->State = HAL_CRYP_STATE_READY;
2285 
2286           /* Process unlocked */
2287           __HAL_UNLOCK(hcryp);
2288           return HAL_ERROR;
2289         }
2290       }
2291       while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2292 
2293       /* Turn back to ALGOMODE of the configuration */
2294       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2295     }
2296     else  /*Algorithm CTR */
2297     {
2298       /*  Set the Key*/
2299       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2300     }
2301 
2302     /* Set IV */
2303     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2304     {
2305       /* Set the Initialization Vector*/
2306       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2307       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2308       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2309       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2310     }
2311   } /* if (DoKeyIVConfig == 1U) */
2312 
2313   /* Set the phase */
2314   hcryp->Phase = CRYP_PHASE_PROCESS;
2315   if (hcryp->Size != 0U)
2316   {
2317     /* Enable interrupts */
2318     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2319 
2320     /* Enable CRYP */
2321     __HAL_CRYP_ENABLE(hcryp);
2322   }
2323   else
2324   {
2325     /* Process locked */
2326     __HAL_UNLOCK(hcryp);
2327 
2328     /* Change the CRYP state */
2329     hcryp->State = HAL_CRYP_STATE_READY;
2330   }
2331   /* Return function status */
2332   return HAL_OK;
2333 }
2334 /**
2335   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
2336   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2337   *         the configuration information for CRYP module
2338   * @retval HAL status
2339   */
CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef * hcryp)2340 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
2341 {
2342   __IO uint32_t count = 0U;
2343   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2344 
2345   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2346   {
2347     if (hcryp->KeyIVConfig == 1U)
2348     {
2349       /* If the Key and IV configuration has to be done only once
2350          and if it has already been done, skip it */
2351       DoKeyIVConfig = 0U;
2352     }
2353     else
2354     {
2355       /* If the Key and IV configuration has to be done only once
2356          and if it has not been done already, do it and set KeyIVConfig
2357          to keep track it won't have to be done again next time */
2358       hcryp->KeyIVConfig = 1U;
2359     }
2360   }
2361 
2362   if (DoKeyIVConfig == 1U)
2363   {
2364     /*  Key preparation for ECB/CBC */
2365     if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2366     {
2367       /* change ALGOMODE to key preparation for decryption*/
2368       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2369 
2370       /*  Set the Key*/
2371       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2372 
2373       /* Enable CRYP */
2374       __HAL_CRYP_ENABLE(hcryp);
2375 
2376       /* Wait for BUSY flag to be raised */
2377       count = CRYP_TIMEOUT_KEYPREPARATION;
2378       do
2379       {
2380         count-- ;
2381         if (count == 0U)
2382         {
2383           /* Disable the CRYP peripheral clock */
2384           __HAL_CRYP_DISABLE(hcryp);
2385 
2386           /* Change state */
2387           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2388           hcryp->State = HAL_CRYP_STATE_READY;
2389 
2390           /* Process unlocked */
2391           __HAL_UNLOCK(hcryp);
2392           return HAL_ERROR;
2393         }
2394       }
2395       while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2396 
2397       /* Turn back to ALGOMODE of the configuration */
2398       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2399     }
2400     else  /*Algorithm CTR */
2401     {
2402       /*  Set the Key*/
2403       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2404     }
2405 
2406     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2407     {
2408       /* Set the Initialization Vector*/
2409       hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2410       hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2411       hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2412       hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2413     }
2414   } /* if (DoKeyIVConfig == 1U) */
2415 
2416   /* Set the phase */
2417   hcryp->Phase = CRYP_PHASE_PROCESS;
2418 
2419   if (hcryp->Size != 0U)
2420   {
2421     /* Set the input and output addresses and start DMA transfer */
2422     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
2423                       (uint32_t)(hcryp->pCrypOutBuffPtr));
2424   }
2425   else
2426   {
2427     /* Process unlocked */
2428     __HAL_UNLOCK(hcryp);
2429 
2430     /* Change the CRYP state */
2431     hcryp->State = HAL_CRYP_STATE_READY;
2432   }
2433 
2434   /* Return function status */
2435   return HAL_OK;
2436 }
2437 
2438 
2439 /**
2440   * @brief  DMA CRYP input data process complete callback.
2441   * @param  hdma: DMA handle
2442   * @retval None
2443   */
CRYP_DMAInCplt(DMA_HandleTypeDef * hdma)2444 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
2445 {
2446   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2447 
2448   /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit
2449   in the DMACR register */
2450   hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
2451 
2452   /* Call input data transfer complete callback */
2453 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2454   /*Call registered Input complete callback*/
2455   hcryp->InCpltCallback(hcryp);
2456 #else
2457   /*Call legacy weak Input complete callback*/
2458   HAL_CRYP_InCpltCallback(hcryp);
2459 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2460 }
2461 
2462 /**
2463   * @brief  DMA CRYP output data process complete callback.
2464   * @param  hdma: DMA handle
2465   * @retval None
2466   */
CRYP_DMAOutCplt(DMA_HandleTypeDef * hdma)2467 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
2468 {
2469   uint32_t count;
2470   uint32_t npblb;
2471   uint32_t lastwordsize;
2472   uint32_t temp;  /* Temporary CrypOutBuff */
2473   uint32_t temp_cr_algodir;
2474   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2475 
2476 
2477   /* Disable the DMA transfer for output FIFO */
2478   hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
2479 
2480   /* Last block transfer in case of GCM or CCM with Size not %16*/
2481   if (((hcryp->Size) % 16U) != 0U)
2482   {
2483     /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA  */
2484     hcryp->CrypInCount = (hcryp->Size / 16U) * 4U ;
2485     hcryp->CrypOutCount = hcryp->CrypInCount;
2486 
2487     /* Compute the number of padding bytes in last block of payload */
2488     npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
2489 
2490 #if !defined (CRYP_VER_2_2)
2491     if (hcryp->Version >= REV_ID_B)
2492 #endif /*End of not defined CRYP_VER_2_2*/
2493     {
2494       /* Case of AES GCM payload encryption or AES CCM payload decryption to get right tag */
2495       temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
2496       if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
2497           ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
2498       {
2499         /* Disable the CRYP */
2500         __HAL_CRYP_DISABLE(hcryp);
2501 
2502         /* Specify the number of non-valid bytes using NPBLB register*/
2503         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
2504 
2505         /* Enable CRYP to start the final phase */
2506         __HAL_CRYP_ENABLE(hcryp);
2507       }
2508     }
2509 
2510     /* Number of valid words (lastwordsize) in last block */
2511     if ((npblb % 4U) == 0U)
2512     {
2513       lastwordsize = (16U - npblb) / 4U;
2514     }
2515     else
2516     {
2517       lastwordsize = ((16U - npblb) / 4U) + 1U;
2518     }
2519     /* Write the last input block in the IN FIFO */
2520     for (count = 0U; count < lastwordsize; count ++)
2521     {
2522       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2523       hcryp->CrypInCount++;
2524     }
2525     /* Pad the data with zeros to have a complete block */
2526     while (count < 4U)
2527     {
2528       hcryp->Instance->DIN  = 0U;
2529       count++;
2530     }
2531     /* Wait for OFNE flag to be raised */
2532     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
2533     do
2534     {
2535       count-- ;
2536       if (count == 0U)
2537       {
2538         /* Disable the CRYP peripheral clock */
2539         __HAL_CRYP_DISABLE(hcryp);
2540 
2541         /* Change state */
2542         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2543         hcryp->State = HAL_CRYP_STATE_READY;
2544 
2545         /* Process unlocked */
2546         __HAL_UNLOCK(hcryp);
2547 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2548         /*Call registered error callback*/
2549         hcryp->ErrorCallback(hcryp);
2550 #else
2551         /*Call legacy weak error callback*/
2552         HAL_CRYP_ErrorCallback(hcryp);
2553 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2554       }
2555     }
2556     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
2557 
2558     /*Read the output block from the output FIFO */
2559     for (count = 0U; count < 4U; count++)
2560     {
2561       /* Read the output block from the output FIFO and put them in temporary buffer
2562          then get CrypOutBuff from temporary buffer */
2563       temp = hcryp->Instance->DOUT;
2564 
2565       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2566       hcryp->CrypOutCount++;
2567     }
2568   } /*End of last block transfer in case of GCM or CCM */
2569 
2570   if ((hcryp->Init.Algorithm & CRYP_AES_GCM) != CRYP_AES_GCM)
2571   {
2572     /* Disable CRYP  (not allowed in  GCM)*/
2573     __HAL_CRYP_DISABLE(hcryp);
2574   }
2575 
2576   /* Change the CRYP state to ready */
2577   hcryp->State = HAL_CRYP_STATE_READY;
2578 
2579   /* Process unlocked */
2580   __HAL_UNLOCK(hcryp);
2581 
2582   /* Call output data transfer complete callback */
2583 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2584   /*Call registered Output complete callback*/
2585   hcryp->OutCpltCallback(hcryp);
2586 #else
2587   /*Call legacy weak Output complete callback*/
2588   HAL_CRYP_OutCpltCallback(hcryp);
2589 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2590 }
2591 
2592 /**
2593   * @brief  DMA CRYP communication error callback.
2594   * @param  hdma: DMA handle
2595   * @retval None
2596   */
CRYP_DMAError(DMA_HandleTypeDef * hdma)2597 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
2598 {
2599   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2600 
2601   /* Change the CRYP peripheral state */
2602   hcryp->State = HAL_CRYP_STATE_READY;
2603 
2604   /* DMA error code field */
2605   hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2606 
2607   /* Call error callback */
2608 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2609   /*Call registered error callback*/
2610   hcryp->ErrorCallback(hcryp);
2611 #else
2612   /*Call legacy weak error callback*/
2613   HAL_CRYP_ErrorCallback(hcryp);
2614 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2615 }
2616 
2617 /**
2618   * @brief  Set the DMA configuration and start the DMA transfer
2619   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2620   *         the configuration information for CRYP module
2621   * @param  inputaddr: address of the input buffer
2622   * @param  Size: size of the input buffer, must be a multiple of 16.
2623   * @param  outputaddr: address of the output buffer
2624   * @retval None
2625   */
CRYP_SetDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size,uint32_t outputaddr)2626 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2627 {
2628   /* Set the CRYP DMA transfer complete callback */
2629   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2630 
2631   /* Set the DMA input error callback */
2632   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2633 
2634   /* Set the CRYP DMA transfer complete callback */
2635   hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2636 
2637   /* Set the DMA output error callback */
2638   hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2639 
2640   /* Enable CRYP */
2641   __HAL_CRYP_ENABLE(hcryp);
2642 
2643   /* Enable the input DMA Stream */
2644   if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DIN, Size) != HAL_OK)
2645   {
2646     /* DMA error code field */
2647     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2648 
2649     /* Call error callback */
2650 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2651     /*Call registered error callback*/
2652     hcryp->ErrorCallback(hcryp);
2653 #else
2654     /*Call legacy weak error callback*/
2655     HAL_CRYP_ErrorCallback(hcryp);
2656 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2657   }
2658 
2659   /* Enable the output DMA Stream */
2660   if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size) != HAL_OK)
2661   {
2662     /* DMA error code field */
2663     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2664 
2665     /* Call error callback */
2666 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2667     /*Call registered error callback*/
2668     hcryp->ErrorCallback(hcryp);
2669 #else
2670     /*Call legacy weak error callback*/
2671     HAL_CRYP_ErrorCallback(hcryp);
2672 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2673   }
2674   /* Enable In/Out DMA request */
2675   hcryp->Instance->DMACR = CRYP_DMACR_DOEN | CRYP_DMACR_DIEN;
2676 }
2677 
2678 /**
2679   * @brief  Process Data: Write Input data in polling mode and used in AES functions.
2680   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2681   *         the configuration information for CRYP module
2682   * @param  Timeout: Specify Timeout value
2683   * @retval None
2684   */
CRYP_AES_ProcessData(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2685 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2686 {
2687 
2688   uint32_t temp[4];  /* Temporary CrypOutBuff */
2689   uint16_t incount;  /* Temporary CrypInCount Value */
2690   uint16_t outcount;  /* Temporary CrypOutCount Value */
2691   uint32_t i;
2692 
2693   /*Temporary CrypOutCount Value*/
2694   incount = hcryp->CrypInCount;
2695 
2696   if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < ((hcryp->Size) / 4U)))
2697   {
2698     /* Write the input block in the IN FIFO */
2699     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2700     hcryp->CrypInCount++;
2701     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2702     hcryp->CrypInCount++;
2703     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2704     hcryp->CrypInCount++;
2705     hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2706     hcryp->CrypInCount++;
2707   }
2708 
2709   /* Wait for OFNE flag to be raised */
2710   if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
2711   {
2712     /* Disable the CRYP peripheral clock */
2713     __HAL_CRYP_DISABLE(hcryp);
2714 
2715     /* Change state & error code*/
2716     hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2717     hcryp->State = HAL_CRYP_STATE_READY;
2718 
2719     /* Process unlocked */
2720     __HAL_UNLOCK(hcryp);
2721 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2722     /*Call registered error callback*/
2723     hcryp->ErrorCallback(hcryp);
2724 #else
2725     /*Call legacy weak error callback*/
2726     HAL_CRYP_ErrorCallback(hcryp);
2727 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2728   }
2729   /*Temporary CrypOutCount Value*/
2730   outcount = hcryp->CrypOutCount;
2731 
2732   if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < ((hcryp->Size) / 4U)))
2733   {
2734     /* Read the output block from the Output FIFO and put them in temporary buffer
2735        then get CrypOutBuff from temporary buffer  */
2736     for (i = 0U; i < 4U; i++)
2737     {
2738       temp[i] = hcryp->Instance->DOUT;
2739     }
2740     i = 0U;
2741     while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
2742     {
2743       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2744       hcryp->CrypOutCount++;
2745       i++;
2746     }
2747   }
2748 }
2749 
2750 /**
2751   * @brief  Handle CRYP block input/output data handling under interruption.
2752   * @note   The function is called under interruption only, once
2753   *         interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
2754   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2755   *         the configuration information for CRYP module.
2756   * @retval HAL status
2757   */
CRYP_AES_IT(CRYP_HandleTypeDef * hcryp)2758 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
2759 {
2760   uint32_t temp[4];  /* Temporary CrypOutBuff */
2761   uint16_t incount; /* Temporary CrypInCount Value */
2762   uint16_t outcount;  /* Temporary CrypOutCount Value */
2763   uint32_t i;
2764 
2765   if (hcryp->State == HAL_CRYP_STATE_BUSY)
2766   {
2767     /*Temporary CrypOutCount Value*/
2768     incount = hcryp->CrypInCount;
2769 
2770     if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
2771     {
2772       /* Write the input block in the IN FIFO */
2773       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2774       hcryp->CrypInCount++;
2775       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2776       hcryp->CrypInCount++;
2777       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2778       hcryp->CrypInCount++;
2779       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2780       hcryp->CrypInCount++;
2781       if (hcryp->CrypInCount == (hcryp->Size / 4U))
2782       {
2783         /* Disable interrupts */
2784         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
2785 
2786         /* Call the input data transfer complete callback */
2787 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2788         /*Call registered Input complete callback*/
2789         hcryp->InCpltCallback(hcryp);
2790 #else
2791         /*Call legacy weak Input complete callback*/
2792         HAL_CRYP_InCpltCallback(hcryp);
2793 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2794       }
2795     }
2796 
2797     /*Temporary CrypOutCount Value*/
2798     outcount = hcryp->CrypOutCount;
2799 
2800     if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
2801     {
2802       /* Read the output block from the output FIFO and put them in temporary buffer
2803          then get CrypOutBuff from temporary buffer  */
2804       for (i = 0U; i < 4U; i++)
2805       {
2806         temp[i] = hcryp->Instance->DOUT;
2807       }
2808       i = 0U;
2809       while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
2810       {
2811         *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2812         hcryp->CrypOutCount++;
2813         i++;
2814       }
2815       if (hcryp->CrypOutCount == (hcryp->Size / 4U))
2816       {
2817         /* Disable interrupts */
2818         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
2819 
2820         /* Change the CRYP state */
2821         hcryp->State = HAL_CRYP_STATE_READY;
2822 
2823         /* Disable CRYP */
2824         __HAL_CRYP_DISABLE(hcryp);
2825 
2826         /* Process unlocked */
2827         __HAL_UNLOCK(hcryp);
2828 
2829         /* Call output transfer complete callback */
2830 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2831         /*Call registered Output complete callback*/
2832         hcryp->OutCpltCallback(hcryp);
2833 #else
2834         /*Call legacy weak Output complete callback*/
2835         HAL_CRYP_OutCpltCallback(hcryp);
2836 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2837       }
2838     }
2839   }
2840   else
2841   {
2842     /* Process unlocked */
2843     __HAL_UNLOCK(hcryp);
2844     /* Busy error code field */
2845     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
2846 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2847     /*Call registered error callback*/
2848     hcryp->ErrorCallback(hcryp);
2849 #else
2850     /*Call legacy weak error callback*/
2851     HAL_CRYP_ErrorCallback(hcryp);
2852 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2853   }
2854 }
2855 
2856 /**
2857   * @brief  Writes Key in Key registers.
2858   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2859   *         the configuration information for CRYP module
2860   * @param  KeySize: Size of Key
2861   * @retval None
2862   */
CRYP_SetKey(CRYP_HandleTypeDef * hcryp,uint32_t KeySize)2863 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
2864 {
2865   switch (KeySize)
2866   {
2867     case CRYP_KEYSIZE_256B:
2868       hcryp->Instance->K0LR = *(uint32_t *)(hcryp->Init.pKey);
2869       hcryp->Instance->K0RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2870       hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2871       hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2872       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2873       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2874       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 6);
2875       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 7);
2876       break;
2877     case CRYP_KEYSIZE_192B:
2878       hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
2879       hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2880       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2881       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2882       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2883       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2884       break;
2885     case CRYP_KEYSIZE_128B:
2886       hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey);
2887       hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2888       hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2889       hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2890 
2891       break;
2892     default:
2893       break;
2894   }
2895 }
2896 
2897 /**
2898   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
2899   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2900   *         the configuration information for CRYP module
2901   * @param  Timeout: Timeout duration
2902   * @retval HAL status
2903   */
CRYP_AESGCM_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2904 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2905 {
2906   uint32_t tickstart;
2907   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
2908   uint32_t npblb ;
2909   uint32_t temp[4];  /* Temporary CrypOutBuff */
2910   uint32_t index ;
2911   uint32_t lastwordsize ;
2912   uint32_t nolastpaddingbytes;
2913   uint8_t *pval;
2914   uint16_t outcount;  /* Temporary CrypOutCount Value */
2915   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2916 
2917   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2918   {
2919     if (hcryp->KeyIVConfig == 1U)
2920     {
2921       /* If the Key and IV configuration has to be done only once
2922          and if it has already been done, skip it */
2923       DoKeyIVConfig = 0U;
2924       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
2925     }
2926     else
2927     {
2928       /* If the Key and IV configuration has to be done only once
2929          and if it has not been done already, do it and set KeyIVConfig
2930          to keep track it won't have to be done again next time */
2931       hcryp->KeyIVConfig = 1U;
2932       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
2933     }
2934   }
2935   else
2936   {
2937     hcryp->SizesSum = hcryp->Size;
2938   }
2939 
2940   if (DoKeyIVConfig == 1U)
2941   {
2942     /*  Reset CrypHeaderCount */
2943     hcryp->CrypHeaderCount = 0U;
2944 
2945     /****************************** Init phase **********************************/
2946 
2947     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2948 
2949     /* Set the key */
2950     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2951 
2952     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
2953     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2954     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2955     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2956     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2957 
2958     /* Enable the CRYP peripheral */
2959     __HAL_CRYP_ENABLE(hcryp);
2960 
2961     /* Get tick */
2962     tickstart = HAL_GetTick();
2963 
2964     /*Wait for the CRYPEN bit to be cleared*/
2965     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2966     {
2967       /* Check for the Timeout */
2968       if (Timeout != HAL_MAX_DELAY)
2969       {
2970         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2971         {
2972           /* Disable the CRYP peripheral clock */
2973           __HAL_CRYP_DISABLE(hcryp);
2974 
2975           /* Change state */
2976           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2977           hcryp->State = HAL_CRYP_STATE_READY;
2978 
2979           /* Process unlocked */
2980           __HAL_UNLOCK(hcryp);
2981           return HAL_ERROR;
2982         }
2983       }
2984     }
2985 
2986     /************************ Header phase *************************************/
2987 
2988     if (CRYP_GCMCCM_SetHeaderPhase(hcryp,  Timeout) != HAL_OK)
2989     {
2990       return HAL_ERROR;
2991     }
2992 
2993     /*************************Payload phase ************************************/
2994 
2995     /* Set the phase */
2996     hcryp->Phase = CRYP_PHASE_PROCESS;
2997 
2998     /* Disable the CRYP peripheral */
2999     __HAL_CRYP_DISABLE(hcryp);
3000 
3001 #if !defined (CRYP_VER_2_2)
3002     if (hcryp->Version >= REV_ID_B)
3003 #endif /*End of not defined CRYP_VER_2_2*/
3004     {
3005       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3006       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3007     }
3008 
3009     /* Select payload phase once the header phase is performed */
3010     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3011 
3012     /* Enable the CRYP peripheral */
3013     __HAL_CRYP_ENABLE(hcryp);
3014   } /* if (DoKeyIVConfig == 1U) */
3015 
3016   if ((hcryp->Size % 16U) != 0U)
3017   {
3018     /* recalculate  wordsize */
3019     wordsize = ((wordsize / 4U) * 4U) ;
3020   }
3021 
3022   /* Get tick */
3023   tickstart = HAL_GetTick();
3024   /*Temporary CrypOutCount Value*/
3025   outcount = hcryp->CrypOutCount;
3026 
3027   /* Write input data and get output Data */
3028   while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3029   {
3030     /* Write plain data and get cipher data */
3031     CRYP_AES_ProcessData(hcryp, Timeout);
3032 
3033     /*Temporary CrypOutCount Value*/
3034     outcount = hcryp->CrypOutCount;
3035 
3036     /* Check for the Timeout */
3037     if (Timeout != HAL_MAX_DELAY)
3038     {
3039       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3040       {
3041         /* Disable the CRYP peripheral clock */
3042         __HAL_CRYP_DISABLE(hcryp);
3043 
3044         /* Change state & error code */
3045         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3046         hcryp->State = HAL_CRYP_STATE_READY;
3047 
3048         /* Process unlocked */
3049         __HAL_UNLOCK(hcryp);
3050         return HAL_ERROR;
3051       }
3052     }
3053   }
3054 
3055   if ((hcryp->Size % 16U) != 0U)
3056   {
3057 
3058 #if !defined (CRYP_VER_2_2)
3059     if (hcryp->Version >= REV_ID_B)
3060 #endif /*End of not defined CRYP_VER_2_2*/
3061     {
3062       /* Compute the number of padding bytes in last block of payload */
3063       npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3064 
3065       /*  Set Npblb in case of AES GCM payload encryption to get right tag*/
3066       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3067       {
3068         /* Disable the CRYP */
3069         __HAL_CRYP_DISABLE(hcryp);
3070 
3071         /* Specify the number of non-valid bytes using NPBLB register*/
3072         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3073 
3074         /* Enable CRYP to start the final phase */
3075         __HAL_CRYP_ENABLE(hcryp);
3076       }
3077       /* Number of valid words (lastwordsize) in last block */
3078       if ((npblb % 4U) == 0U)
3079       {
3080         lastwordsize = (16U - npblb) / 4U;
3081       }
3082       else
3083       {
3084         lastwordsize = ((16U - npblb) / 4U) + 1U;
3085       }
3086 
3087       /* Write the last input block in the IN FIFO */
3088       for (index = 0U; index < lastwordsize; index ++)
3089       {
3090         hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3091         hcryp->CrypInCount++;
3092       }
3093 
3094       /* Pad the data with zeros to have a complete block */
3095       while (index < 4U)
3096       {
3097         hcryp->Instance->DIN  = 0U;
3098         index++;
3099       }
3100 
3101       /* Wait for OFNE flag to be raised */
3102       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3103       {
3104         /* Disable the CRYP peripheral clock */
3105         __HAL_CRYP_DISABLE(hcryp);
3106 
3107         /* Change state */
3108         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3109         hcryp->State = HAL_CRYP_STATE_READY;
3110 
3111         /* Process Unlocked */
3112         __HAL_UNLOCK(hcryp);
3113 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3114         /*Call registered error callback*/
3115         hcryp->ErrorCallback(hcryp);
3116 #else
3117         /*Call legacy weak error callback*/
3118         HAL_CRYP_ErrorCallback(hcryp);
3119 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3120       }
3121 
3122       /*Read the output block from the output FIFO */
3123       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3124       {
3125         for (index = 0U; index < 4U; index++)
3126         {
3127           /* Read the output block from the output FIFO and put them in temporary buffer
3128           then get CrypOutBuff from temporary buffer */
3129           temp[index] = hcryp->Instance->DOUT;
3130         }
3131 
3132         for (index = 0U; index < lastwordsize; index++)
3133         {
3134           pval = (uint8_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount));
3135 
3136           if (index == (lastwordsize - 1U))
3137           {
3138             nolastpaddingbytes = npblb % 4U;
3139 
3140             switch (nolastpaddingbytes)
3141             {
3142               case 1:
3143                 *(pval) = (uint8_t)(temp[index]);
3144                 pval++;
3145                 *(pval) = (uint8_t)(temp[index] >> 8U);
3146                 pval++;
3147                 *(pval) = (uint8_t)(temp[index] >> 16U);
3148                 break;
3149               case 2:
3150                 *(pval) = (uint8_t)(temp[index]);
3151                 pval++;
3152                 *(pval) = (uint8_t)(temp[index] >> 8U);
3153                 break;
3154               case 3:
3155                 *(pval) = (uint8_t)(temp[index]);
3156                 break;
3157               default:
3158                 *(pval) = (uint8_t)(temp[index]);
3159                 pval++;
3160                 *(pval) = (uint8_t)(temp[index] >> 8U);
3161                 pval++;
3162                 *(pval) = (uint8_t)(temp[index] >> 16U);
3163                 pval++;
3164                 *(pval) = (uint8_t)(temp[index] >> 24U);
3165                 break;
3166             }
3167           }
3168           else
3169           {
3170             *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
3171           }
3172 
3173           hcryp->CrypOutCount++;
3174         }
3175       }
3176     }
3177 #if !defined (CRYP_VER_2_2)
3178     else /*  Workaround to be used */
3179     {
3180       /*  Workaround 2 for STM32H7 below rev.B To generate correct TAG only when size of the last block of
3181       payload is inferior to 128 bits, in case of GCM encryption or CCM decryption*/
3182       CRYP_Workaround(hcryp, Timeout);
3183     } /* end of NPBLB or Workaround*/
3184 #endif /*End of not defined CRYP_VER_2_2*/
3185   }
3186 
3187   /* Return function status */
3188   return HAL_OK;
3189 }
3190 
3191 /**
3192   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
3193   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3194   *         the configuration information for CRYP module
3195   * @retval HAL status
3196   */
CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef * hcryp)3197 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3198 {
3199   __IO uint32_t count = 0U;
3200   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3201 
3202   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3203   {
3204     if (hcryp->KeyIVConfig == 1U)
3205     {
3206       /* If the Key and IV configuration has to be done only once
3207       and if it has already been done, skip it */
3208       DoKeyIVConfig = 0U;
3209       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3210     }
3211     else
3212     {
3213       /* If the Key and IV configuration has to be done only once
3214       and if it has not been done already, do it and set KeyIVConfig
3215       to keep track it won't have to be done again next time */
3216       hcryp->KeyIVConfig = 1U;
3217       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3218     }
3219   }
3220   else
3221   {
3222     hcryp->SizesSum = hcryp->Size;
3223   }
3224 
3225   /* Configure Key, IV and process message (header and payload) */
3226   if (DoKeyIVConfig == 1U)
3227   {
3228     /*  Reset CrypHeaderCount */
3229     hcryp->CrypHeaderCount = 0U;
3230 
3231     /******************************* Init phase *********************************/
3232 
3233     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3234 
3235     /* Set the key */
3236     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3237 
3238     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3239     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3240     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3241     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3242     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3243 
3244     /* Enable the CRYP peripheral */
3245     __HAL_CRYP_ENABLE(hcryp);
3246 
3247     /*Wait for the CRYPEN bit to be cleared*/
3248     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3249     do
3250     {
3251       count-- ;
3252       if (count == 0U)
3253       {
3254         /* Disable the CRYP peripheral clock */
3255         __HAL_CRYP_DISABLE(hcryp);
3256 
3257         /* Change state */
3258         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3259         hcryp->State = HAL_CRYP_STATE_READY;
3260 
3261         /* Process unlocked */
3262         __HAL_UNLOCK(hcryp);
3263         return HAL_ERROR;
3264       }
3265     }
3266     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3267 
3268     /***************************** Header phase *********************************/
3269 
3270     /* Select header phase */
3271     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3272   } /* end of if (DoKeyIVConfig == 1U) */
3273   /* Enable interrupts */
3274   __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3275 
3276   /* Enable CRYP */
3277   __HAL_CRYP_ENABLE(hcryp);
3278 
3279   /* Return function status */
3280   return HAL_OK;
3281 }
3282 
3283 
3284 /**
3285   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
3286   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3287   *         the configuration information for CRYP module
3288   * @retval HAL status
3289   */
CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef * hcryp)3290 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3291 {
3292   __IO uint32_t count = 0U;
3293   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3294   uint32_t index;
3295   uint32_t npblb;
3296   uint32_t lastwordsize;
3297   uint32_t temp[4];  /* Temporary CrypOutBuff */
3298   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3299 
3300   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3301   {
3302     if (hcryp->KeyIVConfig == 1U)
3303     {
3304       /* If the Key and IV configuration has to be done only once
3305          and if it has already been done, skip it */
3306       DoKeyIVConfig = 0U;
3307       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3308     }
3309     else
3310     {
3311       /* If the Key and IV configuration has to be done only once
3312          and if it has not been done already, do it and set KeyIVConfig
3313          to keep track it won't have to be done again next time */
3314       hcryp->KeyIVConfig = 1U;
3315       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3316     }
3317   }
3318   else
3319   {
3320     hcryp->SizesSum = hcryp->Size;
3321   }
3322 
3323   if (DoKeyIVConfig == 1U)
3324   {
3325     /*  Reset CrypHeaderCount */
3326     hcryp->CrypHeaderCount = 0U;
3327 
3328     /*************************** Init phase ************************************/
3329 
3330     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3331 
3332     /* Set the key */
3333     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3334 
3335     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3336     hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3337     hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3338     hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3339     hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3340 
3341     /* Enable the CRYP peripheral */
3342     __HAL_CRYP_ENABLE(hcryp);
3343 
3344     /*Wait for the CRYPEN bit to be cleared*/
3345     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3346     do
3347     {
3348       count-- ;
3349       if (count == 0U)
3350       {
3351         /* Disable the CRYP peripheral clock */
3352         __HAL_CRYP_DISABLE(hcryp);
3353 
3354         /* Change state */
3355         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3356         hcryp->State = HAL_CRYP_STATE_READY;
3357 
3358         /* Process unlocked */
3359         __HAL_UNLOCK(hcryp);
3360         return HAL_ERROR;
3361       }
3362     }
3363     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3364 
3365     /************************ Header phase *************************************/
3366 
3367     if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
3368     {
3369       return HAL_ERROR;
3370     }
3371 
3372     /************************ Payload phase ************************************/
3373 
3374     /* Set the phase */
3375     hcryp->Phase = CRYP_PHASE_PROCESS;
3376 
3377     /* Disable the CRYP peripheral */
3378     __HAL_CRYP_DISABLE(hcryp);
3379 
3380 #if !defined (CRYP_VER_2_2)
3381     if (hcryp->Version >= REV_ID_B)
3382 #endif /*End of not defined CRYP_VER_2_2*/
3383     {
3384       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3385       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3386     }
3387 
3388     /* Select payload phase once the header phase is performed */
3389     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3390 
3391   } /* if (DoKeyIVConfig == 1U) */
3392 
3393   if (hcryp->Size == 0U)
3394   {
3395     /* Process unLocked */
3396     __HAL_UNLOCK(hcryp);
3397 
3398     /* Change the CRYP state and phase */
3399     hcryp->State = HAL_CRYP_STATE_READY;
3400   }
3401   else if (hcryp->Size >= 16U)
3402   {
3403     /* for STM32H7 below rev.B : Size should be %4  otherwise Tag will  be incorrectly generated for GCM Encryption:
3404     Workaround is implemented in polling mode, so if last block of payload <128bit don't use DMA mode otherwise
3405     TAG is incorrectly generated */
3406 
3407     /*DMA transfer must not include the last block in case of Size is not %16 */
3408     wordsize = wordsize - (wordsize % 4U);
3409 
3410     /*DMA transfer */
3411     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)wordsize,
3412                       (uint32_t)(hcryp->pCrypOutBuffPtr));
3413   }
3414   else /* length of input data is < 16 */
3415   {
3416     /* Compute the number of padding bytes in last block of payload */
3417     npblb = 16U - (uint32_t)hcryp->Size;
3418 
3419 #if !defined (CRYP_VER_2_2)
3420     if (hcryp->Version >= REV_ID_B)
3421 #endif /*End of not defined CRYP_VER_2_2*/
3422     {
3423       /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3424       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3425       {
3426         /* Specify the number of non-valid bytes using NPBLB register*/
3427         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3428       }
3429     }
3430     /* Enable CRYP to start the final phase */
3431     __HAL_CRYP_ENABLE(hcryp);
3432 
3433     /* Number of valid words (lastwordsize) in last block */
3434     if ((npblb % 4U) == 0U)
3435     {
3436       lastwordsize = (16U - npblb) / 4U;
3437     }
3438     else
3439     {
3440       lastwordsize = ((16U - npblb) / 4U) + 1U;
3441     }
3442 
3443     /* Write the last input block in the IN FIFO */
3444     for (index = 0; index < lastwordsize; index ++)
3445     {
3446       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3447       hcryp->CrypInCount++;
3448     }
3449 
3450     /* Pad the data with zeros to have a complete block */
3451     while (index < 4U)
3452     {
3453       hcryp->Instance->DIN  = 0U;
3454       index++;
3455     }
3456 
3457     /* Wait for OFNE flag to be raised */
3458     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
3459     do
3460     {
3461       count-- ;
3462       if (count == 0U)
3463       {
3464         /* Disable the CRYP peripheral clock */
3465         __HAL_CRYP_DISABLE(hcryp);
3466 
3467         /* Change state */
3468         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3469         hcryp->State = HAL_CRYP_STATE_READY;
3470 
3471         /* Process unlocked */
3472         __HAL_UNLOCK(hcryp);
3473 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3474         /*Call registered error callback*/
3475         hcryp->ErrorCallback(hcryp);
3476 #else
3477         /*Call legacy weak error callback*/
3478         HAL_CRYP_ErrorCallback(hcryp);
3479 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3480       }
3481     }
3482     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
3483 
3484     /*Read the output block from the output FIFO */
3485     for (index = 0U; index < 4U; index++)
3486     {
3487       /* Read the output block from the output FIFO and put them in temporary buffer
3488       then get CrypOutBuff from temporary buffer */
3489       temp[index] = hcryp->Instance->DOUT;
3490     }
3491     for (index = 0; index < lastwordsize; index++)
3492     {
3493       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3494       hcryp->CrypOutCount++;
3495     }
3496 
3497     /* Change the CRYP state to ready */
3498     hcryp->State = HAL_CRYP_STATE_READY;
3499 
3500     /* Process unlocked */
3501     __HAL_UNLOCK(hcryp);
3502   }
3503 
3504   /* Return function status */
3505   return HAL_OK;
3506 }
3507 
3508 
3509 /**
3510   * @brief  AES CCM encryption/decryption processing in polling mode
3511   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3512   *         the configuration information for CRYP module
3513   * @param  Timeout: Timeout duration
3514   * @retval HAL status
3515   */
CRYP_AESCCM_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)3516 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3517 {
3518   uint32_t tickstart;
3519   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
3520   uint32_t npblb ;
3521   uint32_t lastwordsize ;
3522   uint32_t temp[4] ;  /* Temporary CrypOutBuff */
3523   uint32_t index ;
3524   uint16_t outcount;  /* Temporary CrypOutCount Value */
3525   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3526 
3527   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3528   {
3529     if (hcryp->KeyIVConfig == 1U)
3530     {
3531       /* If the Key and IV configuration has to be done only once
3532       and if it has already been done, skip it */
3533       DoKeyIVConfig = 0U;
3534       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3535     }
3536     else
3537     {
3538       /* If the Key and IV configuration has to be done only once
3539       and if it has not been done already, do it and set KeyIVConfig
3540       to keep track it won't have to be done again next time */
3541       hcryp->KeyIVConfig = 1U;
3542       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3543     }
3544   }
3545   else
3546   {
3547     hcryp->SizesSum = hcryp->Size;
3548   }
3549 
3550   if (DoKeyIVConfig == 1U)
3551   {
3552     /*  Reset CrypHeaderCount */
3553     hcryp->CrypHeaderCount = 0U;
3554 
3555     /********************** Init phase ******************************************/
3556 
3557     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3558 
3559     /* Set the key */
3560     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3561 
3562     /* Set the initialization vector (IV) with CTR1 information */
3563     hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3564     hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3565     hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3566     hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
3567 
3568     /* Enable the CRYP peripheral */
3569     __HAL_CRYP_ENABLE(hcryp);
3570 
3571 #if defined (CRYP_VER_2_2)
3572     {
3573       /* for STM32H7 rev.B and above Write  B0 packet into CRYP_DR*/
3574       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3575       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3576       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3577       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3578     }
3579 #else
3580     if (hcryp->Version >= REV_ID_B)
3581     {
3582       /* for STM32H7 rev.B and above Write  B0 packet into CRYP_DR*/
3583       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3584       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3585       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3586       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3587     }
3588     else /* data has to be swapped according to the DATATYPE */
3589     {
3590       if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
3591       {
3592         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3593         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3594         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3595         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3596       }
3597       else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
3598       {
3599         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3600         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3601         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3602         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3603       }
3604       else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
3605       {
3606         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3607         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3608         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3609         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3610       }
3611       else
3612       {
3613         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3614         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3615         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3616         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3617       }
3618     }
3619 #endif /* CRYP_VER_2_2 */
3620     /* Get tick */
3621     tickstart = HAL_GetTick();
3622 
3623     /*Wait for the CRYPEN bit to be cleared*/
3624     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
3625     {
3626       /* Check for the Timeout */
3627       if (Timeout != HAL_MAX_DELAY)
3628       {
3629         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3630         {
3631           /* Disable the CRYP peripheral clock */
3632           __HAL_CRYP_DISABLE(hcryp);
3633 
3634           /* Change state */
3635           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3636           hcryp->State = HAL_CRYP_STATE_READY;
3637 
3638           /* Process unlocked */
3639           __HAL_UNLOCK(hcryp);
3640           return HAL_ERROR;
3641         }
3642       }
3643     }
3644 
3645     /************************* Header phase *************************************/
3646     /* Header block(B1) : associated data length expressed in bytes concatenated
3647     with Associated Data (A)*/
3648 
3649     if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
3650     {
3651       return HAL_ERROR;
3652     }
3653     /********************** Payload phase ***************************************/
3654 
3655     /* Set the phase */
3656     hcryp->Phase = CRYP_PHASE_PROCESS;
3657 
3658     /* Disable the CRYP peripheral */
3659     __HAL_CRYP_DISABLE(hcryp);
3660 #if !defined (CRYP_VER_2_2)
3661     if (hcryp->Version >= REV_ID_B)
3662 #endif /*End of not defined CRYP_VER_2_2*/
3663     {
3664       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3665       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3666     }
3667 
3668     /* Select payload phase once the header phase is performed */
3669     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3670 
3671     /* Enable the CRYP peripheral */
3672     __HAL_CRYP_ENABLE(hcryp);
3673 
3674   } /* if (DoKeyIVConfig == 1U) */
3675 
3676   if ((hcryp->Size % 16U) != 0U)
3677   {
3678     /* recalculate  wordsize */
3679     wordsize = ((wordsize / 4U) * 4U) ;
3680   }
3681   /* Get tick */
3682   tickstart = HAL_GetTick();
3683 
3684   /*Temporary CrypOutCount Value*/
3685   outcount = hcryp->CrypOutCount;
3686 
3687   /* Write input data and get output data */
3688   while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3689   {
3690     /* Write plain data and get cipher data */
3691     CRYP_AES_ProcessData(hcryp, Timeout);
3692 
3693     /*Temporary CrypOutCount Value*/
3694     outcount = hcryp->CrypOutCount;
3695 
3696     /* Check for the Timeout */
3697     if (Timeout != HAL_MAX_DELAY)
3698     {
3699       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3700       {
3701         /* Disable the CRYP peripheral clock */
3702         __HAL_CRYP_DISABLE(hcryp);
3703 
3704         /* Change state */
3705         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3706         hcryp->State = HAL_CRYP_STATE_READY;
3707 
3708         /* Process unlocked */
3709         __HAL_UNLOCK(hcryp);
3710         return HAL_ERROR;
3711       }
3712     }
3713   }
3714 
3715   if ((hcryp->Size % 16U) != 0U)
3716   {
3717 #if !defined (CRYP_VER_2_2)
3718     if (hcryp->Version >= REV_ID_B)
3719 #endif /*End of not defined CRYP_VER_2_2*/
3720     {
3721       /* Compute the number of padding bytes in last block of payload */
3722       npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3723 
3724       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
3725       {
3726         /* Disable the CRYP */
3727         __HAL_CRYP_DISABLE(hcryp);
3728 
3729         /* Set Npblb in case of AES CCM payload decryption to get right tag  */
3730         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3731 
3732         /* Enable CRYP to start the final phase */
3733         __HAL_CRYP_ENABLE(hcryp);
3734       }
3735 
3736       /* Number of valid words (lastwordsize) in last block */
3737       if ((npblb % 4U) == 0U)
3738       {
3739         lastwordsize = (16U - npblb) / 4U;
3740       }
3741       else
3742       {
3743         lastwordsize = ((16U - npblb) / 4U) + 1U;
3744       }
3745 
3746       /* Write the last input block in the IN FIFO */
3747       for (index = 0U; index < lastwordsize; index ++)
3748       {
3749         hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3750         hcryp->CrypInCount++;
3751       }
3752 
3753       /* Pad the data with zeros to have a complete block */
3754       while (index < 4U)
3755       {
3756         hcryp->Instance->DIN  = 0U;
3757         index++;
3758       }
3759 
3760       /* Wait for OFNE flag to be raised */
3761       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3762       {
3763         /* Disable the CRYP peripheral clock */
3764         __HAL_CRYP_DISABLE(hcryp);
3765 
3766         /* Change state */
3767         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3768         hcryp->State = HAL_CRYP_STATE_READY;
3769 
3770         /* Process Unlocked */
3771         __HAL_UNLOCK(hcryp);
3772 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3773         /*Call registered error callback*/
3774         hcryp->ErrorCallback(hcryp);
3775 #else
3776         /*Call legacy weak error callback*/
3777         HAL_CRYP_ErrorCallback(hcryp);
3778 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3779       }
3780 
3781       /*Read the output block from the output FIFO */
3782       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3783       {
3784         for (index = 0U; index < 4U; index++)
3785         {
3786           /* Read the output block from the output FIFO and put them in temporary buffer
3787           then get CrypOutBuff from temporary buffer */
3788           temp[index] = hcryp->Instance->DOUT;
3789         }
3790         for (index = 0; index < lastwordsize; index++)
3791         {
3792           *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3793           hcryp->CrypOutCount++;
3794         }
3795       }
3796     }
3797 #if !defined (CRYP_VER_2_2)
3798     else /* No NPBLB, Workaround to be used */
3799     {
3800       /* CRYP Workaround :  CRYP1 generates correct TAG  during CCM decryption only when ciphertext
3801       blocks size is multiple of 128 bits. If lthe size of the last block of payload is inferior to 128 bits,
3802       when CCM decryption is selected, then the TAG message will be wrong.*/
3803       CRYP_Workaround(hcryp, Timeout);
3804     }
3805 #endif /*End of not defined CRYP_VER_2_2*/
3806   }
3807 
3808   /* Return function status */
3809   return HAL_OK;
3810 }
3811 
3812 /**
3813   * @brief  AES CCM encryption/decryption process in interrupt mode
3814   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3815   *         the configuration information for CRYP module
3816   * @retval HAL status
3817   */
CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef * hcryp)3818 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3819 {
3820   __IO uint32_t count = 0U;
3821   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3822 
3823   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3824   {
3825     if (hcryp->KeyIVConfig == 1U)
3826     {
3827       /* If the Key and IV configuration has to be done only once
3828       and if it has already been done, skip it */
3829       DoKeyIVConfig = 0U;
3830       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3831     }
3832     else
3833     {
3834       /* If the Key and IV configuration has to be done only once
3835       and if it has not been done already, do it and set KeyIVConfig
3836       to keep track it won't have to be done again next time */
3837       hcryp->KeyIVConfig = 1U;
3838       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3839     }
3840   }
3841   else
3842   {
3843     hcryp->SizesSum = hcryp->Size;
3844   }
3845 
3846   /* Configure Key, IV and process message (header and payload) */
3847   if (DoKeyIVConfig == 1U)
3848   {
3849     /*  Reset CrypHeaderCount */
3850     hcryp->CrypHeaderCount = 0U;
3851 
3852     /************ Init phase ************/
3853 
3854     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3855 
3856     /* Set the key */
3857     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3858 
3859     /* Set the initialization vector (IV) with CTR1 information */
3860     hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3861     hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3862     hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3863     hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
3864 
3865     /* Enable the CRYP peripheral */
3866     __HAL_CRYP_ENABLE(hcryp);
3867 
3868     /*Write the B0 packet into CRYP_DR*/
3869 #if !defined (CRYP_VER_2_2)
3870     if (hcryp->Version >= REV_ID_B)
3871 #endif /*End of not defined CRYP_VER_2_2*/
3872     {
3873       /* for STM32H7 rev.B and above data has not to be swapped */
3874       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3875       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3876       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3877       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3878     }
3879 #if !defined (CRYP_VER_2_2)
3880     else /* data has to be swapped according to the DATATYPE */
3881     {
3882       if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
3883       {
3884         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3885         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3886         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3887         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3888       }
3889       else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
3890       {
3891         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3892         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3893         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3894         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3895       }
3896       else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
3897       {
3898         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3899         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3900         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3901         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3902       }
3903       else
3904       {
3905         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3906         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3907         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3908         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3909       }
3910     }
3911 #endif /*End of not defined CRYP_VER_2_2*/
3912     /*Wait for the CRYPEN bit to be cleared*/
3913     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3914     do
3915     {
3916       count-- ;
3917       if (count == 0U)
3918       {
3919         /* Disable the CRYP peripheral clock */
3920         __HAL_CRYP_DISABLE(hcryp);
3921 
3922         /* Change state */
3923         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3924         hcryp->State = HAL_CRYP_STATE_READY;
3925 
3926         /* Process unlocked */
3927         __HAL_UNLOCK(hcryp);
3928         return HAL_ERROR;
3929       }
3930     }
3931     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3932 
3933     /* Select header phase */
3934     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3935   } /* end of if (DoKeyIVConfig == 1U) */
3936   /* Enable interrupts */
3937   __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3938 
3939   /* Enable CRYP */
3940   __HAL_CRYP_ENABLE(hcryp);
3941 
3942   /* Return function status */
3943   return HAL_OK;
3944 }
3945 /**
3946   * @brief  AES CCM encryption/decryption process in DMA mode
3947   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3948   *         the configuration information for CRYP module
3949   * @retval HAL status
3950   */
CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef * hcryp)3951 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3952 {
3953   __IO uint32_t count    = 0U;
3954   uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3955   uint32_t index;
3956   uint32_t npblb;
3957   uint32_t lastwordsize;
3958   uint32_t temp[4];  /* Temporary CrypOutBuff */
3959   uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3960 
3961   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3962   {
3963     if (hcryp->KeyIVConfig == 1U)
3964     {
3965       /* If the Key and IV configuration has to be done only once
3966       and if it has already been done, skip it */
3967       DoKeyIVConfig = 0U;
3968       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3969     }
3970     else
3971     {
3972       /* If the Key and IV configuration has to be done only once
3973       and if it has not been done already, do it and set KeyIVConfig
3974       to keep track it won't have to be done again next time */
3975       hcryp->KeyIVConfig = 1U;
3976       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3977     }
3978   }
3979   else
3980   {
3981     hcryp->SizesSum = hcryp->Size;
3982   }
3983 
3984   if (DoKeyIVConfig == 1U)
3985   {
3986     /*  Reset CrypHeaderCount */
3987     hcryp->CrypHeaderCount = 0U;
3988 
3989     /************************** Init phase **************************************/
3990 
3991     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3992 
3993     /* Set the key */
3994     CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3995 
3996     /* Set the initialization vector (IV) with CTR1 information */
3997     hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3998     hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3999     hcryp->Instance->IV1LR = hcryp->Init.B0[2];
4000     hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) |  CRYP_CCM_CTR1_2;
4001 
4002     /* Enable the CRYP peripheral */
4003     __HAL_CRYP_ENABLE(hcryp);
4004 
4005     /*Write the B0 packet into CRYP_DR*/
4006 #if !defined (CRYP_VER_2_2)
4007     if (hcryp->Version >= REV_ID_B)
4008 #endif /*End of not defined CRYP_VER_2_2*/
4009     {
4010       /* for STM32H7 rev.B and above data has not to be swapped */
4011       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
4012       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
4013       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
4014       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
4015     }
4016 #if !defined (CRYP_VER_2_2)
4017     else /* data has to be swapped according to the DATATYPE */
4018     {
4019       if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
4020       {
4021         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
4022         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
4023         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
4024         hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
4025       }
4026       else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
4027       {
4028         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
4029         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
4030         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
4031         hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
4032       }
4033       else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
4034       {
4035         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
4036         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
4037         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
4038         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
4039       }
4040       else
4041       {
4042         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
4043         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
4044         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
4045         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
4046       }
4047     }
4048 #endif /*End of not defined CRYP_VER_2_2*/
4049     /*Wait for the CRYPEN bit to be cleared*/
4050     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
4051     do
4052     {
4053       count-- ;
4054       if (count == 0U)
4055       {
4056         /* Disable the CRYP peripheral clock */
4057         __HAL_CRYP_DISABLE(hcryp);
4058 
4059         /* Change state */
4060         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4061         hcryp->State = HAL_CRYP_STATE_READY;
4062 
4063         /* Process unlocked */
4064         __HAL_UNLOCK(hcryp);
4065         return HAL_ERROR;
4066       }
4067     }
4068     while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
4069 
4070     /********************* Header phase *****************************************/
4071 
4072     if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
4073     {
4074       return HAL_ERROR;
4075     }
4076 
4077     /******************** Payload phase *****************************************/
4078 
4079     /* Set the phase */
4080     hcryp->Phase = CRYP_PHASE_PROCESS;
4081 
4082     /* Disable the CRYP peripheral */
4083     __HAL_CRYP_DISABLE(hcryp);
4084 #if !defined (CRYP_VER_2_2)
4085     if (hcryp->Version >= REV_ID_B)
4086 #endif /*End of not defined CRYP_VER_2_2*/
4087     {
4088       /* Set to 0 the number of non-valid bytes using NPBLB register*/
4089       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4090     }
4091 
4092     /* Select payload phase once the header phase is performed */
4093     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4094   } /* if (DoKeyIVConfig == 1U) */
4095 
4096   if (hcryp->Size == 0U)
4097   {
4098     /* Process unLocked */
4099     __HAL_UNLOCK(hcryp);
4100 
4101     /* Change the CRYP state and phase */
4102     hcryp->State = HAL_CRYP_STATE_READY;
4103   }
4104   else if (hcryp->Size >= 16U)
4105   {
4106     /* for STM32H7 below rev.B ::  Size should be %4  otherwise Tag will  be incorrectly generated for CCM Decryption,
4107     Workaround is implemented in polling mode*/
4108     /*DMA transfer must not include the last block in case of Size is not %16 */
4109     wordsize = wordsize - (wordsize % 4U);
4110 
4111     /*DMA transfer */
4112     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t) wordsize,
4113                       (uint32_t)(hcryp->pCrypOutBuffPtr));
4114   }
4115   else /* length of input data is  < 16U */
4116   {
4117     /* Compute the number of padding bytes in last block of payload */
4118     npblb = 16U - (uint32_t)(hcryp->Size);
4119 
4120 #if !defined (CRYP_VER_2_2)
4121     if (hcryp->Version >= REV_ID_B)
4122 #endif /*End of not defined CRYP_VER_2_2*/
4123     {
4124       /* Set Npblb in case of AES CCM payload decryption to get right tag*/
4125       if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4126       {
4127         /* Specify the number of non-valid bytes using NPBLB register*/
4128         MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4129       }
4130     }
4131     /* Enable CRYP to start the final phase */
4132     __HAL_CRYP_ENABLE(hcryp);
4133 
4134     /* Number of valid words (lastwordsize) in last block */
4135     if ((npblb % 4U) == 0U)
4136     {
4137       lastwordsize = (16U - npblb) / 4U;
4138     }
4139     else
4140     {
4141       lastwordsize = ((16U - npblb) / 4U) + 1U;
4142     }
4143 
4144     /* Write the last input block in the IN FIFO */
4145     for (index = 0U; index < lastwordsize; index ++)
4146     {
4147       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4148       hcryp->CrypInCount++;
4149     }
4150 
4151     /* Pad the data with zeros to have a complete block */
4152     while (index < 4U)
4153     {
4154       hcryp->Instance->DIN  = 0U;
4155       index++;
4156     }
4157 
4158     /* Wait for OFNE flag to be raised */
4159     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4160     do
4161     {
4162       count-- ;
4163       if (count == 0U)
4164       {
4165         /* Disable the CRYP peripheral clock */
4166         __HAL_CRYP_DISABLE(hcryp);
4167 
4168         /* Change state */
4169         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4170         hcryp->State = HAL_CRYP_STATE_READY;
4171 
4172         /* Process unlocked */
4173         __HAL_UNLOCK(hcryp);
4174 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4175         /*Call registered error callback*/
4176         hcryp->ErrorCallback(hcryp);
4177 #else
4178         /*Call legacy weak error callback*/
4179         HAL_CRYP_ErrorCallback(hcryp);
4180 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4181       }
4182     }
4183     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
4184 
4185     /*Read the output block from the output FIFO */
4186     for (index = 0U; index < 4U; index++)
4187     {
4188       /* Read the output block from the output FIFO and put them in temporary buffer
4189       then get CrypOutBuff from temporary buffer */
4190       temp[index] = hcryp->Instance->DOUT;
4191     }
4192     for (index = 0; index < lastwordsize; index++)
4193     {
4194       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
4195       hcryp->CrypOutCount++;
4196     }
4197 
4198     /* Change the CRYP state to ready */
4199     hcryp->State = HAL_CRYP_STATE_READY;
4200 
4201     /* Process unlocked */
4202     __HAL_UNLOCK(hcryp);
4203   }
4204 
4205   /* Return function status */
4206   return HAL_OK;
4207 }
4208 
4209 /**
4210   * @brief  Sets the payload phase in interrupt mode
4211   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4212   *         the configuration information for CRYP module
4213   * @retval state
4214   */
CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef * hcryp)4215 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
4216 {
4217   uint32_t loopcounter;
4218   uint32_t temp[4];  /* Temporary CrypOutBuff */
4219   uint32_t lastwordsize;
4220   uint32_t npblb;
4221   uint32_t temp_cr_algodir;
4222   uint8_t negative = 0U;
4223   uint32_t i;
4224 
4225   /***************************** Payload phase *******************************/
4226 
4227   if ((hcryp->Size / 4U) < hcryp->CrypInCount)
4228   {
4229     negative = 1U;
4230   }
4231 
4232   if (hcryp->Size == 0U)
4233   {
4234     /* Disable interrupts */
4235     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4236 
4237     /* Process unlocked */
4238     __HAL_UNLOCK(hcryp);
4239 
4240     /* Change the CRYP state */
4241     hcryp->State = HAL_CRYP_STATE_READY;
4242   }
4243 
4244   else if ((((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) &&
4245            (negative == 0U))
4246   {
4247     if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM) != 0x0U)
4248     {
4249       /* Write the input block in the IN FIFO */
4250       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4251       hcryp->CrypInCount++;
4252       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4253       hcryp->CrypInCount++;
4254       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4255       hcryp->CrypInCount++;
4256       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4257       hcryp->CrypInCount++;
4258       if (((hcryp->Size / 4U) == hcryp->CrypInCount) && ((hcryp->Size % 16U) == 0U))
4259       {
4260         /* Disable interrupts */
4261         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4262         /* Call the input data transfer complete callback */
4263 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4264         /*Call registered Input complete callback*/
4265         hcryp->InCpltCallback(hcryp);
4266 #else
4267         /*Call legacy weak Input complete callback*/
4268         HAL_CRYP_InCpltCallback(hcryp);
4269 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4270       }
4271 
4272       if (hcryp->CrypOutCount < (hcryp->Size / 4U))
4273       {
4274         if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4275         {
4276           /* Read the output block from the Output FIFO and put them in temporary buffer
4277           then get CrypOutBuff from temporary buffer  */
4278           for (i = 0U; i < 4U; i++)
4279           {
4280             temp[i] = hcryp->Instance->DOUT;
4281           }
4282           i = 0U;
4283           while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
4284           {
4285             *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4286             hcryp->CrypOutCount++;
4287             i++;
4288           }
4289           if (((hcryp->Size / 4U) == hcryp->CrypOutCount) && ((hcryp->Size % 16U) == 0U))
4290           {
4291             /* Disable interrupts */
4292             __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
4293 
4294             /* Change the CRYP state */
4295             hcryp->State = HAL_CRYP_STATE_READY;
4296 
4297             /* Disable CRYP */
4298             __HAL_CRYP_DISABLE(hcryp);
4299 
4300             /* Process unlocked */
4301             __HAL_UNLOCK(hcryp);
4302 
4303             /* Call output transfer complete callback */
4304 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4305             /*Call registered Output complete callback*/
4306             hcryp->OutCpltCallback(hcryp);
4307 #else
4308             /*Call legacy weak Output complete callback*/
4309             HAL_CRYP_OutCpltCallback(hcryp);
4310 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4311           }
4312         }
4313       }
4314     }
4315   }
4316   else if ((hcryp->Size % 16U) != 0U)
4317   {
4318     /* Set padding only in case of input fifo interrupt */
4319     if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM) != 0x0U)
4320     {
4321       /* Compute the number of padding bytes in last block of payload */
4322       npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4323 
4324 #if !defined (CRYP_VER_2_2)
4325       if (hcryp->Version >= REV_ID_B)
4326 #endif /*End of not defined CRYP_VER_2_2*/
4327       {
4328         /* Set Npblb in case of AES GCM payload encryption and CCM decryption to get right tag */
4329         temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
4330 
4331         if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
4332             ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4333         {
4334           /* Disable the CRYP */
4335           __HAL_CRYP_DISABLE(hcryp);
4336 
4337           /* Specify the number of non-valid bytes using NPBLB register*/
4338           MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4339 
4340           /* Enable CRYP to start the final phase */
4341           __HAL_CRYP_ENABLE(hcryp);
4342         }
4343       }
4344 
4345       /* Number of valid words (lastwordsize) in last block */
4346       if ((npblb % 4U) == 0U)
4347       {
4348         lastwordsize = (16U - npblb) / 4U;
4349       }
4350       else
4351       {
4352         lastwordsize = ((16U - npblb) / 4U) + 1U;
4353       }
4354 
4355       /* Write the last input block in the IN FIFO */
4356       for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4357       {
4358         hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4359         hcryp->CrypInCount++;
4360       }
4361       /* Pad the data with zeros to have a complete block */
4362       while (loopcounter < 4U)
4363       {
4364         hcryp->Instance->DIN  = 0U;
4365         loopcounter++;
4366       }
4367 
4368       /* Disable the input FIFO Interrupt */
4369       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4370     }
4371 
4372     /*Read the output block from the output FIFO */
4373     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4374     {
4375       for (i = 0U; i < 4U; i++)
4376       {
4377         temp[i] = hcryp->Instance->DOUT;
4378       }
4379       if (((hcryp->Size) / 4U) == 0U)
4380       {
4381         for (i = 0U; (uint16_t)i < ((hcryp->Size) % 4U); i++)
4382         {
4383           *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4384           hcryp->CrypOutCount++;
4385         }
4386       }
4387       i = 0U;
4388       while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
4389       {
4390         *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4391         hcryp->CrypOutCount++;
4392         i++;
4393       }
4394     }
4395 
4396     /* Disable the output FIFO Interrupt */
4397     if (hcryp->CrypOutCount >= ((hcryp->Size) / 4U))
4398     {
4399       /* Disable interrupts */
4400       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI | CRYP_IT_INI);
4401 
4402       /* Change the CRYP peripheral state */
4403       hcryp->State = HAL_CRYP_STATE_READY;
4404 
4405       /* Process unlocked */
4406       __HAL_UNLOCK(hcryp);
4407 
4408       /* Call output transfer complete callback */
4409 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4410       /*Call registered Output complete callback*/
4411       hcryp->OutCpltCallback(hcryp);
4412 #else
4413       /*Call legacy weak Output complete callback*/
4414       HAL_CRYP_OutCpltCallback(hcryp);
4415 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4416     }
4417   }
4418   else
4419   {
4420     /* Nothing to do */
4421   }
4422 }
4423 
4424 
4425 /**
4426   * @brief  Sets the header phase in polling mode
4427   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4428   *         the configuration information for CRYP module(Header & HeaderSize)
4429   * @param  Timeout: Timeout value
4430   * @retval state
4431   */
CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)4432 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4433 {
4434   uint32_t loopcounter;
4435   uint32_t size_in_bytes;
4436   uint32_t tmp;
4437   const uint32_t mask[4] = {0x0U, 0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
4438 
4439   /***************************** Header phase for GCM/GMAC or CCM *********************************/
4440 
4441 
4442   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
4443   {
4444     size_in_bytes = hcryp->Init.HeaderSize * 4U;
4445   }
4446   else
4447   {
4448     size_in_bytes = hcryp->Init.HeaderSize;
4449   }
4450 
4451   if ((size_in_bytes != 0U))
4452   {
4453     /* Select header phase */
4454     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4455 
4456     /* Enable the CRYP peripheral */
4457     __HAL_CRYP_ENABLE(hcryp);
4458 
4459     /* If size_in_bytes is a multiple of blocks (a multiple of four 32-bits words ) */
4460     if ((size_in_bytes % 16U) == 0U)
4461     {
4462       /*  No padding */
4463       for (loopcounter = 0U; (loopcounter < (size_in_bytes / 4U)); loopcounter += 4U)
4464 
4465       {
4466         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4467         hcryp->CrypHeaderCount++ ;
4468         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4469         hcryp->CrypHeaderCount++ ;
4470         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4471         hcryp->CrypHeaderCount++ ;
4472         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4473         hcryp->CrypHeaderCount++ ;
4474 
4475         /* Wait for IFEM to be raised */
4476         if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4477         {
4478           /* Disable the CRYP peripheral clock */
4479           __HAL_CRYP_DISABLE(hcryp);
4480 
4481           /* Change state */
4482           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4483           hcryp->State = HAL_CRYP_STATE_READY;
4484 
4485           /* Process unlocked */
4486           __HAL_UNLOCK(hcryp);
4487           return HAL_ERROR;
4488         }
4489       }
4490     }
4491     else
4492     {
4493       /* Write header block in the IN FIFO without last block */
4494       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 16U) * 4U)); loopcounter += 4U)
4495       {
4496         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4497         hcryp->CrypHeaderCount++ ;
4498         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4499         hcryp->CrypHeaderCount++ ;
4500         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4501         hcryp->CrypHeaderCount++ ;
4502         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4503         hcryp->CrypHeaderCount++ ;
4504 
4505         /* Wait for IFEM to be raised */
4506         if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4507         {
4508           /* Disable the CRYP peripheral clock */
4509           __HAL_CRYP_DISABLE(hcryp);
4510 
4511           /* Change state */
4512           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4513           hcryp->State = HAL_CRYP_STATE_READY;
4514 
4515           /* Process unlocked */
4516           __HAL_UNLOCK(hcryp);
4517           return HAL_ERROR;
4518         }
4519       }
4520       /*  Last block optionally pad the data with zeros*/
4521       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 4U) % 4U)); loopcounter++)
4522       {
4523         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4524         hcryp->CrypHeaderCount++ ;
4525       }
4526       /* If the header size is a multiple of words */
4527       if ((size_in_bytes % 4U) == 0U)
4528       {
4529         /* Pad the data with zeros to have a complete block */
4530         while (loopcounter < 4U)
4531         {
4532           hcryp->Instance->DIN = 0x0U;
4533           loopcounter++;
4534         }
4535       }
4536       else
4537       {
4538         /* Enter last bytes, padded with zeroes */
4539         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4540         tmp &= mask[size_in_bytes % 4U];
4541         hcryp->Instance->DIN = tmp;
4542         loopcounter++;
4543         /* Pad the data with zeros to have a complete block */
4544         while (loopcounter < 4U)
4545         {
4546           hcryp->Instance->DIN = 0x0U;
4547           loopcounter++;
4548         }
4549       }
4550       /* Wait for CCF IFEM to be raised */
4551       if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4552       {
4553         /* Disable the CRYP peripheral clock */
4554         __HAL_CRYP_DISABLE(hcryp);
4555 
4556         /* Change state */
4557         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4558         hcryp->State = HAL_CRYP_STATE_READY;
4559 
4560         /* Process unlocked */
4561         __HAL_UNLOCK(hcryp);
4562         return HAL_ERROR;
4563       }
4564     }
4565     /* Wait until the complete message has been processed */
4566     if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
4567     {
4568       /* Disable the CRYP peripheral clock */
4569       __HAL_CRYP_DISABLE(hcryp);
4570 
4571       /* Change state */
4572       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4573       hcryp->State = HAL_CRYP_STATE_READY;
4574 
4575       /* Process unlocked & return error */
4576       __HAL_UNLOCK(hcryp);
4577       return HAL_ERROR;
4578     }
4579   }
4580   /* Return function status */
4581   return HAL_OK;
4582 }
4583 
4584 /**
4585   * @brief  Sets the header phase when using DMA in process
4586   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4587   *         the configuration information for CRYP module(Header & HeaderSize)
4588   * @retval None
4589   */
CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef * hcryp)4590 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
4591 {
4592   __IO uint32_t count  = 0U;
4593   uint32_t loopcounter;
4594 
4595   /***************************** Header phase for GCM/GMAC or CCM *********************************/
4596   if ((hcryp->Init.HeaderSize != 0U))
4597   {
4598     /* Select header phase */
4599     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4600 
4601     /* Enable the CRYP peripheral */
4602     __HAL_CRYP_ENABLE(hcryp);
4603 
4604     if ((hcryp->Init.HeaderSize % 4U) == 0U)
4605     {
4606       /* HeaderSize %4, no padding */
4607       for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4608       {
4609         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4610         hcryp->CrypHeaderCount++ ;
4611         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4612         hcryp->CrypHeaderCount++ ;
4613         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4614         hcryp->CrypHeaderCount++ ;
4615         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4616         hcryp->CrypHeaderCount++ ;
4617 
4618         /* Wait for IFEM to be raised */
4619         count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4620         do
4621         {
4622           count-- ;
4623           if (count == 0U)
4624           {
4625             /* Disable the CRYP peripheral clock */
4626             __HAL_CRYP_DISABLE(hcryp);
4627 
4628             /* Change state */
4629             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4630             hcryp->State = HAL_CRYP_STATE_READY;
4631 
4632             /* Process unlocked */
4633             __HAL_UNLOCK(hcryp);
4634             return HAL_ERROR;
4635           }
4636         }
4637         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4638       }
4639     }
4640     else
4641     {
4642       /*Write header block in the IN FIFO without last block */
4643       for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U)));
4644            loopcounter += 4U)
4645       {
4646         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4647         hcryp->CrypHeaderCount++ ;
4648         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4649         hcryp->CrypHeaderCount++ ;
4650         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4651         hcryp->CrypHeaderCount++ ;
4652         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4653         hcryp->CrypHeaderCount++ ;
4654 
4655         /* Wait for IFEM to be raised */
4656         count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4657         do
4658         {
4659           count-- ;
4660           if (count == 0U)
4661           {
4662             /* Disable the CRYP peripheral clock */
4663             __HAL_CRYP_DISABLE(hcryp);
4664 
4665             /* Change state */
4666             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4667             hcryp->State = HAL_CRYP_STATE_READY;
4668 
4669             /* Process unlocked */
4670             __HAL_UNLOCK(hcryp);
4671             return HAL_ERROR;
4672           }
4673         }
4674         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4675       }
4676       /*  Last block optionally pad the data with zeros*/
4677       for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4678       {
4679         hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4680         hcryp->CrypHeaderCount++ ;
4681       }
4682       while (loopcounter < 4U)
4683       {
4684         /* Pad the data with zeros to have a complete block */
4685         hcryp->Instance->DIN = 0x0U;
4686         loopcounter++;
4687       }
4688       /* Wait for IFEM to be raised */
4689       count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4690       do
4691       {
4692         count-- ;
4693         if (count == 0U)
4694         {
4695           /* Disable the CRYP peripheral clock */
4696           __HAL_CRYP_DISABLE(hcryp);
4697           /* Change state */
4698           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4699           hcryp->State = HAL_CRYP_STATE_READY;
4700           /* Process unlocked */
4701           __HAL_UNLOCK(hcryp);
4702           return HAL_ERROR;
4703         }
4704       }
4705       while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4706     }
4707     /* Wait until the complete message has been processed */
4708     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4709     do
4710     {
4711       count-- ;
4712       if (count == 0U)
4713       {
4714         /* Disable the CRYP peripheral clock */
4715         __HAL_CRYP_DISABLE(hcryp);
4716         /* Change state */
4717         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4718         hcryp->State = HAL_CRYP_STATE_READY;
4719         /* Process unlocked */
4720         __HAL_UNLOCK(hcryp);
4721         return HAL_ERROR;
4722       }
4723     }
4724     while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
4725   }
4726 
4727   /* Return function status */
4728   return HAL_OK;
4729 }
4730 
4731 /**
4732   * @brief  Sets the header phase in interrupt mode
4733   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4734   *         the configuration information for CRYP module(Header & HeaderSize)
4735   * @retval None
4736   */
CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef * hcryp)4737 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
4738 {
4739   uint32_t loopcounter;
4740 
4741   /***************************** Header phase *********************************/
4742 
4743   if (hcryp->Init.HeaderSize ==  hcryp->CrypHeaderCount)
4744   {
4745     /* Disable interrupts */
4746     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4747 
4748     /* Disable the CRYP peripheral */
4749     __HAL_CRYP_DISABLE(hcryp);
4750 
4751 #if !defined (CRYP_VER_2_2)
4752     if (hcryp->Version >= REV_ID_B)
4753 #endif /*End of not defined CRYP_VER_2_2*/
4754     {
4755       /* Set to 0 the number of non-valid bytes using NPBLB register*/
4756       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4757     }
4758 
4759     /* Set the phase */
4760     hcryp->Phase = CRYP_PHASE_PROCESS;
4761 
4762     /* Select payload phase once the header phase is performed */
4763     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4764 
4765     /* Enable Interrupts */
4766     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4767 
4768     /* Enable the CRYP peripheral */
4769     __HAL_CRYP_ENABLE(hcryp);
4770   }
4771   else if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U)
4772 
4773   {
4774     /* HeaderSize %4, no padding */
4775     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4776     hcryp->CrypHeaderCount++ ;
4777     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4778     hcryp->CrypHeaderCount++  ;
4779     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4780     hcryp->CrypHeaderCount++ ;
4781     hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4782     hcryp->CrypHeaderCount++ ;
4783   }
4784   else
4785   {
4786     /*  Last block optionally pad the data with zeros*/
4787     for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
4788     {
4789       hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4790       hcryp->CrypHeaderCount++ ;
4791     }
4792     while (loopcounter < 4U)
4793     {
4794       /* Pad the data with zeros to have a complete block */
4795       hcryp->Instance->DIN = 0x0U;
4796       loopcounter++;
4797     }
4798   }
4799 }
4800 
4801 #if !defined (CRYP_VER_2_2)
4802 /**
4803   * @brief  Workaround used for GCM/CCM mode.
4804   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4805   *         the configuration information for CRYP module
4806   * @param  Timeout: Timeout value
4807   * @retval None
4808   */
CRYP_Workaround(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)4809 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4810 {
4811   uint32_t  iv1temp;
4812   uint32_t  temp[4] = {0};
4813   uint32_t  temp2[4] = {0};
4814   uint32_t intermediate_data[4] = {0};
4815   uint32_t index;
4816   uint32_t lastwordsize;
4817   uint32_t npblb;
4818 
4819   /* Compute the number of padding bytes in last block of payload */
4820   npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4821 
4822   /* Number of valid words (lastwordsize) in last block */
4823   if ((npblb % 4U) == 0U)
4824   {
4825     lastwordsize = (16U - npblb) / 4U;
4826   }
4827   else
4828   {
4829     lastwordsize = ((16U - npblb) / 4U) + 1U;
4830   }
4831 
4832   /* Workaround 2, case GCM encryption */
4833   if (hcryp->Init.Algorithm == CRYP_AES_GCM)
4834   {
4835     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4836     {
4837       /*Workaround in order to properly compute authentication tags while doing
4838        a GCM encryption with the last block of payload size inferior to 128 bits*/
4839       /* Disable CRYP to start the final phase */
4840       __HAL_CRYP_DISABLE(hcryp);
4841 
4842       /*Update CRYP_IV1R register and ALGOMODE*/
4843       hcryp->Instance->IV1RR = ((hcryp->Instance->CSGCMCCM7R) - 1U);
4844       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
4845 
4846       /* Enable CRYP to start the final phase */
4847       __HAL_CRYP_ENABLE(hcryp);
4848     }
4849 
4850     for (index = 0; index < lastwordsize ; index ++)
4851     {
4852       /* Write the last input block in the IN FIFO */
4853       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4854       hcryp->CrypInCount++;
4855     }
4856     while (index < 4U)
4857     {
4858       /* Pad the data with zeros to have a complete block */
4859       hcryp->Instance->DIN  = 0U;
4860       index++;
4861     }
4862     /* Wait for OFNE flag to be raised */
4863     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4864     {
4865       /* Disable the CRYP peripheral clock */
4866       __HAL_CRYP_DISABLE(hcryp);
4867 
4868       /* Change state */
4869       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4870       hcryp->State = HAL_CRYP_STATE_READY;
4871 
4872       /* Process Unlocked */
4873       __HAL_UNLOCK(hcryp);
4874 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4875       /*Call registered error callback*/
4876       hcryp->ErrorCallback(hcryp);
4877 #else
4878       /*Call legacy weak error callback*/
4879       HAL_CRYP_ErrorCallback(hcryp);
4880 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4881     }
4882     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4883     {
4884       for (index = 0U; index < 4U; index++)
4885       {
4886         /* Read the output block from the output FIFO */
4887         intermediate_data[index] = hcryp->Instance->DOUT;
4888 
4889         /* Intermediate data buffer to be used in for the workaround*/
4890         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
4891         hcryp->CrypOutCount++;
4892       }
4893     }
4894 
4895     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4896     {
4897       /*workaround in order to properly compute authentication tags while doing
4898       a GCM encryption with the last block of payload size inferior to 128 bits*/
4899       /* Change the AES mode to GCM mode and Select Final phase */
4900       /* configured  CHMOD GCM   */
4901       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_GCM);
4902 
4903       /* configured  final phase  */
4904       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
4905 
4906       if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_NO_SWAP)
4907       {
4908         if ((npblb % 4U) == 1U)
4909         {
4910           intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
4911         }
4912         if ((npblb % 4U) == 2U)
4913         {
4914           intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
4915         }
4916         if ((npblb % 4U) == 3U)
4917         {
4918           intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
4919         }
4920       }
4921       else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_BYTE_SWAP)
4922       {
4923         if ((npblb % 4U) == 1U)
4924         {
4925           intermediate_data[lastwordsize - 1U] &= __REV(0xFFFFFF00U);
4926         }
4927         if ((npblb % 4U) == 2U)
4928         {
4929           intermediate_data[lastwordsize - 1U] &= __REV(0xFFFF0000U);
4930         }
4931         if ((npblb % 4U) == 3U)
4932         {
4933           intermediate_data[lastwordsize - 1U] &= __REV(0xFF000000U);
4934         }
4935       }
4936       else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_HALFWORD_SWAP)
4937       {
4938         if ((npblb % 4U) == 1U)
4939         {
4940           intermediate_data[lastwordsize - 1U] &= __ROR((0xFFFFFF00U), 16);
4941         }
4942         if ((npblb % 4U) == 2U)
4943         {
4944           intermediate_data[lastwordsize - 1U] &= __ROR((0xFFFF0000U), 16);
4945         }
4946         if ((npblb % 4U) == 3U)
4947         {
4948           intermediate_data[lastwordsize - 1U] &= __ROR((0xFF000000U), 16);
4949         }
4950       }
4951       else /*CRYP_BIT_SWAP*/
4952       {
4953         if ((npblb % 4U) == 1U)
4954         {
4955           intermediate_data[lastwordsize - 1U] &= __RBIT(0xFFFFFF00U);
4956         }
4957         if ((npblb % 4U) == 2U)
4958         {
4959           intermediate_data[lastwordsize - 1U] &= __RBIT(0xFFFF0000U);
4960         }
4961         if ((npblb % 4U) == 3U)
4962         {
4963           intermediate_data[lastwordsize - 1U] &= __RBIT(0xFF000000U);
4964         }
4965       }
4966 
4967       for (index = 0U; index < lastwordsize ; index ++)
4968       {
4969         /*Write the intermediate_data in the IN FIFO */
4970         hcryp->Instance->DIN = intermediate_data[index];
4971       }
4972       while (index < 4U)
4973       {
4974         /* Pad the data with zeros to have a complete block */
4975         hcryp->Instance->DIN  = 0x0U;
4976         index++;
4977       }
4978       /* Wait for OFNE flag to be raised */
4979       if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4980       {
4981         /* Disable the CRYP peripheral clock */
4982         __HAL_CRYP_DISABLE(hcryp);
4983 
4984         /* Change state */
4985         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4986         hcryp->State = HAL_CRYP_STATE_READY;
4987 
4988         /* Process unlocked */
4989         __HAL_UNLOCK(hcryp);
4990 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4991         /*Call registered error callback*/
4992         hcryp->ErrorCallback(hcryp);
4993 #else
4994         /*Call legacy weak error callback*/
4995         HAL_CRYP_ErrorCallback(hcryp);
4996 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4997       }
4998 
4999       if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
5000       {
5001         for (index = 0U; index < 4U; index++)
5002         {
5003           intermediate_data[index] = hcryp->Instance->DOUT;
5004         }
5005       }
5006     }
5007   } /* End of GCM encryption */
5008   else
5009   {
5010     /* Workaround 2, case CCM decryption, in order to properly compute
5011       authentication tags while doing a CCM decryption with the last block
5012       of payload size inferior to 128 bits*/
5013 
5014     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
5015     {
5016       iv1temp = hcryp->Instance->CSGCMCCM7R;
5017 
5018       /* Disable CRYP to start the final phase */
5019       __HAL_CRYP_DISABLE(hcryp);
5020 
5021       temp[0] =  hcryp->Instance->CSGCMCCM0R;
5022       temp[1] =  hcryp->Instance->CSGCMCCM1R;
5023       temp[2] =  hcryp->Instance->CSGCMCCM2R;
5024       temp[3] =  hcryp->Instance->CSGCMCCM3R;
5025 
5026       hcryp->Instance->IV1RR = iv1temp;
5027 
5028       /* Configured  CHMOD CTR   */
5029       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
5030 
5031       /* Enable CRYP to start the final phase */
5032       __HAL_CRYP_ENABLE(hcryp);
5033     }
5034     /*  Last block optionally pad the data with zeros*/
5035     for (index = 0U; index < lastwordsize; index ++)
5036     {
5037       /* Write the last Input block in the IN FIFO */
5038       hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5039       hcryp->CrypInCount++;
5040     }
5041     while (index < 4U)
5042     {
5043       /* Pad the data with zeros to have a complete block */
5044       hcryp->Instance->DIN  = 0U;
5045       index++;
5046     }
5047     /* Wait for OFNE flag to be raised */
5048     if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
5049     {
5050       /* Disable the CRYP peripheral clock */
5051       __HAL_CRYP_DISABLE(hcryp);
5052 
5053       /* Change state */
5054       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5055       hcryp->State = HAL_CRYP_STATE_READY;
5056 
5057       /* Process Unlocked */
5058       __HAL_UNLOCK(hcryp);
5059 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5060       /*Call registered error callback*/
5061       hcryp->ErrorCallback(hcryp);
5062 #else
5063       /*Call legacy weak error callback*/
5064       HAL_CRYP_ErrorCallback(hcryp);
5065 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5066     }
5067 
5068     if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
5069     {
5070       for (index = 0U; index < 4U; index++)
5071       {
5072         /* Read the Output block from the Output FIFO */
5073         intermediate_data[index] = hcryp->Instance->DOUT;
5074 
5075         /*intermediate data buffer to be used in for the workaround*/
5076         *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
5077         hcryp->CrypOutCount++;
5078       }
5079     }
5080 
5081     if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
5082     {
5083       temp2[0] =  hcryp->Instance->CSGCMCCM0R;
5084       temp2[1] =  hcryp->Instance->CSGCMCCM1R;
5085       temp2[2] =  hcryp->Instance->CSGCMCCM2R;
5086       temp2[3] =  hcryp->Instance->CSGCMCCM3R;
5087 
5088       /* configured  CHMOD CCM   */
5089       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CCM);
5090 
5091       /* configured  Header phase  */
5092       MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_HEADER);
5093 
5094       /*set to zero the bits corresponding to the padded bits*/
5095       for (index = lastwordsize; index < 4U; index ++)
5096       {
5097         intermediate_data[index] = 0U;
5098       }
5099 
5100       if ((npblb % 4U) == 1U)
5101       {
5102         intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
5103       }
5104       if ((npblb % 4U) == 2U)
5105       {
5106         intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
5107       }
5108       if ((npblb % 4U) == 3U)
5109       {
5110         intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
5111       }
5112 
5113       for (index = 0U; index < 4U ; index ++)
5114       {
5115         intermediate_data[index] ^=  temp[index];
5116         intermediate_data[index] ^=  temp2[index];
5117       }
5118       for (index = 0U; index < 4U; index ++)
5119       {
5120         /* Write the last Input block in the IN FIFO */
5121         hcryp->Instance->DIN  = intermediate_data[index] ;
5122       }
5123 
5124       /* Wait for BUSY flag to be raised */
5125       if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
5126       {
5127         /* Disable the CRYP peripheral clock */
5128         __HAL_CRYP_DISABLE(hcryp);
5129 
5130         /* Change state */
5131         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5132         hcryp->State = HAL_CRYP_STATE_READY;
5133 
5134         /* Process Unlocked */
5135         __HAL_UNLOCK(hcryp);
5136 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5137         /*Call registered error callback*/
5138         hcryp->ErrorCallback(hcryp);
5139 #else
5140         /*Call legacy weak error callback*/
5141         HAL_CRYP_ErrorCallback(hcryp);
5142 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5143       }
5144     }
5145   } /* End of CCM WKA*/
5146 
5147   /* Process Unlocked */
5148   __HAL_UNLOCK(hcryp);
5149 }
5150 #endif /*End of not defined CRYP_VER_2_2*/
5151 
5152 /**
5153   * @brief  Handle CRYP hardware block Timeout when waiting for IFEM flag to be raised.
5154   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5155   *         the configuration information for CRYP module.
5156   * @param  Timeout: Timeout duration.
5157   * @retval HAL status
5158   */
CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5159 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5160 {
5161   uint32_t tickstart;
5162 
5163   /* Get timeout */
5164   tickstart = HAL_GetTick();
5165 
5166   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
5167   {
5168     /* Check for the Timeout */
5169     if (Timeout != HAL_MAX_DELAY)
5170     {
5171       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5172       {
5173         return HAL_ERROR;
5174       }
5175     }
5176   }
5177   return HAL_OK;
5178 }
5179 /**
5180   * @brief  Handle CRYP hardware block Timeout when waiting for BUSY flag to be raised.
5181   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5182   *         the configuration information for CRYP module.
5183   * @param  Timeout: Timeout duration.
5184   * @retval HAL status
5185   */
CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5186 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5187 {
5188   uint32_t tickstart;
5189 
5190   /* Get timeout */
5191   tickstart = HAL_GetTick();
5192 
5193   while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY))
5194   {
5195     /* Check for the Timeout */
5196     if (Timeout != HAL_MAX_DELAY)
5197     {
5198       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5199       {
5200         return HAL_ERROR;
5201       }
5202     }
5203   }
5204   return HAL_OK;
5205 }
5206 
5207 
5208 /**
5209   * @brief  Handle CRYP hardware block Timeout when waiting for OFNE flag to be raised.
5210   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5211   *         the configuration information for CRYP module.
5212   * @param  Timeout: Timeout duration.
5213   * @retval HAL status
5214   */
CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5215 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef  *hcryp, uint32_t Timeout)
5216 {
5217   uint32_t tickstart;
5218 
5219   /* Get timeout */
5220   tickstart = HAL_GetTick();
5221 
5222   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
5223   {
5224     /* Check for the Timeout */
5225     if (Timeout != HAL_MAX_DELAY)
5226     {
5227       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5228       {
5229         return HAL_ERROR;
5230       }
5231     }
5232   }
5233   return HAL_OK;
5234 }
5235 
5236 
5237 /**
5238   * @}
5239   */
5240 
5241 
5242 
5243 /**
5244   * @}
5245   */
5246 
5247 #endif /* HAL_CRYP_MODULE_ENABLED */
5248 
5249 
5250 /**
5251   * @}
5252   */
5253 #endif /* CRYP */
5254 /**
5255   * @}
5256   */
5257 
5258