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