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