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