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