1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_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, de-initialization, set config and get config functions
9   *           + DMA callback functions
10   *           + CRYP IRQ handler management
11   *           + Peripheral State functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2022 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                      ##### How to use this driver #####
27   ==============================================================================
28     [..]
29       The CRYP HAL driver can be used as follows:
30 
31       (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
32          (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()or __HAL_RCC_AES_CLK_ENABLE
33          (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
34              (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
35              (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
36              (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
37          (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
38              (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
39              (+++) Configure and enable two DMA channels one for managing data transfer from
40                  memory to peripheral (input channel) and another channel for managing data
41                  transfer from peripheral to memory (output channel)
42              (+++) Associate the initialized DMA handle to the CRYP DMA handle
43                  using  __HAL_LINKDMA()
44              (+++) Configure the priority and enable the NVIC for the transfer complete
45                  interrupt on the two DMA channels. The output channel should have higher
46                  priority than the input channel HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
47 
48       (#)Initialize the CRYP according to the specified parameters :
49          (##) The data type: 1-bit, 8-bit, 16-bit or 32-bit.
50          (##) The key size: 128, 192 or 256.
51          (##) The AES Algorithm ECB/CBC/CTR/GCM or CCM.
52          (##) The initialization vector (counter). It is not used in ECB mode.
53          (##) The key buffer used for encryption/decryption.
54              (+++) In some specific configurations, the key is written by the application
55                    code out of the HAL scope. In that case, user can still resort to the
56                    HAL APIs as usual but must make sure that pKey pointer is set to NULL.
57          (##) The DataWidthUnit field. It specifies whether the data length (or the payload
58                length for authentication algorithms) is in words or bytes.
59          (##) The Header used only in AES GCM and CCM Algorithm for authentication.
60          (##) The HeaderSize used to give size of header buffer in word or bytes, depending upon HeaderWidthUnit field.
61          (##) The HeaderWidthUnit field. It specifies whether the header length
62               (for authentication algorithms) is in words or bytes.
63          (##) The B0 block is the first authentication block used only  in AES CCM mode.
64          (##) The KeyIVConfigSkip used to process several messages in a row.
65          (##) The KeyMode used to special key operation modes (for SAES : wrapped key, shared key with AES peripheral).
66          (##) The KeySelect, Only for SAES, used to select key from different key source.
67          (##) The KeyProtection, Only for SAES, used for security context enforcement.
68 
69       (#)Three processing (encryption/decryption) functions are available:
70          (##) Polling mode: encryption and decryption APIs are blocking functions
71               i.e. they process the data and wait till the processing is finished,
72               e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
73          (##) Interrupt mode: encryption and decryption APIs are not blocking functions
74               i.e. they process the data under interrupt,
75               e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
76          (##) DMA mode: encryption and decryption APIs are not blocking functions
77               i.e. the data transfer is ensured by DMA,
78               e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
79 
80       (#)When the processing function is called at first time after HAL_CRYP_Init()
81          the CRYP peripheral is configured and processes the buffer in input.
82          At second call, no need to Initialize the CRYP, user have to get current configuration via
83          HAL_CRYP_GetConfig() API, then only  HAL_CRYP_SetConfig() is requested to set
84          new parameters, finally user can  start encryption/decryption.
85 
86        (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
87 
88        (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
89           without having to configure again the Key or the Initialization Vector between each API call,
90           the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
91           Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
92           or HAL_CRYP_Decrypt_DMA().
93 
94     [..]
95       The cryptographic processor supports following standards:
96       (#) The advanced encryption standard (AES) supported:
97          (##)128-bit data block processing
98          (##) chaining modes supported :
99              (+++)  Electronic Code Book(ECB)
100              (+++)  Cipher Block Chaining (CBC)
101              (+++)  Counter mode (CTR)
102              (+++)  Galois/counter mode (GCM/GMAC)
103              (+++)  Counter with Cipher Block Chaining-Message(CCM)
104          (##) keys length Supported : 128-bit and 256-bit
105 
106     [..]
107     (@) Specific care must be taken to format the key and the Initialization Vector IV!
108 
109     [..] If the key is defined as a 128-bit long array key[127..0] = {b127 ... b0} where
110          b127 is the MSB and b0 the LSB, the key must be stored in MCU memory
111          (+) as a sequence of words where the MSB word comes first (occupies the
112            lowest memory address)
113           (++)   address n+0 : 0b b127 .. b120 b119 .. b112 b111 .. b104 b103 .. b96
114           (++)   address n+4 : 0b b95 .. b88 b87 .. b80 b79 .. b72 b71 .. b64
115           (++)   address n+8 : 0b b63 .. b56 b55 .. b48 b47 .. b40 b39 .. b32
116           (++)   address n+C : 0b b31 .. b24 b23 .. b16 b15 .. b8 b7 .. b0
117      [..] Hereafter, another illustration when considering a 128-bit long key made of 16 bytes {B15..B0}.
118          The 4 32-bit words that make the key must be stored as follows in MCU memory:
119           (+)    address n+0 : 0x B15 B14 B13 B12
120           (+)    address n+4 : 0x B11 B10 B9 B8
121           (+)    address n+8 : 0x B7 B6 B5 B4
122           (+)    address n+C : 0x B3 B2 B1 B0
123      [..]  which leads to the expected setting
124        (+)       AES_KEYR3 = 0x B15 B14 B13 B12
125        (+)       AES_KEYR2 = 0x B11 B10 B9 B8
126        (+)       AES_KEYR1 = 0x B7 B6 B5 B4
127        (+)       AES_KEYR0 = 0x B3 B2 B1 B0
128 
129     [..]  Same format must be applied for a 256-bit long key made of 32 bytes {B31..B0}.
130           The 8 32-bit words that make the key must be stored as follows in MCU memory:
131           (+)    address n+00 : 0x B31 B30 B29 B28
132           (+)    address n+04 : 0x B27 B26 B25 B24
133           (+)    address n+08 : 0x B23 B22 B21 B20
134           (+)    address n+0C : 0x B19 B18 B17 B16
135           (+)    address n+10 : 0x B15 B14 B13 B12
136           (+)    address n+14 : 0x B11 B10 B9 B8
137           (+)    address n+18 : 0x B7 B6 B5 B4
138           (+)    address n+1C : 0x B3 B2 B1 B0
139      [..]  which leads to the expected setting
140        (+)       AES_KEYR7 = 0x B31 B30 B29 B28
141        (+)       AES_KEYR6 = 0x B27 B26 B25 B24
142        (+)       AES_KEYR5 = 0x B23 B22 B21 B20
143        (+)       AES_KEYR4 = 0x B19 B18 B17 B16
144        (+)       AES_KEYR3 = 0x B15 B14 B13 B12
145        (+)       AES_KEYR2 = 0x B11 B10 B9 B8
146        (+)       AES_KEYR1 = 0x B7 B6 B5 B4
147        (+)       AES_KEYR0 = 0x B3 B2 B1 B0
148 
149     [..] Initialization Vector IV (4 32-bit words) format must follow the same as
150          that of a 128-bit long key.
151 
152     [..] Note that key and IV registers are not sensitive to swap mode selection.
153 
154     [..]  This section describes the AES Galois/counter mode (GCM) supported by the peripherals:
155       (#)  Algorithm supported :
156          (##) Galois/counter mode (GCM)
157          (##) Galois message authentication code (GMAC) :is exactly the same as
158               GCM algorithm composed only by an header.
159       (#)  Four phases are performed in GCM :
160          (##) Init phase: peripheral prepares the GCM hash subkey (H) and do the IV processing
161          (##) Header phase: peripheral processes the Additional Authenticated Data (AAD), with hash
162           computation only.
163          (##) Payload phase: peripheral processes the plaintext (P) with hash computation + keystream
164           encryption + data XORing. It works in a similar way for ciphertext (C).
165          (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data.
166               HAL_CRYPEx_AESGCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond
167               to the Tag. user should consider only part of this 4 words, if Tag length is less than 128 bits.
168       (#)  structure of message construction in GCM is defined as below  :
169          (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
170          (##) The authenticated header A (also knows as Additional Authentication Data AAD)
171           this part of the message is only authenticated, not encrypted.
172          (##) The plaintext message P is both authenticated and encrypted as ciphertext.
173           GCM standard specifies that ciphertext has same bit length as the plaintext.
174          (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
175           (on 64 bits)
176 
177     [..]  A more detailed description of the GCM message structure is available below.
178 
179     [..]  This section describe The AES Counter with Cipher Block Chaining-Message
180           Authentication Code (CCM) supported by the peripheral:
181       (#)  Specific parameters for CCM  :
182 
183          (##) B0 block  : follows NIST Special Publication 800-38C,
184          (##) B1 block (header)
185          (##) CTRx block  : control blocks
186 
187     [..]  A detailed description of the CCM message structure is available below.
188 
189       (#)    CCM in peripheral:
190          (##) To perform message payload encryption or decryption AES is configured in CTR mode.
191          (##) For authentication two phases are performed :
192           - Header phase: peripheral processes the Additional Authenticated Data (AAD) first, then the cleartext message
193           only cleartext payload (not the ciphertext payload) is used and no output.
194          (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data.
195               HAL_CRYPEx_AESCCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond to the Tag.
196               user should consider only part of this 4 words, if Tag length is less than 128 bits
197   *** Callback registration ***
198   =============================
199 
200   [..]
201   The compilation define  USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
202   allows the user to configure dynamically the driver callbacks.
203   Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
204   to register an interrupt callback.
205 
206   [..]
207   Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
208     (+) InCpltCallback     :  Input FIFO transfer completed callback.
209     (+) OutCpltCallback    : Output FIFO transfer completed callback.
210     (+) ErrorCallback      : callback for error detection.
211     (+) MspInitCallback    : CRYP MspInit.
212     (+) MspDeInitCallback  : CRYP MspDeInit.
213   This function takes as parameters the HAL peripheral handle, the Callback ID
214   and a pointer to the user callback function.
215 
216   [..]
217   Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
218   weak function.
219   @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
220   and the Callback ID.
221   This function allows to reset following callbacks:
222     (+) InCpltCallback     :  Input FIFO transfer completed callback.
223     (+) OutCpltCallback    : Output FIFO transfer completed callback.
224     (+) ErrorCallback      : callback for error detection.
225     (+) MspInitCallback    : CRYP MspInit.
226     (+) MspDeInitCallback  : CRYP MspDeInit.
227 
228   [..]
229   By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
230   all callbacks are set to the corresponding weak functions :
231   examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
232   Exception done for MspInit and MspDeInit functions that are
233   reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
234   these callbacks are null (not registered beforehand).
235   if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
236   keep and use the user MspInit/MspDeInit functions (registered beforehand)
237 
238   [..]
239   Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
240   Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
241   in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
242   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
243   In that case first register the MspInit/MspDeInit user callbacks
244   using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
245   or @ref HAL_CRYP_Init() function.
246 
247   [..]
248   When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
249   not defined, the callback registration feature is not available and all callbacks
250   are set to the corresponding weak functions.
251 
252 
253   *** Suspend/Resume feature ***
254   ==============================
255 
256   [..]
257   The compilation define USE_HAL_CRYP_SUSPEND_RESUME when set to 1
258   allows the user to resort to the suspend/resume feature.
259   A low priority block processing can be suspended to process a high priority block
260   instead. When the high priority block processing is over, the low priority block
261   processing can be resumed, restarting from the point where it was suspended. This
262   feature is applicable only in non-blocking interrupt mode.
263 
264   [..] User must resort to HAL_CRYP_Suspend() to suspend the low priority block
265   processing. This API manages the hardware block processing suspension and saves all the
266   internal data that will be needed to restart later on. Upon HAL_CRYP_Suspend() completion,
267   the user can launch the processing of any other block (high priority block processing).
268 
269   [..] When the high priority block processing is over, user must invoke HAL_CRYP_Resume()
270   to resume the low priority block processing. Ciphering (or deciphering) restarts from
271   the suspension point and ends as usual.
272 
273   [..] HAL_CRYP_Suspend() reports an error when the suspension request is sent too late
274   (i.e when the low priority block processing is about to end). There is no use to
275   suspend the tag generation processing for authentication algorithms.
276 
277     [..]
278     (@) If the key is written out of HAL scope (case pKey pointer set to NULL by the user),
279         the block processing suspension/resumption mechanism is NOT applicable.
280 
281     [..]
282     (@) If the Key and Initialization Vector are configured only once and configuration is
283         skipped for consecutive processings (case KeyIVConfigSkip set to CRYP_KEYIVCONFIG_ONCE),
284         the block processing suspension/resumption mechanism is NOT applicable.
285 
286   @endverbatim
287   */
288 
289 /* Includes ------------------------------------------------------------------*/
290 #include "stm32h5xx_hal.h"
291 
292 /** @addtogroup STM32H5xx_HAL_Driver
293   * @{
294   */
295 
296 /** @addtogroup CRYP
297   * @{
298   */
299 
300 #if defined(AES)
301 #ifdef HAL_CRYP_MODULE_ENABLED
302 
303 /* Private typedef -----------------------------------------------------------*/
304 /* Private define ------------------------------------------------------------*/
305 /** @addtogroup CRYP_Private_Defines
306   * @{
307   */
308 #define CRYP_GENERAL_TIMEOUT             82U
309 #define CRYP_TIMEOUT_KEYPREPARATION      82U  /*!< The latency of key preparation operation is 82 clock cycles.*/
310 #define CRYP_TIMEOUT_GCMCCMINITPHASE     299U /*!< The latency of GCM/CCM init phase to prepare hash subkey
311                                                  is 299 clock cycles.*/
312 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE   290U /*!< The latency of GCM/CCM header phase is 290 clock cycles.*/
313 
314 #define CRYP_PHASE_READY                 0x00000001U /*!< CRYP peripheral is ready for initialization. */
315 #define CRYP_PHASE_PROCESS               0x00000002U /*!< CRYP peripheral is in processing phase */
316 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
317 #define  CRYP_PHASE_HEADER_SUSPENDED     0x00000004U    /*!< GCM/GMAC/CCM header phase is suspended */
318 #define  CRYP_PHASE_PAYLOAD_SUSPENDED    0x00000005U    /*!< GCM/CCM payload phase is suspended     */
319 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
320 #define  CRYP_PHASE_HEADER_DMA_FEED      0x00000006U    /*!< GCM/GMAC/CCM header is fed to the peripheral in DMA mode */
321 
322 #define CRYP_OPERATINGMODE_ENCRYPT                   0x00000000U     /*!< Encryption mode(Mode 1)  */
323 #define CRYP_OPERATINGMODE_KEYDERIVATION             AES_CR_MODE_0   /*!< Key derivation mode  only used when performing ECB and CBC decryptions (Mode 2) */
324 #define CRYP_OPERATINGMODE_DECRYPT                   AES_CR_MODE_1   /*!< Decryption    (Mode 3)    */
325 #define CRYP_PHASE_INIT                              0x00000000U     /*!< GCM/GMAC (or CCM) init phase */
326 #define CRYP_PHASE_HEADER                            AES_CR_GCMPH_0  /*!< GCM/GMAC or CCM header phase */
327 #define CRYP_PHASE_PAYLOAD                           AES_CR_GCMPH_1  /*!< GCM(/CCM) payload phase      */
328 #define CRYP_PHASE_FINAL                             AES_CR_GCMPH    /*!< GCM/GMAC or CCM  final phase */
329 
330 /*  CTR1 information to use in CCM algorithm */
331 #define CRYP_CCM_CTR1_0                  0x07FFFFFFU
332 #define CRYP_CCM_CTR1_1                  0xFFFFFF00U
333 #define CRYP_CCM_CTR1_2                  0x00000001U
334 
335 /**
336   * @}
337   */
338 
339 /* Private macro -------------------------------------------------------------*/
340 /** @addtogroup CRYP_Private_Macros
341   * @{
342   */
343 
344 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__)\
345   MODIFY_REG((__HANDLE__)->Instance->CR, AES_CR_GCMPH, (uint32_t)(__PHASE__))
346 
347 /**
348   * @}
349   */
350 
351 /* Private struct -------------------------------------------------------------*/
352 /* Private variables ---------------------------------------------------------*/
353 /* Private function prototypes -----------------------------------------------*/
354 /** @addtogroup CRYP_Private_Functions
355   * @{
356   */
357 
358 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
359 static HAL_StatusTypeDef CRYP_SetHeaderDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size);
360 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
361 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
362 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
363 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
364 static void CRYP_SetIV(CRYP_HandleTypeDef *hcryp);
365 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
366 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
367 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
368 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
369 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
370 static HAL_StatusTypeDef CRYP_GCMCCM_SetPayloadPhase_DMA(CRYP_HandleTypeDef *hcryp);
371 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
372 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
373 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
374 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
375 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
376 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
377 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
378 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
379 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
380 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
381 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
382 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
383 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
384 static void CRYP_ClearCCFlagWhenHigh(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
385 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
386 static void CRYP_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output);
387 static void CRYP_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input);
388 static void CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output);
389 static void CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input);
390 static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output, uint32_t KeySize);
391 static void CRYP_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input, uint32_t KeySize);
392 static void CRYP_PhaseProcessingResume(CRYP_HandleTypeDef *hcryp);
393 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
394 
395 
396 /**
397   * @}
398   */
399 
400 /* Exported functions ---------------------------------------------------------*/
401 
402 /** @addtogroup CRYP_Exported_Functions
403   * @{
404   */
405 
406 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
407   * @brief    Initialization and Configuration functions.
408   *
409 @verbatim
410   ========================================================================================
411      ##### Initialization, de-initialization and Set and Get configuration functions #####
412   ========================================================================================
413     [..]  This section provides functions allowing to:
414       (+) Initialize the CRYP
415       (+) DeInitialize the CRYP
416       (+) Initialize the CRYP MSP
417       (+) DeInitialize the CRYP MSP
418       (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
419           Parameters which are configured in This section are :
420           (+) Key size
421           (+) Data Type : 32,16, 8 or 1bit
422           (+) AlgoMode : ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
423       (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
424       (+) For interleave mode, API HAL_CRYP_SaveContext and HAL_CRYP_RestoreContext to be used to save then Restore CRYP
425           configuration and parameters. CRYP_IVCONFIG_ONCE should be selected for KeyIVConfigSkip parameter.
426           Only polling mode is supported, interleave mode should be used with HAL_CRYP_Encrypt and HAL_CRYP_Decrypt API.
427 
428 @endverbatim
429   * @{
430   */
431 
432 /**
433   * @brief  Initializes the CRYP according to the specified
434   *         parameters in the CRYP_ConfigTypeDef and creates the associated handle.
435   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
436   *         the configuration information for CRYP module
437   * @retval HAL status
438   */
HAL_CRYP_Init(CRYP_HandleTypeDef * hcryp)439 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
440 {
441   uint32_t cr_value;
442 #if defined(SAES)
443   uint32_t tickstart;
444 #endif /* SAES */
445 
446   /* Check the CRYP handle allocation */
447   if (hcryp == NULL)
448   {
449     return HAL_ERROR;
450   }
451 
452   /* Check parameters */
453   assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
454   assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
455   assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
456   assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
457 
458 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
459   if (hcryp->State == HAL_CRYP_STATE_RESET)
460   {
461     /* Allocate lock resource and initialize it */
462     hcryp->Lock = HAL_UNLOCKED;
463 
464     hcryp->InCpltCallback  = HAL_CRYP_InCpltCallback;  /* Legacy weak InCpltCallback   */
465     hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback  */
466     hcryp->ErrorCallback   = HAL_CRYP_ErrorCallback;   /* Legacy weak ErrorCallback    */
467 
468     if (hcryp->MspInitCallback == NULL)
469     {
470       hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit  */
471     }
472 
473     /* Init the low level hardware */
474     hcryp->MspInitCallback(hcryp);
475   }
476 #else
477   if (hcryp->State == HAL_CRYP_STATE_RESET)
478   {
479     /* Allocate lock resource and initialize it */
480     hcryp->Lock = HAL_UNLOCKED;
481 
482     /* Init the low level hardware */
483     HAL_CRYP_MspInit(hcryp);
484   }
485 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
486 
487   if (hcryp->Instance == AES)
488   {
489     /* Set the key size, data type and Algorithm */
490     cr_value = (uint32_t)(hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm | hcryp->Init.KeyMode);
491     /* Set the key size, data type, algorithm and mode */
492     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD, cr_value);
493   }
494   else
495   {
496     /* SAES is initializing, fetching random number from the RNG */
497     tickstart = HAL_GetTick();
498     while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY))
499     {
500       /* Check for the Timeout */
501       if ((HAL_GetTick() - tickstart) > CRYP_GENERAL_TIMEOUT)
502       {
503         __HAL_CRYP_DISABLE(hcryp);
504         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
505         hcryp->State = HAL_CRYP_STATE_READY;
506         __HAL_UNLOCK(hcryp);
507         return HAL_ERROR;
508       }
509     }
510     /* SAES is initializing, no random number fetching error flagged */
511     tickstart = HAL_GetTick();
512     while (HAL_IS_BIT_SET(hcryp->Instance->ISR, CRYP_FLAG_RNGEIF))
513     {
514       /* Check for the Timeout */
515       if ((HAL_GetTick() - tickstart) > CRYP_GENERAL_TIMEOUT)
516       {
517         __HAL_CRYP_DISABLE(hcryp);
518         hcryp->ErrorCode |= HAL_CRYP_ERROR_RNG;
519         hcryp->State = HAL_CRYP_STATE_READY;
520         __HAL_UNLOCK(hcryp);
521         return HAL_ERROR;
522       }
523     }
524     cr_value = (uint32_t)(hcryp->Init.KeyMode | hcryp->Init.DataType | hcryp->Init.KeySize | \
525                           hcryp->Init.Algorithm | hcryp->Init.KeySelect | hcryp->Init.KeyProtection);
526     /* Set the key size, data type, algorithm, Key selection and key protection */
527     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD | AES_CR_KEYSEL |
528                AES_CR_KEYPROT, cr_value);
529   }
530   /* Reset Error Code field */
531   hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
532 
533   /* Reset peripheral Key and IV configuration flag */
534   hcryp->KeyIVConfig = 0U;
535 
536   /* Change the CRYP state */
537   hcryp->State = HAL_CRYP_STATE_READY;
538 
539   /* Set the default CRYP phase */
540   hcryp->Phase = CRYP_PHASE_READY;
541 
542   return HAL_OK;
543 }
544 
545 /**
546   * @brief  De-Initializes the CRYP peripheral.
547   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
548   *         the configuration information for CRYP module
549   * @retval HAL status
550   */
HAL_CRYP_DeInit(CRYP_HandleTypeDef * hcryp)551 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
552 {
553   /* Check the CRYP handle allocation */
554   if (hcryp == NULL)
555   {
556     return HAL_ERROR;
557   }
558 
559   /* Set the default CRYP phase */
560   hcryp->Phase = CRYP_PHASE_READY;
561 
562   /* Reset CrypInCount and CrypOutCount */
563   hcryp->CrypInCount = 0;
564   hcryp->CrypOutCount = 0;
565   hcryp->CrypHeaderCount = 0;
566 
567   /* Disable the CRYP peripheral clock */
568   __HAL_CRYP_DISABLE(hcryp);
569 
570   /* Set IPRST for software reset */
571   SET_BIT(hcryp->Instance->CR, AES_CR_IPRST);
572 
573   /* Clear IPRST to allow writing registers */
574   CLEAR_BIT(hcryp->Instance->CR, AES_CR_IPRST);
575 
576 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
577   if (hcryp->MspDeInitCallback == NULL)
578   {
579     hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit  */
580   }
581   /* DeInit the low level hardware */
582   hcryp->MspDeInitCallback(hcryp);
583 #else
584   /* DeInit the low level hardware: CLOCK, NVIC.*/
585   HAL_CRYP_MspDeInit(hcryp);
586 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
587 
588   /* Change the CRYP state */
589   hcryp->State = HAL_CRYP_STATE_RESET;
590   __HAL_UNLOCK(hcryp);
591 
592   return HAL_OK;
593 }
594 
595 /**
596   * @brief  Configure the CRYP according to the specified
597   *         parameters in the CRYP_ConfigTypeDef
598   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
599   * @param  pConf pointer to a CRYP_ConfigTypeDef structure that contains
600   *         the configuration information for CRYP module
601   * @retval HAL status
602   */
HAL_CRYP_SetConfig(CRYP_HandleTypeDef * hcryp,CRYP_ConfigTypeDef * pConf)603 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
604 {
605   /* Check the CRYP handle allocation */
606   if ((hcryp == NULL) || (pConf == NULL))
607   {
608     return HAL_ERROR;
609   }
610 
611   /* Check parameters */
612   assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
613   assert_param(IS_CRYP_DATATYPE(pConf->DataType));
614   assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
615 
616   if (hcryp->State == HAL_CRYP_STATE_READY)
617   {
618     /* Change the CRYP state */
619     hcryp->State = HAL_CRYP_STATE_BUSY;
620     __HAL_LOCK(hcryp);
621 
622     /* Set CRYP parameters */
623     hcryp->Init.DataType   = pConf->DataType;
624     hcryp->Init.pKey       = pConf->pKey;
625     hcryp->Init.Algorithm  = pConf->Algorithm;
626     hcryp->Init.KeySize    = pConf->KeySize;
627     hcryp->Init.pInitVect  = pConf->pInitVect;
628     hcryp->Init.Header     = pConf->Header;
629     hcryp->Init.HeaderSize = pConf->HeaderSize;
630     hcryp->Init.B0         = pConf->B0;
631     hcryp->Init.DataWidthUnit = pConf->DataWidthUnit;
632     hcryp->Init.KeyMode = pConf->KeyMode;
633     hcryp->Init.HeaderWidthUnit = pConf->HeaderWidthUnit;
634     hcryp->Init.KeyIVConfigSkip = pConf->KeyIVConfigSkip;
635 
636     if (hcryp->Instance == AES)
637     {
638       /* Set the key size, data type, AlgoMode and operating mode */
639       MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD | AES_CR_KMOD,
640                  hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm | hcryp->Init.KeyMode);
641     }
642     else
643     {
644       hcryp->Init.KeySelect        = pConf->KeySelect;
645       hcryp->Init.KeyProtection    = pConf->KeyProtection;
646 
647       /* In case of HSW, HW or SW key selection, we should specify Key mode selection (SAES_CR_KMOD) */
648       if ((hcryp->Init.KeySelect != CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_WRAPPED))
649       {
650         /* Disable AES to change key mode */
651         __HAL_CRYP_DISABLE(hcryp);
652         /* Set key mode selection (Normal, Wrapped or Shared key )*/
653         MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED);
654       }
655 
656       /* Set the key size data type, AlgoMode and operating mode */
657       MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD | \
658                  AES_CR_KEYSEL | AES_CR_KEYPROT | AES_CR_KMOD, hcryp->Init.DataType | hcryp->Init.KeySize | \
659                  hcryp->Init.Algorithm | hcryp->Init.KeySelect | hcryp->Init.KeyProtection | hcryp->Init.KeyMode);
660       /* Set to 0 the number of non-valid bytes using NPBLB field of CR register*/
661       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
662     }
663     /* Clear error flags */
664     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_RWEIF);
665     __HAL_UNLOCK(hcryp);
666 
667     /* Reset Error Code field */
668     hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
669 
670     /* Change the CRYP state */
671     hcryp->State = HAL_CRYP_STATE_READY;
672 
673     /* Set the default CRYP phase */
674     hcryp->Phase = CRYP_PHASE_READY;
675 
676     return HAL_OK;
677   }
678   else
679   {
680     /* Busy error code field */
681     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
682     return HAL_ERROR;
683   }
684 }
685 
686 /**
687   * @brief  Get CRYP Configuration parameters in associated handle.
688   * @param  pConf pointer to a CRYP_ConfigTypeDef structure
689   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
690   *         the configuration information for CRYP module
691   * @retval HAL status
692   */
HAL_CRYP_GetConfig(CRYP_HandleTypeDef * hcryp,CRYP_ConfigTypeDef * pConf)693 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
694 {
695   /* Check the CRYP handle allocation */
696   if ((hcryp == NULL) || (pConf == NULL))
697   {
698     return HAL_ERROR;
699   }
700 
701   if (hcryp->State == HAL_CRYP_STATE_READY)
702   {
703     /* Change the CRYP state */
704     hcryp->State = HAL_CRYP_STATE_BUSY;
705     __HAL_LOCK(hcryp);
706 
707     /* Get CRYP parameters */
708     pConf->DataType        = hcryp->Init.DataType;
709     pConf->pKey            = hcryp->Init.pKey;
710     pConf->Algorithm       = hcryp->Init.Algorithm;
711     pConf->KeySize         = hcryp->Init.KeySize;
712     pConf->pInitVect       = hcryp->Init.pInitVect;
713     pConf->Header          = hcryp->Init.Header;
714     pConf->HeaderSize      = hcryp->Init.HeaderSize;
715     pConf->B0              = hcryp->Init.B0;
716     pConf->DataWidthUnit   = hcryp->Init.DataWidthUnit;
717     pConf->KeyMode         = hcryp->Init.KeyMode;
718     pConf->KeySelect       = hcryp->Init.KeySelect;
719     pConf->KeyProtection   = hcryp->Init.KeyProtection;
720     pConf->KeyIVConfigSkip = hcryp->Init.KeyIVConfigSkip;
721     pConf->HeaderWidthUnit = hcryp->Init.HeaderWidthUnit;
722 
723     __HAL_UNLOCK(hcryp);
724 
725     /* Change the CRYP state */
726     hcryp->State = HAL_CRYP_STATE_READY;
727 
728     return HAL_OK;
729   }
730   else
731   {
732     /* Busy error code field */
733     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
734     return HAL_ERROR;
735   }
736 }
737 /**
738   * @brief  Initializes the CRYP MSP.
739   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
740   *         the configuration information for CRYP module
741   * @retval None
742   */
HAL_CRYP_MspInit(CRYP_HandleTypeDef * hcryp)743 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
744 {
745   /* Prevent unused argument(s) compilation warning */
746   UNUSED(hcryp);
747 
748   /* NOTE : This function Should not be modified, when the callback is needed,
749             the HAL_CRYP_MspInit could be implemented in the user file
750    */
751 }
752 
753 /**
754   * @brief  DeInitializes CRYP MSP.
755   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
756   *         the configuration information for CRYP module
757   * @retval None
758   */
HAL_CRYP_MspDeInit(CRYP_HandleTypeDef * hcryp)759 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
760 {
761   /* Prevent unused argument(s) compilation warning */
762   UNUSED(hcryp);
763 
764   /* NOTE : This function Should not be modified, when the callback is needed,
765             the HAL_CRYP_MspDeInit could be implemented in the user file
766    */
767 }
768 
769 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
770 /**
771   * @brief  Register a User CRYP Callback
772   *         To be used instead of the weak predefined callback
773   * @param hcryp cryp handle
774   * @param CallbackID ID of the callback to be registered
775   *        This parameter can be one of the following values:
776   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
777   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
778   *          @arg @ref HAL_CRYP_ERROR_CB_ID Error callback ID
779   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
780   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
781   * @param pCallback pointer to the Callback function
782   * @retval status
783   */
HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef * hcryp,HAL_CRYP_CallbackIDTypeDef CallbackID,pCRYP_CallbackTypeDef pCallback)784 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID,
785                                             pCRYP_CallbackTypeDef pCallback)
786 {
787   HAL_StatusTypeDef status = HAL_OK;
788 
789   if (pCallback == NULL)
790   {
791     /* Update the error code */
792     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
793 
794     return HAL_ERROR;
795   }
796 
797   if (hcryp->State == HAL_CRYP_STATE_READY)
798   {
799     switch (CallbackID)
800     {
801       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
802         hcryp->InCpltCallback = pCallback;
803         break;
804 
805       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
806         hcryp->OutCpltCallback = pCallback;
807         break;
808 
809       case HAL_CRYP_ERROR_CB_ID :
810         hcryp->ErrorCallback = pCallback;
811         break;
812 
813       case HAL_CRYP_MSPINIT_CB_ID :
814         hcryp->MspInitCallback = pCallback;
815         break;
816 
817       case HAL_CRYP_MSPDEINIT_CB_ID :
818         hcryp->MspDeInitCallback = pCallback;
819         break;
820 
821       default :
822         /* Update the error code */
823         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
824         /* Return error status */
825         status =  HAL_ERROR;
826         break;
827     }
828   }
829   else if (hcryp->State == HAL_CRYP_STATE_RESET)
830   {
831     switch (CallbackID)
832     {
833       case HAL_CRYP_MSPINIT_CB_ID :
834         hcryp->MspInitCallback = pCallback;
835         break;
836 
837       case HAL_CRYP_MSPDEINIT_CB_ID :
838         hcryp->MspDeInitCallback = pCallback;
839         break;
840 
841       default :
842         /* Update the error code */
843         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
844         /* Return error status */
845         status =  HAL_ERROR;
846         break;
847     }
848   }
849   else
850   {
851     /* Update the error code */
852     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
853     /* Return error status */
854     status =  HAL_ERROR;
855   }
856 
857   return status;
858 }
859 
860 /**
861   * @brief  Unregister an CRYP Callback
862   *         CRYP callback is redirected to the weak predefined callback
863   * @param hcryp cryp handle
864   * @param CallbackID ID of the callback to be unregistered
865   *        This parameter can be one of the following values:
866   *          @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
867   *          @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
868   *          @arg @ref HAL_CRYP_ERROR_CB_ID Error callback ID
869   *          @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
870   *          @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
871   * @retval status
872   */
HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef * hcryp,HAL_CRYP_CallbackIDTypeDef CallbackID)873 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
874 {
875   HAL_StatusTypeDef status = HAL_OK;
876 
877 
878   if (hcryp->State == HAL_CRYP_STATE_READY)
879   {
880     switch (CallbackID)
881     {
882       case HAL_CRYP_INPUT_COMPLETE_CB_ID :
883         hcryp->InCpltCallback = HAL_CRYP_InCpltCallback;    /*!< Legacy weak  InCpltCallback  */
884         break;
885 
886       case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
887         hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback;  /*!< Legacy weak OutCpltCallback   */
888         break;
889 
890       case HAL_CRYP_ERROR_CB_ID :
891         hcryp->ErrorCallback = HAL_CRYP_ErrorCallback;      /*!< Legacy weak ErrorCallback     */
892         break;
893 
894       case HAL_CRYP_MSPINIT_CB_ID :
895         hcryp->MspInitCallback = HAL_CRYP_MspInit;          /*!< Legacy weak MspInit           */
896         break;
897 
898       case HAL_CRYP_MSPDEINIT_CB_ID :
899         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;      /*!< Legacy weak MspDeInit         */
900         break;
901 
902       default :
903         /* Update the error code */
904         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;/*!< Legacy weak ERROR INVALID CALLBACK  */
905         /* Return error status */
906         status =  HAL_ERROR;
907         break;
908     }
909   }
910   else if (hcryp->State == HAL_CRYP_STATE_RESET)
911   {
912     switch (CallbackID)
913     {
914       case HAL_CRYP_MSPINIT_CB_ID :
915         hcryp->MspInitCallback = HAL_CRYP_MspInit;
916         break;
917 
918       case HAL_CRYP_MSPDEINIT_CB_ID :
919         hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
920         break;
921 
922       default :
923         /* Update the error code */
924         hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
925         /* Return error status */
926         status =  HAL_ERROR;
927         break;
928     }
929   }
930   else
931   {
932     /* Update the error code */
933     hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
934     /* Return error status */
935     status =  HAL_ERROR;
936   }
937 
938   return status;
939 }
940 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
941 
942 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
943 /**
944   * @brief  Request CRYP processing suspension when in interruption mode.
945   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
946   *         the configuration information for CRYP module.
947   * @note   Set the handle field SuspendRequest to the appropriate value so that
948   *         the on-going CRYP processing is suspended as soon as the required
949   *         conditions are met.
950   * @note   HAL_CRYP_ProcessSuspend() can only be invoked when the processing is done
951   *         in non-blocking interrupt mode.
952   * @note   It is advised not to suspend the CRYP processing when the DMA controller
953   *         is managing the data transfer.
954   * @retval None
955   */
HAL_CRYP_ProcessSuspend(CRYP_HandleTypeDef * hcryp)956 void HAL_CRYP_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
957 {
958   /* Set Handle SuspendRequest field */
959   hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
960 }
961 
962 /**
963   * @brief  CRYP processing suspension and peripheral internal parameters storage.
964   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
965   *         the configuration information for CRYP module
966   * @note   peripheral internal parameters are stored to be readily available when
967   *         suspended processing is resumed later on.
968   * @retval HAL status
969   */
HAL_CRYP_Suspend(CRYP_HandleTypeDef * hcryp)970 HAL_StatusTypeDef HAL_CRYP_Suspend(CRYP_HandleTypeDef *hcryp)
971 {
972   HAL_CRYP_STATETypeDef state;
973 
974   /* Request suspension */
975   HAL_CRYP_ProcessSuspend(hcryp);
976 
977   do
978   {
979     state = HAL_CRYP_GetState(hcryp);
980   } while ((state != HAL_CRYP_STATE_SUSPENDED) && (state != HAL_CRYP_STATE_READY));
981 
982   if (HAL_CRYP_GetState(hcryp) == HAL_CRYP_STATE_READY)
983   {
984     /* Processing was already over or was about to end. No suspension done */
985     return HAL_ERROR;
986   }
987   else
988   {
989     /* Suspend Processing */
990 
991     /* If authentication algorithms on-going, carry out first saving steps
992        before disable the peripheral */
993     if ((hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC) || \
994         (hcryp->Init.Algorithm == CRYP_AES_CCM))
995     {
996       /* Save Suspension registers */
997       CRYP_Read_SuspendRegisters(hcryp, hcryp->SUSPxR_saved);
998       /* Save Key */
999       CRYP_Read_KeyRegisters(hcryp, hcryp->Key_saved, hcryp->Init.KeySize);
1000       /* Save IV */
1001       CRYP_Read_IVRegisters(hcryp, hcryp->IV_saved);
1002     }
1003     /* Disable AES */
1004     __HAL_CRYP_DISABLE(hcryp);
1005 
1006     /* Save low-priority block CRYP handle parameters */
1007     hcryp->Init_saved              = hcryp->Init;
1008     hcryp->pCrypInBuffPtr_saved    = hcryp->pCrypInBuffPtr;
1009     hcryp->pCrypOutBuffPtr_saved   = hcryp->pCrypOutBuffPtr;
1010     hcryp->CrypInCount_saved       = hcryp->CrypInCount;
1011     hcryp->CrypOutCount_saved      = hcryp->CrypOutCount;
1012     hcryp->Phase_saved             = hcryp->Phase;
1013     hcryp->State_saved             = hcryp->State;
1014     hcryp->Size_saved              = ((hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)\
1015                                       ? (hcryp->Size / 4U) : hcryp->Size);
1016     hcryp->SizesSum_saved          = hcryp->SizesSum;
1017     hcryp->CrypHeaderCount_saved   = hcryp->CrypHeaderCount;
1018     hcryp->SuspendRequest          = HAL_CRYP_SUSPEND_NONE;
1019 
1020     if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1021         (hcryp->Init.Algorithm == CRYP_AES_CTR))
1022     {
1023       /* Save Initialisation Vector registers */
1024       CRYP_Read_IVRegisters(hcryp, hcryp->IV_saved);
1025     }
1026 
1027     /* Save Control register */
1028     hcryp->CR_saved = hcryp->Instance->CR;
1029   }
1030   return HAL_OK;
1031 }
1032 
1033 /**
1034   * @brief  CRYP processing resumption.
1035   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1036   *         the configuration information for CRYP module
1037   * @note   Processing restarts at the exact point where it was suspended, based
1038   *         on the parameters saved at suspension time.
1039   * @retval HAL status
1040   */
HAL_CRYP_Resume(CRYP_HandleTypeDef * hcryp)1041 HAL_StatusTypeDef HAL_CRYP_Resume(CRYP_HandleTypeDef *hcryp)
1042 {
1043   /* Check the CRYP handle allocation */
1044   if (hcryp == NULL)
1045   {
1046     return HAL_ERROR;
1047   }
1048 
1049   if (hcryp->State_saved != HAL_CRYP_STATE_SUSPENDED)
1050   {
1051     /* CRYP was not suspended */
1052     return HAL_ERROR;
1053   }
1054   else
1055   {
1056     /* Restore low-priority block CRYP handle parameters */
1057     hcryp->Init            = hcryp->Init_saved;
1058     hcryp->State           = hcryp->State_saved;
1059 
1060     /* Chaining algorithms case */
1061     if ((hcryp->Init_saved.Algorithm == CRYP_AES_ECB) || \
1062         (hcryp->Init_saved.Algorithm == CRYP_AES_CBC) || \
1063         (hcryp->Init_saved.Algorithm == CRYP_AES_CTR))
1064     {
1065       /* Restore low-priority block CRYP handle parameters */
1066       if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1067           (hcryp->Init.Algorithm == CRYP_AES_CTR))
1068       {
1069         hcryp->Init.pInitVect     = hcryp->IV_saved;
1070       }
1071       __HAL_CRYP_DISABLE(hcryp);
1072 
1073       (void) HAL_CRYP_Init(hcryp);
1074     }
1075     else    /* Authentication algorithms case */
1076     {
1077       /* Restore low-priority block CRYP handle parameters */
1078       hcryp->Phase           = hcryp->Phase_saved;
1079       hcryp->CrypHeaderCount = hcryp->CrypHeaderCount_saved;
1080       hcryp->SizesSum        = hcryp->SizesSum_saved;
1081 
1082       /* Disable AES and write-back SUSPxR registers */;
1083       __HAL_CRYP_DISABLE(hcryp);
1084       /* Restore AES Suspend Registers */
1085       CRYP_Write_SuspendRegisters(hcryp, hcryp->SUSPxR_saved);
1086       /* Restore Control,  Key and IV Registers, then enable AES */
1087       hcryp->Instance->CR = hcryp->CR_saved;
1088       CRYP_Write_KeyRegisters(hcryp, hcryp->Key_saved, hcryp->Init.KeySize);
1089       CRYP_Write_IVRegisters(hcryp, hcryp->IV_saved);
1090       __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
1091       __HAL_CRYP_ENABLE(hcryp);
1092 
1093       /* At the same time, set handle state back to READY to be able to resume the AES calculations
1094       without the processing APIs returning HAL_BUSY when called. */
1095       hcryp->State        = HAL_CRYP_STATE_READY;
1096     }
1097 
1098     /* Resume low-priority block processing under IT */
1099     hcryp->ResumingFlag = 1U;
1100     if (READ_BIT(hcryp->CR_saved, AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
1101     {
1102       if (HAL_CRYP_Encrypt_IT(hcryp, hcryp->pCrypInBuffPtr_saved, hcryp->Size_saved,
1103                               hcryp->pCrypOutBuffPtr_saved) != HAL_OK)
1104       {
1105         return HAL_ERROR;
1106       }
1107     }
1108     else
1109     {
1110       if (HAL_CRYP_Decrypt_IT(hcryp, hcryp->pCrypInBuffPtr_saved, hcryp->Size_saved,
1111                               hcryp->pCrypOutBuffPtr_saved) != HAL_OK)
1112       {
1113         return HAL_ERROR;
1114       }
1115     }
1116   }
1117   return HAL_OK;
1118 }
1119 #endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */
1120 
1121 /**
1122   * @brief  CRYP peripheral parameters storage when processing Interleaved mode .
1123   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1124   *         the configuration information for CRYP module
1125   * @param  pcont pointer to a CRYP_ContextTypeDef structure where CRYP parameters will be stored.
1126   * @retval HAL status
1127   */
HAL_CRYP_SaveContext(CRYP_HandleTypeDef * hcryp,CRYP_ContextTypeDef * pcont)1128 HAL_StatusTypeDef  HAL_CRYP_SaveContext(CRYP_HandleTypeDef *hcryp, CRYP_ContextTypeDef *pcont)
1129 {
1130   /* Check the CRYP handle allocation */
1131   if ((hcryp == NULL) || (pcont == NULL))
1132   {
1133     return HAL_ERROR;
1134   }
1135 
1136   if (hcryp->State == HAL_CRYP_STATE_READY)
1137   {
1138     /* Save CRYP handle parameters */
1139     pcont->DataType        = (uint32_t)(hcryp->Init.DataType);
1140     pcont->KeySize         = (uint32_t)(hcryp->Init.KeySize);
1141     pcont->pKey            = hcryp->Init.pKey;
1142     pcont->pInitVect       = hcryp->Init.pInitVect;
1143     pcont->Algorithm       = (uint32_t)(hcryp->Init.Algorithm);
1144     pcont->DataWidthUnit   = (uint32_t)(hcryp->Init.DataWidthUnit);
1145     pcont->KeyIVConfigSkip = (uint32_t)(hcryp->Init.KeyIVConfigSkip);
1146     pcont->KeyMode         = (uint32_t)(hcryp->Init.KeyMode);
1147     pcont->Phase           = (uint32_t)(hcryp->Phase);
1148     pcont->KeyIVConfig     = (uint32_t)(hcryp->KeyIVConfig);
1149 
1150     /* Save CRYP CR register content */
1151     pcont->CR_Reg = READ_REG(hcryp->Instance->CR);
1152 
1153     /* Save IER register content */
1154     pcont->IER_Reg = READ_BIT(hcryp->Instance->IER, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
1155 
1156 
1157     if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1158         (hcryp->Init.Algorithm == CRYP_AES_CTR))
1159     {
1160       /* Save Initialisation Vector registers */
1161       pcont->IVR0_Reg = READ_REG(hcryp->Instance->IVR0);
1162       pcont->IVR1_Reg = READ_REG(hcryp->Instance->IVR1);
1163       pcont->IVR2_Reg = READ_REG(hcryp->Instance->IVR2);
1164       pcont->IVR3_Reg = READ_REG(hcryp->Instance->IVR3);
1165     }
1166 
1167     /* To load Key for next piece of message */
1168     hcryp->KeyIVConfig = 0;
1169 
1170     return HAL_OK;
1171   }
1172   else
1173   {
1174     /* Busy error code field */
1175     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1176     return HAL_ERROR;
1177   }
1178 
1179 }
1180 
1181 /**
1182   * @brief  Restore CRYP parameters needed for Interleaved mode.
1183   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1184   *         the configuration information for CRYP module
1185   * @param  pcont pointer to a CRYP_ContextTypeDef structure that contains CRYP parameters stored.
1186   * @retval HAL status
1187   */
HAL_CRYP_RestoreContext(CRYP_HandleTypeDef * hcryp,CRYP_ContextTypeDef * pcont)1188 HAL_StatusTypeDef HAL_CRYP_RestoreContext(CRYP_HandleTypeDef *hcryp, CRYP_ContextTypeDef *pcont)
1189 {
1190   /* Check the CRYP handle allocation */
1191   if ((hcryp == NULL) || (pcont == NULL))
1192   {
1193     return HAL_ERROR;
1194   }
1195 
1196   if (hcryp->State == HAL_CRYP_STATE_READY)
1197   {
1198     /* Restore CRYP handle parameters */
1199     hcryp->Init.DataType        = pcont->DataType;
1200     hcryp->Init.KeySize         = pcont->KeySize;
1201     hcryp->Init.pKey            = pcont->pKey;
1202     hcryp->Init.pInitVect       = pcont->pInitVect;
1203     hcryp->Init.Algorithm       = pcont->Algorithm;
1204     hcryp->Init.DataWidthUnit   = pcont->DataWidthUnit;
1205     hcryp->Init.KeyIVConfigSkip = pcont->KeyIVConfigSkip;
1206     hcryp->Init.KeyMode         = pcont->KeyMode;
1207     hcryp->Phase                = pcont->Phase;
1208     hcryp->KeyIVConfig          = pcont->KeyIVConfig;
1209 
1210     /* Restore CRYP CR register content */
1211     WRITE_REG(hcryp->Instance->CR, (uint32_t)(pcont->CR_Reg));
1212 
1213     /* Restore CRYP IER register content */
1214     WRITE_REG(hcryp->Instance->IER, (uint32_t)(pcont->IER_Reg));
1215 
1216     if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1217         (hcryp->Init.Algorithm == CRYP_AES_CTR))
1218     {
1219       /* Restore Initialisation Vector registers */
1220       WRITE_REG(hcryp->Instance->IVR0, (uint32_t)(pcont->IVR0_Reg));
1221       WRITE_REG(hcryp->Instance->IVR1, (uint32_t)(pcont->IVR1_Reg));
1222       WRITE_REG(hcryp->Instance->IVR2, (uint32_t)(pcont->IVR2_Reg));
1223       WRITE_REG(hcryp->Instance->IVR3, (uint32_t)(pcont->IVR3_Reg));
1224     }
1225     return HAL_OK;
1226   }
1227   else
1228   {
1229     /* Busy error code field */
1230     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1231     return HAL_ERROR;
1232   }
1233 }
1234 
1235 /**
1236   * @}
1237   */
1238 
1239 /** @defgroup CRYP_Exported_Functions_Group2 Encryption Decryption functions
1240   * @brief    Encryption Decryption functions.
1241   *
1242 @verbatim
1243   ==============================================================================
1244                       ##### Encrypt Decrypt  functions #####
1245   ==============================================================================
1246     [..]  This section provides API allowing to Encrypt/Decrypt Data following
1247       (+) Standard AES algorithms supported by the peripheral:
1248            - Electronic Code Book(ECB)
1249            - Cipher Block Chaining (CBC)
1250            - Counter mode (CTR)
1251            - Cipher Block Chaining (CBC)
1252            - Counter mode (CTR)
1253            - Galois/counter mode (GCM)
1254            - Counter with Cipher Block Chaining-Message(CCM)
1255     [..]  Three processing functions are available:
1256       (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
1257       (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
1258       (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
1259 
1260 @endverbatim
1261   * @{
1262   */
1263 
1264 /* GCM message structure additional details
1265 
1266                                   ICB
1267           +-------------------------------------------------------+
1268           |       Initialization vector (IV)      |  Counter      |
1269           |----------------|----------------|-----------|---------|
1270          127              95                63            31       0
1271 
1272 
1273               Bit Number    Register           Contents
1274               ----------   ---------------       -----------
1275               127 ...96    CRYP_IV1R[31:0]     ICB[127:96]
1276               95  ...64    CRYP_IV1L[31:0]     B0[95:64]
1277               63 ... 32    CRYP_IV0R[31:0]     ICB[63:32]
1278               31 ... 0     CRYP_IV0L[31:0]     ICB[31:0], where 32-bit counter= 0x2
1279 
1280 
1281                                  GCM last block definition
1282           +-------------------------------------------------------------------+
1283           |  Bit[0]   |  Bit[32]           |  Bit[64]  | Bit[96]              |
1284           |-----------|--------------------|-----------|----------------------|
1285           |   0x0     | Header length[31:0]|     0x0   | Payload length[31:0] |
1286           |-----------|--------------------|-----------|----------------------|
1287 */
1288 
1289 /* CCM message blocks description
1290 
1291          (##) B0 block  : According to NIST Special Publication 800-38C,
1292             The first block B0 is formatted as follows, where l(m) is encoded in
1293             most-significant-byte first order:
1294 
1295                 Octet Number   Contents
1296                 ------------   ---------
1297                 0              Flags
1298                 1 ... 15-q     Nonce N
1299                 16-q ... 15    Q
1300 
1301             the Flags field is formatted as follows:
1302 
1303                 Bit Number   Contents
1304                 ----------   ----------------------
1305                 7            Reserved (always zero)
1306                 6            Adata
1307                 5 ... 3      (t-2)/2
1308                 2 ... 0      [q-1]3
1309 
1310               - Q: a bit string representation of the octet length of P (plaintext)
1311               - q The octet length of the binary representation of the octet length of the payload
1312               - A nonce (N), n The octet length of the where n+q=15.
1313               - Flags: most significant octet containing four flags for control information,
1314               - t The octet length of the MAC.
1315          (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
1316               the associated data length expressed in bytes (a) defined as below:
1317             - If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
1318             - If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
1319             - If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
1320          (##) CTRx block  : control blocks
1321             - Generation of CTR1 from first block B0 information :
1322               equal to B0 with first 5 bits zeroed and most significant bits storing octet
1323               length of P also zeroed, then incremented by one
1324 
1325                 Bit Number    Register           Contents
1326                 ----------   ---------------       -----------
1327                 127 ...96    CRYP_IV1R[31:0]     B0[127:96], where Q length bits are set to 0, except for
1328                                                  bit 0 that is set to 1
1329                 95  ...64    CRYP_IV1L[31:0]     B0[95:64]
1330                 63 ... 32    CRYP_IV0R[31:0]     B0[63:32]
1331                 31 ... 0     CRYP_IV0L[31:0]     B0[31:0], where flag bits set to 0
1332 
1333             - Generation of CTR0: same as CTR1 with bit[0] set to zero.
1334 */
1335 
1336 /**
1337   * @brief  Encryption mode.
1338   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1339   *         the configuration information for CRYP module
1340   * @param  pInput Pointer to the input buffer (plaintext)
1341   * @param  Size  Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1342   * @param  pOutput Pointer to the output buffer(ciphertext)
1343   * @param  Timeout Specify Timeout value
1344   * @retval HAL status
1345   */
HAL_CRYP_Encrypt(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint16_t Size,uint32_t * pOutput,uint32_t Timeout)1346 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput,
1347                                    uint32_t Timeout)
1348 {
1349   uint32_t algo;
1350   HAL_StatusTypeDef status;
1351 #ifdef  USE_FULL_ASSERT
1352   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1353 
1354   /* Check input buffer size */
1355   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1356 #endif /* USE_FULL_ASSERT */
1357 
1358   if (hcryp->State == HAL_CRYP_STATE_READY)
1359   {
1360     /* Change state Busy */
1361     hcryp->State = HAL_CRYP_STATE_BUSY;
1362     __HAL_LOCK(hcryp);
1363 
1364     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
1365     hcryp->CrypInCount = 0U;
1366     hcryp->CrypOutCount = 0U;
1367     hcryp->pCrypInBuffPtr = pInput;
1368     hcryp->pCrypOutBuffPtr = pOutput;
1369 
1370     /* Calculate Size parameter in Byte */
1371     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1372     {
1373       hcryp->Size = Size * 4U;
1374     }
1375     else
1376     {
1377       hcryp->Size = Size;
1378     }
1379 
1380     if (hcryp->Instance == AES)
1381     {
1382       /* Set the operating mode */
1383       MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1384     }
1385     else
1386     {
1387       /* Set the operating mode and normal key selection */
1388       MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE | AES_CR_KMOD, CRYP_OPERATINGMODE_ENCRYPT | CRYP_KEYMODE_NORMAL);
1389     }
1390     /* Algo get algorithm selected */
1391     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1392 
1393     switch (algo)
1394     {
1395       case CRYP_AES_ECB:
1396       case CRYP_AES_CBC:
1397       case CRYP_AES_CTR:
1398         /* AES encryption */
1399         status = CRYP_AES_Encrypt(hcryp, Timeout);
1400         break;
1401 
1402       case CRYP_AES_GCM_GMAC:
1403         /* AES GCM encryption */
1404         status = CRYP_AESGCM_Process(hcryp, Timeout);
1405         break;
1406 
1407       case CRYP_AES_CCM:
1408         /* AES CCM encryption */
1409         status = CRYP_AESCCM_Process(hcryp, Timeout);
1410         break;
1411 
1412       default:
1413         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1414         status = HAL_ERROR;
1415         break;
1416     }
1417 
1418     if (status == HAL_OK)
1419     {
1420       /* Change the CRYP peripheral state */
1421       hcryp->State = HAL_CRYP_STATE_READY;
1422       __HAL_UNLOCK(hcryp);
1423     }
1424   }
1425   else
1426   {
1427     /* Busy error code field */
1428     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1429     status = HAL_ERROR;
1430   }
1431   return status;
1432 }
1433 
1434 /**
1435   * @brief  Decryption mode.
1436   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1437   *         the configuration information for CRYP module
1438   * @param  pInput Pointer to the input buffer (ciphertext )
1439   * @param  Size Length of the input buffer either in word or in byte, according to DataWidthUnit
1440   * @param  pOutput Pointer to the output buffer(plaintext)
1441   * @param  Timeout Specify Timeout value
1442   * @retval HAL status
1443   */
HAL_CRYP_Decrypt(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint16_t Size,uint32_t * pOutput,uint32_t Timeout)1444 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput,
1445                                    uint32_t Timeout)
1446 {
1447   HAL_StatusTypeDef status;
1448   uint32_t algo;
1449 #ifdef  USE_FULL_ASSERT
1450   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1451 
1452   /* Check input buffer size */
1453   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1454 #endif /* USE_FULL_ASSERT */
1455 
1456   if (hcryp->State == HAL_CRYP_STATE_READY)
1457   {
1458     /* Change state Busy */
1459     hcryp->State = HAL_CRYP_STATE_BUSY;
1460     __HAL_LOCK(hcryp);
1461 
1462     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr  parameters*/
1463     hcryp->CrypInCount = 0U;
1464     hcryp->CrypOutCount = 0U;
1465     hcryp->pCrypInBuffPtr = pInput;
1466     hcryp->pCrypOutBuffPtr = pOutput;
1467 
1468     /*  Calculate Size parameter in Byte*/
1469     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1470     {
1471       hcryp->Size = Size * 4U;
1472     }
1473     else
1474     {
1475       hcryp->Size = Size;
1476     }
1477 
1478     /* Set Decryption operating mode*/
1479     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1480 
1481     /* algo get algorithm selected */
1482     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1483 
1484     switch (algo)
1485     {
1486       case CRYP_AES_ECB:
1487       case CRYP_AES_CBC:
1488       case CRYP_AES_CTR:
1489         /* AES decryption */
1490         status = CRYP_AES_Decrypt(hcryp, Timeout);
1491         break;
1492 
1493       case CRYP_AES_GCM_GMAC:
1494         /* AES GCM decryption */
1495         status = CRYP_AESGCM_Process(hcryp, Timeout);
1496         break;
1497 
1498       case CRYP_AES_CCM:
1499         /* AES CCM decryption */
1500         status = CRYP_AESCCM_Process(hcryp, Timeout);
1501         break;
1502 
1503       default:
1504         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1505         status = HAL_ERROR;
1506         break;
1507     }
1508 
1509     if (status == HAL_OK)
1510     {
1511       /* Change the CRYP peripheral state */
1512       hcryp->State = HAL_CRYP_STATE_READY;
1513       __HAL_UNLOCK(hcryp);
1514     }
1515   }
1516   else
1517   {
1518     /* Busy error code field */
1519     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1520     status = HAL_ERROR;
1521   }
1522 
1523   return status;
1524 }
1525 
1526 /**
1527   * @brief  Encryption in interrupt mode.
1528   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1529   *         the configuration information for CRYP module
1530   * @param  pInput Pointer to the input buffer (plaintext)
1531   * @param  Size Length of the input buffer either in word or in byte, according to DataWidthUnit
1532   * @param  pOutput Pointer to the output buffer(ciphertext)
1533   * @retval HAL status
1534   */
HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint16_t Size,uint32_t * pOutput)1535 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput)
1536 {
1537   HAL_StatusTypeDef status;
1538   uint32_t algo;
1539 #ifdef  USE_FULL_ASSERT
1540   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1541 
1542   /* Check input buffer size */
1543   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1544 #endif /* USE_FULL_ASSERT */
1545 
1546   if (hcryp->State == HAL_CRYP_STATE_READY)
1547   {
1548     /* Change state Busy */
1549     hcryp->State = HAL_CRYP_STATE_BUSY;
1550     __HAL_LOCK(hcryp);
1551 
1552     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1553 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
1554     if (hcryp->ResumingFlag == 1U)
1555     {
1556       hcryp->ResumingFlag = 0U;
1557       if (hcryp->Phase != CRYP_PHASE_HEADER_SUSPENDED)
1558       {
1559         hcryp->CrypInCount = (uint16_t) hcryp->CrypInCount_saved;
1560         hcryp->CrypOutCount = (uint16_t) hcryp->CrypOutCount_saved;
1561       }
1562       else
1563       {
1564         hcryp->CrypInCount = 0U;
1565         hcryp->CrypOutCount = 0U;
1566       }
1567     }
1568     else
1569 #endif  /* USE_HAL_CRYP_SUSPEND_RESUME */
1570     {
1571       hcryp->CrypInCount = 0U;
1572       hcryp->CrypOutCount = 0U;
1573     }
1574 
1575     hcryp->pCrypInBuffPtr = pInput;
1576     hcryp->pCrypOutBuffPtr = pOutput;
1577 
1578     /*  Calculate Size parameter in Byte*/
1579     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1580     {
1581       hcryp->Size = Size * 4U;
1582     }
1583     else
1584     {
1585       hcryp->Size = Size;
1586     }
1587 
1588     /* Set encryption operating mode*/
1589     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1590 
1591     /* algo get algorithm selected */
1592     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1593 
1594     switch (algo)
1595     {
1596 
1597       case CRYP_AES_ECB:
1598       case CRYP_AES_CBC:
1599       case CRYP_AES_CTR:
1600         /* AES encryption */
1601         status = CRYP_AES_Encrypt_IT(hcryp);
1602         break;
1603 
1604       case CRYP_AES_GCM_GMAC:
1605         /* AES GCM encryption */
1606         status = CRYP_AESGCM_Process_IT(hcryp);
1607         break;
1608 
1609       case CRYP_AES_CCM:
1610         /* AES CCM encryption */
1611         status = CRYP_AESCCM_Process_IT(hcryp);
1612         break;
1613 
1614       default:
1615         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1616         status = HAL_ERROR;
1617         break;
1618     }
1619   }
1620   else
1621   {
1622     /* Busy error code field */
1623     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1624     status = HAL_ERROR;
1625   }
1626 
1627   return status;
1628 }
1629 
1630 /**
1631   * @brief  Decryption in interrupt mode.
1632   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1633   *         the configuration information for CRYP module
1634   * @param  pInput Pointer to the input buffer (ciphertext )
1635   * @param  Size Length of the input buffer either in word or in byte, according to DataWidthUnit
1636   * @param  pOutput Pointer to the output buffer(plaintext)
1637   * @retval HAL status
1638   */
HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint16_t Size,uint32_t * pOutput)1639 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput)
1640 {
1641   HAL_StatusTypeDef status;
1642   uint32_t algo;
1643 #ifdef  USE_FULL_ASSERT
1644   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1645 
1646   /* Check input buffer size */
1647   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1648 #endif /* USE_FULL_ASSERT */
1649 
1650   if (hcryp->State == HAL_CRYP_STATE_READY)
1651   {
1652     /* Change state Busy */
1653     hcryp->State = HAL_CRYP_STATE_BUSY;
1654     __HAL_LOCK(hcryp);
1655 
1656     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1657 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
1658     if (hcryp->ResumingFlag == 1U)
1659     {
1660       hcryp->ResumingFlag = 0U;
1661       if (hcryp->Phase != CRYP_PHASE_HEADER_SUSPENDED)
1662       {
1663         hcryp->CrypInCount = (uint16_t) hcryp->CrypInCount_saved;
1664         hcryp->CrypOutCount = (uint16_t) hcryp->CrypOutCount_saved;
1665       }
1666       else
1667       {
1668         hcryp->CrypInCount = 0U;
1669         hcryp->CrypOutCount = 0U;
1670       }
1671     }
1672     else
1673 #endif  /* USE_HAL_CRYP_SUSPEND_RESUME */
1674     {
1675       hcryp->CrypInCount = 0U;
1676       hcryp->CrypOutCount = 0U;
1677     }
1678     hcryp->pCrypInBuffPtr = pInput;
1679     hcryp->pCrypOutBuffPtr = pOutput;
1680 
1681     /*  Calculate Size parameter in Byte*/
1682     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1683     {
1684       hcryp->Size = Size * 4U;
1685     }
1686     else
1687     {
1688       hcryp->Size = Size;
1689     }
1690 
1691     /* Set decryption operating mode*/
1692     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1693 
1694     /* algo get algorithm selected */
1695     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1696 
1697     switch (algo)
1698     {
1699       case CRYP_AES_ECB:
1700       case CRYP_AES_CBC:
1701       case CRYP_AES_CTR:
1702         /* AES decryption */
1703         status = CRYP_AES_Decrypt_IT(hcryp);
1704         break;
1705 
1706       case CRYP_AES_GCM_GMAC:
1707         /* AES GCM decryption */
1708         status = CRYP_AESGCM_Process_IT(hcryp);
1709         break;
1710 
1711       case CRYP_AES_CCM:
1712         /* AES CCM decryption */
1713         status = CRYP_AESCCM_Process_IT(hcryp);
1714         break;
1715 
1716       default:
1717         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1718         status = HAL_ERROR;
1719         break;
1720     }
1721   }
1722   else
1723   {
1724     /* Busy error code field */
1725     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1726     status = HAL_ERROR;
1727   }
1728 
1729   return status;
1730 }
1731 
1732 /**
1733   * @brief  Encryption in DMA mode.
1734   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1735   *         the configuration information for CRYP module
1736   * @param  pInput Pointer to the input buffer (plaintext)
1737   * @param  Size Length of the input buffer either in word or in byte, according to DataWidthUnit
1738   * @param  pOutput Pointer to the output buffer(ciphertext)
1739   * @retval HAL status
1740   */
HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint16_t Size,uint32_t * pOutput)1741 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput)
1742 {
1743   HAL_StatusTypeDef status;
1744   uint32_t count;
1745   uint32_t algo;
1746   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1747 #ifdef  USE_FULL_ASSERT
1748   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1749 
1750   /* Check input buffer size */
1751   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1752 #endif /* USE_FULL_ASSERT */
1753 
1754   if (hcryp->State == HAL_CRYP_STATE_READY)
1755   {
1756     /* Change state Busy */
1757     hcryp->State = HAL_CRYP_STATE_BUSY;
1758     __HAL_LOCK(hcryp);
1759 
1760     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1761     hcryp->CrypInCount = 0U;
1762     hcryp->CrypOutCount = 0U;
1763     hcryp->pCrypInBuffPtr = pInput;
1764     hcryp->pCrypOutBuffPtr = pOutput;
1765 
1766     /*  Calculate Size parameter in Byte*/
1767     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1768     {
1769       hcryp->Size = Size * 4U;
1770     }
1771     else
1772     {
1773       hcryp->Size = Size;
1774     }
1775 
1776     /* Set encryption operating mode*/
1777     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1778 
1779     /* algo get algorithm selected */
1780     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1781 
1782     switch (algo)
1783     {
1784       case CRYP_AES_ECB:
1785       case CRYP_AES_CBC:
1786       case CRYP_AES_CTR:
1787         if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1788         {
1789           if (hcryp->KeyIVConfig == 1U)
1790           {
1791             /* If the Key and IV configuration has to be done only once
1792                and if it has already been done, skip it */
1793             dokeyivconfig = 0U;
1794           }
1795           else
1796           {
1797             /* If the Key and IV configuration has to be done only once
1798                and if it has not been done already, do it and set KeyIVConfig
1799                to keep track it won't have to be done again next time */
1800             hcryp->KeyIVConfig = 1U;
1801           }
1802         }
1803 
1804         if ((dokeyivconfig == 1U) && (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG))
1805         {
1806           if (hcryp->Instance == AES)
1807           {
1808             /* Set the Key */
1809             if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
1810             {
1811               CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1812             }
1813             else /* After sharing the key, AES should set KMOD[1:0] to 00.*/
1814             {
1815               hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
1816             }
1817           }
1818           else
1819           {
1820             /* We should re-write Key, in the case where we change key after first operation */
1821             if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
1822             {
1823               /* Set the Key */
1824               CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1825             }
1826             /* Wait for KEYVALID flag to be set */
1827             count = CRYP_TIMEOUT_KEYPREPARATION;
1828             do
1829             {
1830               count--;
1831               if (count == 0U)
1832               {
1833                 /* Disable the SAES peripheral clock */
1834                 __HAL_CRYP_DISABLE(hcryp);
1835 
1836                 /* Change state */
1837                 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
1838                 hcryp->State = HAL_CRYP_STATE_READY;
1839                 __HAL_UNLOCK(hcryp);
1840                 return HAL_ERROR;
1841               }
1842             } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID));
1843           }
1844           /* Set the Initialization Vector */
1845           if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1846           {
1847             CRYP_SetIV(hcryp);
1848           }
1849         } /* If (dokeyivconfig == 1U) */
1850 
1851         /* Peripheral Key configuration to not do, IV to configure for CBC */
1852         if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYNOCONFIG)
1853         {
1854           if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1855           {
1856             /* Set the Initialization Vector */
1857             CRYP_SetIV(hcryp);
1858           }
1859         }
1860 
1861         /* Set the phase */
1862         hcryp->Phase = CRYP_PHASE_PROCESS;
1863 
1864         /* Start DMA process transfer for AES */
1865         CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size), (uint32_t)(hcryp->pCrypOutBuffPtr));
1866         status = HAL_OK;
1867         break;
1868 
1869       case CRYP_AES_GCM_GMAC:
1870         /* AES GCM encryption */
1871         status = CRYP_AESGCM_Process_DMA(hcryp);
1872         break;
1873 
1874       case CRYP_AES_CCM:
1875         /* AES CCM encryption */
1876         status = CRYP_AESCCM_Process_DMA(hcryp);
1877         break;
1878 
1879       default:
1880         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1881         status = HAL_ERROR;
1882         break;
1883     }
1884   }
1885   else
1886   {
1887     /* Busy error code field */
1888     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1889     status = HAL_ERROR;
1890   }
1891 
1892   return status;
1893 }
1894 
1895 /**
1896   * @brief  Decryption in DMA mode.
1897   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
1898   *         the configuration information for CRYP module
1899   * @param  pInput Pointer to the input buffer (ciphertext )
1900   * @param  Size Length of the input buffer either in word or in byte, according to DataWidthUnit
1901   * @param  pOutput Pointer to the output buffer(plaintext)
1902   * @retval HAL status
1903   */
HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint16_t Size,uint32_t * pOutput)1904 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput)
1905 {
1906   HAL_StatusTypeDef status;
1907   uint32_t algo;
1908 #ifdef  USE_FULL_ASSERT
1909   uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD;
1910 
1911   /* Check input buffer size */
1912   assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size));
1913 #endif /* USE_FULL_ASSERT */
1914 
1915   if (hcryp->State == HAL_CRYP_STATE_READY)
1916   {
1917 
1918     /* Change state Busy */
1919     hcryp->State = HAL_CRYP_STATE_BUSY;
1920     __HAL_LOCK(hcryp);
1921 
1922     /*  Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1923     hcryp->CrypInCount = 0U;
1924     hcryp->CrypOutCount = 0U;
1925     hcryp->pCrypInBuffPtr = pInput;
1926     hcryp->pCrypOutBuffPtr = pOutput;
1927 
1928     /*  Calculate Size parameter in Byte*/
1929     if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1930     {
1931       hcryp->Size = Size * 4U;
1932     }
1933     else
1934     {
1935       hcryp->Size = Size;
1936     }
1937 
1938     /* Set decryption operating mode*/
1939     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1940 
1941     /* algo get algorithm selected */
1942     algo = hcryp->Instance->CR & AES_CR_CHMOD;
1943 
1944     switch (algo)
1945     {
1946       case CRYP_AES_ECB:
1947       case CRYP_AES_CBC:
1948       case CRYP_AES_CTR:
1949         /* AES decryption */
1950         status = CRYP_AES_Decrypt_DMA(hcryp);
1951         break;
1952 
1953       case CRYP_AES_GCM_GMAC:
1954         /* AES GCM decryption */
1955         status = CRYP_AESGCM_Process_DMA(hcryp);
1956         break;
1957 
1958       case CRYP_AES_CCM:
1959         /* AES CCM decryption */
1960         status = CRYP_AESCCM_Process_DMA(hcryp);
1961         break;
1962 
1963       default:
1964         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1965         status = HAL_ERROR;
1966         break;
1967     }
1968   }
1969   else
1970   {
1971     /* Busy error code field */
1972     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1973     status = HAL_ERROR;
1974   }
1975   return status;
1976 }
1977 
1978 /**
1979   * @}
1980   */
1981 
1982 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1983   * @brief    CRYP IRQ handler.
1984   *
1985 @verbatim
1986   ==============================================================================
1987                 ##### CRYP IRQ handler management #####
1988   ==============================================================================
1989 [..]  This section provides CRYP IRQ handler and callback functions.
1990       (+) HAL_CRYP_IRQHandler CRYP interrupt request
1991       (+) HAL_CRYP_InCpltCallback input data transfer complete callback
1992       (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
1993       (+) HAL_CRYP_ErrorCallback  CRYP error callback
1994       (+) HAL_CRYP_GetState return the CRYP state
1995       (+) HAL_CRYP_GetError return the CRYP error code
1996 @endverbatim
1997   * @{
1998   */
1999 
2000 /**
2001   * @brief  This function handles cryptographic interrupt request.
2002   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2003   *         the configuration information for CRYP module
2004   * @retval None
2005   */
HAL_CRYP_IRQHandler(CRYP_HandleTypeDef * hcryp)2006 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
2007 {
2008   /* Check if Read or write error occurred */
2009   if (__HAL_CRYP_GET_IT_SOURCE(hcryp, CRYP_IT_RWEIE) != RESET)
2010   {
2011     /* If write Error occurred */
2012     if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_WRERR) != RESET)
2013     {
2014       hcryp->ErrorCode |= HAL_CRYP_ERROR_WRITE;
2015       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_RWEIF);
2016     }
2017     /* If read Error occurred */
2018     if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_RDERR) != RESET)
2019     {
2020       hcryp->ErrorCode |= HAL_CRYP_ERROR_READ;
2021       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_RWEIF);
2022     }
2023   }
2024   /* Check if Key error occurred */
2025   if (__HAL_CRYP_GET_IT_SOURCE(hcryp, CRYP_IT_KEIE) != RESET)
2026   {
2027     if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_KEIF) != RESET)
2028     {
2029       hcryp->ErrorCode |= HAL_CRYP_ERROR_KEY;
2030       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_KEIF);
2031       /*Call weak error callback*/
2032       HAL_CRYP_ErrorCallback(hcryp);
2033     }
2034   }
2035 
2036   if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_CCF) != RESET)
2037   {
2038     if (__HAL_CRYP_GET_IT_SOURCE(hcryp, CRYP_IT_CCFIE) != RESET)
2039     {
2040       /* Clear computation complete flag */
2041       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
2042 
2043       if ((hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC) || (hcryp->Init.Algorithm == CRYP_AES_CCM))
2044       {
2045         /* if header phase */
2046         if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
2047         {
2048           CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
2049         }
2050         else  /* if payload phase */
2051         {
2052           CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
2053         }
2054       }
2055       else  /* AES Algorithm ECB,CBC or CTR*/
2056       {
2057         CRYP_AES_IT(hcryp);
2058       }
2059     }
2060   }
2061 }
2062 
2063 /**
2064   * @brief  Return the CRYP error code.
2065   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2066   *                 the configuration information for the  CRYP peripheral
2067   * @retval CRYP error code
2068   */
HAL_CRYP_GetError(CRYP_HandleTypeDef * hcryp)2069 uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp)
2070 {
2071   return hcryp->ErrorCode;
2072 }
2073 
2074 /**
2075   * @brief  Returns the CRYP state.
2076   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2077   *         the configuration information for CRYP module.
2078   * @retval HAL state
2079   */
HAL_CRYP_GetState(CRYP_HandleTypeDef * hcryp)2080 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp)
2081 {
2082   return hcryp->State;
2083 }
2084 
2085 /**
2086   * @brief  Input FIFO transfer completed callback.
2087   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2088   *         the configuration information for CRYP module.
2089   * @retval None
2090   */
HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef * hcryp)2091 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
2092 {
2093   /* Prevent unused argument(s) compilation warning */
2094   UNUSED(hcryp);
2095 
2096   /* NOTE : This function should not be modified; when the callback is needed,
2097             the HAL_CRYP_InCpltCallback can be implemented in the user file
2098    */
2099 }
2100 
2101 /**
2102   * @brief  Output FIFO transfer completed callback.
2103   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2104   *         the configuration information for CRYP module.
2105   * @retval None
2106   */
HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef * hcryp)2107 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
2108 {
2109   /* Prevent unused argument(s) compilation warning */
2110   UNUSED(hcryp);
2111 
2112   /* NOTE : This function should not be modified; when the callback is needed,
2113             the HAL_CRYP_OutCpltCallback can be implemented in the user file
2114    */
2115 }
2116 
2117 /**
2118   * @brief  CRYP error callback.
2119   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2120   *         the configuration information for CRYP module.
2121   * @retval None
2122   */
HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef * hcryp)2123 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
2124 {
2125   /* Prevent unused argument(s) compilation warning */
2126   UNUSED(hcryp);
2127 
2128   /* NOTE : This function should not be modified; when the callback is needed,
2129             the HAL_CRYP_ErrorCallback can be implemented in the user file
2130    */
2131 }
2132 /**
2133   * @}
2134   */
2135 
2136 /**
2137   * @}
2138   */
2139 
2140 /* Private functions ---------------------------------------------------------*/
2141 /** @addtogroup CRYP_Private_Functions
2142   * @{
2143   */
2144 
2145 /**
2146   * @brief  Encryption in ECB/CBC & CTR Algorithm with AES Standard
2147   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
2148   * @param  Timeout specify Timeout value
2149   * @retval HAL status
2150   */
CRYP_AES_Encrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2151 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2152 {
2153   uint16_t incount;  /* Temporary CrypInCount Value */
2154   uint16_t outcount;  /* Temporary CrypOutCount Value */
2155   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2156   uint32_t tickstart;
2157 
2158   if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE))
2159   {
2160     if (hcryp->KeyIVConfig == 1U)
2161     {
2162       /* If the Key and IV configuration has to be done only once
2163          and if it has already been done, skip it */
2164       dokeyivconfig = 0U;
2165     }
2166     else
2167     {
2168       /* If the Key and IV configuration has to be done only once
2169          and if it has not been done already, do it and set KeyIVConfig
2170          to keep track it won't have to be done again next time */
2171       hcryp->KeyIVConfig = 1U;
2172     }
2173   }
2174 
2175   if (dokeyivconfig == 1U)
2176   {
2177     if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || \
2178         (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ALWAYS))
2179     {
2180       if (hcryp->Instance == AES)
2181       {
2182         /* Set the Key */
2183         if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
2184         {
2185           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2186         }
2187         else /* After sharing the key, AES should set KMOD[1:0] to 00.*/
2188         {
2189           hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
2190         }
2191       }
2192       else
2193       {
2194         /* We should re-write Key, in the case where we change key after first operation */
2195         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
2196         {
2197           /* Set the Key */
2198           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2199         }
2200         /* Get tick */
2201         tickstart = HAL_GetTick();
2202 
2203         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID))
2204         {
2205           /* Check for the Timeout */
2206           if (Timeout != HAL_MAX_DELAY)
2207           {
2208             if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2209             {
2210               /* Disable the CRYP peripheral clock */
2211               __HAL_CRYP_DISABLE(hcryp);
2212 
2213               /* Change state */
2214               hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2215               hcryp->State = HAL_CRYP_STATE_READY;
2216               __HAL_UNLOCK(hcryp);
2217               return HAL_ERROR;
2218             }
2219           }
2220         }
2221       }
2222       if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2223       {
2224         /* Set the Initialization Vector */
2225         CRYP_SetIV(hcryp);
2226       }
2227     }
2228     /* key & IV configuration for CBC and CTR in interleave mode */
2229     if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE)
2230     {
2231       /* Set the Key */
2232       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2233       if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2234       {
2235         /* Set the Initialization Vector*/
2236         CRYP_SetIV(hcryp);
2237       }
2238     }
2239   } /* If (dokeyivconfig == 1U) */
2240   else
2241   {
2242     /* interleave mode Key configuration  */
2243     if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE)
2244     {
2245       /* Set the Key */
2246       CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2247     }
2248   }
2249   /* Peripheral Key configuration to not do, IV to configure for CBC */
2250   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYNOCONFIG)
2251   {
2252     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2253     {
2254       /* Set the Initialization Vector*/
2255       CRYP_SetIV(hcryp);
2256     }
2257   }
2258 
2259   /* Set the phase */
2260   hcryp->Phase = CRYP_PHASE_PROCESS;
2261 
2262   /* Enable CRYP */
2263   __HAL_CRYP_ENABLE(hcryp);
2264 
2265   incount = hcryp->CrypInCount;
2266   outcount = hcryp->CrypOutCount;
2267   while ((incount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2268   {
2269     /* Write plain data and get cipher data */
2270     CRYP_AES_ProcessData(hcryp, Timeout);
2271     incount = hcryp->CrypInCount;
2272     outcount = hcryp->CrypOutCount;
2273   }
2274 
2275   /* Disable CRYP */
2276   __HAL_CRYP_DISABLE(hcryp);
2277 
2278   /* Change the CRYP state */
2279   hcryp->State = HAL_CRYP_STATE_READY;
2280 
2281   return HAL_OK;
2282 }
2283 
2284 /**
2285   * @brief  Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2286   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2287   *         the configuration information for CRYP module
2288   * @retval HAL status
2289   */
CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef * hcryp)2290 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
2291 {
2292   uint32_t count;
2293   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2294 
2295   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2296   {
2297     if (hcryp->KeyIVConfig == 1U)
2298     {
2299       /* If the Key and IV configuration has to be done only once
2300          and if it has already been done, skip it */
2301       dokeyivconfig = 0U;
2302     }
2303     else
2304     {
2305       /* If the Key and IV configuration has to be done only once
2306          and if it has not been done already, do it and set KeyIVConfig
2307          to keep track it won't have to be done again next time */
2308       hcryp->KeyIVConfig = 1U;
2309     }
2310   }
2311 
2312   if ((dokeyivconfig == 1U) && (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG))
2313   {
2314     if (hcryp->Instance == AES)
2315     {
2316       /* Set the Key */
2317       if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
2318       {
2319         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2320       }
2321       else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
2322       {
2323         hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
2324       }
2325     }
2326     else
2327     {
2328       /* we should re-write Key, in the case where we change key after first operation*/
2329       if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
2330       {
2331         /* Set the Key */
2332         CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2333       }
2334       /* Wait for KEYVALID flag to be set */
2335       count = CRYP_TIMEOUT_KEYPREPARATION;
2336       do
2337       {
2338         count--;
2339         if (count == 0U)
2340         {
2341           /* Disable the SAES peripheral clock */
2342           __HAL_CRYP_DISABLE(hcryp);
2343 
2344           /* Change state */
2345           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2346           hcryp->State = HAL_CRYP_STATE_READY;
2347           __HAL_UNLOCK(hcryp);
2348           return HAL_ERROR;
2349         }
2350       } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID));
2351     }
2352     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2353     {
2354       /* Set the Initialization Vector*/
2355       CRYP_SetIV(hcryp);
2356     }
2357   } /* if (dokeyivconfig == 1U) */
2358   /* Peripheral Key configuration to not do, IV to configure for CBC */
2359   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYNOCONFIG)
2360   {
2361     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2362     {
2363       /* Set the Initialization Vector*/
2364       CRYP_SetIV(hcryp);
2365     }
2366   }
2367 
2368   /* Set the phase */
2369   hcryp->Phase = CRYP_PHASE_PROCESS;
2370 
2371   if (hcryp->Size != 0U)
2372   {
2373     /* Enable CRYP */
2374     __HAL_CRYP_ENABLE(hcryp);
2375 
2376     /* Write the input block in the IN FIFO */
2377     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2378     hcryp->CrypInCount++;
2379     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2380     hcryp->CrypInCount++;
2381     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2382     hcryp->CrypInCount++;
2383     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2384     hcryp->CrypInCount++;
2385 
2386     /* Enable computation complete flag and Key, Read and Write error interrupts */
2387     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
2388   }
2389   else
2390   {
2391     /* Change the CRYP state */
2392     hcryp->State = HAL_CRYP_STATE_READY;
2393     __HAL_UNLOCK(hcryp);
2394   }
2395 
2396   return HAL_OK;
2397 }
2398 
2399 /**
2400   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard
2401   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
2402   * @param  Timeout Specify Timeout value
2403   * @retval HAL status
2404   */
CRYP_AES_Decrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2405 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2406 {
2407   uint16_t incount;  /* Temporary CrypInCount Value */
2408   uint16_t outcount;  /* Temporary CrypOutCount Value */
2409   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2410 
2411   if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE))
2412   {
2413     if (hcryp->KeyIVConfig == 1U)
2414     {
2415       /* If the Key and IV configuration has to be done only once
2416          and if it has already been done, skip it */
2417       dokeyivconfig = 0U;
2418     }
2419     else
2420     {
2421       /* If the Key and IV configuration has to be done only once
2422          and if it has not been done already, do it and set KeyIVConfig
2423          to keep track it won't have to be done again next time */
2424       hcryp->KeyIVConfig = 1U;
2425     }
2426   }
2427 
2428   if (dokeyivconfig == 1U)
2429   {
2430     if (hcryp->Instance == AES)
2431     {
2432       /*  Key preparation for ECB/CBC */
2433       if (hcryp->Init.Algorithm != CRYP_AES_CTR)   /*ECB or CBC*/
2434       {
2435         /* key preparation for decryption, operating mode 2*/
2436         MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL);
2437         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2438 
2439         /* Set the Key */
2440         if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || \
2441             (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ALWAYS))
2442         {
2443           if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
2444           {
2445             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2446           }
2447           else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
2448           {
2449             hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
2450           }
2451         }
2452 
2453         /* interleave mode Key configuration  */
2454         else if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE)
2455         {
2456           /* Set the Key */
2457           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2458         }
2459         else
2460         {
2461           /* Nothing to do */
2462         }
2463 
2464         /* Enable CRYP */
2465         __HAL_CRYP_ENABLE(hcryp);
2466 
2467         /* Wait for CCF flag to be raised */
2468         if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2469         {
2470           return HAL_ERROR;
2471         }
2472         /* Clear CCF Flag */
2473         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
2474 
2475         /* Return to decryption operating mode(Mode 3)*/
2476         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2477       }
2478       else  /*Algorithm CTR */
2479       {
2480         /* Set the Key */
2481         if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2482         {
2483           if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
2484           {
2485             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2486           }
2487           else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
2488           {
2489             hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
2490           }
2491         }
2492       }
2493     }
2494     else /*SAES*/
2495     {
2496       if (hcryp->Init.Algorithm != CRYP_AES_CTR)   /*ECB or CBC*/
2497       {
2498         /* key preparation for decryption, operating mode 2*/
2499         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2500 
2501         /* we should re-write Key, in the case where we change key after first operation*/
2502         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
2503         {
2504           if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2505           {
2506             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2507           }
2508         }
2509 
2510         /* Enable SAES */
2511         __HAL_CRYP_ENABLE(hcryp);
2512 
2513         /* Wait for CCF flag to be raised */
2514         if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2515         {
2516           return HAL_ERROR;
2517         }
2518         /* Clear CCF Flag */
2519         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
2520 
2521         /*  End of Key preparation for ECB/CBC */
2522         /* Return to decryption operating mode(Mode 3)*/
2523         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2524       }
2525       else  /*Algorithm CTR */
2526       {
2527         /* we should re-write Key, in the case where we change key after first operation*/
2528         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
2529         {
2530           if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2531           {
2532             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2533           }
2534         }
2535       }
2536     }
2537     /* Set IV */
2538     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2539     {
2540       /* Set the Initialization Vector*/
2541       CRYP_SetIV(hcryp);
2542     }
2543   } /* if (dokeyivconfig == 1U) */
2544 
2545   else /* if (dokeyivconfig == 0U) */
2546   {
2547     /* interleave mode Key configuration  */
2548     if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE)
2549     {
2550       if (hcryp->Instance == AES)
2551       {
2552         /*  Key preparation for ECB/CBC */
2553         if (hcryp->Init.Algorithm != CRYP_AES_CTR)   /*ECB or CBC*/
2554         {
2555           /* key preparation for decryption, operating mode 2*/
2556           MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL);
2557           MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2558 
2559           /* Set the Key */
2560           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2561 
2562           /* Enable CRYP */
2563           __HAL_CRYP_ENABLE(hcryp);
2564 
2565           /* Wait for CCF flag to be raised */
2566           if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2567           {
2568             return HAL_ERROR;
2569           }
2570           /* Clear CCF Flag */
2571           __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
2572 
2573           /* Return to decryption operating mode(Mode 3)*/
2574           MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2575         }
2576         else  /*Algorithm CTR */
2577         {
2578           /* Set the Key */
2579           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2580 
2581         }
2582       }
2583     }
2584 
2585   }
2586   /* Set the phase */
2587   hcryp->Phase = CRYP_PHASE_PROCESS;
2588 
2589   /* Enable CRYP */
2590   __HAL_CRYP_ENABLE(hcryp);
2591 
2592   incount = hcryp->CrypInCount;
2593   outcount = hcryp->CrypOutCount;
2594   while ((incount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2595   {
2596     /* Write plain data and get cipher data */
2597     CRYP_AES_ProcessData(hcryp, Timeout);
2598     incount = hcryp->CrypInCount;
2599     outcount = hcryp->CrypOutCount;
2600   }
2601   /* Disable CRYP */
2602   __HAL_CRYP_DISABLE(hcryp);
2603 
2604   /* Change the CRYP state */
2605   hcryp->State = HAL_CRYP_STATE_READY;
2606 
2607   return HAL_OK;
2608 }
2609 /**
2610   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2611   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2612   *         the configuration information for CRYP module
2613   * @retval HAL status
2614   */
CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef * hcryp)2615 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
2616 {
2617   uint32_t count;
2618   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2619 
2620   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2621   {
2622     if (hcryp->KeyIVConfig == 1U)
2623     {
2624       /* If the Key and IV configuration has to be done only once
2625          and if it has already been done, skip it */
2626       dokeyivconfig = 0U;
2627     }
2628     else
2629     {
2630       /* If the Key and IV configuration has to be done only once
2631          and if it has not been done already, do it and set KeyIVConfig
2632          to keep track it won't have to be done again next time */
2633       hcryp->KeyIVConfig = 1U;
2634     }
2635   }
2636 
2637   if (dokeyivconfig == 1U)
2638   {
2639     if (hcryp->Instance == AES)
2640     {
2641       /*  Key preparation for ECB/CBC */
2642       if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2643       {
2644         /* key preparation for decryption, operating mode 2*/
2645         MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL);
2646         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2647 
2648         /* Set the Key */
2649         if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2650         {
2651           if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
2652           {
2653             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2654           }
2655           else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
2656           {
2657             hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
2658           }
2659         }
2660 
2661         /* Enable CRYP */
2662         __HAL_CRYP_ENABLE(hcryp);
2663 
2664         /* Wait for CCF flag to be raised */
2665         count = CRYP_TIMEOUT_KEYPREPARATION;
2666         do
2667         {
2668           count--;
2669           if (count == 0U)
2670           {
2671             /* Disable the CRYP peripheral clock */
2672             __HAL_CRYP_DISABLE(hcryp);
2673 
2674             /* Change state */
2675             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2676             hcryp->State = HAL_CRYP_STATE_READY;
2677             __HAL_UNLOCK(hcryp);
2678             return HAL_ERROR;
2679           }
2680         } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
2681 
2682         /* Clear CCF Flag */
2683         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
2684 
2685         /* Return to decryption operating mode(Mode 3)*/
2686         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2687       }
2688 
2689       else  /*Algorithm CTR */
2690       {
2691         if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2692         {
2693           if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
2694           {
2695             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2696           }
2697           else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
2698           {
2699             hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
2700           }
2701         }
2702       }
2703     }
2704     else /*SAES*/
2705     {
2706       /*  Key preparation for ECB/CBC */
2707       if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2708       {
2709         /* key preparation for decryption, operating mode 2*/
2710         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2711 
2712         /* we should re-write Key, in the case where we change key after first operation*/
2713         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
2714         {
2715           if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2716           {
2717             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2718           }
2719         }
2720         /* Enable SAES */
2721         __HAL_CRYP_ENABLE(hcryp);
2722 
2723         /* Wait for CCF flag to be raised */
2724         count = CRYP_TIMEOUT_KEYPREPARATION;
2725         do
2726         {
2727           count--;
2728           if (count == 0U)
2729           {
2730             /* Disable the CRYP peripheral clock */
2731             __HAL_CRYP_DISABLE(hcryp);
2732 
2733             /* Change state */
2734             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2735             hcryp->State = HAL_CRYP_STATE_READY;
2736             __HAL_UNLOCK(hcryp);
2737             return HAL_ERROR;
2738           }
2739         } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
2740 
2741         /* Clear CCF Flag */
2742         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
2743 
2744         /*  End of Key preparation for ECB/CBC */
2745         /* Return to decryption operating mode(Mode 3)*/
2746         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2747       }
2748       else  /*Algorithm CTR */
2749       {
2750         /* we should re-write Key, in the case where we change key after first operation*/
2751         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
2752         {
2753           if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2754           {
2755             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2756           }
2757         }
2758       }
2759     }
2760     /* Set IV */
2761     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2762     {
2763       /* Set the Initialization Vector*/
2764       CRYP_SetIV(hcryp);
2765     }
2766   } /* if (dokeyivconfig == 1U) */
2767 
2768   /* Set the phase */
2769   hcryp->Phase = CRYP_PHASE_PROCESS;
2770   if (hcryp->Size != 0U)
2771   {
2772     /* Enable CRYP */
2773     __HAL_CRYP_ENABLE(hcryp);
2774 
2775     /* Write the input block in the IN FIFO */
2776     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2777     hcryp->CrypInCount++;
2778     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2779     hcryp->CrypInCount++;
2780     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2781     hcryp->CrypInCount++;
2782     hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2783     hcryp->CrypInCount++;
2784 
2785     /* Enable computation complete flag and error interrupts */
2786     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
2787   }
2788   else
2789   {
2790     __HAL_UNLOCK(hcryp);
2791 
2792     /* Change the CRYP state */
2793     hcryp->State = HAL_CRYP_STATE_READY;
2794   }
2795 
2796   return HAL_OK;
2797 }
2798 /**
2799   * @brief  Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
2800   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
2801   *         the configuration information for CRYP module
2802   * @retval HAL status
2803   */
CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef * hcryp)2804 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
2805 {
2806   uint32_t count;
2807   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2808 
2809   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2810   {
2811     if (hcryp->KeyIVConfig == 1U)
2812     {
2813       /* If the Key and IV configuration has to be done only once
2814          and if it has already been done, skip it */
2815       dokeyivconfig = 0U;
2816     }
2817     else
2818     {
2819       /* If the Key and IV configuration has to be done only once
2820          and if it has not been done already, do it and set KeyIVConfig
2821          to keep track it won't have to be done again next time */
2822       hcryp->KeyIVConfig = 1U;
2823     }
2824   }
2825 
2826   if (dokeyivconfig == 1U)
2827   {
2828     if (hcryp->Instance == AES)
2829     {
2830       /*  Key preparation for ECB/CBC */
2831       if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2832       {
2833         /* key preparation for decryption, operating mode 2*/
2834         MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL);
2835         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2836 
2837         /* Set the Key */
2838         if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2839         {
2840           if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
2841           {
2842             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2843           }
2844           else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
2845           {
2846             hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
2847           }
2848         }
2849 
2850         /* Enable CRYP */
2851         __HAL_CRYP_ENABLE(hcryp);
2852 
2853         /* Wait for CCF flag to be raised */
2854         count = CRYP_TIMEOUT_KEYPREPARATION;
2855         do
2856         {
2857           count--;
2858           if (count == 0U)
2859           {
2860             /* Disable the CRYP peripheral clock */
2861             __HAL_CRYP_DISABLE(hcryp);
2862 
2863             /* Change state */
2864             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2865             hcryp->State = HAL_CRYP_STATE_READY;
2866             __HAL_UNLOCK(hcryp);
2867             return HAL_ERROR;
2868           }
2869         } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
2870 
2871         /* Clear CCF Flag */
2872         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
2873 
2874         /* Return to decryption operating mode(Mode 3)*/
2875         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2876       }
2877       else  /*Algorithm CTR */
2878       {
2879         /* Set the Key */
2880         if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2881         {
2882           if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
2883           {
2884             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2885           }
2886           else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
2887           {
2888             hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
2889           }
2890         }
2891       }
2892     }
2893     else /*SAES*/
2894     {
2895       /*  Key preparation for ECB/CBC */
2896       if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2897       {
2898         /* key preparation for decryption, operating mode 2*/
2899         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2900 
2901         /* we should re-write Key, in the case where we change key after first operation*/
2902         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
2903         {
2904           if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2905           {
2906             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2907           }
2908         }
2909         /* Enable SAES */
2910         __HAL_CRYP_ENABLE(hcryp);
2911 
2912         /* Wait for CCF flag to be raised */
2913         count = CRYP_TIMEOUT_KEYPREPARATION;
2914         do
2915         {
2916           count--;
2917           if (count == 0U)
2918           {
2919             /* Disable the CRYP peripheral clock */
2920             __HAL_CRYP_DISABLE(hcryp);
2921 
2922             /* Change state */
2923             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2924             hcryp->State = HAL_CRYP_STATE_READY;
2925             __HAL_UNLOCK(hcryp);
2926             return HAL_ERROR;
2927           }
2928         } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
2929 
2930         /* Clear CCF Flag */
2931         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
2932 
2933         /*  End of Key preparation for ECB/CBC */
2934         /* Return to decryption operating mode(Mode 3)*/
2935         MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2936       }
2937       else  /*Algorithm CTR */
2938       {
2939         /* we should re-write Key, in the case where we change key after first operation*/
2940         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
2941         {
2942           if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
2943           {
2944             CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2945           }
2946         }
2947       }
2948     }
2949 
2950     if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2951     {
2952       /* Set the Initialization Vector*/
2953       CRYP_SetIV(hcryp);
2954     }
2955   } /* if (dokeyivconfig == 1U) */
2956 
2957   /* Set the phase */
2958   hcryp->Phase = CRYP_PHASE_PROCESS;
2959 
2960   if (hcryp->Size != 0U)
2961   {
2962     /* Set the input and output addresses and start DMA transfer */
2963     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size), (uint32_t)(hcryp->pCrypOutBuffPtr));
2964   }
2965   else
2966   {
2967     __HAL_UNLOCK(hcryp);
2968 
2969     /* Change the CRYP state */
2970     hcryp->State = HAL_CRYP_STATE_READY;
2971   }
2972 
2973   return HAL_OK;
2974 }
2975 
2976 
2977 /**
2978   * @brief  DMA CRYP input data process complete callback.
2979   * @param  hdma DMA handle
2980   * @retval None
2981   */
CRYP_DMAInCplt(DMA_HandleTypeDef * hdma)2982 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
2983 {
2984   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2985   uint32_t loopcounter;
2986   uint32_t headersize_in_bytes;
2987   uint32_t tmp;
2988   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
2989                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
2990                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU
2991                       }; /*  8-bit data type */
2992   uint32_t algo;
2993 
2994   /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit
2995      in the DMACR register */
2996   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
2997 
2998   if (hcryp->Phase == CRYP_PHASE_HEADER_DMA_FEED)
2999   {
3000     /* DMA is disabled, CCF is meaningful. Wait for computation completion before moving forward */
3001     CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE);
3002 
3003     /* Set the phase */
3004     hcryp->Phase = CRYP_PHASE_PROCESS;
3005 
3006     if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
3007     {
3008       headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
3009     }
3010     else
3011     {
3012       headersize_in_bytes = hcryp->Init.HeaderSize;
3013     }
3014 
3015     if ((headersize_in_bytes % 16U) != 0U)
3016     {
3017       /* Write last words that couldn't be fed by DMA */
3018       hcryp->CrypHeaderCount = (uint16_t)((headersize_in_bytes / 16U) * 4U);
3019       for (loopcounter = 0U; (loopcounter < ((headersize_in_bytes / 4U) % 4U)); loopcounter++)
3020       {
3021         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3022         hcryp->CrypHeaderCount++ ;
3023       }
3024       /* If the header size is a multiple of words */
3025       if ((headersize_in_bytes % 4U) == 0U)
3026       {
3027         /* Pad the data with zeros to have a complete block */
3028         while (loopcounter < 4U)
3029         {
3030           hcryp->Instance->DINR = 0x0U;
3031           loopcounter++;
3032         }
3033       }
3034       else
3035       {
3036         /* Enter last bytes, padded with zeros */
3037         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3038         tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
3039         hcryp->Instance->DINR = tmp;
3040         loopcounter++;
3041         /* Pad the data with zeros to have a complete block */
3042         while (loopcounter < 4U)
3043         {
3044           hcryp->Instance->DINR = 0x0U;
3045           loopcounter++;
3046         }
3047       }
3048 
3049       /* Wait for computation completion before moving forward */
3050       CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE);
3051     } /* if ((headersize_in_bytes % 16U) != 0U) */
3052 
3053     /* Set to 0 the number of non-valid bytes using NPBLB register*/
3054     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3055 
3056     /* Select payload phase once the header phase is performed */
3057     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3058 
3059     /* Initiate payload DMA IN and processed data DMA OUT transfers */
3060     (void)CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp);
3061   }
3062   else
3063   {
3064 
3065     /* ECB, CBC or CTR end of input data feeding or
3066        end of GCM/CCM payload data feeding through DMA */
3067     algo = hcryp->Instance->CR & AES_CR_CHMOD;
3068 
3069     /* Don't call input data transfer complete callback only if
3070        it remains some input data to write to the peripheral.
3071        This case can only occur for GCM and CCM with a payload length
3072        not a multiple of 16 bytes */
3073     if (!(((algo == CRYP_AES_GCM_GMAC) || (algo == CRYP_AES_CCM)) && \
3074           (((hcryp->Size) % 16U) != 0U)))
3075     {
3076       /* Call input data transfer complete callback */
3077 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3078       /*Call registered Input complete callback*/
3079       hcryp->InCpltCallback(hcryp);
3080 #else
3081       /*Call legacy weak Input complete callback*/
3082       HAL_CRYP_InCpltCallback(hcryp);
3083 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3084     }
3085   } /* if (hcryp->Phase == CRYP_PHASE_HEADER_DMA_FEED) */
3086 }
3087 
3088 /**
3089   * @brief  DMA CRYP output data process complete callback.
3090   * @param  hdma DMA handle
3091   * @retval None
3092   */
CRYP_DMAOutCplt(DMA_HandleTypeDef * hdma)3093 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
3094 {
3095   uint32_t count;
3096   uint32_t npblb;
3097   uint32_t lastwordsize;
3098   uint32_t temp[4];  /* Temporary CrypOutBuff */
3099   uint32_t mode;
3100 
3101   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3102 
3103   /* Disable the DMA transfer for output FIFO request by resetting
3104   the DMAOUTEN bit in the CR register */
3105 
3106   CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
3107 
3108   /* Clear CCF flag */
3109   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
3110 
3111   /* Last block transfer in case of GCM or CCM with Size not %16*/
3112   if (((hcryp->Size) % 16U) != 0U)
3113   {
3114     /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA  */
3115     hcryp->CrypInCount = (hcryp->Size / 16U) * 4U;
3116     hcryp->CrypOutCount = hcryp->CrypInCount;
3117 
3118     /* Compute the number of padding bytes in last block of payload */
3119     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
3120 
3121     mode = hcryp->Instance->CR & AES_CR_MODE;
3122     if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
3123         ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
3124     {
3125       /* Specify the number of non-valid bytes using NPBLB register*/
3126       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3127     }
3128 
3129     /* Number of valid words (lastwordsize) in last block */
3130     if ((npblb % 4U) == 0U)
3131     {
3132       lastwordsize = (16U - npblb) / 4U;
3133     }
3134     else
3135     {
3136       lastwordsize = ((16U - npblb) / 4U) + 1U;
3137     }
3138 
3139     /*  Last block optionally pad the data with zeros*/
3140     for (count = 0U; count < lastwordsize; count++)
3141     {
3142       hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3143       hcryp->CrypInCount++;
3144     }
3145     while (count < 4U)
3146     {
3147       /* Pad the data with zeros to have a complete block */
3148       hcryp->Instance->DINR = 0x0U;
3149       count++;
3150     }
3151     /* Call input data transfer complete callback */
3152 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3153     /*Call registered Input complete callback*/
3154     hcryp->InCpltCallback(hcryp);
3155 #else
3156     /*Call legacy weak Input complete callback*/
3157     HAL_CRYP_InCpltCallback(hcryp);
3158 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3159 
3160     /*Wait on CCF flag*/
3161     CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE);
3162 
3163     /*Read the output block from the output FIFO */
3164     for (count = 0U; count < 4U; count++)
3165     {
3166       /* Read the output block from the output FIFO and put them in temporary buffer
3167          then get CrypOutBuff from temporary buffer */
3168       temp[count] = hcryp->Instance->DOUTR;
3169     }
3170 
3171     count = 0U;
3172     while ((hcryp->CrypOutCount < ((hcryp->Size + 3U) / 4U)) && (count < 4U))
3173     {
3174       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[count];
3175       hcryp->CrypOutCount++;
3176       count++;
3177     }
3178   }
3179 
3180   if (((hcryp->Init.Algorithm & CRYP_AES_GCM_GMAC) != CRYP_AES_GCM_GMAC)
3181       && ((hcryp->Init.Algorithm & CRYP_AES_CCM) != CRYP_AES_CCM))
3182   {
3183     /* Disable CRYP (not allowed in  GCM)*/
3184     __HAL_CRYP_DISABLE(hcryp);
3185   }
3186 
3187   /* Change the CRYP state to ready */
3188   hcryp->State = HAL_CRYP_STATE_READY;
3189   __HAL_UNLOCK(hcryp);
3190 
3191   /* Call output data transfer complete callback */
3192 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3193   /*Call registered Output complete callback*/
3194   hcryp->OutCpltCallback(hcryp);
3195 #else
3196   /*Call legacy weak Output complete callback*/
3197   HAL_CRYP_OutCpltCallback(hcryp);
3198 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3199 }
3200 
3201 /**
3202   * @brief  DMA CRYP communication error callback.
3203   * @param  hdma DMA handle
3204   * @retval None
3205   */
CRYP_DMAError(DMA_HandleTypeDef * hdma)3206 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
3207 {
3208   CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3209 
3210   /* Change the CRYP peripheral state */
3211   hcryp->State = HAL_CRYP_STATE_READY;
3212 
3213   /* DMA error code field */
3214   hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
3215 
3216   /* Clear CCF flag */
3217   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
3218 
3219   /* Call error callback */
3220 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3221   /*Call registered error callback*/
3222   hcryp->ErrorCallback(hcryp);
3223 #else
3224   /*Call legacy weak error callback*/
3225   HAL_CRYP_ErrorCallback(hcryp);
3226 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3227 }
3228 
3229 /**
3230   * @brief  Set the DMA configuration and start the DMA transfer
3231   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3232   *         the configuration information for CRYP module
3233   * @param  inputaddr address of the input buffer
3234   * @param  Size size of the input and output buffers in words, must be a multiple of 4.
3235   * @param  outputaddr address of the output buffer
3236   * @retval None
3237   */
CRYP_SetDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size,uint32_t outputaddr)3238 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
3239 {
3240   HAL_StatusTypeDef status;
3241 
3242   /* Set the CRYP DMA transfer complete callback */
3243   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
3244 
3245   /* Set the DMA input error callback */
3246   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
3247 
3248   /* Set the CRYP DMA transfer complete callback */
3249   hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
3250 
3251   /* Set the DMA output error callback */
3252   hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
3253 
3254   if ((hcryp->Init.Algorithm & CRYP_AES_GCM_GMAC) != CRYP_AES_GCM_GMAC)
3255   {
3256     /* Enable CRYP (not allowed in  GCM & CCM)*/
3257     __HAL_CRYP_ENABLE(hcryp);
3258   }
3259 
3260   /* Enable the DMA input channel */
3261   if ((hcryp->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
3262   {
3263     if ((hcryp->hdmain->LinkedListQueue != NULL) && (hcryp->hdmain->LinkedListQueue->Head != NULL))
3264     {
3265       /* Enable the DMA channel */
3266       hcryp->hdmain->LinkedListQueue->Head->\
3267       LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = Size; /* Set DMA data size */
3268       hcryp->hdmain->LinkedListQueue->Head->\
3269       LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = inputaddr; /* Set DMA source address */
3270       hcryp->hdmain->LinkedListQueue->Head->\
3271       LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hcryp->Instance->DINR; /* Set DMA destination address */
3272 
3273       status = HAL_DMAEx_List_Start_IT(hcryp->hdmain);
3274     }
3275     else
3276     {
3277       /* Return error status */
3278       status = HAL_ERROR;
3279     }
3280   }
3281   else
3282   {
3283     status = HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size);
3284   }
3285 
3286   if (status != HAL_OK)
3287   {
3288     /* DMA error code field */
3289     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
3290 
3291     /*Call registered error callback*/
3292 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3293     hcryp->ErrorCallback(hcryp);
3294 #else
3295     /*Call legacy weak error callback*/
3296     HAL_CRYP_ErrorCallback(hcryp);
3297 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3298   }
3299   /* Enable the DMA output channel */
3300   if ((hcryp->hdmaout->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
3301   {
3302     if ((hcryp->hdmaout->LinkedListQueue != NULL) && (hcryp->hdmaout->LinkedListQueue->Head != NULL))
3303     {
3304       /* Enable the DMA channel */
3305       hcryp->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = \
3306           Size; /* Set DMA data size           */
3307       hcryp->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \
3308           (uint32_t)&hcryp->Instance->DOUTR;    /* Set DMA source address      */
3309       hcryp->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = \
3310           outputaddr;   /* Set DMA destination address */
3311 
3312       status = HAL_DMAEx_List_Start_IT(hcryp->hdmaout);
3313     }
3314     else
3315     {
3316       /* Return error status */
3317       status = HAL_ERROR;
3318     }
3319   }
3320   else
3321   {
3322     status = HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size);
3323   }
3324 
3325   if (status != HAL_OK)
3326   {
3327     /* DMA error code field */
3328     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
3329 
3330     /* Call error callback */
3331 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3332     /*Call registered error callback*/
3333     hcryp->ErrorCallback(hcryp);
3334 #else
3335     /*Call legacy weak error callback*/
3336     HAL_CRYP_ErrorCallback(hcryp);
3337 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3338   }
3339   /* Enable In and Out DMA requests */
3340   SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
3341 }
3342 
3343 /**
3344   * @brief  Set the DMA configuration and start the header DMA transfer
3345   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3346   *         the configuration information for CRYP module
3347   * @param  inputaddr address of the input buffer
3348   * @param  Size size of the input buffer in words, must be a multiple of 4
3349   * @retval None
3350   */
CRYP_SetHeaderDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size)3351 static HAL_StatusTypeDef CRYP_SetHeaderDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size)
3352 {
3353   HAL_StatusTypeDef status;
3354 
3355   /* Set the CRYP DMA transfer complete callback */
3356   hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
3357 
3358   /* Set the DMA input error callback */
3359   hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
3360 
3361   /* Mark that header is fed to the peripheral in DMA mode */
3362   hcryp->Phase = CRYP_PHASE_HEADER_DMA_FEED;
3363 
3364   /* Enable the DMA input channel */
3365   if ((hcryp->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
3366   {
3367     if ((hcryp->hdmain->LinkedListQueue != NULL) && (hcryp->hdmain->LinkedListQueue->Head != NULL))
3368     {
3369       /* Enable the DMA channel */
3370       hcryp->hdmain->LinkedListQueue->Head->\
3371       LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = Size; /* Set DMA data size */
3372       hcryp->hdmain->LinkedListQueue->Head->\
3373       LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = inputaddr; /* Set DMA source address */
3374       hcryp->hdmain->LinkedListQueue->Head->\
3375       LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hcryp->Instance->DINR; /* Set DMA destination address */
3376 
3377       status = HAL_DMAEx_List_Start_IT(hcryp->hdmain);
3378     }
3379     else
3380     {
3381       /* Return error status */
3382       status = HAL_ERROR;
3383     }
3384   }
3385   else
3386   {
3387     status = HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size);
3388   }
3389   if (status != HAL_OK)
3390   {
3391     /* DMA error code field */
3392     hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
3393 
3394     /* Call error callback */
3395 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3396     /*Call registered error callback*/
3397     hcryp->ErrorCallback(hcryp);
3398 #else
3399     /*Call legacy weak error callback*/
3400     HAL_CRYP_ErrorCallback(hcryp);
3401 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3402   }
3403 
3404   /* Enable IN DMA requests */
3405   SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
3406 
3407   return status;
3408 }
3409 
3410 /**
3411   * @brief  Process Data: Write Input data in polling mode and used in AES functions.
3412   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3413   *         the configuration information for CRYP module
3414   * @param  Timeout Specify Timeout value
3415   * @retval None
3416   */
CRYP_AES_ProcessData(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)3417 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3418 {
3419 
3420   uint32_t temp[4];  /* Temporary CrypOutBuff */
3421   uint32_t i;
3422 
3423   /* Write the input block in the IN FIFO */
3424   hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3425   hcryp->CrypInCount++;
3426   hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3427   hcryp->CrypInCount++;
3428   hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3429   hcryp->CrypInCount++;
3430   hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3431   hcryp->CrypInCount++;
3432 
3433   /* Wait for CCF flag to be raised */
3434   if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3435   {
3436     /*Call registered error callback*/
3437 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3438     hcryp->ErrorCallback(hcryp);
3439 #else
3440     /*Call legacy weak error callback*/
3441     HAL_CRYP_ErrorCallback(hcryp);
3442 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3443   }
3444 
3445   /* Clear CCF Flag */
3446   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
3447 
3448   /* Read the output block from the output FIFO and put them in temporary buffer then
3449      get CrypOutBuff from temporary buffer*/
3450   for (i = 0U; i < 4U; i++)
3451   {
3452     temp[i] = hcryp->Instance->DOUTR;
3453   }
3454   i = 0U;
3455   while ((hcryp->CrypOutCount < ((hcryp->Size + 3U) / 4U)) && (i < 4U))
3456   {
3457     *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
3458     hcryp->CrypOutCount++;
3459     i++;
3460   }
3461 }
3462 
3463 /**
3464   * @brief  Handle CRYP block input/output data handling under interruption.
3465   * @note   The function is called under interruption only, once
3466   *         interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
3467   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3468   *         the configuration information for CRYP module.
3469   * @retval HAL status
3470   */
CRYP_AES_IT(CRYP_HandleTypeDef * hcryp)3471 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
3472 {
3473   uint32_t temp[4];  /* Temporary CrypOutBuff */
3474   uint32_t i;
3475 
3476   if (hcryp->State == HAL_CRYP_STATE_BUSY)
3477   {
3478     /* Read the output block from the output FIFO and put them in temporary buffer then
3479        get CrypOutBuff from temporary buffer*/
3480     for (i = 0U; i < 4U; i++)
3481     {
3482       temp[i] = hcryp->Instance->DOUTR;
3483     }
3484     i = 0U;
3485     while ((hcryp->CrypOutCount < ((hcryp->Size + 3U) / 4U)) && (i < 4U))
3486     {
3487       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
3488       hcryp->CrypOutCount++;
3489       i++;
3490     }
3491     if (hcryp->CrypOutCount == (hcryp->Size / 4U))
3492     {
3493       /* Disable Computation Complete flag and errors interrupts */
3494       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
3495 
3496       /* Change the CRYP state */
3497       hcryp->State = HAL_CRYP_STATE_READY;
3498 
3499       /* Disable CRYP */
3500       __HAL_CRYP_DISABLE(hcryp);
3501       __HAL_UNLOCK(hcryp);
3502 
3503       /* Call Output transfer complete callback */
3504 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3505       /*Call registered Output complete callback*/
3506       hcryp->OutCpltCallback(hcryp);
3507 #else
3508       /*Call legacy weak Output complete callback*/
3509       HAL_CRYP_OutCpltCallback(hcryp);
3510 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3511     }
3512     else
3513     {
3514 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
3515       /* If suspension flag has been raised, suspend processing
3516          only if not already at the end of the payload */
3517       if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
3518       {
3519         /* Clear CCF Flag */
3520         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
3521 
3522         /* reset SuspendRequest */
3523         hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
3524         /* Disable Computation Complete Flag and Errors Interrupts */
3525         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
3526         /* Change the CRYP state */
3527         hcryp->State = HAL_CRYP_STATE_SUSPENDED;
3528         /* Mark that the payload phase is suspended */
3529         hcryp->Phase = CRYP_PHASE_PAYLOAD_SUSPENDED;
3530         __HAL_UNLOCK(hcryp);
3531       }
3532       else
3533 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
3534       {
3535         /* Write the input block in the IN FIFO */
3536         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3537         hcryp->CrypInCount++;
3538         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3539         hcryp->CrypInCount++;
3540         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3541         hcryp->CrypInCount++;
3542         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3543         hcryp->CrypInCount++;
3544 
3545         if (hcryp->CrypInCount == (hcryp->Size / 4U))
3546         {
3547           /* Call Input transfer complete callback */
3548 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3549           /*Call registered Input complete callback*/
3550           hcryp->InCpltCallback(hcryp);
3551 #else
3552           /*Call legacy weak Input complete callback*/
3553           HAL_CRYP_InCpltCallback(hcryp);
3554 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3555         }
3556       }
3557     }
3558   }
3559   else
3560   {
3561     /* Busy error code field */
3562     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
3563 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3564     /*Call registered error callback*/
3565     hcryp->ErrorCallback(hcryp);
3566 #else
3567     /*Call legacy weak error callback*/
3568     HAL_CRYP_ErrorCallback(hcryp);
3569 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3570   }
3571 }
3572 
3573 /**
3574   * @brief  Writes Key in Key registers.
3575   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3576   *         the configuration information for CRYP module
3577   * @param  KeySize Size of Key
3578   * @note   If pKey is NULL, the Key registers are not written.
3579   * @retval None
3580   */
CRYP_SetKey(CRYP_HandleTypeDef * hcryp,uint32_t KeySize)3581 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
3582 {
3583   if (hcryp->Init.pKey != NULL)
3584   {
3585     switch (KeySize)
3586     {
3587       case CRYP_KEYSIZE_256B:
3588         hcryp->Instance->KEYR7 = *(uint32_t *)(hcryp->Init.pKey);
3589         hcryp->Instance->KEYR6 = *(uint32_t *)(hcryp->Init.pKey + 1U);
3590         hcryp->Instance->KEYR5 = *(uint32_t *)(hcryp->Init.pKey + 2U);
3591         hcryp->Instance->KEYR4 = *(uint32_t *)(hcryp->Init.pKey + 3U);
3592         hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey + 4U);
3593         hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 5U);
3594         hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 6U);
3595         hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 7U);
3596         break;
3597       case CRYP_KEYSIZE_128B:
3598         hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey);
3599         hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 1U);
3600         hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 2U);
3601         hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 3U);
3602         break;
3603       default:
3604         break;
3605     }
3606   }
3607 }
3608 
3609 /**
3610   * @brief  Writes initialization vector in IV registers.
3611   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3612   *         the configuration information for CRYP module
3613   * @note   If IV is NULL, the IV registers are not written.
3614   * @retval None
3615   */
CRYP_SetIV(CRYP_HandleTypeDef * hcryp)3616 static void CRYP_SetIV(CRYP_HandleTypeDef *hcryp)
3617 {
3618   if (hcryp->Init.pInitVect != NULL)
3619   {
3620     /* Set the Initialization Vector*/
3621     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
3622     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
3623     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
3624     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
3625   }
3626 }
3627 
3628 /**
3629   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
3630   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3631   *         the configuration information for CRYP module
3632   * @param  Timeout Timeout duration
3633   * @retval HAL status
3634   */
CRYP_AESGCM_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)3635 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3636 {
3637   uint32_t tickstart;
3638   uint32_t wordsize = ((uint32_t)hcryp->Size / 4U);
3639   uint32_t npblb;
3640   uint32_t temp[4];  /* Temporary CrypOutBuff */
3641   uint32_t index;
3642   uint32_t lastwordsize;
3643   uint32_t incount;  /* Temporary CrypInCount Value */
3644   uint32_t outcount;  /* Temporary CrypOutCount Value */
3645   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3646 
3647   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3648   {
3649     if (hcryp->KeyIVConfig == 1U)
3650     {
3651       /* If the Key and IV configuration has to be done only once
3652          and if it has already been done, skip it */
3653       dokeyivconfig = 0U;
3654       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3655     }
3656     else
3657     {
3658       /* If the Key and IV configuration has to be done only once
3659          and if it has not been done already, do it and set KeyIVConfig
3660          to keep track it won't have to be done again next time */
3661       hcryp->KeyIVConfig = 1U;
3662       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3663     }
3664   }
3665   else
3666   {
3667     hcryp->SizesSum = hcryp->Size;
3668   }
3669 
3670   if (dokeyivconfig == 1U)
3671   {
3672 
3673     /*  Reset CrypHeaderCount */
3674     hcryp->CrypHeaderCount = 0U;
3675 
3676     /****************************** Init phase **********************************/
3677 
3678     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3679     /* Set the Key */
3680     if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
3681     {
3682       if (hcryp->Instance == AES)
3683       {
3684         if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
3685         {
3686           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3687         }
3688         else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
3689         {
3690           hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
3691         }
3692       }
3693       else /*SAES*/
3694       {
3695         /* We should re-write Key, in the case where we change key after first operation */
3696         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
3697         {
3698           /* Set the Key */
3699           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3700         }
3701         /* Get tick */
3702         tickstart = HAL_GetTick();
3703 
3704         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID))
3705         {
3706           /* Check for the Timeout */
3707           if (Timeout != HAL_MAX_DELAY)
3708           {
3709             if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3710             {
3711               /* Disable the CRYP peripheral clock */
3712               __HAL_CRYP_DISABLE(hcryp);
3713 
3714               /* Change state */
3715               hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3716               hcryp->State = HAL_CRYP_STATE_READY;
3717               __HAL_UNLOCK(hcryp);
3718               return HAL_ERROR;
3719             }
3720           }
3721         }
3722       }
3723     }
3724     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3725     CRYP_SetIV(hcryp);
3726 
3727     /* Enable the CRYP peripheral */
3728     __HAL_CRYP_ENABLE(hcryp);
3729 
3730     /* just wait for hash computation */
3731     if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3732     {
3733       return HAL_ERROR;
3734     }
3735     /* Clear CCF flag */
3736     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
3737 
3738     /************************ Header phase *************************************/
3739 
3740     if (CRYP_GCMCCM_SetHeaderPhase(hcryp,  Timeout) != HAL_OK)
3741     {
3742       return HAL_ERROR;
3743     }
3744 
3745     /*************************Payload phase ************************************/
3746 
3747     /* Set the phase */
3748     hcryp->Phase = CRYP_PHASE_PROCESS;
3749 
3750     /* Select payload phase once the header phase is performed */
3751     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3752 
3753     /* Set to 0 the number of non-valid bytes using NPBLB register*/
3754     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3755 
3756   } /* if (dokeyivconfig == 1U) */
3757 
3758   if ((hcryp->Size % 16U) != 0U)
3759   {
3760     /* recalculate  wordsize */
3761     wordsize = ((wordsize / 4U) * 4U);
3762   }
3763 
3764   /* Get tick */
3765   tickstart = HAL_GetTick();
3766 
3767   /* Write input data and get output Data */
3768   incount = hcryp->CrypInCount;
3769   outcount = hcryp->CrypOutCount;
3770   while ((incount < wordsize) && (outcount < wordsize))
3771   {
3772     /* Write plain data and get cipher data */
3773     CRYP_AES_ProcessData(hcryp, Timeout);
3774 
3775     /* Check for the Timeout */
3776     if (Timeout != HAL_MAX_DELAY)
3777     {
3778       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3779       {
3780         /* Disable the CRYP peripheral clock */
3781         __HAL_CRYP_DISABLE(hcryp);
3782 
3783         /* Change state & error code */
3784         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3785         hcryp->State = HAL_CRYP_STATE_READY;
3786         __HAL_UNLOCK(hcryp);
3787         return HAL_ERROR;
3788       }
3789     }
3790     incount = hcryp->CrypInCount;
3791     outcount = hcryp->CrypOutCount;
3792   }
3793 
3794   if ((hcryp->Size % 16U) != 0U)
3795   {
3796     /* Compute the number of padding bytes in last block of payload */
3797     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
3798 
3799     /*  Set Npblb in case of AES GCM payload encryption to get right tag*/
3800     if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
3801     {
3802       /* Set to 0 the number of non-valid bytes using NPBLB register*/
3803       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3804     }
3805     /* Number of valid words (lastwordsize) in last block */
3806     if ((npblb % 4U) == 0U)
3807     {
3808       lastwordsize = (16U - npblb) / 4U;
3809     }
3810     else
3811     {
3812       lastwordsize = ((16U - npblb) / 4U) + 1U;
3813     }
3814     /*  last block optionally pad the data with zeros*/
3815     for (index = 0U; index < lastwordsize; index ++)
3816     {
3817       /* Write the last Input block in the IN FIFO */
3818       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3819       hcryp->CrypInCount++;
3820     }
3821     while (index < 4U)
3822     {
3823       /* pad the data with zeros to have a complete block */
3824       hcryp->Instance->DINR  = 0U;
3825       index++;
3826     }
3827     /* Wait for CCF flag to be raised */
3828     if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3829     {
3830 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3831       /*Call registered error callback*/
3832       hcryp->ErrorCallback(hcryp);
3833 #else
3834       /*Call legacy weak error callback*/
3835       HAL_CRYP_ErrorCallback(hcryp);
3836 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3837     }
3838 
3839     /* Clear CCF Flag */
3840     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
3841 
3842     /*Read the output block from the output FIFO */
3843     for (index = 0U; index < 4U; index++)
3844     {
3845       /* Read the output block from the output FIFO and put them in temporary buffer then
3846          get CrypOutBuff from temporary buffer */
3847       temp[index] = hcryp->Instance->DOUTR;
3848     }
3849     for (index = 0U; index < lastwordsize; index++)
3850     {
3851       *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
3852       hcryp->CrypOutCount++;
3853     }
3854   }
3855 
3856   return HAL_OK;
3857 }
3858 
3859 /**
3860   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
3861   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
3862   *         the configuration information for CRYP module
3863   * @retval HAL status
3864   */
CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef * hcryp)3865 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3866 {
3867   uint32_t count;
3868   uint32_t loopcounter;
3869   uint32_t lastwordsize;
3870   uint32_t npblb;
3871   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3872   uint32_t headersize_in_bytes;
3873   uint32_t tmp;
3874   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
3875                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
3876                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU
3877                       }; /*  8-bit data type */
3878 
3879 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
3880   if ((hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) || (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED))
3881   {
3882     CRYP_PhaseProcessingResume(hcryp);
3883     return HAL_OK;
3884   }
3885 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
3886 
3887   /* Manage header size given in bytes to handle cases where
3888      header size is not a multiple of 4 bytes */
3889   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
3890   {
3891     headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
3892   }
3893   else
3894   {
3895     headersize_in_bytes = hcryp->Init.HeaderSize;
3896   }
3897 
3898   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3899   {
3900     if (hcryp->KeyIVConfig == 1U)
3901     {
3902       /* If the Key and IV configuration has to be done only once
3903          and if it has already been done, skip it */
3904       dokeyivconfig = 0U;
3905       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3906     }
3907     else
3908     {
3909       /* If the Key and IV configuration has to be done only once
3910          and if it has not been done already, do it and set KeyIVConfig
3911          to keep track it won't have to be done again next time */
3912       hcryp->KeyIVConfig = 1U;
3913       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3914     }
3915   }
3916   else
3917   {
3918     hcryp->SizesSum = hcryp->Size;
3919   }
3920 
3921   /* Configure Key, IV and process message (header and payload) */
3922   if (dokeyivconfig == 1U)
3923   {
3924     /*  Reset CrypHeaderCount */
3925     hcryp->CrypHeaderCount = 0U;
3926 
3927     /******************************* Init phase *********************************/
3928 
3929     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3930     /* Set the Key */
3931     if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
3932     {
3933       if (hcryp->Instance == AES)
3934       {
3935         if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
3936         {
3937           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3938         }
3939         else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
3940         {
3941           hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
3942         }
3943       }
3944       else /*SAES*/
3945       {
3946         /* We should re-write Key, in the case where we change key after first operation */
3947         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
3948         {
3949           /* Set the Key */
3950           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3951         }
3952         /* Wait for KEYVALID flag to be set */
3953         count = CRYP_TIMEOUT_KEYPREPARATION;
3954         do
3955         {
3956           count--;
3957           if (count == 0U)
3958           {
3959             /* Disable the SAES peripheral clock */
3960             __HAL_CRYP_DISABLE(hcryp);
3961 
3962             /* Change state */
3963             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3964             hcryp->State = HAL_CRYP_STATE_READY;
3965             __HAL_UNLOCK(hcryp);
3966             return HAL_ERROR;
3967           }
3968         } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID));
3969       }
3970     }
3971     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3972     CRYP_SetIV(hcryp);
3973 
3974     /* Enable the CRYP peripheral */
3975     __HAL_CRYP_ENABLE(hcryp);
3976 
3977     /* just wait for hash computation */
3978     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3979     do
3980     {
3981       count--;
3982       if (count == 0U)
3983       {
3984         /* Disable the CRYP peripheral clock */
3985         __HAL_CRYP_DISABLE(hcryp);
3986 
3987         /* Change state */
3988         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3989         hcryp->State = HAL_CRYP_STATE_READY;
3990         __HAL_UNLOCK(hcryp);
3991         return HAL_ERROR;
3992       }
3993     } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
3994 
3995     /* Clear CCF flag */
3996     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
3997 
3998     /***************************** Header phase *********************************/
3999 
4000     /* Select header phase */
4001     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4002 
4003     /* Enable computation complete flag and error interrupts */
4004     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
4005 
4006     /* Enable the CRYP peripheral */
4007     __HAL_CRYP_ENABLE(hcryp);
4008 
4009     if (hcryp->Init.HeaderSize == 0U) /*header phase is  skipped*/
4010     {
4011       /* Set the phase */
4012       hcryp->Phase = CRYP_PHASE_PROCESS;
4013 
4014       /* Select payload phase once the header phase is performed */
4015       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
4016 
4017       /* Set to 0 the number of non-valid bytes using NPBLB register*/
4018       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
4019 
4020       /* Write the payload Input block in the IN FIFO */
4021       if (hcryp->Size == 0U)
4022       {
4023         /* Disable interrupts */
4024         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
4025 
4026         /* Change the CRYP state */
4027         hcryp->State = HAL_CRYP_STATE_READY;
4028         __HAL_UNLOCK(hcryp);
4029       }
4030       else if (hcryp->Size >= 16U)
4031       {
4032         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4033         hcryp->CrypInCount++;
4034         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4035         hcryp->CrypInCount++;
4036         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4037         hcryp->CrypInCount++;
4038         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4039         hcryp->CrypInCount++;
4040         if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4041         {
4042           /* Call Input transfer complete callback */
4043 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4044           /*Call registered Input complete callback*/
4045           hcryp->InCpltCallback(hcryp);
4046 #else
4047           /*Call legacy weak Input complete callback*/
4048           HAL_CRYP_InCpltCallback(hcryp);
4049 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4050         }
4051       }
4052       else /* Size < 16Bytes  : first block is the last block*/
4053       {
4054         /* Size should be %4  otherwise Tag will  be incorrectly generated for GCM Encryption:
4055         Workaround is implemented in polling mode, so if last block of
4056         payload <128bit do not use CRYP_Encrypt_IT otherwise TAG is incorrectly generated for GCM Encryption. */
4057 
4058 
4059         /* Compute the number of padding bytes in last block of payload */
4060         npblb = 16U - ((uint32_t)hcryp->Size);
4061 
4062         if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
4063         {
4064           /* Set to 0 the number of non-valid bytes using NPBLB register*/
4065           MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4066         }
4067 
4068         /* Number of valid words (lastwordsize) in last block */
4069         if ((npblb % 4U) == 0U)
4070         {
4071           lastwordsize = (16U - npblb) / 4U;
4072         }
4073         else
4074         {
4075           lastwordsize = ((16U - npblb) / 4U) + 1U;
4076         }
4077 
4078         /*  last block optionally pad the data with zeros*/
4079         for (loopcounter = 0U; loopcounter < lastwordsize ; loopcounter++)
4080         {
4081           hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4082           hcryp->CrypInCount++;
4083         }
4084         while (loopcounter < 4U)
4085         {
4086           /* pad the data with zeros to have a complete block */
4087           hcryp->Instance->DINR = 0x0U;
4088           loopcounter++;
4089         }
4090         /* Call Input transfer complete callback */
4091 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4092         /*Call registered Input complete callback*/
4093         hcryp->InCpltCallback(hcryp);
4094 #else
4095         /*Call legacy weak Input complete callback*/
4096         HAL_CRYP_InCpltCallback(hcryp);
4097 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4098       }
4099     }
4100     /* Enter header data */
4101     /* Cher first whether header length is small enough to enter the full header in one shot */
4102     else if (headersize_in_bytes <= 16U)
4103     {
4104       /* Write header data, padded with zeros if need be */
4105       for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++)
4106       {
4107         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4108         hcryp->CrypHeaderCount++ ;
4109       }
4110       /* If the header size is a multiple of words */
4111       if ((headersize_in_bytes % 4U) == 0U)
4112       {
4113         /* Pad the data with zeros to have a complete block */
4114         while (loopcounter < 4U)
4115         {
4116           hcryp->Instance->DINR = 0x0U;
4117           loopcounter++;
4118           hcryp->CrypHeaderCount++;
4119         }
4120       }
4121       else
4122       {
4123         /* Enter last bytes, padded with zeros */
4124         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4125         tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
4126         hcryp->Instance->DINR = tmp;
4127         loopcounter++;
4128         hcryp->CrypHeaderCount++ ;
4129         /* Pad the data with zeros to have a complete block */
4130         while (loopcounter < 4U)
4131         {
4132           hcryp->Instance->DINR = 0x0U;
4133           loopcounter++;
4134           hcryp->CrypHeaderCount++;
4135         }
4136       }
4137       /* Call Input transfer complete callback */
4138 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4139       /*Call registered Input complete callback*/
4140       hcryp->InCpltCallback(hcryp);
4141 #else
4142       /*Call legacy weak Input complete callback*/
4143       HAL_CRYP_InCpltCallback(hcryp);
4144 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4145     }
4146     else
4147     {
4148       /* Write the first input header block in the Input FIFO,
4149          the following header data will be fed after interrupt occurrence */
4150       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4151       hcryp->CrypHeaderCount++;
4152       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4153       hcryp->CrypHeaderCount++;
4154       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4155       hcryp->CrypHeaderCount++;
4156       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4157       hcryp->CrypHeaderCount++;
4158     }
4159 
4160   } /* end of if (dokeyivconfig == 1U) */
4161   else  /* Key and IV have already been configured,
4162           header has already been processed;
4163           only process here message payload */
4164   {
4165 
4166     /* Enable computation complete flag and error interrupts */
4167     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
4168 
4169     /* Set to 0 the number of non-valid bytes using NPBLB register*/
4170     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
4171 
4172     /* Write the payload Input block in the IN FIFO */
4173     if (hcryp->Size == 0U)
4174     {
4175       /* Disable interrupts */
4176       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
4177 
4178       /* Change the CRYP state */
4179       hcryp->State = HAL_CRYP_STATE_READY;
4180       __HAL_UNLOCK(hcryp);
4181     }
4182     else if (hcryp->Size >= 16U)
4183     {
4184       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4185       hcryp->CrypInCount++;
4186       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4187       hcryp->CrypInCount++;
4188       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4189       hcryp->CrypInCount++;
4190       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4191       hcryp->CrypInCount++;
4192       if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4193       {
4194         /* Call Input transfer complete callback */
4195 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4196         /*Call registered Input complete callback*/
4197         hcryp->InCpltCallback(hcryp);
4198 #else
4199         /*Call legacy weak Input complete callback*/
4200         HAL_CRYP_InCpltCallback(hcryp);
4201 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4202       }
4203     }
4204     else /* Size < 16Bytes  : first block is the last block*/
4205     {
4206       /* Size should be %4  otherwise Tag will  be incorrectly generated for GCM Encryption:
4207       Workaround is implemented in polling mode, so if last block of
4208       payload <128bit do not use CRYP_Encrypt_IT otherwise TAG is incorrectly generated for GCM Encryption. */
4209 
4210 
4211       /* Compute the number of padding bytes in last block of payload */
4212       npblb = 16U - ((uint32_t)hcryp->Size);
4213 
4214       if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
4215       {
4216         /* Set to 0 the number of non-valid bytes using NPBLB register*/
4217         MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4218       }
4219 
4220       /* Number of valid words (lastwordsize) in last block */
4221       if ((npblb % 4U) == 0U)
4222       {
4223         lastwordsize = (16U - npblb) / 4U;
4224       }
4225       else
4226       {
4227         lastwordsize = ((16U - npblb) / 4U) + 1U;
4228       }
4229 
4230       /*  last block optionally pad the data with zeros*/
4231       for (loopcounter = 0U; loopcounter < lastwordsize ; loopcounter++)
4232       {
4233         hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4234         hcryp->CrypInCount++;
4235       }
4236       while (loopcounter < 4U)
4237       {
4238         /* pad the data with zeros to have a complete block */
4239         hcryp->Instance->DINR = 0x0U;
4240         loopcounter++;
4241       }
4242       /* Call Input transfer complete callback */
4243 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4244       /*Call registered Input complete callback*/
4245       hcryp->InCpltCallback(hcryp);
4246 #else
4247       /*Call legacy weak Input complete callback*/
4248       HAL_CRYP_InCpltCallback(hcryp);
4249 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4250     }
4251   }
4252 
4253   return HAL_OK;
4254 }
4255 
4256 
4257 /**
4258   * @brief  Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
4259   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
4260   *         the configuration information for CRYP module
4261   * @retval HAL status
4262   */
CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef * hcryp)4263 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
4264 {
4265   uint32_t count;
4266   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
4267 
4268   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
4269   {
4270     if (hcryp->KeyIVConfig == 1U)
4271     {
4272       /* If the Key and IV configuration has to be done only once
4273          and if it has already been done, skip it */
4274       dokeyivconfig = 0U;
4275       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
4276     }
4277     else
4278     {
4279       /* If the Key and IV configuration has to be done only once
4280          and if it has not been done already, do it and set KeyIVConfig
4281          to keep track it won't have to be done again next time */
4282       hcryp->KeyIVConfig = 1U;
4283       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
4284     }
4285   }
4286   else
4287   {
4288     hcryp->SizesSum = hcryp->Size;
4289   }
4290 
4291   if (dokeyivconfig == 1U)
4292   {
4293 
4294     /*  Reset CrypHeaderCount */
4295     hcryp->CrypHeaderCount = 0U;
4296 
4297     /*************************** Init phase ************************************/
4298 
4299     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
4300     /* Set the Key */
4301     if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
4302     {
4303       if (hcryp->Instance == AES)
4304       {
4305         if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
4306         {
4307           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4308         }
4309         else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
4310         {
4311           hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
4312         }
4313       }
4314       else /*SAES*/
4315       {
4316         /* We should re-write Key, in the case where we change key after first operation */
4317         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
4318         {
4319           /* Set the Key */
4320           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4321         }
4322         /* Wait for KEYVALID flag to be set */
4323         count = CRYP_TIMEOUT_KEYPREPARATION;
4324         do
4325         {
4326           count--;
4327           if (count == 0U)
4328           {
4329             /* Disable the SAES peripheral clock */
4330             __HAL_CRYP_DISABLE(hcryp);
4331 
4332             /* Change state */
4333             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4334             hcryp->State = HAL_CRYP_STATE_READY;
4335             __HAL_UNLOCK(hcryp);
4336             return HAL_ERROR;
4337           }
4338         } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID));
4339       }
4340     }
4341     /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
4342     CRYP_SetIV(hcryp);
4343 
4344     /* Enable the CRYP peripheral */
4345     __HAL_CRYP_ENABLE(hcryp);
4346 
4347     /* just wait for hash computation */
4348     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
4349     do
4350     {
4351       count--;
4352       if (count == 0U)
4353       {
4354         /* Disable the CRYP peripheral clock */
4355         __HAL_CRYP_DISABLE(hcryp);
4356 
4357         /* Change state */
4358         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4359         hcryp->State = HAL_CRYP_STATE_READY;
4360         __HAL_UNLOCK(hcryp);
4361         return HAL_ERROR;
4362       }
4363     } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
4364 
4365     /* Clear CCF flag */
4366     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
4367 
4368     /************************ Header phase *************************************/
4369 
4370     if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
4371     {
4372       return HAL_ERROR;
4373     }
4374 
4375   }
4376   else
4377   {
4378     /* Initialization and header phases already done, only do payload phase */
4379     if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK)
4380     {
4381       return HAL_ERROR;
4382     }
4383   } /* if (DoKeyIVConfig == 1U) */
4384 
4385   return HAL_OK;
4386 }
4387 
4388 
4389 /**
4390   * @brief  AES CCM encryption/decryption processing in polling mode
4391   *         encrypt/decrypt are performed with authentication preparation.
4392   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
4393   *         the configuration information for CRYP module
4394   * @param  Timeout Timeout duration
4395   * @retval HAL status
4396   */
CRYP_AESCCM_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)4397 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4398 {
4399   uint32_t tickstart;
4400   uint32_t wordsize = ((uint32_t)hcryp->Size / 4U);
4401   uint32_t loopcounter;
4402   uint32_t npblb;
4403   uint32_t lastwordsize;
4404   uint32_t temp[4];  /* Temporary CrypOutBuff */
4405   uint32_t incount;  /* Temporary CrypInCount Value */
4406   uint32_t outcount;  /* Temporary CrypOutCount Value */
4407   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
4408 
4409   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
4410   {
4411     if (hcryp->KeyIVConfig == 1U)
4412     {
4413       /* If the Key and IV configuration has to be done only once
4414          and if it has already been done, skip it */
4415       dokeyivconfig = 0U;
4416       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
4417     }
4418     else
4419     {
4420       /* If the Key and IV configuration has to be done only once
4421          and if it has not been done already, do it and set KeyIVConfig
4422          to keep track it won't have to be done again next time */
4423       hcryp->KeyIVConfig = 1U;
4424       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
4425     }
4426   }
4427   else
4428   {
4429     hcryp->SizesSum = hcryp->Size;
4430   }
4431 
4432   if (dokeyivconfig == 1U)
4433   {
4434     /*  Reset CrypHeaderCount */
4435     hcryp->CrypHeaderCount = 0U;
4436 
4437     /********************** Init phase ******************************************/
4438 
4439     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
4440     /* Set the Key */
4441     if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
4442     {
4443       if (hcryp->Instance == AES)
4444       {
4445         if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
4446         {
4447           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4448         }
4449         else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
4450         {
4451           hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
4452         }
4453       }
4454       else /*SAES*/
4455       {
4456         /* We should re-write Key, in the case where we change key after first operation */
4457         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
4458         {
4459           /* Set the Key */
4460           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4461         }
4462         /* Get tick */
4463         tickstart = HAL_GetTick();
4464 
4465         while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID))
4466         {
4467           /* Check for the Timeout */
4468           if (Timeout != HAL_MAX_DELAY)
4469           {
4470             if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
4471             {
4472               /* Disable the CRYP peripheral clock */
4473               __HAL_CRYP_DISABLE(hcryp);
4474 
4475               /* Change state */
4476               hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4477               hcryp->State = HAL_CRYP_STATE_READY;
4478               __HAL_UNLOCK(hcryp);
4479               return HAL_ERROR;
4480             }
4481           }
4482         }
4483       }
4484     }
4485     /* Set the initialization vector (IV) with B0 */
4486     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
4487     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
4488     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
4489     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
4490 
4491     /* Enable the CRYP peripheral */
4492     __HAL_CRYP_ENABLE(hcryp);
4493 
4494     /* just wait for hash computation */
4495     if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4496     {
4497       return HAL_ERROR;
4498     }
4499     /* Clear CCF flag */
4500     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
4501 
4502     /************************ Header phase *************************************/
4503     /* Header block(B1) : associated data length expressed in bytes concatenated
4504     with Associated Data (A)*/
4505     if (CRYP_GCMCCM_SetHeaderPhase(hcryp,  Timeout) != HAL_OK)
4506     {
4507       return HAL_ERROR;
4508     }
4509 
4510     /*************************Payload phase ************************************/
4511 
4512     /* Set the phase */
4513     hcryp->Phase = CRYP_PHASE_PROCESS;
4514 
4515     /* Select payload phase once the header phase is performed */
4516     MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
4517 
4518     /* Set to 0 the number of non-valid bytes using NPBLB register*/
4519     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
4520 
4521   } /* if (dokeyivconfig == 1U) */
4522 
4523   if ((hcryp->Size % 16U) != 0U)
4524   {
4525     /* recalculate  wordsize */
4526     wordsize = ((wordsize / 4U) * 4U);
4527   }
4528   /* Get tick */
4529   tickstart = HAL_GetTick();
4530 
4531   /* Write input data and get output data */
4532   incount = hcryp->CrypInCount;
4533   outcount = hcryp->CrypOutCount;
4534   while ((incount < wordsize) && (outcount < wordsize))
4535   {
4536     /* Write plain data and get cipher data */
4537     CRYP_AES_ProcessData(hcryp, Timeout);
4538 
4539     /* Check for the Timeout */
4540     if (Timeout != HAL_MAX_DELAY)
4541     {
4542       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
4543       {
4544         /* Disable the CRYP peripheral clock */
4545         __HAL_CRYP_DISABLE(hcryp);
4546 
4547         /* Change state */
4548         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4549         hcryp->State = HAL_CRYP_STATE_READY;
4550         __HAL_UNLOCK(hcryp);
4551         return HAL_ERROR;
4552       }
4553     }
4554     incount = hcryp->CrypInCount;
4555     outcount = hcryp->CrypOutCount;
4556   }
4557 
4558   if ((hcryp->Size % 16U) != 0U)
4559   {
4560     /* Compute the number of padding bytes in last block of payload */
4561     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
4562 
4563     if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT)
4564     {
4565       /* Set Npblb in case of AES CCM payload decryption to get right tag  */
4566       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20);
4567 
4568     }
4569     /* Number of valid words (lastwordsize) in last block */
4570     if ((npblb % 4U) == 0U)
4571     {
4572       lastwordsize = (16U - npblb) / 4U;
4573     }
4574     else
4575     {
4576       lastwordsize = ((16U - npblb) / 4U) + 1U;
4577     }
4578 
4579     /* Write the last input block in the IN FIFO */
4580     for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter ++)
4581     {
4582       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4583       hcryp->CrypInCount++;
4584     }
4585 
4586     /* Pad the data with zeros to have a complete block */
4587     while (loopcounter < 4U)
4588     {
4589       hcryp->Instance->DINR  = 0U;
4590       loopcounter++;
4591     }
4592     /* just wait for hash computation */
4593     if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4594     {
4595       return HAL_ERROR;
4596     }
4597     /* Clear CCF flag */
4598     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
4599 
4600     for (loopcounter = 0U; loopcounter < 4U; loopcounter++)
4601     {
4602       /* Read the output block from the output FIFO and put them in temporary buffer then
4603          get CrypOutBuff from temporary buffer */
4604       temp[loopcounter] = hcryp->Instance->DOUTR;
4605     }
4606     for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4607     {
4608       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[loopcounter];
4609       hcryp->CrypOutCount++;
4610     }
4611   }
4612 
4613   return HAL_OK;
4614 }
4615 
4616 /**
4617   * @brief  AES CCM encryption/decryption process in interrupt mode
4618   *         encrypt/decrypt are performed with authentication preparation.
4619   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
4620   *         the configuration information for CRYP module
4621   * @retval HAL status
4622   */
CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef * hcryp)4623 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
4624 {
4625   uint32_t count;
4626   uint32_t loopcounter;
4627   uint32_t lastwordsize;
4628   uint32_t npblb;
4629   uint32_t mode;
4630   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
4631   uint32_t headersize_in_bytes;
4632   uint32_t tmp;
4633   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
4634                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
4635                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU
4636                       }; /*  8-bit data type */
4637 
4638 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
4639   if ((hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) || (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED))
4640   {
4641     CRYP_PhaseProcessingResume(hcryp);
4642     return HAL_OK;
4643   }
4644 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
4645 
4646   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
4647   {
4648     if (hcryp->KeyIVConfig == 1U)
4649     {
4650       /* If the Key and IV configuration has to be done only once
4651          and if it has already been done, skip it */
4652       dokeyivconfig = 0U;
4653       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
4654     }
4655     else
4656     {
4657       /* If the Key and IV configuration has to be done only once
4658          and if it has not been done already, do it and set KeyIVConfig
4659          to keep track it won't have to be done again next time */
4660       hcryp->KeyIVConfig = 1U;
4661       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
4662     }
4663   }
4664   else
4665   {
4666     hcryp->SizesSum = hcryp->Size;
4667   }
4668 
4669   /* Configure Key, IV and process message (header and payload) */
4670   if (dokeyivconfig == 1U)
4671   {
4672     /*  Reset CrypHeaderCount */
4673     hcryp->CrypHeaderCount = 0U;
4674 
4675     /********************** Init phase ******************************************/
4676 
4677     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
4678     /* Set the Key */
4679     if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
4680     {
4681       if (hcryp->Instance == AES)
4682       {
4683         if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
4684         {
4685           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4686         }
4687         else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
4688         {
4689           hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
4690         }
4691       }
4692       else /*SAES*/
4693       {
4694         /* We should re-write Key, in the case where we change key after first operation */
4695         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
4696         {
4697           /* Set the Key */
4698           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4699         }
4700         /* Wait for KEYVALID flag to be set */
4701         count = CRYP_TIMEOUT_KEYPREPARATION;
4702         do
4703         {
4704           count--;
4705           if (count == 0U)
4706           {
4707             /* Disable the SAES peripheral clock */
4708             __HAL_CRYP_DISABLE(hcryp);
4709 
4710             /* Change state */
4711             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4712             hcryp->State = HAL_CRYP_STATE_READY;
4713             __HAL_UNLOCK(hcryp);
4714             return HAL_ERROR;
4715           }
4716         } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID));
4717       }
4718     }
4719     /* Set the initialization vector (IV) with B0 */
4720     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
4721     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
4722     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
4723     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
4724 
4725     /* Enable the CRYP peripheral */
4726     __HAL_CRYP_ENABLE(hcryp);
4727 
4728     /* just wait for hash computation */
4729     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
4730     do
4731     {
4732       count--;
4733       if (count == 0U)
4734       {
4735         /* Disable the CRYP peripheral clock */
4736         __HAL_CRYP_DISABLE(hcryp);
4737 
4738         /* Change state */
4739         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4740         hcryp->State = HAL_CRYP_STATE_READY;
4741         __HAL_UNLOCK(hcryp);
4742         return HAL_ERROR;
4743       }
4744     } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
4745 
4746     /* Clear CCF flag */
4747     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
4748 
4749     /***************************** Header phase *********************************/
4750 
4751     /* Select header phase */
4752     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4753 
4754     /* Enable computation complete flag and error interrupts */
4755     __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
4756 
4757     /* Enable the CRYP peripheral */
4758     __HAL_CRYP_ENABLE(hcryp);
4759 
4760     if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
4761     {
4762       headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
4763     }
4764     else
4765     {
4766       headersize_in_bytes = hcryp->Init.HeaderSize;
4767     }
4768 
4769     if (headersize_in_bytes == 0U) /* Header phase is  skipped */
4770     {
4771       /* Set the phase */
4772       hcryp->Phase = CRYP_PHASE_PROCESS;
4773       /* Select payload phase once the header phase is performed */
4774       CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4775       /* Set to 0 the number of non-valid bytes using NPBLB register*/
4776       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
4777 
4778       if (hcryp->Init.Algorithm == CRYP_AES_CCM)
4779       {
4780         /* Increment CrypHeaderCount to pass in CRYP_GCMCCM_SetPayloadPhase_IT */
4781         hcryp->CrypHeaderCount++;
4782       }
4783       /* Write the payload Input block in the IN FIFO */
4784       if (hcryp->Size == 0U)
4785       {
4786         /* Disable interrupts */
4787         __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
4788 
4789         /* Change the CRYP state */
4790         hcryp->State = HAL_CRYP_STATE_READY;
4791         __HAL_UNLOCK(hcryp);
4792       }
4793       else if (hcryp->Size >= 16U)
4794       {
4795         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4796         hcryp->CrypInCount++;
4797         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4798         hcryp->CrypInCount++;
4799         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4800         hcryp->CrypInCount++;
4801         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4802         hcryp->CrypInCount++;
4803 
4804         if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4805         {
4806           /* Call Input transfer complete callback */
4807 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4808           /*Call registered Input complete callback*/
4809           hcryp->InCpltCallback(hcryp);
4810 #else
4811           /*Call legacy weak Input complete callback*/
4812           HAL_CRYP_InCpltCallback(hcryp);
4813 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4814         }
4815       }
4816       else /* Size < 4 words  : first block is the last block*/
4817       {
4818         /* Compute the number of padding bytes in last block of payload */
4819         npblb = 16U - (uint32_t)hcryp->Size;
4820 
4821         mode = hcryp->Instance->CR & AES_CR_MODE;
4822         if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
4823             ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4824         {
4825           /* Specify the number of non-valid bytes using NPBLB register*/
4826           MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4827         }
4828 
4829         /* Number of valid words (lastwordsize) in last block */
4830         if ((npblb % 4U) == 0U)
4831         {
4832           lastwordsize = (16U - npblb) / 4U;
4833         }
4834         else
4835         {
4836           lastwordsize = ((16U - npblb) / 4U) + 1U;
4837         }
4838 
4839         /*  Last block optionally pad the data with zeros*/
4840         for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4841         {
4842           hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4843           hcryp->CrypInCount++;
4844         }
4845         while (loopcounter < 4U)
4846         {
4847           /* Pad the data with zeros to have a complete block */
4848           hcryp->Instance->DINR = 0x0U;
4849           loopcounter++;
4850         }
4851         /* Call Input transfer complete callback */
4852 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4853         /*Call registered Input complete callback*/
4854         hcryp->InCpltCallback(hcryp);
4855 #else
4856         /*Call legacy weak Input complete callback*/
4857         HAL_CRYP_InCpltCallback(hcryp);
4858 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4859       }
4860     }
4861     /* Enter header data */
4862     /* Check first whether header length is small enough to enter the full header in one shot */
4863     else if (headersize_in_bytes <= 16U)
4864     {
4865       /*  Last block optionally pad the data with zeros*/
4866       for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++)
4867       {
4868         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4869         hcryp->CrypHeaderCount++;
4870       }
4871       /* If the header size is a multiple of words */
4872       if ((headersize_in_bytes % 4U) == 0U)
4873       {
4874         /* Pad the data with zeros to have a complete block */
4875         while (loopcounter < 4U)
4876         {
4877           hcryp->Instance->DINR = 0x0U;
4878           loopcounter++;
4879         }
4880       }
4881       else
4882       {
4883         /* Enter last bytes, padded with zeros */
4884         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4885         tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
4886         hcryp->Instance->DINR = tmp;
4887         hcryp->CrypHeaderCount++;
4888         loopcounter++;
4889         /* Pad the data with zeros to have a complete block */
4890         while (loopcounter < 4U)
4891         {
4892           /* pad the data with zeros to have a complete block */
4893           hcryp->Instance->DINR = 0x0U;
4894           loopcounter++;
4895         }
4896       }
4897       /* Call Input transfer complete callback */
4898 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4899       /*Call registered Input complete callback*/
4900       hcryp->InCpltCallback(hcryp);
4901 #else
4902       /*Call legacy weak Input complete callback*/
4903       HAL_CRYP_InCpltCallback(hcryp);
4904 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4905     }
4906     else
4907     {
4908       /* Write the first input header block in the Input FIFO,
4909          the following header data will be fed after interrupt occurrence */
4910       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4911       hcryp->CrypHeaderCount++;
4912       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4913       hcryp->CrypHeaderCount++;
4914       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4915       hcryp->CrypHeaderCount++;
4916       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4917       hcryp->CrypHeaderCount++;
4918     }/* if (hcryp->Init.HeaderSize == 0U) */ /* Header phase is  skipped*/
4919 
4920   } /* end of if (dokeyivconfig == 1U) */
4921   else  /* Key and IV have already been configured,
4922           header has already been processed;
4923           only process here message payload */
4924   {
4925     /* Write the payload Input block in the IN FIFO */
4926     if (hcryp->Size == 0U)
4927     {
4928       /* Disable interrupts */
4929       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
4930 
4931       /* Change the CRYP state */
4932       hcryp->State = HAL_CRYP_STATE_READY;
4933       __HAL_UNLOCK(hcryp);
4934     }
4935     else if (hcryp->Size >= 16U)
4936     {
4937       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4938       hcryp->CrypInCount++;
4939       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4940       hcryp->CrypInCount++;
4941       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4942       hcryp->CrypInCount++;
4943       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4944       hcryp->CrypInCount++;
4945 
4946       if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4947       {
4948         /* Call Input transfer complete callback */
4949 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4950         /*Call registered Input complete callback*/
4951         hcryp->InCpltCallback(hcryp);
4952 #else
4953         /*Call legacy weak Input complete callback*/
4954         HAL_CRYP_InCpltCallback(hcryp);
4955 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4956       }
4957     }
4958     else /* Size < 4 words  : first block is the last block*/
4959     {
4960       /* Compute the number of padding bytes in last block of payload */
4961       npblb = 16U - (uint32_t)hcryp->Size;
4962 
4963       mode = hcryp->Instance->CR & AES_CR_MODE;
4964       if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
4965           ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4966       {
4967         /* Specify the number of non-valid bytes using NPBLB register*/
4968         MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4969       }
4970 
4971       /* Number of valid words (lastwordsize) in last block */
4972       if ((npblb % 4U) == 0U)
4973       {
4974         lastwordsize = (16U - npblb) / 4U;
4975       }
4976       else
4977       {
4978         lastwordsize = ((16U - npblb) / 4U) + 1U;
4979       }
4980 
4981       /*  Last block optionally pad the data with zeros*/
4982       for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4983       {
4984         hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4985         hcryp->CrypInCount++;
4986       }
4987       while (loopcounter < 4U)
4988       {
4989         /* Pad the data with zeros to have a complete block */
4990         hcryp->Instance->DINR = 0x0U;
4991         loopcounter++;
4992       }
4993       /* Call Input transfer complete callback */
4994 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4995       /*Call registered Input complete callback*/
4996       hcryp->InCpltCallback(hcryp);
4997 #else
4998       /*Call legacy weak Input complete callback*/
4999       HAL_CRYP_InCpltCallback(hcryp);
5000 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5001     }
5002   }
5003 
5004   return HAL_OK;
5005 }
5006 
5007 /**
5008   * @brief  AES CCM encryption/decryption process in DMA mode
5009   *         encrypt/decrypt are performed with authentication preparation.
5010   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5011   *         the configuration information for CRYP module
5012   * @retval HAL status
5013   */
CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef * hcryp)5014 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
5015 {
5016   uint32_t count;
5017   uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */
5018 
5019   if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
5020   {
5021     if (hcryp->KeyIVConfig == 1U)
5022     {
5023       /* If the Key and IV configuration has to be done only once
5024          and if it has already been done, skip it */
5025       dokeyivconfig = 0U;
5026       hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
5027     }
5028     else
5029     {
5030       /* If the Key and IV configuration has to be done only once
5031          and if it has not been done already, do it and set KeyIVConfig
5032          to keep track it won't have to be done again next time */
5033       hcryp->KeyIVConfig = 1U;
5034       hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
5035     }
5036   }
5037   else
5038   {
5039     hcryp->SizesSum = hcryp->Size;
5040   }
5041 
5042   if (dokeyivconfig == 1U)
5043   {
5044 
5045     /*  Reset CrypHeaderCount */
5046     hcryp->CrypHeaderCount = 0U;
5047 
5048 
5049     /********************** Init phase ******************************************/
5050 
5051     CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
5052     /* Set the Key */
5053     if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)
5054     {
5055       if (hcryp->Instance == AES)
5056       {
5057         if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED)
5058         {
5059           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
5060         }
5061         else /*after sharing the key, AES should set KMOD[1:0] to 00.*/
5062         {
5063           hcryp->Instance->CR &=  ~CRYP_KEYMODE_SHARED;
5064         }
5065       }
5066       else /*SAES*/
5067       {
5068         /* We should re-write Key, in the case where we change key after first operation */
5069         if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL))
5070         {
5071           /* Set the Key */
5072           CRYP_SetKey(hcryp, hcryp->Init.KeySize);
5073         }
5074         /* Wait for KEYVALID flag to be set */
5075         count = CRYP_TIMEOUT_KEYPREPARATION;
5076         do
5077         {
5078           count--;
5079           if (count == 0U)
5080           {
5081             /* Disable the SAES peripheral clock */
5082             __HAL_CRYP_DISABLE(hcryp);
5083 
5084             /* Change state */
5085             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5086             hcryp->State = HAL_CRYP_STATE_READY;
5087             __HAL_UNLOCK(hcryp);
5088             return HAL_ERROR;
5089           }
5090         } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID));
5091       }
5092     }
5093     /* Set the initialization vector (IV) with B0 */
5094     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
5095     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
5096     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
5097     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
5098 
5099     /* Enable the CRYP peripheral */
5100     __HAL_CRYP_ENABLE(hcryp);
5101 
5102     /* just wait for hash computation */
5103     count = CRYP_TIMEOUT_GCMCCMINITPHASE;
5104     do
5105     {
5106       count--;
5107       if (count == 0U)
5108       {
5109         /* Disable the CRYP peripheral clock */
5110         __HAL_CRYP_DISABLE(hcryp);
5111 
5112         /* Change state */
5113         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5114         hcryp->State = HAL_CRYP_STATE_READY;
5115         __HAL_UNLOCK(hcryp);
5116         return HAL_ERROR;
5117       }
5118     } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
5119 
5120     /* Clear CCF flag */
5121     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5122 
5123 
5124     /********************* Header phase *****************************************/
5125 
5126     if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
5127     {
5128       return HAL_ERROR;
5129     }
5130 
5131   }
5132   else
5133   {
5134     /* Initialization and header phases already done, only do payload phase */
5135     if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK)
5136     {
5137       return HAL_ERROR;
5138     }
5139   } /* if (DoKeyIVConfig == 1U) */
5140 
5141   return HAL_OK;
5142 }
5143 
5144 /**
5145   * @brief  Sets the payload phase in interrupt mode
5146   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5147   *         the configuration information for CRYP module
5148   * @retval state
5149   */
CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef * hcryp)5150 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
5151 {
5152   uint32_t loopcounter;
5153   uint32_t temp[4];  /* Temporary CrypOutBuff */
5154   uint32_t lastwordsize;
5155   uint32_t npblb;
5156   uint32_t mode;
5157   uint16_t incount;  /* Temporary CrypInCount Value */
5158   uint16_t outcount;  /* Temporary CrypOutCount Value */
5159   uint32_t i;
5160 
5161   /***************************** Payload phase *******************************/
5162 
5163   /* Read the output block from the output FIFO and put them in temporary buffer then
5164      get CrypOutBuff from temporary buffer*/
5165   for (i = 0U; i < 4U; i++)
5166   {
5167     temp[i] = hcryp->Instance->DOUTR;
5168   }
5169   i = 0U;
5170   while ((hcryp->CrypOutCount < ((hcryp->Size + 3U) / 4U)) && (i < 4U))
5171   {
5172     *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
5173     hcryp->CrypOutCount++;
5174     i++;
5175   }
5176   incount = hcryp->CrypInCount;
5177   outcount = hcryp->CrypOutCount;
5178   if ((outcount >= (hcryp->Size / 4U)) && ((incount * 4U) >=  hcryp->Size))
5179   {
5180 
5181     /* When in CCM with Key and IV configuration skipped, don't disable interruptions */
5182     if (!((hcryp->Init.Algorithm == CRYP_AES_CCM) && (hcryp->KeyIVConfig == 1U)))
5183     {
5184       /* Disable computation complete flag and errors interrupts */
5185       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
5186     }
5187 
5188     /* Change the CRYP state */
5189     hcryp->State = HAL_CRYP_STATE_READY;
5190     __HAL_UNLOCK(hcryp);
5191 
5192     /* Call output transfer complete callback */
5193 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5194     /*Call registered Output complete callback*/
5195     hcryp->OutCpltCallback(hcryp);
5196 #else
5197     /*Call legacy weak Output complete callback*/
5198     HAL_CRYP_OutCpltCallback(hcryp);
5199 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5200   }
5201 
5202   else if (((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U)
5203   {
5204 
5205 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
5206     /* If suspension flag has been raised, suspend processing
5207        only if not already at the end of the payload */
5208     if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
5209     {
5210       /* Clear CCF Flag */
5211       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5212 
5213       /* reset SuspendRequest */
5214       hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
5215       /* Disable Computation Complete Flag and Errors Interrupts */
5216       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
5217       /* Change the CRYP state */
5218       hcryp->State = HAL_CRYP_STATE_SUSPENDED;
5219       /* Mark that the payload phase is suspended */
5220       hcryp->Phase = CRYP_PHASE_PAYLOAD_SUSPENDED;
5221       __HAL_UNLOCK(hcryp);
5222     }
5223     else
5224 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
5225     {
5226       /* Write the input block in the IN FIFO */
5227       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5228       hcryp->CrypInCount++;
5229       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5230       hcryp->CrypInCount++;
5231       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5232       hcryp->CrypInCount++;
5233       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5234       hcryp->CrypInCount++;
5235       if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
5236       {
5237         /* Call output transfer complete callback */
5238 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5239         /*Call registered Input complete callback*/
5240         hcryp->InCpltCallback(hcryp);
5241 #else
5242         /*Call legacy weak Input complete callback*/
5243         HAL_CRYP_InCpltCallback(hcryp);
5244 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5245       }
5246     }
5247   }
5248   else /* Last block of payload < 128bit*/
5249   {
5250     /* Compute the number of padding bytes in last block of payload */
5251     npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
5252 
5253     mode = hcryp->Instance->CR & AES_CR_MODE;
5254     if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
5255         ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
5256     {
5257       /* Specify the number of non-valid bytes using NPBLB register*/
5258       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
5259     }
5260 
5261     /* Number of valid words (lastwordsize) in last block */
5262     if ((npblb % 4U) == 0U)
5263     {
5264       lastwordsize = (16U - npblb) / 4U;
5265     }
5266     else
5267     {
5268       lastwordsize = ((16U - npblb) / 4U) + 1U;
5269     }
5270 
5271     /*  Last block optionally pad the data with zeros*/
5272     for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
5273     {
5274       hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5275       hcryp->CrypInCount++;
5276     }
5277     while (loopcounter < 4U)
5278     {
5279       /* pad the data with zeros to have a complete block */
5280       hcryp->Instance->DINR = 0x0U;
5281       loopcounter++;
5282     }
5283   }
5284 }
5285 
5286 /**
5287   * @brief  Sets the payload phase in DMA mode
5288   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5289   *         the configuration information for CRYP module
5290   * @retval state
5291   */
CRYP_GCMCCM_SetPayloadPhase_DMA(CRYP_HandleTypeDef * hcryp)5292 static HAL_StatusTypeDef CRYP_GCMCCM_SetPayloadPhase_DMA(CRYP_HandleTypeDef *hcryp)
5293 {
5294   uint32_t index;
5295   uint32_t npblb;
5296   uint32_t lastwordsize;
5297   uint32_t temp[4];  /* Temporary CrypOutBuff */
5298   uint32_t count;
5299   uint32_t reg;
5300 
5301   /************************ Payload phase ************************************/
5302   if (hcryp->Size == 0U)
5303   {
5304     /* Process unLocked */
5305     __HAL_UNLOCK(hcryp);
5306 
5307     /* Change the CRYP state and phase */
5308     hcryp->State = HAL_CRYP_STATE_READY;
5309   }
5310   else if (hcryp->Size >= 16U)
5311   {
5312     /*DMA transfer must not include the last block in case of Size is not %16 */
5313     CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)((hcryp->Size / 16U) * 16U),
5314                       (uint32_t)(hcryp->pCrypOutBuffPtr));
5315   }
5316   else /* length of input data is < 16 */
5317   {
5318     /* Compute the number of padding bytes in last block of payload */
5319     npblb = 16U - (uint32_t)hcryp->Size;
5320 
5321     /* Set Npblb in case of AES GCM payload encryption or AES CCM payload decryption to get right tag*/
5322     reg = hcryp->Instance->CR & (AES_CR_CHMOD | AES_CR_MODE);
5323     if ((reg == (CRYP_AES_GCM_GMAC | CRYP_OPERATINGMODE_ENCRYPT)) || \
5324         (reg == (CRYP_AES_CCM | CRYP_OPERATINGMODE_DECRYPT)))
5325     {
5326       /* Specify the number of non-valid bytes using NPBLB register*/
5327       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
5328     }
5329 
5330     /* Number of valid words (lastwordsize) in last block */
5331     if ((npblb % 4U) == 0U)
5332     {
5333       lastwordsize = (16U - npblb) / 4U;
5334     }
5335     else
5336     {
5337       lastwordsize = ((16U - npblb) / 4U) + 1U;
5338     }
5339 
5340     /*  last block optionally pad the data with zeros*/
5341     for (index = 0U; index < lastwordsize; index ++)
5342     {
5343       /* Write the last Input block in the IN FIFO */
5344       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5345       hcryp->CrypInCount++;
5346     }
5347     while (index < 4U)
5348     {
5349       /* pad the data with zeros to have a complete block */
5350       hcryp->Instance->DINR  = 0U;
5351       index++;
5352     }
5353     /* Call the input data transfer complete callback */
5354 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5355     /*Call registered Input complete callback*/
5356     hcryp->InCpltCallback(hcryp);
5357 #else
5358     /*Call legacy weak Input complete callback*/
5359     HAL_CRYP_InCpltCallback(hcryp);
5360 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5361     /* Wait for CCF flag to be raised */
5362     count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
5363     do
5364     {
5365       count-- ;
5366       if (count == 0U)
5367       {
5368         /* Disable the CRYP peripheral clock */
5369         __HAL_CRYP_DISABLE(hcryp);
5370 
5371         /* Change state */
5372         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5373         hcryp->State = HAL_CRYP_STATE_READY;
5374 
5375         /* Process unlocked */
5376         __HAL_UNLOCK(hcryp);
5377         return HAL_ERROR;
5378       }
5379     } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
5380 
5381     /* Clear CCF Flag */
5382     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5383 
5384     /*Read the output block from the output FIFO */
5385     for (index = 0U; index < 4U; index++)
5386     {
5387       /* Read the output block from the output FIFO and put them in temporary
5388          buffer then get CrypOutBuff from temporary buffer */
5389       temp[index] = hcryp->Instance->DOUTR;
5390     }
5391     for (index = 0U; index < lastwordsize; index++)
5392     {
5393       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
5394       hcryp->CrypOutCount++;
5395     }
5396 
5397     /* Change the CRYP state to ready */
5398     hcryp->State = HAL_CRYP_STATE_READY;
5399 
5400     /* Process unlocked */
5401     __HAL_UNLOCK(hcryp);
5402     /* Call Output transfer complete callback */
5403 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5404     /*Call registered Output complete callback*/
5405     hcryp->OutCpltCallback(hcryp);
5406 #else
5407     /*Call legacy weak Output complete callback*/
5408     HAL_CRYP_OutCpltCallback(hcryp);
5409 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5410   }
5411 
5412   return HAL_OK;
5413 }
5414 
5415 /**
5416   * @brief  Sets the header phase in polling mode
5417   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5418   *         the configuration information for CRYP module(Header & HeaderSize)
5419   * @param  Timeout Timeout value
5420   * @retval state
5421   */
CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5422 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5423 {
5424   uint32_t loopcounter;
5425   uint32_t size_in_bytes;
5426   uint32_t tmp;
5427   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
5428                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
5429                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU
5430                       }; /*  8-bit data type */
5431 
5432   /***************************** Header phase for GCM/GMAC or CCM *********************************/
5433   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
5434   {
5435     size_in_bytes = hcryp->Init.HeaderSize * 4U;
5436   }
5437   else
5438   {
5439     size_in_bytes = hcryp->Init.HeaderSize;
5440   }
5441 
5442   if ((size_in_bytes != 0U))
5443   {
5444     /* Select header phase */
5445     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
5446 
5447     /* Enable the CRYP peripheral */
5448     __HAL_CRYP_ENABLE(hcryp);
5449 
5450     /* If size_in_bytes is a multiple of blocks (a multiple of four 32-bits words ) */
5451     if ((size_in_bytes % 16U) == 0U)
5452     {
5453       /*  No padding */
5454       for (loopcounter = 0U; (loopcounter < (size_in_bytes / 4U)); loopcounter += 4U)
5455       {
5456         /* Write the input block in the data input register */
5457         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5458         hcryp->CrypHeaderCount++;
5459         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5460         hcryp->CrypHeaderCount++;
5461         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5462         hcryp->CrypHeaderCount++;
5463         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5464         hcryp->CrypHeaderCount++;
5465 
5466         if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
5467         {
5468           return HAL_ERROR;
5469         }
5470         /* Clear CCF flag */
5471         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5472       }
5473     }
5474     else
5475     {
5476       /* Write header block in the IN FIFO without last block */
5477       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 16U) * 4U)); loopcounter += 4U)
5478       {
5479         /* Write the input block in the data input register */
5480         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5481         hcryp->CrypHeaderCount++;
5482         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5483         hcryp->CrypHeaderCount++;
5484         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5485         hcryp->CrypHeaderCount++;
5486         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5487         hcryp->CrypHeaderCount++;
5488 
5489         if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
5490         {
5491           return HAL_ERROR;
5492         }
5493         /* Clear CCF flag */
5494         __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5495       }
5496       /* Write last complete words */
5497       for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 4U) % 4U)); loopcounter++)
5498       {
5499         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5500         hcryp->CrypHeaderCount++;
5501       }
5502       /* If the header size is a multiple of words */
5503       if ((size_in_bytes % 4U) == 0U)
5504       {
5505         /* Pad the data with zeros to have a complete block */
5506         while (loopcounter < 4U)
5507         {
5508           hcryp->Instance->DINR = 0x0U;
5509           loopcounter++;
5510         }
5511       }
5512       else
5513       {
5514         /* Enter last bytes, padded with zeros */
5515         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5516         tmp &= mask[(hcryp->Init.DataType * 2U) + (size_in_bytes % 4U)];
5517         hcryp->Instance->DINR = tmp;
5518         loopcounter++;
5519         /* Pad the data with zeros to have a complete block */
5520         while (loopcounter < 4U)
5521         {
5522           hcryp->Instance->DINR = 0x0U;
5523           loopcounter++;
5524         }
5525       }
5526 
5527       if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
5528       {
5529         return HAL_ERROR;
5530       }
5531       /* Clear CCF flag */
5532       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5533     }
5534   }
5535   else
5536   {
5537     /*Workaround 1: only AES, before re-enabling the peripheral, datatype can be configured.*/
5538     MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE, hcryp->Init.DataType);
5539 
5540     /* Select header phase */
5541     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
5542 
5543     /* Enable the CRYP peripheral */
5544     __HAL_CRYP_ENABLE(hcryp);
5545   }
5546 
5547   return HAL_OK;
5548 }
5549 
5550 /**
5551   * @brief  Sets the header phase when using DMA in process
5552   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5553   *         the configuration information for CRYP module(Header & HeaderSize)
5554   * @retval None
5555   */
CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef * hcryp)5556 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
5557 {
5558   uint32_t loopcounter;
5559   uint32_t headersize_in_bytes;
5560   uint32_t tmp;
5561   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
5562                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
5563                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU
5564                       }; /*  8-bit data type */
5565 
5566   /***************************** Header phase for GCM/GMAC or CCM *********************************/
5567   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
5568   {
5569     headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
5570   }
5571   else
5572   {
5573     headersize_in_bytes = hcryp->Init.HeaderSize;
5574   }
5575 
5576   /* Select header phase */
5577   CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
5578 
5579   /* Enable the CRYP peripheral */
5580   __HAL_CRYP_ENABLE(hcryp);
5581 
5582   /* Set the phase */
5583   hcryp->Phase = CRYP_PHASE_PROCESS;
5584 
5585   /* If header size is at least equal to 16 bytes, feed the header through DMA.
5586      If size_in_bytes is not a multiple of blocks (is not a multiple of four 32-bit words ),
5587      last bytes feeding and padding will be done in CRYP_DMAInCplt() */
5588   if (headersize_in_bytes >= 16U)
5589   {
5590     /* Initiate header DMA transfer */
5591     if (CRYP_SetHeaderDMAConfig(hcryp, (uint32_t)(hcryp->Init.Header),
5592                                 (uint16_t)((headersize_in_bytes / 16U) * 16U)) != HAL_OK)
5593     {
5594       return HAL_ERROR;
5595     }
5596   }
5597   else
5598   {
5599     if (headersize_in_bytes != 0U)
5600     {
5601       /* Header length is larger than 0 and strictly less than 16 bytes */
5602       /* Write last complete words */
5603       for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++)
5604       {
5605         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5606         hcryp->CrypHeaderCount++ ;
5607       }
5608       /* If the header size is a multiple of words */
5609       if ((headersize_in_bytes % 4U) == 0U)
5610       {
5611         /* Pad the data with zeros to have a complete block */
5612         while (loopcounter < 4U)
5613         {
5614           hcryp->Instance->DINR = 0x0U;
5615           loopcounter++;
5616         }
5617       }
5618       else
5619       {
5620         /* Enter last bytes, padded with zeros */
5621         tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5622         tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
5623         hcryp->Instance->DINR = tmp;
5624         loopcounter++;
5625         /* Pad the data with zeros to have a complete block */
5626         while (loopcounter < 4U)
5627         {
5628           hcryp->Instance->DINR = 0x0U;
5629           loopcounter++;
5630         }
5631       }
5632 
5633       if (CRYP_WaitOnCCFlag(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE) != HAL_OK)
5634       {
5635         /* Disable the CRYP peripheral clock */
5636         __HAL_CRYP_DISABLE(hcryp);
5637 
5638         /* Change state */
5639         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5640         hcryp->State = HAL_CRYP_STATE_READY;
5641 
5642         /* Process unlocked */
5643         __HAL_UNLOCK(hcryp);
5644         return HAL_ERROR;
5645       }
5646       /* Clear CCF flag */
5647       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5648     } /* if (headersize_in_bytes != 0U) */
5649 
5650     /* Move to payload phase if header length is null or
5651        if the header length was less than 16 and header written by software instead of DMA */
5652 
5653     /* Set to 0 the number of non-valid bytes using NPBLB register*/
5654     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
5655 
5656     /* Select payload phase once the header phase is performed */
5657     CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
5658 
5659     /* Initiate payload DMA IN and processed data DMA OUT transfers */
5660     if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK)
5661     {
5662       return HAL_ERROR;
5663     }
5664   } /* if (headersize_in_bytes >= 16U) */
5665 
5666   return HAL_OK;
5667 }
5668 
5669 /**
5670   * @brief  Sets the header phase in interrupt mode
5671   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5672   *         the configuration information for CRYP module(Header & HeaderSize)
5673   * @retval None
5674   */
CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef * hcryp)5675 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
5676 {
5677   uint32_t loopcounter;
5678   uint32_t lastwordsize;
5679   uint32_t npblb;
5680   uint32_t mode;
5681   uint32_t headersize_in_bytes;
5682   uint32_t tmp;
5683   uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U,  /* 32-bit data type */
5684                        0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU,  /* 16-bit data type */
5685                        0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU
5686                       }; /*  8-bit data type */
5687 
5688   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
5689   {
5690     headersize_in_bytes = hcryp->Init.HeaderSize * 4U;
5691   }
5692   else
5693   {
5694     headersize_in_bytes = hcryp->Init.HeaderSize;
5695   }
5696 
5697   /***************************** Header phase *********************************/
5698   /* Test whether or not the header phase is over.
5699      If the test below is true, move to payload phase */
5700   if (headersize_in_bytes <= ((uint32_t)(hcryp->CrypHeaderCount) * 4U))
5701   {
5702     /* Set the phase */
5703     hcryp->Phase = CRYP_PHASE_PROCESS;
5704     /* Select payload phase */
5705     MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
5706     /* Set to 0 the number of non-valid bytes using NPBLB register*/
5707     MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
5708 
5709     if (hcryp->Init.Algorithm == CRYP_AES_CCM)
5710     {
5711       /* Increment CrypHeaderCount to pass in CRYP_GCMCCM_SetPayloadPhase_IT */
5712       hcryp->CrypHeaderCount++;
5713     }
5714     /* Write the payload Input block in the IN FIFO */
5715     if (hcryp->Size == 0U)
5716     {
5717       /* Disable interrupts */
5718       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
5719 
5720       /* Change the CRYP state */
5721       hcryp->State = HAL_CRYP_STATE_READY;
5722       __HAL_UNLOCK(hcryp);
5723     }
5724     else if (hcryp->Size >= 16U)
5725     {
5726       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5727       hcryp->CrypInCount++;
5728       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5729       hcryp->CrypInCount++;
5730       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5731       hcryp->CrypInCount++;
5732       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5733       hcryp->CrypInCount++;
5734 
5735       if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
5736       {
5737         /* Call the input data transfer complete callback */
5738 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5739         /*Call registered Input complete callback*/
5740         hcryp->InCpltCallback(hcryp);
5741 #else
5742         /*Call legacy weak Input complete callback*/
5743         HAL_CRYP_InCpltCallback(hcryp);
5744 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5745       }
5746     }
5747     else /* Size < 4 words  : first block is the last block*/
5748     {
5749       /* Compute the number of padding bytes in last block of payload */
5750       npblb = 16U - ((uint32_t)hcryp->Size);
5751       mode = hcryp->Instance->CR & AES_CR_MODE;
5752       if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
5753           ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
5754       {
5755         /* Specify the number of non-valid bytes using NPBLB register*/
5756         MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
5757       }
5758 
5759       /* Number of valid words (lastwordsize) in last block */
5760       if ((npblb % 4U) == 0U)
5761       {
5762         lastwordsize = (16U - npblb) / 4U;
5763       }
5764       else
5765       {
5766         lastwordsize = ((16U - npblb) / 4U) + 1U;
5767       }
5768 
5769       /*  Last block optionally pad the data with zeros*/
5770       for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
5771       {
5772         hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5773         hcryp->CrypInCount++;
5774       }
5775       while (loopcounter < 4U)
5776       {
5777         /* Pad the data with zeros to have a complete block */
5778         hcryp->Instance->DINR = 0x0U;
5779         loopcounter++;
5780       }
5781       /* Call the input data transfer complete callback */
5782 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5783       /*Call registered Input complete callback*/
5784       hcryp->InCpltCallback(hcryp);
5785 #else
5786       /*Call legacy weak Input complete callback*/
5787       HAL_CRYP_InCpltCallback(hcryp);
5788 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5789     }
5790   }
5791   else if ((((headersize_in_bytes / 4U) - (hcryp->CrypHeaderCount)) >= 4U))
5792   {
5793     /* Can enter full 4 header words */
5794 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
5795     /* If suspension flag has been raised, suspend processing
5796        only if not already at the end of the header */
5797     if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
5798     {
5799       /* Clear CCF Flag */
5800       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5801 
5802       /* reset SuspendRequest */
5803       hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
5804       /* Disable Computation Complete Flag and Errors Interrupts */
5805       __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
5806       /* Change the CRYP state */
5807       hcryp->State = HAL_CRYP_STATE_SUSPENDED;
5808       /* Mark that the payload phase is suspended */
5809       hcryp->Phase = CRYP_PHASE_HEADER_SUSPENDED;
5810       __HAL_UNLOCK(hcryp);
5811     }
5812     else
5813 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
5814     {
5815       /* Write the input block in the IN FIFO */
5816       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5817       hcryp->CrypHeaderCount++;
5818       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5819       hcryp->CrypHeaderCount++;
5820       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5821       hcryp->CrypHeaderCount++;
5822       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5823       hcryp->CrypHeaderCount++;
5824     }
5825   }
5826   else /* Write last header block (4 words), padded with zeros if needed */
5827   {
5828 
5829     for (loopcounter = 0U; (loopcounter < ((headersize_in_bytes / 4U) % 4U)); loopcounter++)
5830     {
5831       hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5832       hcryp->CrypHeaderCount++ ;
5833     }
5834     /* If the header size is a multiple of words */
5835     if ((headersize_in_bytes % 4U) == 0U)
5836     {
5837       /* Pad the data with zeros to have a complete block */
5838       while (loopcounter < 4U)
5839       {
5840         hcryp->Instance->DINR = 0x0U;
5841         loopcounter++;
5842         hcryp->CrypHeaderCount++;
5843       }
5844     }
5845     else
5846     {
5847       /* Enter last bytes, padded with zeros */
5848       tmp =  *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5849       tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)];
5850       hcryp->Instance->DINR = tmp;
5851       loopcounter++;
5852       hcryp->CrypHeaderCount++;
5853       /* Pad the data with zeros to have a complete block */
5854       while (loopcounter < 4U)
5855       {
5856         hcryp->Instance->DINR = 0x0U;
5857         loopcounter++;
5858         hcryp->CrypHeaderCount++;
5859       }
5860     }
5861   }
5862 }
5863 
5864 /**
5865   * @brief  Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
5866   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5867   *         the configuration information for CRYP module.
5868   * @param  Timeout Timeout duration.
5869   * @note   This function can only be used in thread mode.
5870   * @retval HAL status
5871   */
CRYP_WaitOnCCFlag(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5872 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5873 {
5874   uint32_t tickstart;
5875 
5876   /* Get timeout */
5877   tickstart = HAL_GetTick();
5878 
5879   while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
5880   {
5881     /* Check for the Timeout */
5882     if (Timeout != HAL_MAX_DELAY)
5883     {
5884       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5885       {
5886         __HAL_CRYP_DISABLE(hcryp);
5887         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5888         hcryp->State = HAL_CRYP_STATE_READY;
5889         __HAL_UNLOCK(hcryp);
5890         return HAL_ERROR;
5891       }
5892     }
5893   }
5894   return HAL_OK;
5895 }
5896 
5897 /**
5898   * @brief  Wait for Computation Complete Flag (CCF) to raise then clear it.
5899   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5900   *         the configuration information for CRYP module.
5901   * @param  Timeout Timeout duration.
5902   * @note   This function can be used in thread or handler mode.
5903   * @retval HAL status
5904   */
CRYP_ClearCCFlagWhenHigh(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5905 static void CRYP_ClearCCFlagWhenHigh(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5906 {
5907   uint32_t count = Timeout;
5908 
5909   do
5910   {
5911     count-- ;
5912     if (count == 0U)
5913     {
5914       /* Disable the CRYP peripheral clock */
5915       __HAL_CRYP_DISABLE(hcryp);
5916 
5917       /* Change state */
5918       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5919 
5920       /* Process unlocked */
5921       __HAL_UNLOCK(hcryp);
5922       hcryp->State = HAL_CRYP_STATE_READY;
5923 
5924 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
5925       /*Call registered error callback*/
5926       hcryp->ErrorCallback(hcryp);
5927 #else
5928       /*Call legacy weak error callback*/
5929       HAL_CRYP_ErrorCallback(hcryp);
5930 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5931     }
5932   } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF));
5933 
5934   /* Clear CCF flag */
5935   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
5936 }
5937 
5938 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
5939 /**
5940   * @brief  In case of message processing suspension, read the Initialization Vector.
5941   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5942   *         the configuration information for CRYP module.
5943   * @param  Output Pointer to the buffer containing the saved Initialization Vector.
5944   * @note   This value has to be stored for reuse by writing the AES_IVRx registers
5945   *         as soon as the suspended processing has to be resumed.
5946   * @retval None
5947   */
CRYP_Read_IVRegisters(CRYP_HandleTypeDef * hcryp,const uint32_t * Output)5948 static void CRYP_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output)
5949 {
5950   uint32_t outputaddr = (uint32_t)Output;
5951 
5952   *(uint32_t *)(outputaddr) = hcryp->Instance->IVR3;
5953   outputaddr += 4U;
5954   *(uint32_t *)(outputaddr) = hcryp->Instance->IVR2;
5955   outputaddr += 4U;
5956   *(uint32_t *)(outputaddr) = hcryp->Instance->IVR1;
5957   outputaddr += 4U;
5958   *(uint32_t *)(outputaddr) = hcryp->Instance->IVR0;
5959 }
5960 
5961 /**
5962   * @brief  In case of message processing resumption, rewrite the Initialization
5963   *         Vector in the AES_IVRx registers.
5964   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5965   *         the configuration information for CRYP module.
5966   * @param  Input Pointer to the buffer containing the saved Initialization Vector to
5967   *         write back in the CRYP hardware block.
5968   * @note   AES must be disabled when reconfiguring the IV values.
5969   * @retval None
5970   */
CRYP_Write_IVRegisters(CRYP_HandleTypeDef * hcryp,const uint32_t * Input)5971 static void CRYP_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input)
5972 {
5973   uint32_t ivaddr = (uint32_t)Input;
5974 
5975   hcryp->Instance->IVR3 = *(uint32_t *)(ivaddr);
5976   ivaddr += 4U;
5977   hcryp->Instance->IVR2 = *(uint32_t *)(ivaddr);
5978   ivaddr += 4U;
5979   hcryp->Instance->IVR1 = *(uint32_t *)(ivaddr);
5980   ivaddr += 4U;
5981   hcryp->Instance->IVR0 = *(uint32_t *)(ivaddr);
5982 }
5983 
5984 /**
5985   * @brief  In case of message GCM/GMAC/CCM processing suspension,
5986   *         read the Suspend Registers.
5987   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
5988   *         the configuration information for CRYP module.
5989   * @param  Output Pointer to the buffer containing the saved Suspend Registers.
5990   * @note   These values have to be stored for reuse by writing back the AES_SUSPxR registers
5991   *         as soon as the suspended processing has to be resumed.
5992   * @retval None
5993   */
CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef * hcryp,const uint32_t * Output)5994 static void CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output)
5995 {
5996   uint32_t outputaddr = (uint32_t)Output;
5997   uint32_t count = 0U;
5998 
5999   /* In case of GCM payload phase encryption, check that suspension can be carried out */
6000   if (READ_BIT(hcryp->Instance->CR, (AES_CR_CHMOD | AES_CR_GCMPH | AES_CR_MODE)) == (CRYP_AES_GCM_GMAC |
6001       AES_CR_GCMPH_1 | 0x0))
6002   {
6003 
6004     /* Wait for BUSY flag to be cleared */
6005     count = 0xFFF;
6006     do
6007     {
6008       count--;
6009       if (count == 0U)
6010       {
6011         /* Change state */
6012         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
6013         hcryp->State = HAL_CRYP_STATE_READY;
6014         __HAL_UNLOCK(hcryp);
6015         HAL_CRYP_ErrorCallback(hcryp);
6016         return;
6017       }
6018     } while (HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY));
6019 
6020   }
6021 
6022   *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP7R;
6023   outputaddr += 4U;
6024   *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP6R;
6025   outputaddr += 4U;
6026   *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP5R;
6027   outputaddr += 4U;
6028   *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP4R;
6029   outputaddr += 4U;
6030   *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP3R;
6031   outputaddr += 4U;
6032   *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP2R;
6033   outputaddr += 4U;
6034   *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP1R;
6035   outputaddr += 4U;
6036   *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP0R;
6037 }
6038 
6039 /**
6040   * @brief  In case of message GCM/GMAC/CCM processing resumption, rewrite the Suspend
6041   *         Registers in the AES_SUSPxR registers.
6042   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
6043   *         the configuration information for CRYP module.
6044   * @param  Input Pointer to the buffer containing the saved suspend registers to
6045   *         write back in the CRYP hardware block.
6046   * @note   AES must be disabled when reconfiguring the suspend registers.
6047   * @retval None
6048   */
CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef * hcryp,const uint32_t * Input)6049 static void CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input)
6050 {
6051   uint32_t ivaddr = (uint32_t)Input;
6052 
6053   hcryp->Instance->SUSP7R = *(uint32_t *)(ivaddr);
6054   ivaddr += 4U;
6055   hcryp->Instance->SUSP6R = *(uint32_t *)(ivaddr);
6056   ivaddr += 4U;
6057   hcryp->Instance->SUSP5R = *(uint32_t *)(ivaddr);
6058   ivaddr += 4U;
6059   hcryp->Instance->SUSP4R = *(uint32_t *)(ivaddr);
6060   ivaddr += 4U;
6061   hcryp->Instance->SUSP3R = *(uint32_t *)(ivaddr);
6062   ivaddr += 4U;
6063   hcryp->Instance->SUSP2R = *(uint32_t *)(ivaddr);
6064   ivaddr += 4U;
6065   hcryp->Instance->SUSP1R = *(uint32_t *)(ivaddr);
6066   ivaddr += 4U;
6067   hcryp->Instance->SUSP0R = *(uint32_t *)(ivaddr);
6068 }
6069 
6070 /**
6071   * @brief  In case of message GCM/GMAC/CCM processing suspension, read the Key Registers.
6072   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
6073   *         the configuration information for CRYP module.
6074   * @param  Output Pointer to the buffer containing the saved Key Registers.
6075   * @param  KeySize Indicates the key size (128 or 256 bits).
6076   * @note   These values have to be stored for reuse by writing back the AES_KEYRx registers
6077   *         as soon as the suspended processing has to be resumed.
6078   * @retval None
6079   */
CRYP_Read_KeyRegisters(CRYP_HandleTypeDef * hcryp,const uint32_t * Output,uint32_t KeySize)6080 static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output, uint32_t KeySize)
6081 {
6082   uint32_t keyaddr = (uint32_t)Output;
6083 
6084   switch (KeySize)
6085   {
6086     case CRYP_KEYSIZE_256B:
6087       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey);
6088       keyaddr += 4U;
6089       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 1U);
6090       keyaddr += 4U;
6091       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 2U);
6092       keyaddr += 4U;
6093       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 3U);
6094       keyaddr += 4U;
6095       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 4U);
6096       keyaddr += 4U;
6097       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 5U);
6098       keyaddr += 4U;
6099       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 6U);
6100       keyaddr += 4U;
6101       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 7U);
6102       break;
6103     case CRYP_KEYSIZE_128B:
6104       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey);
6105       keyaddr += 4U;
6106       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 1U);
6107       keyaddr += 4U;
6108       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 2U);
6109       keyaddr += 4U;
6110       *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 3U);
6111       break;
6112     default:
6113       break;
6114   }
6115 }
6116 
6117 /**
6118   * @brief  In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key
6119   *         Registers in the AES_KEYRx registers.
6120   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
6121   *         the configuration information for CRYP module.
6122   * @param  Input Pointer to the buffer containing the saved key registers to
6123   *         write back in the CRYP hardware block.
6124   * @param  KeySize Indicates the key size (128 or 256 bits)
6125   * @note   AES must be disabled when reconfiguring the Key registers.
6126   * @retval None
6127   */
CRYP_Write_KeyRegisters(CRYP_HandleTypeDef * hcryp,const uint32_t * Input,uint32_t KeySize)6128 static void CRYP_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input, uint32_t KeySize)
6129 {
6130   uint32_t keyaddr = (uint32_t)Input;
6131 
6132   if (KeySize == CRYP_KEYSIZE_256B)
6133   {
6134     hcryp->Instance->KEYR7 = *(uint32_t *)(keyaddr);
6135     keyaddr += 4U;
6136     hcryp->Instance->KEYR6 = *(uint32_t *)(keyaddr);
6137     keyaddr += 4U;
6138     hcryp->Instance->KEYR5 = *(uint32_t *)(keyaddr);
6139     keyaddr += 4U;
6140     hcryp->Instance->KEYR4 = *(uint32_t *)(keyaddr);
6141     keyaddr += 4U;
6142   }
6143 
6144   hcryp->Instance->KEYR3 = *(uint32_t *)(keyaddr);
6145   keyaddr += 4U;
6146   hcryp->Instance->KEYR2 = *(uint32_t *)(keyaddr);
6147   keyaddr += 4U;
6148   hcryp->Instance->KEYR1 = *(uint32_t *)(keyaddr);
6149   keyaddr += 4U;
6150   hcryp->Instance->KEYR0 = *(uint32_t *)(keyaddr);
6151 }
6152 
6153 /**
6154   * @brief  Authentication phase resumption in case of GCM/GMAC/CCM process in interrupt mode
6155   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
6156   *         the configuration information for CRYP module(Header & HeaderSize)
6157   * @retval None
6158   */
CRYP_PhaseProcessingResume(CRYP_HandleTypeDef * hcryp)6159 static void CRYP_PhaseProcessingResume(CRYP_HandleTypeDef *hcryp)
6160 {
6161   uint32_t loopcounter;
6162   uint16_t lastwordsize;
6163   uint16_t npblb;
6164   uint32_t cr_temp;
6165 
6166   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_RWEIF | CRYP_CLEAR_CCF);
6167 
6168   /* Enable computation complete flag and error interrupts */
6169   __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
6170 
6171   /* Enable the CRYP peripheral */
6172   __HAL_CRYP_ENABLE(hcryp);
6173 
6174   /* Case of header phase resumption =================================================*/
6175   if (hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED)
6176   {
6177     /* Set the phase */
6178     hcryp->Phase = CRYP_PHASE_PROCESS;
6179 
6180     /* Select header phase */
6181     CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
6182 
6183     if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount) >= 4U))
6184     {
6185       /* Write the input block in the IN FIFO */
6186       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
6187       hcryp->CrypHeaderCount++;
6188       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
6189       hcryp->CrypHeaderCount++;
6190       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
6191       hcryp->CrypHeaderCount++;
6192       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
6193       hcryp->CrypHeaderCount++;
6194     }
6195     else /*HeaderSize < 4 or HeaderSize >4 & HeaderSize %4 != 0*/
6196     {
6197       /*  Last block optionally pad the data with zeros*/
6198       for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
6199       {
6200         hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
6201         hcryp->CrypHeaderCount++;
6202       }
6203       while (loopcounter < 4U)
6204       {
6205         /* pad the data with zeros to have a complete block */
6206         hcryp->Instance->DINR = 0x0U;
6207         loopcounter++;
6208       }
6209     }
6210   }
6211   /* Case of payload phase resumption =================================================*/
6212   else
6213   {
6214     if (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED)
6215     {
6216 
6217       /* Set the phase */
6218       hcryp->Phase = CRYP_PHASE_PROCESS;
6219 
6220       /* Select payload phase once the header phase is performed */
6221       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
6222 
6223       /* Set to 0 the number of non-valid bytes using NPBLB register*/
6224       MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
6225 
6226       if (((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U)
6227       {
6228         /* Write the input block in the IN FIFO */
6229         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
6230         hcryp->CrypInCount++;
6231         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
6232         hcryp->CrypInCount++;
6233         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
6234         hcryp->CrypInCount++;
6235         hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
6236         hcryp->CrypInCount++;
6237         if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
6238         {
6239           /* Call input transfer complete callback */
6240 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
6241           /*Call registered Input complete callback*/
6242           hcryp->InCpltCallback(hcryp);
6243 #else
6244           /*Call legacy weak Input complete callback*/
6245           HAL_CRYP_InCpltCallback(hcryp);
6246 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
6247         }
6248       }
6249       else /* Last block of payload < 128bit*/
6250       {
6251         /* Compute the number of padding bytes in last block of payload */
6252         npblb = (((hcryp->Size / 16U) + 1U) * 16U) - (hcryp->Size);
6253         cr_temp = hcryp->Instance->CR;
6254         if ((((cr_temp & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
6255             (((cr_temp & AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
6256         {
6257           /* Specify the number of non-valid bytes using NPBLB register*/
6258           MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, ((uint32_t)npblb) << 20U);
6259         }
6260 
6261         /* Number of valid words (lastwordsize) in last block */
6262         if ((npblb % 4U) == 0U)
6263         {
6264           lastwordsize = (16U - npblb) / 4U;
6265         }
6266         else
6267         {
6268           lastwordsize = ((16U - npblb) / 4U) + 1U;
6269         }
6270 
6271         /*  Last block optionally pad the data with zeros*/
6272         for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
6273         {
6274           hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
6275           hcryp->CrypInCount++;
6276         }
6277         while (loopcounter < 4U)
6278         {
6279           /* pad the data with zeros to have a complete block */
6280           hcryp->Instance->DINR = 0x0U;
6281           loopcounter++;
6282         }
6283       }
6284     }
6285   }
6286 }
6287 #endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */
6288 /**
6289   * @}
6290   */
6291 
6292 
6293 #endif /* HAL_CRYP_MODULE_ENABLED */
6294 
6295 #endif /* AES */
6296 /**
6297   * @}
6298   */
6299 
6300 /**
6301   * @}
6302   */
6303