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