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