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