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