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