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