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