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