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