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