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