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