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