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