Merge pull request #11494 from haslinghuis/dshot_gpio
[betaflight.git] / lib / main / STM32G4 / Drivers / STM32G4xx_HAL_Driver / Src / stm32g4xx_hal_cryp.c
blobeb2ac5b5b1abe16b566d994ef755b33b29aa8276
1 /**
2 ******************************************************************************
3 * @file stm32g4xx_hal_cryp.c
4 * @author MCD Application Team
5 * @brief CRYP HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Cryptography (CRYP) peripheral:
8 * + Initialization, de-initialization, set config and get config functions
9 * + DES/TDES, AES processing functions
10 * + DMA callback functions
11 * + CRYP IRQ handler management
12 * + Peripheral State functions
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
19 The CRYP HAL driver can be used in CRYP or TinyAES peripheral as follows:
21 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
22 (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()or __HAL_RCC_AES_CLK_ENABLE for TinyAES peripheral
23 (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
24 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
25 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
26 (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
27 (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
28 (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
29 (+++) Configure and enable two DMA streams one for managing data transfer from
30 memory to peripheral (input stream) and another stream for managing data
31 transfer from peripheral to memory (output stream)
32 (+++) Associate the initialized DMA handle to the CRYP DMA handle
33 using __HAL_LINKDMA()
34 (+++) Configure the priority and enable the NVIC for the transfer complete
35 interrupt on the two DMA Streams. The output stream should have higher
36 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
38 (#)Initialize the CRYP according to the specified parameters :
39 (##) The data type: 1-bit, 8-bit, 16-bit or 32-bit.
40 (##) The key size: 128, 192 or 256.
41 (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM.
42 (##) The initialization vector (counter). It is not used in ECB mode.
43 (##) The key buffer used for encryption/decryption.
44 (+++) In some specific configurations, the key is written by the application
45 code out of the HAL scope. In that case, user can still resort to the
46 HAL APIs as usual but must make sure that pKey pointer is set to NULL.
47 (##) The Header used only in AES GCM and CCM Algorithm for authentication.
48 (##) The HeaderSize The size of header buffer in word.
49 (##) The B0 block is the first authentication block used only in AES CCM mode.
51 (#)Three processing (encryption/decryption) functions are available:
52 (##) Polling mode: encryption and decryption APIs are blocking functions
53 i.e. they process the data and wait till the processing is finished,
54 e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
55 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
56 i.e. they process the data under interrupt,
57 e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
58 (##) DMA mode: encryption and decryption APIs are not blocking functions
59 i.e. the data transfer is ensured by DMA,
60 e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
62 (#)When the processing function is called at first time after HAL_CRYP_Init()
63 the CRYP peripheral is configured and processes the buffer in input.
64 At second call, no need to Initialize the CRYP, user have to get current configuration via
65 HAL_CRYP_GetConfig() API, then only HAL_CRYP_SetConfig() is requested to set
66 new parametres, finally user can start encryption/decryption.
68 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
70 (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
71 without having to configure again the Key or the Initialization Vector between each API call,
72 the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
73 Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
74 or HAL_CRYP_Decrypt_DMA().
76 [..]
77 The cryptographic processor supports following standards:
78 (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 peripheral:
79 (##)64-bit data block processing
80 (##) chaining modes supported :
81 (+++) Electronic Code Book(ECB)
82 (+++) Cipher Block Chaining (CBC)
83 (##) keys length supported :64-bit, 128-bit and 192-bit.
84 (#) The advanced encryption standard (AES) supported by CRYP1 & TinyAES peripheral:
85 (##)128-bit data block processing
86 (##) chaining modes supported :
87 (+++) Electronic Code Book(ECB)
88 (+++) Cipher Block Chaining (CBC)
89 (+++) Counter mode (CTR)
90 (+++) Galois/counter mode (GCM/GMAC)
91 (+++) Counter with Cipher Block Chaining-Message(CCM)
92 (##) keys length Supported :
93 (+++) for CRYP1 peripheral: 128-bit, 192-bit and 256-bit.
94 (+++) for TinyAES peripheral: 128-bit and 256-bit
96 [..]
97 (@) Specific care must be taken to format the key and the Initialization Vector IV!
99 [..] If the key is defined as a 128-bit long array key[127..0] = {b127 ... b0} where
100 b127 is the MSB and b0 the LSB, the key must be stored in MCU memory
101 (+) as a sequence of words where the MSB word comes first (occupies the
102 lowest memory address)
103 (++) address n+0 : 0b b127 .. b120 b119 .. b112 b111 .. b104 b103 .. b96
104 (++) address n+4 : 0b b95 .. b88 b87 .. b80 b79 .. b72 b71 .. b64
105 (++) address n+8 : 0b b63 .. b56 b55 .. b48 b47 .. b40 b39 .. b32
106 (++) address n+C : 0b b31 .. b24 b23 .. b16 b15 .. b8 b7 .. b0
107 [..] Hereafter, another illustration when considering a 128-bit long key made of 16 bytes {B15..B0}.
108 The 4 32-bit words that make the key must be stored as follows in MCU memory:
109 (+) address n+0 : 0x B15 B14 B13 B12
110 (+) address n+4 : 0x B11 B10 B9 B8
111 (+) address n+8 : 0x B7 B6 B5 B4
112 (+) address n+C : 0x B3 B2 B1 B0
113 [..] which leads to the expected setting
114 (+) AES_KEYR3 = 0x B15 B14 B13 B12
115 (+) AES_KEYR2 = 0x B11 B10 B9 B8
116 (+) AES_KEYR1 = 0x B7 B6 B5 B4
117 (+) AES_KEYR0 = 0x B3 B2 B1 B0
119 [..] Same format must be applied for a 256-bit long key made of 32 bytes {B31..B0}.
120 The 8 32-bit words that make the key must be stored as follows in MCU memory:
121 (+) address n+00 : 0x B31 B30 B29 B28
122 (+) address n+04 : 0x B27 B26 B25 B24
123 (+) address n+08 : 0x B23 B22 B21 B20
124 (+) address n+0C : 0x B19 B18 B17 B16
125 (+) address n+10 : 0x B15 B14 B13 B12
126 (+) address n+14 : 0x B11 B10 B9 B8
127 (+) address n+18 : 0x B7 B6 B5 B4
128 (+) address n+1C : 0x B3 B2 B1 B0
129 [..] which leads to the expected setting
130 (+) AES_KEYR7 = 0x B31 B30 B29 B28
131 (+) AES_KEYR6 = 0x B27 B26 B25 B24
132 (+) AES_KEYR5 = 0x B23 B22 B21 B20
133 (+) AES_KEYR4 = 0x B19 B18 B17 B16
134 (+) AES_KEYR3 = 0x B15 B14 B13 B12
135 (+) AES_KEYR2 = 0x B11 B10 B9 B8
136 (+) AES_KEYR1 = 0x B7 B6 B5 B4
137 (+) AES_KEYR0 = 0x B3 B2 B1 B0
139 [..] Initialization Vector IV (4 32-bit words) format must follow the same as
140 that of a 128-bit long key.
142 [..] Note that key and IV registers are not sensitive to swap mode selection.
144 [..] This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 and TinyAES peripherals:
145 (#) Algorithm supported :
146 (##) Galois/counter mode (GCM)
147 (##) Galois message authentication code (GMAC) :is exactly the same as
148 GCM algorithm composed only by an header.
149 (#) Four phases are performed in GCM :
150 (##) Init phase: peripheral prepares the GCM hash subkey (H) and do the IV processing
151 (##) Header phase: peripheral processes the Additional Authenticated Data (AAD), with hash
152 computation only.
153 (##) Payload phase: peripheral processes the plaintext (P) with hash computation + keystream
154 encryption + data XORing. It works in a similar way for ciphertext (C).
155 (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data.
156 (#) structure of message construction in GCM is defined as below :
157 (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
160 +-------------------------------------------------------+
161 | Initialization vector (IV) | Counter |
162 |----------------|----------------|-----------|---------|
163 127 95 63 31 0
166 Bit Number Register Contents
167 ---------- --------------- -----------
168 127 ...96 CRYP_IV1R[31:0] ICB[127:96]
169 95 ...64 CRYP_IV1L[31:0] B0[95:64]
170 63 ... 32 CRYP_IV0R[31:0] ICB[63:32]
171 31 ... 0 CRYP_IV0L[31:0] ICB[31:0], where 32-bit counter= 0x2
175 (##) The authenticated header A (also knows as Additional Authentication Data AAD)
176 this part of the message is only authenticated, not encrypted.
177 (##) The plaintext message P is both authenticated and encrypted as ciphertext.
178 GCM standard specifies that ciphertext has same bit length as the plaintext.
179 (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
180 (on 64 bits)
181 GCM last block definition
182 +-------------------------------------------------------------------+
183 | Bit[0] | Bit[32] | Bit[64] | Bit[96] |
184 |-----------|--------------------|-----------|----------------------|
185 | 0x0 | Header length[31:0]| 0x0 | Payload length[31:0] |
186 |-----------|--------------------|-----------|----------------------|
188 [..] This section describe The AES Counter with Cipher Block Chaining-Message
189 Authentication Code (CCM) supported by both CRYP1 and TinyAES peripheral:
190 (#) Specific parameters for CCM :
192 (##) B0 block : According to NIST Special Publication 800-38C,
193 The first block B0 is formatted as follows, where l(m) is encoded in
194 most-significant-byte first order:
196 Octet Number Contents
197 ------------ ---------
198 0 Flags
199 1 ... 15-q Nonce N
200 16-q ... 15 Q
202 the Flags field is formatted as follows:
204 Bit Number Contents
205 ---------- ----------------------
206 7 Reserved (always zero)
207 6 Adata
208 5 ... 3 (t-2)/2
209 2 ... 0 [q-1]3
211 - Q: a bit string representation of the octet length of P (plaintext)
212 - q The octet length of the binary representation of the octet length of the payload
213 - A nonce (N), n The octet length of the where n+q=15.
214 - Flags: most significant octet containing four flags for control information,
215 - t The octet length of the MAC.
216 (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
217 the associated data length expressed in bytes (a) defined as below:
218 - If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
219 - If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
220 - If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
221 (##) CTRx block : control blocks
222 - Generation of CTR1 from first block B0 information :
223 equal to B0 with first 5 bits zeroed and most significant bits storing octet
224 length of P also zeroed, then incremented by one
226 Bit Number Register Contents
227 ---------- --------------- -----------
228 127 ...96 CRYP_IV1R[31:0] B0[127:96], where Q length bits are set to 0, except for
229 bit 0 that is set to 1
230 95 ...64 CRYP_IV1L[31:0] B0[95:64]
231 63 ... 32 CRYP_IV0R[31:0] B0[63:32]
232 31 ... 0 CRYP_IV0L[31:0] B0[31:0], where flag bits set to 0
234 - Generation of CTR0: same as CTR1 with bit[0] set to zero.
236 (#) Four phases are performed in CCM for CRYP1 peripheral:
237 (##) Init phase: peripheral prepares the GCM hash subkey (H) and do the IV processing
238 (##) Header phase: peripheral processes the Additional Authenticated Data (AAD), with hash
239 computation only.
240 (##) Payload phase: peripheral processes the plaintext (P) with hash computation + keystream
241 encryption + data XORing. It works in a similar way for ciphertext (C).
242 (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data.
243 (#) CCM in TinyAES peripheral:
244 (##) To perform message payload encryption or decryption AES is configured in CTR mode.
245 (##) For authentication two phases are performed :
246 - Header phase: peripheral processes the Additional Authenticated Data (AAD) first, then the cleartext message
247 only cleartext payload (not the ciphertext payload) is used and no outpout.
248 (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data.
250 *** Callback registration ***
251 =============================================
253 The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
254 allows the user to configure dynamically the driver callbacks.
255 Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
256 to register an interrupt callback.
258 Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
259 (+) InCpltCallback : Input FIFO transfer completed callback.
260 (+) OutCpltCallback : Output FIFO transfer completed callback.
261 (+) ErrorCallback : callback for error detection.
262 (+) MspInitCallback : CRYP MspInit.
263 (+) MspDeInitCallback : CRYP MspDeInit.
264 This function takes as parameters the HAL peripheral handle, the Callback ID
265 and a pointer to the user callback function.
267 Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
268 weak function.
269 @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
270 and the Callback ID.
271 This function allows to reset following callbacks:
272 (+) InCpltCallback : Input FIFO transfer completed callback.
273 (+) OutCpltCallback : Output FIFO transfer completed callback.
274 (+) ErrorCallback : callback for error detection.
275 (+) MspInitCallback : CRYP MspInit.
276 (+) MspDeInitCallback : CRYP MspDeInit.
278 By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
279 all callbacks are set to the corresponding weak functions :
280 examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
281 Exception done for MspInit and MspDeInit functions that are
282 reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
283 these callbacks are null (not registered beforehand).
284 if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
285 keep and use the user MspInit/MspDeInit functions (registered beforehand)
287 Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
288 Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
289 in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
290 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
291 In that case first register the MspInit/MspDeInit user callbacks
292 using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
293 or @ref HAL_CRYP_Init() function.
295 When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
296 not defined, the callback registration feature is not available and all callbacks
297 are set to the corresponding weak functions.
300 *** Suspend/Resume feature ***
301 =============================================
303 The compilation define USE_HAL_CRYP_SUSPEND_RESUME when set to 1
304 allows the user to resort to the suspend/resume feature.
305 A low priority block processing can be suspended to process a high priority block
306 instead. When the high priority block processing is over, the low priority block
307 processing can be resumed, restarting from the point where it was suspended. This
308 feature is applicable only in non-blocking interrupt mode.
310 [..] User must resort to HAL_CRYP_Suspend() to suspend the low priority block
311 processing. This API manages the hardware block processing suspension and saves all the
312 internal data that will be needed to restart later on. Upon HAL_CRYP_Suspend() completion,
313 the user can launch the processing of any other block (high priority block processing).
315 [..] When the high priority block processing is over, user must invoke HAL_CRYP_Resume()
316 to resume the low priority block processing. Ciphering (or deciphering) restarts from
317 the suspension point and ends as usual.
319 [..] HAL_CRYP_Suspend() reports an error when the suspension request is sent too late
320 (i.e when the low priority block processing is about to end). There is no use to
321 suspend the tag generation processing for authentication algorithms.
323 [..]
324 (@) If the key is written out of HAL scope (case pKey pointer set to NULL by the user),
325 the block processing suspension/resumption mechanism is NOT applicable.
327 [..]
328 (@) If the Key and Initialization Vector are configured only once and configuration is
329 skipped for consecutive processings (case KeyIVConfigSkip set to CRYP_KEYIVCONFIG_ONCE),
330 the block processing suspension/resumption mechanism is NOT applicable.
332 @endverbatim
333 ******************************************************************************
334 * @attention
336 * <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
337 * All rights reserved.</center></h2>
339 * This software component is licensed by ST under BSD 3-Clause license,
340 * the "License"; You may not use this file except in compliance with the
341 * License. You may obtain a copy of the License at:
342 * opensource.org/licenses/BSD-3-Clause
344 ******************************************************************************
347 /* Includes ------------------------------------------------------------------*/
348 #include "stm32g4xx_hal.h"
350 /** @addtogroup STM32G4xx_HAL_Driver
351 * @{
354 /** @addtogroup CRYP
355 * @{
358 #if defined(AES)
359 #ifdef HAL_CRYP_MODULE_ENABLED
361 /* Private typedef -----------------------------------------------------------*/
362 /* Private define ------------------------------------------------------------*/
363 /** @addtogroup CRYP_Private_Defines
364 * @{
366 #define CRYP_TIMEOUT_KEYPREPARATION 82U /* The latency of key preparation operation is 82 clock cycles.*/
367 #define CRYP_TIMEOUT_GCMCCMINITPHASE 299U /* The latency of GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
368 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE 290U /* The latency of GCM/CCM header phase is 290 clock cycles.*/
370 #define CRYP_PHASE_READY 0x00000001U /*!< CRYP peripheral is ready for initialization. */
371 #define CRYP_PHASE_PROCESS 0x00000002U /*!< CRYP peripheral is in processing phase */
372 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
373 #define CRYP_PHASE_HEADER_SUSPENDED 0x00000004U /*!< GCM/GMAC/CCM header phase is suspended */
374 #define CRYP_PHASE_PAYLOAD_SUSPENDED 0x00000005U /*!< GCM/CCM payload phase is suspended */
375 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
377 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode(Mode 1) */
378 #define CRYP_OPERATINGMODE_KEYDERIVATION AES_CR_MODE_0 /*!< Key derivation mode only used when performing ECB and CBC decryptions (Mode 2) */
379 #define CRYP_OPERATINGMODE_DECRYPT AES_CR_MODE_1 /*!< Decryption (Mode 3) */
380 #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT AES_CR_MODE /*!< Key derivation and decryption only used when performing ECB and CBC decryptions (Mode 4) */
381 #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
382 #define CRYP_PHASE_HEADER AES_CR_GCMPH_0 /*!< GCM/GMAC or CCM header phase */
383 #define CRYP_PHASE_PAYLOAD AES_CR_GCMPH_1 /*!< GCM(/CCM) payload phase */
384 #define CRYP_PHASE_FINAL AES_CR_GCMPH /*!< GCM/GMAC or CCM final phase */
386 /* CTR1 information to use in CCM algorithm */
387 #define CRYP_CCM_CTR1_0 0x07FFFFFFU
388 #define CRYP_CCM_CTR1_1 0xFFFFFF00U
389 #define CRYP_CCM_CTR1_2 0x00000001U
392 * @}
395 /* Private macro -------------------------------------------------------------*/
396 /** @addtogroup CRYP_Private_Macros
397 * @{
400 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__) do{(__HANDLE__)->Instance->CR &= (uint32_t)(~AES_CR_GCMPH);\
401 (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
402 }while(0U)
405 * @}
408 /* Private struct -------------------------------------------------------------*/
409 /* Private variables ---------------------------------------------------------*/
410 /* Private function prototypes -----------------------------------------------*/
411 /** @addtogroup CRYP_Private_Functions
412 * @{
415 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
416 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
417 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
418 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
419 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
420 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
421 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
422 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
423 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
424 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
425 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
426 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
427 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
428 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
429 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
430 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
431 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
432 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
433 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
434 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
435 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
436 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
437 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
438 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
439 static void CRYP_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output);
440 static void CRYP_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input);
441 static void CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output);
442 static void CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input);
443 static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output, uint32_t KeySize);
444 static void CRYP_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input, uint32_t KeySize);
445 static void CRYP_PhaseProcessingResume(CRYP_HandleTypeDef *hcryp);
446 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
450 * @}
453 /* Exported functions ---------------------------------------------------------*/
455 /** @addtogroup CRYP_Exported_Functions
456 * @{
459 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
460 * @brief Initialization and Configuration functions.
462 @verbatim
463 ========================================================================================
464 ##### Initialization, de-initialization and Set and Get configuration functions #####
465 ========================================================================================
466 [..] This section provides functions allowing to:
467 (+) Initialize the CRYP
468 (+) DeInitialize the CRYP
469 (+) Initialize the CRYP MSP
470 (+) DeInitialize the CRYP MSP
471 (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
472 Parameters which are configured in This section are :
473 (+) Key size
474 (+) Data Type : 32,16, 8 or 1bit
475 (+) AlgoMode :
476 - for CRYP1 peripheral :
477 ECB and CBC in DES/TDES Standard
478 ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
479 - for TinyAES2 peripheral, only ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard are supported.
480 (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
482 @endverbatim
483 * @{
487 * @brief Initializes the CRYP according to the specified
488 * parameters in the CRYP_ConfigTypeDef and creates the associated handle.
489 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
490 * the configuration information for CRYP module
491 * @retval HAL status
493 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
495 /* Check the CRYP handle allocation */
496 if (hcryp == NULL)
498 return HAL_ERROR;
501 /* Check parameters */
502 assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
503 assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
504 assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
505 assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
507 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
508 if (hcryp->State == HAL_CRYP_STATE_RESET)
510 /* Allocate lock resource and initialize it */
511 hcryp->Lock = HAL_UNLOCKED;
513 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
514 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
515 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
517 if (hcryp->MspInitCallback == NULL)
519 hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit */
522 /* Init the low level hardware */
523 hcryp->MspInitCallback(hcryp);
525 #else
526 if (hcryp->State == HAL_CRYP_STATE_RESET)
528 /* Allocate lock resource and initialize it */
529 hcryp->Lock = HAL_UNLOCKED;
531 /* Init the low level hardware */
532 HAL_CRYP_MspInit(hcryp);
534 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
536 /* Set the key size (This bit field is do not care in the DES or TDES modes), data type and Algorithm */
537 MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD, hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
539 /* Reset Error Code field */
540 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
542 /* Reset peripheral Key and IV configuration flag */
543 hcryp->KeyIVConfig = 0U;
545 /* Change the CRYP state */
546 hcryp->State = HAL_CRYP_STATE_READY;
548 /* Set the default CRYP phase */
549 hcryp->Phase = CRYP_PHASE_READY;
551 /* Return function status */
552 return HAL_OK;
556 * @brief De-Initializes the CRYP peripheral.
557 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
558 * the configuration information for CRYP module
559 * @retval HAL status
561 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
563 /* Check the CRYP handle allocation */
564 if (hcryp == NULL)
566 return HAL_ERROR;
569 /* Set the default CRYP phase */
570 hcryp->Phase = CRYP_PHASE_READY;
572 /* Reset CrypInCount and CrypOutCount */
573 hcryp->CrypInCount = 0;
574 hcryp->CrypOutCount = 0;
575 hcryp->CrypHeaderCount = 0;
577 /* Disable the CRYP peripheral clock */
578 __HAL_CRYP_DISABLE(hcryp);
580 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
582 if (hcryp->MspDeInitCallback == NULL)
584 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit */
586 /* DeInit the low level hardware */
587 hcryp->MspDeInitCallback(hcryp);
589 #else
591 /* DeInit the low level hardware: CLOCK, NVIC.*/
592 HAL_CRYP_MspDeInit(hcryp);
594 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
596 /* Change the CRYP state */
597 hcryp->State = HAL_CRYP_STATE_RESET;
599 /* Release Lock */
600 __HAL_UNLOCK(hcryp);
602 /* Return function status */
603 return HAL_OK;
607 * @brief Configure the CRYP according to the specified
608 * parameters in the CRYP_ConfigTypeDef
609 * @param hcryp pointer to a CRYP_HandleTypeDef structure
610 * @param pConf pointer to a CRYP_ConfigTypeDef structure that contains
611 * the configuration information for CRYP module
612 * @retval HAL status
614 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
616 /* Check the CRYP handle allocation */
617 if ((hcryp == NULL) || (pConf == NULL))
619 return HAL_ERROR;
622 /* Check parameters */
623 assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
624 assert_param(IS_CRYP_DATATYPE(pConf->DataType));
625 assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
627 if (hcryp->State == HAL_CRYP_STATE_READY)
629 /* Change the CRYP state */
630 hcryp->State = HAL_CRYP_STATE_BUSY;
632 /* Process locked */
633 __HAL_LOCK(hcryp);
635 /* Set CRYP parameters */
636 hcryp->Init.DataType = pConf->DataType;
637 hcryp->Init.pKey = pConf->pKey;
638 hcryp->Init.Algorithm = pConf->Algorithm;
639 hcryp->Init.KeySize = pConf->KeySize;
640 hcryp->Init.pInitVect = pConf->pInitVect;
641 hcryp->Init.Header = pConf->Header;
642 hcryp->Init.HeaderSize = pConf->HeaderSize;
643 hcryp->Init.B0 = pConf->B0;
644 hcryp->Init.DataWidthUnit = pConf->DataWidthUnit;
646 /* Set the key size (This bit field is do not care in the DES or TDES modes), data type and operating mode*/
647 MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD, hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
649 /*clear error flags*/
650 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
652 /* Process Unlocked */
653 __HAL_UNLOCK(hcryp);
655 /* Reset Error Code field */
656 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
658 /* Change the CRYP state */
659 hcryp->State = HAL_CRYP_STATE_READY;
661 /* Set the default CRYP phase */
662 hcryp->Phase = CRYP_PHASE_READY;
664 /* Return function status */
665 return HAL_OK;
667 else
669 /* Process Unlocked */
670 __HAL_UNLOCK(hcryp);
672 /* Busy error code field */
673 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
674 return HAL_ERROR;
679 * @brief Get CRYP Configuration parameters in associated handle.
680 * @param pConf pointer to a CRYP_ConfigTypeDef structure
681 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
682 * the configuration information for CRYP module
683 * @retval HAL status
685 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
687 /* Check the CRYP handle allocation */
688 if ((hcryp == NULL) || (pConf == NULL))
690 return HAL_ERROR;
693 if (hcryp->State == HAL_CRYP_STATE_READY)
695 /* Change the CRYP state */
696 hcryp->State = HAL_CRYP_STATE_BUSY;
698 /* Process locked */
699 __HAL_LOCK(hcryp);
701 /* Get CRYP parameters */
702 pConf->DataType = hcryp->Init.DataType;
703 pConf->pKey = hcryp->Init.pKey;
704 pConf->Algorithm = hcryp->Init.Algorithm;
705 pConf->KeySize = hcryp->Init.KeySize ;
706 pConf->pInitVect = hcryp->Init.pInitVect;
707 pConf->Header = hcryp->Init.Header ;
708 pConf->HeaderSize = hcryp->Init.HeaderSize;
709 pConf->B0 = hcryp->Init.B0;
710 pConf->DataWidthUnit = hcryp->Init.DataWidthUnit;
712 /* Process Unlocked */
713 __HAL_UNLOCK(hcryp);
715 /* Change the CRYP state */
716 hcryp->State = HAL_CRYP_STATE_READY;
718 /* Return function status */
719 return HAL_OK;
721 else
723 /* Process Unlocked */
724 __HAL_UNLOCK(hcryp);
726 /* Busy error code field */
727 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
728 return HAL_ERROR;
732 * @brief Initializes the CRYP MSP.
733 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
734 * the configuration information for CRYP module
735 * @retval None
737 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
739 /* Prevent unused argument(s) compilation warning */
740 UNUSED(hcryp);
742 /* NOTE : This function Should not be modified, when the callback is needed,
743 the HAL_CRYP_MspInit could be implemented in the user file
748 * @brief DeInitializes CRYP MSP.
749 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
750 * the configuration information for CRYP module
751 * @retval None
753 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
755 /* Prevent unused argument(s) compilation warning */
756 UNUSED(hcryp);
758 /* NOTE : This function Should not be modified, when the callback is needed,
759 the HAL_CRYP_MspDeInit could be implemented in the user file
763 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
765 * @brief Register a User CRYP Callback
766 * To be used instead of the weak predefined callback
767 * @param hcryp cryp handle
768 * @param CallbackID ID of the callback to be registered
769 * This parameter can be one of the following values:
770 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
771 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
772 * @arg @ref HAL_CRYP_ERROR_CB_ID Error callback ID
773 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
774 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
775 * @param pCallback pointer to the Callback function
776 * @retval status
778 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID, pCRYP_CallbackTypeDef pCallback)
780 HAL_StatusTypeDef status = HAL_OK;
782 if (pCallback == NULL)
784 /* Update the error code */
785 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
787 return HAL_ERROR;
789 /* Process locked */
790 __HAL_LOCK(hcryp);
792 if (hcryp->State == HAL_CRYP_STATE_READY)
794 switch (CallbackID)
796 case HAL_CRYP_INPUT_COMPLETE_CB_ID :
797 hcryp->InCpltCallback = pCallback;
798 break;
800 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
801 hcryp->OutCpltCallback = pCallback;
802 break;
804 case HAL_CRYP_ERROR_CB_ID :
805 hcryp->ErrorCallback = pCallback;
806 break;
808 case HAL_CRYP_MSPINIT_CB_ID :
809 hcryp->MspInitCallback = pCallback;
810 break;
812 case HAL_CRYP_MSPDEINIT_CB_ID :
813 hcryp->MspDeInitCallback = pCallback;
814 break;
816 default :
817 /* Update the error code */
818 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
819 /* Return error status */
820 status = HAL_ERROR;
821 break;
824 else if (hcryp->State == HAL_CRYP_STATE_RESET)
826 switch (CallbackID)
828 case HAL_CRYP_MSPINIT_CB_ID :
829 hcryp->MspInitCallback = pCallback;
830 break;
832 case HAL_CRYP_MSPDEINIT_CB_ID :
833 hcryp->MspDeInitCallback = pCallback;
834 break;
836 default :
837 /* Update the error code */
838 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
839 /* Return error status */
840 status = HAL_ERROR;
841 break;
844 else
846 /* Update the error code */
847 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
848 /* Return error status */
849 status = HAL_ERROR;
852 /* Release Lock */
853 __HAL_UNLOCK(hcryp);
855 return status;
859 * @brief Unregister an CRYP Callback
860 * CRYP callback is redirected to the weak predefined callback
861 * @param hcryp cryp handle
862 * @param CallbackID ID of the callback to be unregistered
863 * This parameter can be one of the following values:
864 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
865 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
866 * @arg @ref HAL_CRYP_ERROR_CB_ID Error callback ID
867 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
868 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
869 * @retval status
871 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
873 HAL_StatusTypeDef status = HAL_OK;
875 /* Process locked */
876 __HAL_LOCK(hcryp);
878 if (hcryp->State == HAL_CRYP_STATE_READY)
880 switch (CallbackID)
882 case HAL_CRYP_INPUT_COMPLETE_CB_ID :
883 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
884 break;
886 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
887 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
888 break;
890 case HAL_CRYP_ERROR_CB_ID :
891 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
892 break;
894 case HAL_CRYP_MSPINIT_CB_ID :
895 hcryp->MspInitCallback = HAL_CRYP_MspInit;
896 break;
898 case HAL_CRYP_MSPDEINIT_CB_ID :
899 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
900 break;
902 default :
903 /* Update the error code */
904 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
905 /* Return error status */
906 status = HAL_ERROR;
907 break;
910 else if (hcryp->State == HAL_CRYP_STATE_RESET)
912 switch (CallbackID)
914 case HAL_CRYP_MSPINIT_CB_ID :
915 hcryp->MspInitCallback = HAL_CRYP_MspInit;
916 break;
918 case HAL_CRYP_MSPDEINIT_CB_ID :
919 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
920 break;
922 default :
923 /* Update the error code */
924 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
925 /* Return error status */
926 status = HAL_ERROR;
927 break;
930 else
932 /* Update the error code */
933 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
934 /* Return error status */
935 status = HAL_ERROR;
938 /* Release Lock */
939 __HAL_UNLOCK(hcryp);
941 return status;
943 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
945 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
947 * @brief Request CRYP processing suspension when in interruption mode.
948 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
949 * the configuration information for CRYP module.
950 * @note Set the handle field SuspendRequest to the appropriate value so that
951 * the on-going CRYP processing is suspended as soon as the required
952 * conditions are met.
953 * @note HAL_CRYP_ProcessSuspend() can only be invoked when the processing is done
954 * in non-blocking interrupt mode.
955 * @note It is advised not to suspend the CRYP processing when the DMA controller
956 * is managing the data transfer.
957 * @retval None
959 void HAL_CRYP_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
961 /* Set Handle SuspendRequest field */
962 hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
968 * @brief CRYP processing suspension and peripheral internal parameters storage.
969 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
970 * the configuration information for CRYP module
971 * @note peripheral internal parameters are stored to be readily available when
972 * suspended processing is resumed later on.
973 * @retval HAL status
975 HAL_StatusTypeDef HAL_CRYP_Suspend(CRYP_HandleTypeDef *hcryp)
977 /* Request suspension */
978 HAL_CRYP_ProcessSuspend(hcryp);
980 while ((HAL_CRYP_GetState(hcryp) != HAL_CRYP_STATE_SUSPENDED) && \
981 (HAL_CRYP_GetState(hcryp) != HAL_CRYP_STATE_READY));
983 if (HAL_CRYP_GetState(hcryp) == HAL_CRYP_STATE_READY)
985 /* Processing was already over or was about to end. No suspension done */
986 return HAL_ERROR;
988 else
990 /* Suspend Processing */
992 /* If authentication algorithms on-going, carry out first saving steps
993 before disable the peripheral */
994 if ((hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC) || \
995 (hcryp->Init.Algorithm == CRYP_AES_CCM))
997 /* Save Suspension registers */
998 CRYP_Read_SuspendRegisters(hcryp, hcryp->SUSPxR_saved);
999 /* Save Key */
1000 CRYP_Read_KeyRegisters(hcryp, hcryp->Key_saved, hcryp->Init.KeySize);
1001 /* Save IV */
1002 CRYP_Read_IVRegisters(hcryp, hcryp->IV_saved);
1004 /* Disable AES */
1005 __HAL_CRYP_DISABLE(hcryp);
1007 /* Save low-priority block CRYP handle parameters */
1008 hcryp->Init_saved = hcryp->Init;
1009 hcryp->pCrypInBuffPtr_saved = hcryp->pCrypInBuffPtr;
1010 hcryp->pCrypOutBuffPtr_saved = hcryp->pCrypOutBuffPtr;
1011 hcryp->CrypInCount_saved = hcryp->CrypInCount;
1012 hcryp->CrypOutCount_saved = hcryp->CrypOutCount;
1013 hcryp->Phase_saved = hcryp->Phase;
1014 hcryp->State_saved = hcryp->State;
1015 hcryp->Size_saved = ( (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) ? hcryp->Size /4 : hcryp->Size);
1016 hcryp->AutoKeyDerivation_saved = hcryp->AutoKeyDerivation;
1017 hcryp->CrypHeaderCount_saved = hcryp->CrypHeaderCount;
1018 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
1020 if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1021 (hcryp->Init.Algorithm == CRYP_AES_CTR))
1023 /* Save Initialisation Vector registers */
1024 CRYP_Read_IVRegisters(hcryp, hcryp->IV_saved);
1027 /* Save Control register */
1028 hcryp->CR_saved = hcryp->Instance->CR;
1031 return HAL_OK;
1036 * @brief CRYP processing resumption.
1037 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1038 * the configuration information for CRYP module
1039 * @note Processing restarts at the exact point where it was suspended, based
1040 * on the parameters saved at suspension time.
1041 * @retval HAL status
1043 HAL_StatusTypeDef HAL_CRYP_Resume(CRYP_HandleTypeDef *hcryp)
1045 if (hcryp->State_saved != HAL_CRYP_STATE_SUSPENDED)
1047 /* CRYP was not suspended */
1048 return HAL_ERROR;
1050 else
1053 /* Restore low-priority block CRYP handle parameters */
1054 hcryp->Init = hcryp->Init_saved;
1055 hcryp->State = hcryp->State_saved;
1057 /* Chaining algorithms case */
1058 if ((hcryp->Init_saved.Algorithm == CRYP_AES_ECB) || \
1059 (hcryp->Init_saved.Algorithm == CRYP_AES_CBC) || \
1060 (hcryp->Init_saved.Algorithm == CRYP_AES_CTR))
1062 /* Restore low-priority block CRYP handle parameters */
1063 hcryp->AutoKeyDerivation = hcryp->AutoKeyDerivation_saved;
1065 if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \
1066 (hcryp->Init.Algorithm == CRYP_AES_CTR))
1068 hcryp->Init.pInitVect = hcryp->IV_saved;
1070 __HAL_CRYP_DISABLE(hcryp);
1071 if (HAL_CRYP_Init(hcryp) != HAL_OK)
1073 return HAL_ERROR;
1076 else /* Authentication algorithms case */
1078 /* Restore low-priority block CRYP handle parameters */
1079 hcryp->Phase = hcryp->Phase_saved;
1080 hcryp->CrypHeaderCount = hcryp->CrypHeaderCount_saved;
1082 /* Disable AES and write-back SUSPxR registers */;
1083 __HAL_CRYP_DISABLE(hcryp);
1084 /* Restore AES Suspend Registers */
1085 CRYP_Write_SuspendRegisters(hcryp, hcryp->SUSPxR_saved);
1086 /* Restore Control, Key and IV Registers, then enable AES */
1087 hcryp->Instance->CR = hcryp->CR_saved;
1088 CRYP_Write_KeyRegisters(hcryp, hcryp->Key_saved, hcryp->Init.KeySize);
1089 CRYP_Write_IVRegisters(hcryp, hcryp->IV_saved);
1090 __HAL_CRYP_ENABLE_IT(hcryp,CRYP_IT_CCFIE | CRYP_IT_ERRIE);
1091 __HAL_CRYP_ENABLE(hcryp);
1093 /* At the same time, set handle state back to READY to be able to resume the AES calculations
1094 without the processing APIs returning HAL_BUSY when called. */
1095 hcryp->State = HAL_CRYP_STATE_READY;
1099 /* Resume low-priority block processing under IT */
1100 hcryp->ResumingFlag = 1U;
1101 if (READ_BIT(hcryp->CR_saved, AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
1103 if (HAL_CRYP_Encrypt_IT(hcryp, hcryp->pCrypInBuffPtr_saved, hcryp->Size_saved, hcryp->pCrypOutBuffPtr_saved) != HAL_OK)
1105 return HAL_ERROR;
1108 else
1110 if (HAL_CRYP_Decrypt_IT(hcryp, hcryp->pCrypInBuffPtr_saved, hcryp->Size_saved, hcryp->pCrypOutBuffPtr_saved) != HAL_OK)
1112 return HAL_ERROR;
1116 return HAL_OK;
1118 #endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */
1121 * @}
1124 /** @defgroup CRYP_Exported_Functions_Group2 Encryption Decryption functions
1125 * @brief Encryption Decryption functions.
1127 @verbatim
1128 ==============================================================================
1129 ##### Encrypt Decrypt functions #####
1130 ==============================================================================
1131 [..] This section provides API allowing to Encrypt/Decrypt Data following
1132 Standard DES/TDES or AES, and Algorithm configured by the user:
1133 (+) Standard DES/TDES only supported by CRYP1 peripheral, below list of Algorithm supported :
1134 - Electronic Code Book(ECB)
1135 - Cipher Block Chaining (CBC)
1136 (+) Standard AES supported by CRYP1 peripheral & TinyAES, list of Algorithm supported:
1137 - Electronic Code Book(ECB)
1138 - Cipher Block Chaining (CBC)
1139 - Counter mode (CTR)
1140 - Cipher Block Chaining (CBC)
1141 - Counter mode (CTR)
1142 - Galois/counter mode (GCM)
1143 - Counter with Cipher Block Chaining-Message(CCM)
1144 [..] Three processing functions are available:
1145 (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
1146 (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
1147 (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
1149 @endverbatim
1150 * @{
1154 * @brief Encryption mode.
1155 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1156 * the configuration information for CRYP module
1157 * @param Input Pointer to the input buffer (plaintext)
1158 * @param Size Length of the plaintext buffer in word.
1159 * @param Output Pointer to the output buffer(ciphertext)
1160 * @param Timeout Specify Timeout value
1161 * @retval HAL status
1163 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output, uint32_t Timeout)
1165 uint32_t algo;
1166 HAL_StatusTypeDef status;
1168 if (hcryp->State == HAL_CRYP_STATE_READY)
1170 /* Change state Busy */
1171 hcryp->State = HAL_CRYP_STATE_BUSY;
1173 /* Process locked */
1174 __HAL_LOCK(hcryp);
1176 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1177 hcryp->CrypInCount = 0U;
1178 hcryp->CrypOutCount = 0U;
1179 hcryp->pCrypInBuffPtr = Input;
1180 hcryp->pCrypOutBuffPtr = Output;
1182 /* Calculate Size parameter in Byte*/
1183 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1185 hcryp->Size = Size * 4U;
1187 else
1189 hcryp->Size = Size;
1192 /* Set the operating mode*/
1193 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1195 /* algo get algorithm selected */
1196 algo = hcryp->Instance->CR & AES_CR_CHMOD;
1198 switch (algo)
1201 case CRYP_AES_ECB:
1202 case CRYP_AES_CBC:
1203 case CRYP_AES_CTR:
1205 /* AES encryption */
1206 status = CRYP_AES_Encrypt(hcryp, Timeout);
1207 break;
1209 case CRYP_AES_GCM_GMAC:
1211 /* AES GCM encryption */
1212 status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1213 break;
1215 case CRYP_AES_CCM:
1217 /* AES CCM encryption */
1218 status = CRYP_AESCCM_Process(hcryp, Timeout);
1219 break;
1221 default:
1222 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1223 status = HAL_ERROR;
1224 break;
1227 if (status == HAL_OK)
1229 /* Change the CRYP peripheral state */
1230 hcryp->State = HAL_CRYP_STATE_READY;
1232 /* Process unlocked */
1233 __HAL_UNLOCK(hcryp);
1236 else
1238 /* Busy error code field */
1239 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1240 status = HAL_ERROR;
1243 /* Return function status */
1244 return status;
1248 * @brief Decryption mode.
1249 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1250 * the configuration information for CRYP module
1251 * @param Input Pointer to the input buffer (ciphertext )
1252 * @param Size Length of the plaintext buffer in word.
1253 * @param Output Pointer to the output buffer(plaintext)
1254 * @param Timeout Specify Timeout value
1255 * @retval HAL status
1257 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output, uint32_t Timeout)
1259 HAL_StatusTypeDef status;
1260 uint32_t algo;
1262 if (hcryp->State == HAL_CRYP_STATE_READY)
1264 /* Change state Busy */
1265 hcryp->State = HAL_CRYP_STATE_BUSY;
1267 /* Process locked */
1268 __HAL_LOCK(hcryp);
1270 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1271 hcryp->CrypInCount = 0U;
1272 hcryp->CrypOutCount = 0U;
1273 hcryp->pCrypInBuffPtr = Input;
1274 hcryp->pCrypOutBuffPtr = Output;
1276 /* Calculate Size parameter in Byte*/
1277 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1279 hcryp->Size = Size * 4U;
1281 else
1283 hcryp->Size = Size;
1286 /* Set Decryption operating mode*/
1287 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1289 /* algo get algorithm selected */
1290 algo = hcryp->Instance->CR & AES_CR_CHMOD;
1292 switch (algo)
1295 case CRYP_AES_ECB:
1296 case CRYP_AES_CBC:
1297 case CRYP_AES_CTR:
1299 /* AES decryption */
1300 status = CRYP_AES_Decrypt(hcryp, Timeout);
1301 break;
1303 case CRYP_AES_GCM_GMAC:
1305 /* AES GCM decryption */
1306 status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1307 break;
1309 case CRYP_AES_CCM:
1311 /* AES CCM decryption */
1312 status = CRYP_AESCCM_Process(hcryp, Timeout);
1313 break;
1315 default:
1316 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1317 status = HAL_ERROR;
1318 break;
1321 if (status == HAL_OK)
1323 /* Change the CRYP peripheral state */
1324 hcryp->State = HAL_CRYP_STATE_READY;
1326 /* Process unlocked */
1327 __HAL_UNLOCK(hcryp);
1330 else
1332 /* Busy error code field */
1333 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1334 status = HAL_ERROR;
1337 /* Return function status */
1338 return status;
1342 * @brief Encryption in interrupt mode.
1343 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1344 * the configuration information for CRYP module
1345 * @param Input Pointer to the input buffer (plaintext)
1346 * @param Size Length of the plaintext buffer in word
1347 * @param Output Pointer to the output buffer(ciphertext)
1348 * @retval HAL status
1350 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1352 HAL_StatusTypeDef status;
1353 uint32_t algo;
1355 if (hcryp->State == HAL_CRYP_STATE_READY)
1357 /* Change state Busy */
1358 hcryp->State = HAL_CRYP_STATE_BUSY;
1360 /* Process locked */
1361 __HAL_LOCK(hcryp);
1363 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1364 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
1365 if (hcryp->ResumingFlag == 1U)
1367 hcryp->ResumingFlag = 0U;
1368 if (hcryp->Phase != CRYP_PHASE_HEADER_SUSPENDED)
1370 hcryp->CrypInCount = hcryp->CrypInCount_saved;
1371 hcryp->CrypOutCount = hcryp->CrypOutCount_saved;
1373 else
1375 hcryp->CrypInCount = 0U;
1376 hcryp->CrypOutCount = 0U;
1379 else
1380 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
1382 hcryp->CrypInCount = 0U;
1383 hcryp->CrypOutCount = 0U;
1386 hcryp->pCrypInBuffPtr = Input;
1387 hcryp->pCrypOutBuffPtr = Output;
1389 /* Calculate Size parameter in Byte*/
1390 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1392 hcryp->Size = Size * 4U;
1394 else
1396 hcryp->Size = Size;
1399 /* Set encryption operating mode*/
1400 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1402 /* algo get algorithm selected */
1403 algo = hcryp->Instance->CR & AES_CR_CHMOD;
1405 switch (algo)
1408 case CRYP_AES_ECB:
1409 case CRYP_AES_CBC:
1410 case CRYP_AES_CTR:
1412 /* AES encryption */
1413 status = CRYP_AES_Encrypt_IT(hcryp);
1414 break;
1416 case CRYP_AES_GCM_GMAC:
1418 /* AES GCM encryption */
1419 status = CRYP_AESGCM_Process_IT(hcryp) ;
1420 break;
1422 case CRYP_AES_CCM:
1424 /* AES CCM encryption */
1425 status = CRYP_AESCCM_Process_IT(hcryp);
1426 break;
1428 default:
1429 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1430 status = HAL_ERROR;
1431 break;
1434 else
1436 /* Busy error code field */
1437 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1438 status = HAL_ERROR;
1441 /* Return function status */
1442 return status;
1446 * @brief Decryption in interrupt mode.
1447 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1448 * the configuration information for CRYP module
1449 * @param Input Pointer to the input buffer (ciphertext )
1450 * @param Size Length of the plaintext buffer in word.
1451 * @param Output Pointer to the output buffer(plaintext)
1452 * @retval HAL status
1454 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1456 HAL_StatusTypeDef status;
1457 uint32_t algo;
1459 if (hcryp->State == HAL_CRYP_STATE_READY)
1461 /* Change state Busy */
1462 hcryp->State = HAL_CRYP_STATE_BUSY;
1464 /* Process locked */
1465 __HAL_LOCK(hcryp);
1467 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1468 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
1469 if (hcryp->ResumingFlag == 1U)
1471 hcryp->ResumingFlag = 0U;
1472 if (hcryp->Phase != CRYP_PHASE_HEADER_SUSPENDED)
1474 hcryp->CrypInCount = hcryp->CrypInCount_saved;
1475 hcryp->CrypOutCount = hcryp->CrypOutCount_saved;
1477 else
1479 hcryp->CrypInCount = 0U;
1480 hcryp->CrypOutCount = 0U;
1483 else
1484 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
1486 hcryp->CrypInCount = 0U;
1487 hcryp->CrypOutCount = 0U;
1489 hcryp->pCrypInBuffPtr = Input;
1490 hcryp->pCrypOutBuffPtr = Output;
1492 /* Calculate Size parameter in Byte*/
1493 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1495 hcryp->Size = Size * 4U;
1497 else
1499 hcryp->Size = Size;
1502 /* Set decryption operating mode*/
1503 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1505 /* algo get algorithm selected */
1506 algo = hcryp->Instance->CR & AES_CR_CHMOD;
1508 switch (algo)
1511 case CRYP_AES_ECB:
1512 case CRYP_AES_CBC:
1513 case CRYP_AES_CTR:
1515 /* AES decryption */
1516 status = CRYP_AES_Decrypt_IT(hcryp);
1517 break;
1519 case CRYP_AES_GCM_GMAC:
1521 /* AES GCM decryption */
1522 status = CRYP_AESGCM_Process_IT(hcryp) ;
1523 break;
1525 case CRYP_AES_CCM:
1527 /* AES CCM decryption */
1528 status = CRYP_AESCCM_Process_IT(hcryp);
1529 break;
1531 default:
1532 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1533 status = HAL_ERROR;
1534 break;
1537 else
1539 /* Busy error code field */
1540 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1541 status = HAL_ERROR;
1544 /* Return function status */
1545 return status;
1549 * @brief Encryption in DMA mode.
1550 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1551 * the configuration information for CRYP module
1552 * @param Input Pointer to the input buffer (plaintext)
1553 * @param Size Length of the plaintext buffer in word.
1554 * @param Output Pointer to the output buffer(ciphertext)
1555 * @retval HAL status
1557 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1559 HAL_StatusTypeDef status;
1560 uint32_t algo;
1561 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1563 if (hcryp->State == HAL_CRYP_STATE_READY)
1565 /* Change state Busy */
1566 hcryp->State = HAL_CRYP_STATE_BUSY;
1568 /* Process locked */
1569 __HAL_LOCK(hcryp);
1571 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
1572 hcryp->CrypInCount = 0U;
1573 hcryp->CrypOutCount = 0U;
1574 hcryp->pCrypInBuffPtr = Input;
1575 hcryp->pCrypOutBuffPtr = Output;
1577 /* Calculate Size parameter in Byte*/
1578 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1580 hcryp->Size = Size * 4U;
1582 else
1584 hcryp->Size = Size;
1587 /* Set encryption operating mode*/
1588 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
1590 /* algo get algorithm selected */
1591 algo = hcryp->Instance->CR & AES_CR_CHMOD;
1593 switch (algo)
1596 case CRYP_AES_ECB:
1597 case CRYP_AES_CBC:
1598 case CRYP_AES_CTR:
1600 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1602 if (hcryp->KeyIVConfig == 1U)
1604 /* If the Key and IV configuration has to be done only once
1605 and if it has already been done, skip it */
1606 DoKeyIVConfig = 0U;
1608 else
1610 /* If the Key and IV configuration has to be done only once
1611 and if it has not been done already, do it and set KeyIVConfig
1612 to keep track it won't have to be done again next time */
1613 hcryp->KeyIVConfig = 1U;
1617 if (DoKeyIVConfig == 1U)
1619 /* Set the Key*/
1620 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1622 /* Set the Initialization Vector*/
1623 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1625 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
1626 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
1627 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
1628 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
1630 } /* if (DoKeyIVConfig == 1U) */
1632 /* Set the phase */
1633 hcryp->Phase = CRYP_PHASE_PROCESS;
1635 /* Start DMA process transfer for AES */
1636 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
1637 status = HAL_OK;
1638 break;
1640 case CRYP_AES_GCM_GMAC:
1642 /* AES GCM encryption */
1643 status = CRYP_AESGCM_Process_DMA(hcryp) ;
1644 break;
1646 case CRYP_AES_CCM:
1648 /* AES CCM encryption */
1649 status = CRYP_AESCCM_Process_DMA(hcryp);
1650 break;
1652 default:
1653 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1654 status = HAL_ERROR;
1655 break;
1658 else
1660 /* Busy error code field */
1661 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1662 status = HAL_ERROR;
1665 /* Return function status */
1666 return status;
1670 * @brief Decryption in DMA mode.
1671 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1672 * the configuration information for CRYP module
1673 * @param Input Pointer to the input buffer (ciphertext )
1674 * @param Size Length of the plaintext buffer in word
1675 * @param Output Pointer to the output buffer(plaintext)
1676 * @retval HAL status
1678 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1680 HAL_StatusTypeDef status;
1681 uint32_t algo;
1683 if (hcryp->State == HAL_CRYP_STATE_READY)
1686 /* Change state Busy */
1687 hcryp->State = HAL_CRYP_STATE_BUSY;
1689 /* Process locked */
1690 __HAL_LOCK(hcryp);
1692 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1693 hcryp->CrypInCount = 0U;
1694 hcryp->CrypOutCount = 0U;
1695 hcryp->pCrypInBuffPtr = Input;
1696 hcryp->pCrypOutBuffPtr = Output;
1698 /* Calculate Size parameter in Byte*/
1699 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1701 hcryp->Size = Size * 4U;
1703 else
1705 hcryp->Size = Size;
1708 /* Set decryption operating mode*/
1709 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
1711 /* algo get algorithm selected */
1712 algo = hcryp->Instance->CR & AES_CR_CHMOD;
1714 switch (algo)
1717 case CRYP_AES_ECB:
1718 case CRYP_AES_CBC:
1719 case CRYP_AES_CTR:
1721 /* AES decryption */
1722 status = CRYP_AES_Decrypt_DMA(hcryp);
1723 break;
1725 case CRYP_AES_GCM_GMAC:
1727 /* AES GCM decryption */
1728 status = CRYP_AESGCM_Process_DMA(hcryp) ;
1729 break;
1731 case CRYP_AES_CCM:
1733 /* AES CCM decryption */
1734 status = CRYP_AESCCM_Process_DMA(hcryp);
1735 break;
1737 default:
1738 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1739 status = HAL_ERROR;
1740 break;
1743 else
1745 /* Busy error code field */
1746 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1747 status = HAL_ERROR;
1749 /* Return function status */
1750 return status;
1754 * @}
1757 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1758 * @brief CRYP IRQ handler.
1760 @verbatim
1761 ==============================================================================
1762 ##### CRYP IRQ handler management #####
1763 ==============================================================================
1764 [..] This section provides CRYP IRQ handler and callback functions.
1765 (+) HAL_CRYP_IRQHandler CRYP interrupt request
1766 (+) HAL_CRYP_InCpltCallback input data transfer complete callback
1767 (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
1768 (+) HAL_CRYP_ErrorCallback CRYP error callback
1769 (+) HAL_CRYP_GetState return the CRYP state
1770 (+) HAL_CRYP_GetError return the CRYP error code
1771 @endverbatim
1772 * @{
1776 * @brief This function handles cryptographic interrupt request.
1777 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1778 * the configuration information for CRYP module
1779 * @retval None
1781 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
1784 /* Check if error occurred */
1785 if (__HAL_CRYP_GET_IT_SOURCE(hcryp,CRYP_IT_ERRIE) != RESET)
1787 /* If write Error occurred */
1788 if (__HAL_CRYP_GET_FLAG(hcryp,CRYP_IT_WRERR) != RESET)
1790 hcryp->ErrorCode |= HAL_CRYP_ERROR_WRITE;
1792 /* If read Error occurred */
1793 if (__HAL_CRYP_GET_FLAG(hcryp,CRYP_IT_RDERR) != RESET)
1795 hcryp->ErrorCode |= HAL_CRYP_ERROR_READ;
1799 if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_IT_CCF) != RESET)
1801 if(__HAL_CRYP_GET_IT_SOURCE(hcryp, CRYP_IT_CCFIE) != RESET)
1803 /* Clear computation complete flag */
1804 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
1806 if (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)
1809 /* if header phase */
1810 if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
1812 CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
1814 else /* if payload phase */
1816 CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
1819 else if (hcryp->Init.Algorithm == CRYP_AES_CCM)
1821 /* if header phase */
1822 if (hcryp->Init.HeaderSize >= hcryp->CrypHeaderCount)
1824 CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
1826 else /* if payload phase */
1828 CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
1831 else /* AES Algorithm ECB,CBC or CTR*/
1833 CRYP_AES_IT(hcryp);
1840 * @brief Return the CRYP error code.
1841 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1842 * the configuration information for the CRYP peripheral
1843 * @retval CRYP error code
1845 uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp)
1847 return hcryp->ErrorCode;
1851 * @brief Returns the CRYP state.
1852 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1853 * the configuration information for CRYP module.
1854 * @retval HAL state
1856 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp)
1858 return hcryp->State;
1862 * @brief Input FIFO transfer completed callback.
1863 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1864 * the configuration information for CRYP module.
1865 * @retval None
1867 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
1869 /* Prevent unused argument(s) compilation warning */
1870 UNUSED(hcryp);
1872 /* NOTE : This function Should not be modified, when the callback is needed,
1873 the HAL_CRYP_InCpltCallback could be implemented in the user file
1878 * @brief Output FIFO transfer completed callback.
1879 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1880 * the configuration information for CRYP module.
1881 * @retval None
1883 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
1885 /* Prevent unused argument(s) compilation warning */
1886 UNUSED(hcryp);
1888 /* NOTE : This function Should not be modified, when the callback is needed,
1889 the HAL_CRYP_OutCpltCallback could be implemented in the user file
1894 * @brief CRYP error callback.
1895 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1896 * the configuration information for CRYP module.
1897 * @retval None
1899 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
1901 /* Prevent unused argument(s) compilation warning */
1902 UNUSED(hcryp);
1904 /* NOTE : This function Should not be modified, when the callback is needed,
1905 the HAL_CRYP_ErrorCallback could be implemented in the user file
1909 * @}
1913 * @}
1916 /* Private functions ---------------------------------------------------------*/
1917 /** @addtogroup CRYP_Private_Functions
1918 * @{
1922 * @brief Encryption in ECB/CBC & CTR Algorithm with AES Standard
1923 * @param hcryp pointer to a CRYP_HandleTypeDef structure
1924 * @param Timeout specify Timeout value
1925 * @retval HAL status
1927 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
1929 uint16_t incount; /* Temporary CrypInCount Value */
1930 uint16_t outcount; /* Temporary CrypOutCount Value */
1931 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1933 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1935 if (hcryp->KeyIVConfig == 1U)
1937 /* If the Key and IV configuration has to be done only once
1938 and if it has already been done, skip it */
1939 DoKeyIVConfig = 0U;
1941 else
1943 /* If the Key and IV configuration has to be done only once
1944 and if it has not been done already, do it and set KeyIVConfig
1945 to keep track it won't have to be done again next time */
1946 hcryp->KeyIVConfig = 1U;
1950 if (DoKeyIVConfig == 1U)
1952 /* Set the Key*/
1953 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1955 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1957 /* Set the Initialization Vector*/
1958 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
1959 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
1960 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
1961 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
1963 } /* if (DoKeyIVConfig == 1U) */
1965 /* Set the phase */
1966 hcryp->Phase = CRYP_PHASE_PROCESS;
1968 /* Enable CRYP */
1969 __HAL_CRYP_ENABLE(hcryp);
1971 incount = hcryp->CrypInCount;
1972 outcount = hcryp->CrypOutCount;
1973 while ((incount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
1975 /* Write plain Ddta and get cipher data */
1976 CRYP_AES_ProcessData(hcryp, Timeout);
1977 incount = hcryp->CrypInCount;
1978 outcount = hcryp->CrypOutCount;
1981 /* Disable CRYP */
1982 __HAL_CRYP_DISABLE(hcryp);
1984 /* Change the CRYP state */
1985 hcryp->State = HAL_CRYP_STATE_READY;
1987 /* Return function status */
1988 return HAL_OK;
1992 * @brief Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
1993 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
1994 * the configuration information for CRYP module
1995 * @retval HAL status
1997 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
1999 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2001 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2003 if (hcryp->KeyIVConfig == 1U)
2005 /* If the Key and IV configuration has to be done only once
2006 and if it has already been done, skip it */
2007 DoKeyIVConfig = 0U;
2009 else
2011 /* If the Key and IV configuration has to be done only once
2012 and if it has not been done already, do it and set KeyIVConfig
2013 to keep track it won't have to be done again next time */
2014 hcryp->KeyIVConfig = 1U;
2018 if (DoKeyIVConfig == 1U)
2020 /* Set the Key*/
2021 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2023 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2025 /* Set the Initialization Vector*/
2026 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2027 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2028 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2029 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2031 } /* if (DoKeyIVConfig == 1U) */
2033 /* Set the phase */
2034 hcryp->Phase = CRYP_PHASE_PROCESS;
2036 if (hcryp->Size != 0U)
2039 /* Enable computation complete flag and error interrupts */
2040 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
2042 /* Enable CRYP */
2043 __HAL_CRYP_ENABLE(hcryp);
2045 /* Write the input block in the IN FIFO */
2046 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2047 hcryp->CrypInCount++;
2048 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2049 hcryp->CrypInCount++;
2050 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2051 hcryp->CrypInCount++;
2052 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2053 hcryp->CrypInCount++;
2055 else
2057 /* Change the CRYP state */
2058 hcryp->State = HAL_CRYP_STATE_READY;
2060 /* Process unlocked */
2061 __HAL_UNLOCK(hcryp);
2064 /* Return function status */
2065 return HAL_OK;
2069 * @brief Decryption in ECB/CBC & CTR mode with AES Standard
2070 * @param hcryp pointer to a CRYP_HandleTypeDef structure
2071 * @param Timeout Specify Timeout value
2072 * @retval HAL status
2074 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2076 uint16_t incount; /* Temporary CrypInCount Value */
2077 uint16_t outcount; /* Temporary CrypOutCount Value */
2078 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2080 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2082 if (hcryp->KeyIVConfig == 1U)
2084 /* If the Key and IV configuration has to be done only once
2085 and if it has already been done, skip it */
2086 DoKeyIVConfig = 0U;
2088 else
2090 /* If the Key and IV configuration has to be done only once
2091 and if it has not been done already, do it and set KeyIVConfig
2092 to keep track it won't have to be done again next time */
2093 hcryp->KeyIVConfig = 1U;
2097 if (DoKeyIVConfig == 1U)
2099 /* Key preparation for ECB/CBC */
2100 if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/
2102 if (hcryp->AutoKeyDerivation == DISABLE)/*Mode 2 Key preparation*/
2104 /* Set key preparation for decryption operating mode*/
2105 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2107 /* Set the Key*/
2108 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2110 /* Enable CRYP */
2111 __HAL_CRYP_ENABLE(hcryp);
2113 /* Wait for CCF flag to be raised */
2114 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2116 /* Disable the CRYP peripheral clock */
2117 __HAL_CRYP_DISABLE(hcryp);
2119 /* Change state & error code*/
2120 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2121 hcryp->State = HAL_CRYP_STATE_READY;
2123 /* Process unlocked */
2124 __HAL_UNLOCK(hcryp);
2125 return HAL_ERROR;
2127 /* Clear CCF Flag */
2128 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2130 /* Return to decryption operating mode(Mode 3)*/
2131 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2133 else /*Mode 4 : decryption & Key preparation*/
2135 /* Set the Key*/
2136 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2138 /* Set decryption & Key preparation operating mode*/
2139 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT);
2142 else /*Algorithm CTR */
2144 /* Set the Key*/
2145 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2148 /* Set IV */
2149 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2151 /* Set the Initialization Vector*/
2152 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2153 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2154 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2155 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2157 } /* if (DoKeyIVConfig == 1U) */
2159 /* Set the phase */
2160 hcryp->Phase = CRYP_PHASE_PROCESS;
2162 /* Enable CRYP */
2163 __HAL_CRYP_ENABLE(hcryp);
2165 incount = hcryp->CrypInCount;
2166 outcount = hcryp->CrypOutCount;
2167 while ((incount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2169 /* Write plain data and get cipher data */
2170 CRYP_AES_ProcessData(hcryp, Timeout);
2171 incount = hcryp->CrypInCount;
2172 outcount = hcryp->CrypOutCount;
2175 /* Disable CRYP */
2176 __HAL_CRYP_DISABLE(hcryp);
2178 /* Change the CRYP state */
2179 hcryp->State = HAL_CRYP_STATE_READY;
2181 /* Return function status */
2182 return HAL_OK;
2185 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2186 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2187 * the configuration information for CRYP module
2188 * @retval HAL status
2190 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
2192 __IO uint32_t count = 0U;
2193 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2195 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2197 if (hcryp->KeyIVConfig == 1U)
2199 /* If the Key and IV configuration has to be done only once
2200 and if it has already been done, skip it */
2201 DoKeyIVConfig = 0U;
2203 else
2205 /* If the Key and IV configuration has to be done only once
2206 and if it has not been done already, do it and set KeyIVConfig
2207 to keep track it won't have to be done again next time */
2208 hcryp->KeyIVConfig = 1U;
2212 if (DoKeyIVConfig == 1U)
2214 /* Key preparation for ECB/CBC */
2215 if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2217 if (hcryp->AutoKeyDerivation == DISABLE)/*Mode 2 Key preparation*/
2219 /* Set key preparation for decryption operating mode*/
2220 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2222 /* Set the Key*/
2223 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2225 /* Enable CRYP */
2226 __HAL_CRYP_ENABLE(hcryp);
2228 /* Wait for CCF flag to be raised */
2229 count = CRYP_TIMEOUT_KEYPREPARATION;
2232 count-- ;
2233 if (count == 0U)
2235 /* Disable the CRYP peripheral clock */
2236 __HAL_CRYP_DISABLE(hcryp);
2238 /* Change state */
2239 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2240 hcryp->State = HAL_CRYP_STATE_READY;
2242 /* Process unlocked */
2243 __HAL_UNLOCK(hcryp);
2244 return HAL_ERROR;
2247 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
2249 /* Clear CCF Flag */
2250 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2252 /* Return to decryption operating mode(Mode 3)*/
2253 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2255 else /*Mode 4 : decryption & key preparation*/
2257 /* Set the Key*/
2258 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2260 /* Set decryption & key preparation operating mode*/
2261 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT);
2264 else /*Algorithm CTR */
2266 /* Set the Key*/
2267 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2270 /* Set IV */
2271 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2273 /* Set the Initialization Vector*/
2274 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2275 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2276 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2277 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2279 } /* if (DoKeyIVConfig == 1U) */
2281 /* Set the phase */
2282 hcryp->Phase = CRYP_PHASE_PROCESS;
2283 if (hcryp->Size != 0U)
2285 /* Enable computation complete flag and error interrupts */
2286 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
2288 /* Enable CRYP */
2289 __HAL_CRYP_ENABLE(hcryp);
2291 /* Write the input block in the IN FIFO */
2292 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2293 hcryp->CrypInCount++;
2294 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2295 hcryp->CrypInCount++;
2296 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2297 hcryp->CrypInCount++;
2298 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2299 hcryp->CrypInCount++;
2301 else
2303 /* Process locked */
2304 __HAL_UNLOCK(hcryp);
2306 /* Change the CRYP state */
2307 hcryp->State = HAL_CRYP_STATE_READY;
2310 /* Return function status */
2311 return HAL_OK;
2314 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
2315 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2316 * the configuration information for CRYP module
2317 * @retval HAL status
2319 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
2321 __IO uint32_t count = 0U;
2322 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2324 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2326 if (hcryp->KeyIVConfig == 1U)
2328 /* If the Key and IV configuration has to be done only once
2329 and if it has already been done, skip it */
2330 DoKeyIVConfig = 0U;
2332 else
2334 /* If the Key and IV configuration has to be done only once
2335 and if it has not been done already, do it and set KeyIVConfig
2336 to keep track it won't have to be done again next time */
2337 hcryp->KeyIVConfig = 1U;
2341 if (DoKeyIVConfig == 1U)
2343 /* Key preparation for ECB/CBC */
2344 if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2346 if (hcryp->AutoKeyDerivation == DISABLE)/*Mode 2 key preparation*/
2348 /* Set key preparation for decryption operating mode*/
2349 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
2351 /* Set the Key*/
2352 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2354 /* Enable CRYP */
2355 __HAL_CRYP_ENABLE(hcryp);
2357 /* Wait for CCF flag to be raised */
2358 count = CRYP_TIMEOUT_KEYPREPARATION;
2361 count-- ;
2362 if (count == 0U)
2364 /* Disable the CRYP peripheral clock */
2365 __HAL_CRYP_DISABLE(hcryp);
2367 /* Change state */
2368 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2369 hcryp->State = HAL_CRYP_STATE_READY;
2371 /* Process unlocked */
2372 __HAL_UNLOCK(hcryp);
2373 return HAL_ERROR;
2376 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
2378 /* Clear CCF Flag */
2379 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2381 /* Return to decryption operating mode(Mode 3)*/
2382 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
2384 else /*Mode 4 : decryption & key preparation*/
2386 /* Set the Key*/
2387 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2389 /* Set decryption & Key preparation operating mode*/
2390 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT);
2393 else /*Algorithm CTR */
2395 /* Set the Key*/
2396 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2399 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2401 /* Set the Initialization Vector*/
2402 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2403 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2404 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2405 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2407 } /* if (DoKeyIVConfig == 1U) */
2409 /* Set the phase */
2410 hcryp->Phase = CRYP_PHASE_PROCESS;
2412 if (hcryp->Size != 0U)
2414 /* Set the input and output addresses and start DMA transfer */
2415 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
2417 else
2419 /* Process unlocked */
2420 __HAL_UNLOCK(hcryp);
2422 /* Change the CRYP state */
2423 hcryp->State = HAL_CRYP_STATE_READY;
2426 /* Return function status */
2427 return HAL_OK;
2432 * @brief DMA CRYP input data process complete callback.
2433 * @param hdma DMA handle
2434 * @retval None
2436 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
2438 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2440 /* Stop the DMA transfers to the IN FIFO by clearing to "0" the DMAINEN */
2441 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
2443 /* Call input data transfer complete callback */
2444 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2445 /*Call registered Input complete callback*/
2446 hcryp->InCpltCallback(hcryp);
2447 #else
2448 /*Call legacy weak Input complete callback*/
2449 HAL_CRYP_InCpltCallback(hcryp);
2450 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2454 * @brief DMA CRYP output data process complete callback.
2455 * @param hdma DMA handle
2456 * @retval None
2458 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
2460 uint32_t count;
2461 uint32_t npblb;
2462 uint32_t lastwordsize;
2463 uint32_t temp; /* Temporary CrypOutBuff */
2464 uint32_t mode;
2466 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2468 /* Stop the DMA transfers to the OUT FIFO by clearing to "0" the DMAOUTEN */
2469 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
2471 /* Clear CCF flag */
2472 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2474 /* Last block transfer in case of GCM or CCM with Size not %16*/
2475 if (((hcryp->Size) % 16U) != 0U)
2477 /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA */
2478 hcryp->CrypInCount = (hcryp->Size / 16U) * 4U;
2479 hcryp->CrypOutCount = hcryp->CrypInCount;
2481 /* Compute the number of padding bytes in last block of payload */
2482 npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
2484 mode = hcryp->Instance->CR & AES_CR_MODE;
2485 if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
2486 ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
2488 /* Specify the number of non-valid bytes using NPBLB register*/
2489 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
2492 /* Number of valid words (lastwordsize) in last block */
2493 if ((npblb % 4U) == 0U)
2495 lastwordsize = (16U - npblb) / 4U;
2497 else
2499 lastwordsize = ((16U - npblb) / 4U) + 1U;
2502 /* Last block optionally pad the data with zeros*/
2503 for (count = 0U; count < lastwordsize; count++)
2505 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2506 hcryp->CrypInCount++;
2508 while (count < 4U)
2510 /* Pad the data with zeros to have a complete block */
2511 hcryp->Instance->DINR = 0x0U;
2512 count++;
2515 /*Wait on CCF flag*/
2516 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
2519 count-- ;
2520 if (count == 0U)
2522 /* Disable the CRYP peripheral clock */
2523 __HAL_CRYP_DISABLE(hcryp);
2525 /* Change state */
2526 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2527 hcryp->State = HAL_CRYP_STATE_READY;
2529 /* Process unlocked */
2530 __HAL_UNLOCK(hcryp);
2532 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2533 /*Call registered error callback*/
2534 hcryp->ErrorCallback(hcryp);
2535 #else
2536 /*Call legacy weak error callback*/
2537 HAL_CRYP_ErrorCallback(hcryp);
2538 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2541 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
2543 /* Clear CCF flag */
2544 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2546 /*Read the output block from the output FIFO */
2547 for (count = 0U; count < 4U; count++)
2549 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
2550 temp = hcryp->Instance->DOUTR;
2552 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2553 hcryp->CrypOutCount++;
2557 if (((hcryp->Init.Algorithm & CRYP_AES_GCM_GMAC) != CRYP_AES_GCM_GMAC) && ((hcryp->Init.Algorithm & CRYP_AES_CCM) != CRYP_AES_CCM))
2559 /* Disable CRYP (not allowed in GCM)*/
2560 __HAL_CRYP_DISABLE(hcryp);
2563 /* Change the CRYP state to ready */
2564 hcryp->State = HAL_CRYP_STATE_READY;
2566 /* Process unlocked */
2567 __HAL_UNLOCK(hcryp);
2569 /* Call output data transfer complete callback */
2570 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2571 /*Call registered Output complete callback*/
2572 hcryp->OutCpltCallback(hcryp);
2573 #else
2574 /*Call legacy weak Output complete callback*/
2575 HAL_CRYP_OutCpltCallback(hcryp);
2576 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2580 * @brief DMA CRYP communication error callback.
2581 * @param hdma DMA handle
2582 * @retval None
2584 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
2586 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2588 /* Change the CRYP peripheral state */
2589 hcryp->State = HAL_CRYP_STATE_READY;
2591 /* DMA error code field */
2592 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2594 /* Clear CCF flag */
2595 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2597 /* Call error callback */
2598 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2599 /*Call registered error callback*/
2600 hcryp->ErrorCallback(hcryp);
2601 #else
2602 /*Call legacy weak error callback*/
2603 HAL_CRYP_ErrorCallback(hcryp);
2604 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2608 * @brief Set the DMA configuration and start the DMA transfer
2609 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2610 * the configuration information for CRYP module
2611 * @param inputaddr address of the input buffer
2612 * @param Size size of the input buffer, must be a multiple of 16.
2613 * @param outputaddr address of the output buffer
2614 * @retval None
2616 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2618 /* Set the CRYP DMA transfer complete callback */
2619 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2621 /* Set the DMA input error callback */
2622 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2624 /* Set the CRYP DMA transfer complete callback */
2625 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2627 /* Set the DMA output error callback */
2628 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2630 if ((hcryp->Init.Algorithm & CRYP_AES_GCM_GMAC) != CRYP_AES_GCM_GMAC)
2632 /* Enable CRYP (not allowed in GCM & CCM)*/
2633 __HAL_CRYP_ENABLE(hcryp);
2636 /* Enable the DMA input stream */
2637 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size) != HAL_OK)
2639 /* DMA error code field */
2640 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2642 /* Call error callback */
2643 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2644 /*Call registered error callback*/
2645 hcryp->ErrorCallback(hcryp);
2646 #else
2647 /*Call legacy weak error callback*/
2648 HAL_CRYP_ErrorCallback(hcryp);
2649 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2651 /* Enable the DMA output stream */
2652 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size) != HAL_OK)
2654 /* DMA error code field */
2655 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2657 /* Call error callback */
2658 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2659 /*Call registered error callback*/
2660 hcryp->ErrorCallback(hcryp);
2661 #else
2662 /*Call legacy weak error callback*/
2663 HAL_CRYP_ErrorCallback(hcryp);
2664 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2666 /* Enable In and Out DMA requests */
2667 SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
2671 * @brief Process Data: Write Input data in polling mode and used in AES functions.
2672 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2673 * the configuration information for CRYP module
2674 * @param Timeout Specify Timeout value
2675 * @retval None
2677 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2680 uint32_t temp; /* Temporary CrypOutBuff */
2682 /* Write the input block in the IN FIFO */
2683 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2684 hcryp->CrypInCount++;
2685 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2686 hcryp->CrypInCount++;
2687 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2688 hcryp->CrypInCount++;
2689 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2690 hcryp->CrypInCount++;
2692 /* Wait for CCF flag to be raised */
2693 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2695 /* Disable the CRYP peripheral clock */
2696 __HAL_CRYP_DISABLE(hcryp);
2698 /* Change state */
2699 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2700 hcryp->State = HAL_CRYP_STATE_READY;
2702 /* Process unlocked */
2703 __HAL_UNLOCK(hcryp);
2704 /*Call registered error callback*/
2705 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2706 hcryp->ErrorCallback(hcryp);
2707 #else
2708 /*Call legacy weak error callback*/
2709 HAL_CRYP_ErrorCallback(hcryp);
2710 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2713 /* Clear CCF Flag */
2714 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2716 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer*/
2717 temp = hcryp->Instance->DOUTR;
2718 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2719 hcryp->CrypOutCount++;
2720 temp = hcryp->Instance->DOUTR;
2721 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
2722 hcryp->CrypOutCount++;
2723 temp = hcryp->Instance->DOUTR;
2724 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2725 hcryp->CrypOutCount++;
2726 temp = hcryp->Instance->DOUTR;
2727 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
2728 hcryp->CrypOutCount++;
2733 * @brief Handle CRYP block input/output data handling under interruption.
2734 * @note The function is called under interruption only, once
2735 * interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
2736 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2737 * the configuration information for CRYP module.
2738 * @retval HAL status
2740 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
2742 uint32_t temp; /* Temporary CrypOutBuff */
2744 if (hcryp->State == HAL_CRYP_STATE_BUSY)
2746 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer*/
2747 temp = hcryp->Instance->DOUTR;
2748 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2749 hcryp->CrypOutCount++;
2750 temp = hcryp->Instance->DOUTR;
2751 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
2752 hcryp->CrypOutCount++;
2753 temp = hcryp->Instance->DOUTR;
2754 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2755 hcryp->CrypOutCount++;
2756 temp = hcryp->Instance->DOUTR;
2757 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
2758 hcryp->CrypOutCount++;
2760 if (hcryp->CrypOutCount == (hcryp->Size / 4U))
2762 /* Disable Computation Complete flag and errors interrupts */
2763 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
2765 /* Change the CRYP state */
2766 hcryp->State = HAL_CRYP_STATE_READY;
2768 /* Disable CRYP */
2769 __HAL_CRYP_DISABLE(hcryp);
2771 /* Process Unlocked */
2772 __HAL_UNLOCK(hcryp);
2774 /* Call Output transfer complete callback */
2775 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2776 /*Call registered Output complete callback*/
2777 hcryp->OutCpltCallback(hcryp);
2778 #else
2779 /*Call legacy weak Output complete callback*/
2780 HAL_CRYP_OutCpltCallback(hcryp);
2781 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2783 else
2785 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
2786 /* If suspension flag has been raised, suspend processing
2787 only if not already at the end of the payload */
2788 if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
2790 /* Clear CCF Flag */
2791 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2793 /* reset SuspendRequest */
2794 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
2795 /* Disable Computation Complete Flag and Errors Interrupts */
2796 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
2797 /* Change the CRYP state */
2798 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
2799 /* Mark that the payload phase is suspended */
2800 hcryp->Phase = CRYP_PHASE_PAYLOAD_SUSPENDED;
2802 /* Process Unlocked */
2803 __HAL_UNLOCK(hcryp);
2805 else
2806 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
2808 /* Write the input block in the IN FIFO */
2809 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2810 hcryp->CrypInCount++;
2811 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2812 hcryp->CrypInCount++;
2813 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2814 hcryp->CrypInCount++;
2815 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2816 hcryp->CrypInCount++;
2818 if (hcryp->CrypInCount == (hcryp->Size / 4U))
2820 /* Call Input transfer complete callback */
2821 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2822 /*Call registered Input complete callback*/
2823 hcryp->InCpltCallback(hcryp);
2824 #else
2825 /*Call legacy weak Input complete callback*/
2826 HAL_CRYP_InCpltCallback(hcryp);
2827 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2832 else
2834 /* Busy error code field */
2835 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
2836 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
2837 /*Call registered error callback*/
2838 hcryp->ErrorCallback(hcryp);
2839 #else
2840 /*Call legacy weak error callback*/
2841 HAL_CRYP_ErrorCallback(hcryp);
2842 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2847 * @brief Writes Key in Key registers.
2848 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2849 * the configuration information for CRYP module
2850 * @param KeySize Size of Key
2851 * @note If pKey is NULL, the Key registers are not written. This configuration
2852 * occurs when the key is written out of HAL scope.
2853 * @retval None
2855 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
2857 if (hcryp->Init.pKey != NULL)
2859 switch (KeySize)
2861 case CRYP_KEYSIZE_256B:
2862 hcryp->Instance->KEYR7 = *(uint32_t *)(hcryp->Init.pKey);
2863 hcryp->Instance->KEYR6 = *(uint32_t *)(hcryp->Init.pKey + 1U);
2864 hcryp->Instance->KEYR5 = *(uint32_t *)(hcryp->Init.pKey + 2U);
2865 hcryp->Instance->KEYR4 = *(uint32_t *)(hcryp->Init.pKey + 3U);
2866 hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey + 4U);
2867 hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 5U);
2868 hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 6U);
2869 hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 7U);
2870 break;
2871 case CRYP_KEYSIZE_128B:
2872 hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey);
2873 hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 1U);
2874 hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 2U);
2875 hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 3U);
2877 break;
2878 default:
2879 break;
2885 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
2886 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
2887 * the configuration information for CRYP module
2888 * @param Timeout Timeout duration
2889 * @retval HAL status
2891 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2893 uint32_t tickstart;
2894 uint32_t wordsize = ((uint32_t)hcryp->Size / 4U) ;
2895 uint32_t npblb;
2896 uint32_t temp; /* Temporary CrypOutBuff */
2897 uint32_t index;
2898 uint32_t lastwordsize;
2899 uint32_t incount; /* Temporary CrypInCount Value */
2900 uint32_t outcount; /* Temporary CrypOutCount Value */
2901 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2903 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2905 if (hcryp->KeyIVConfig == 1U)
2907 /* If the Key and IV configuration has to be done only once
2908 and if it has already been done, skip it */
2909 DoKeyIVConfig = 0U;
2910 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
2912 else
2914 /* If the Key and IV configuration has to be done only once
2915 and if it has not been done already, do it and set KeyIVConfig
2916 to keep track it won't have to be done again next time */
2917 hcryp->KeyIVConfig = 1U;
2918 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
2921 else
2923 hcryp->SizesSum = hcryp->Size;
2926 if (DoKeyIVConfig == 1U)
2929 /* Reset CrypHeaderCount */
2930 hcryp->CrypHeaderCount = 0U;
2932 /****************************** Init phase **********************************/
2934 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2936 /* Set the key */
2937 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2939 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
2940 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
2941 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2942 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2943 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2945 /* Enable the CRYP peripheral */
2946 __HAL_CRYP_ENABLE(hcryp);
2948 /* just wait for hash computation */
2949 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
2951 /* Change state */
2952 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2953 hcryp->State = HAL_CRYP_STATE_READY;
2955 /* Process unlocked & return error */
2956 __HAL_UNLOCK(hcryp);
2957 return HAL_ERROR;
2959 /* Clear CCF flag */
2960 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
2962 /************************ Header phase *************************************/
2964 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
2966 return HAL_ERROR;
2969 /*************************Payload phase ************************************/
2971 /* Set the phase */
2972 hcryp->Phase = CRYP_PHASE_PROCESS;
2974 /* Select payload phase once the header phase is performed */
2975 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2977 /* Set to 0 the number of non-valid bytes using NPBLB register*/
2978 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
2980 } /* if (DoKeyIVConfig == 1U) */
2982 if ((hcryp->Size % 16U) != 0U)
2984 /* recalculate wordsize */
2985 wordsize = ((wordsize / 4U) * 4U) ;
2988 /* Get tick */
2989 tickstart = HAL_GetTick();
2991 /* Write input data and get output Data */
2992 incount = hcryp->CrypInCount;
2993 outcount = hcryp->CrypOutCount;
2994 while ((incount < wordsize) && (outcount < wordsize))
2996 /* Write plain data and get cipher data */
2997 CRYP_AES_ProcessData(hcryp, Timeout);
2999 /* Check for the Timeout */
3000 if (Timeout != HAL_MAX_DELAY)
3002 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3004 /* Disable the CRYP peripheral clock */
3005 __HAL_CRYP_DISABLE(hcryp);
3007 /* Change state & error code */
3008 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3009 hcryp->State = HAL_CRYP_STATE_READY;
3011 /* Process unlocked */
3012 __HAL_UNLOCK(hcryp);
3013 return HAL_ERROR;
3016 incount = hcryp->CrypInCount;
3017 outcount = hcryp->CrypOutCount;
3020 if ((hcryp->Size % 16U) != 0U)
3022 /* Compute the number of padding bytes in last block of payload */
3023 npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
3025 /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3026 if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
3028 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3029 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3031 /* Number of valid words (lastwordsize) in last block */
3032 if ((npblb % 4U) == 0U)
3034 lastwordsize = (16U - npblb) / 4U;
3036 else
3038 lastwordsize = ((16U - npblb) / 4U) + 1U;
3040 /* last block optionally pad the data with zeros*/
3041 for (index = 0U; index < lastwordsize; index ++)
3043 /* Write the last Input block in the IN FIFO */
3044 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3045 hcryp->CrypInCount++;
3047 while (index < 4U)
3049 /* pad the data with zeros to have a complete block */
3050 hcryp->Instance->DINR = 0U;
3051 index++;
3053 /* Wait for CCF flag to be raised */
3054 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3056 hcryp->State = HAL_CRYP_STATE_READY;
3057 __HAL_UNLOCK(hcryp);
3059 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3060 /*Call registered error callback*/
3061 hcryp->ErrorCallback(hcryp);
3062 #else
3063 /*Call legacy weak error callback*/
3064 HAL_CRYP_ErrorCallback(hcryp);
3065 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3068 /* Clear CCF Flag */
3069 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3071 /*Read the output block from the output FIFO */
3072 for (index = 0U; index < 4U; index++)
3074 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3075 temp = hcryp->Instance->DOUTR;
3077 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
3078 hcryp->CrypOutCount++;
3082 /* Return function status */
3083 return HAL_OK;
3087 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
3088 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3089 * the configuration information for CRYP module
3090 * @retval HAL status
3092 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3094 __IO uint32_t count = 0U;
3095 uint32_t loopcounter;
3096 uint32_t lastwordsize;
3097 uint32_t npblb;
3098 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3100 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
3101 if ((hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) || (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED))
3103 CRYP_PhaseProcessingResume(hcryp);
3104 return HAL_OK;
3106 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
3108 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3110 if (hcryp->KeyIVConfig == 1U)
3112 /* If the Key and IV configuration has to be done only once
3113 and if it has already been done, skip it */
3114 DoKeyIVConfig = 0U;
3115 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3117 else
3119 /* If the Key and IV configuration has to be done only once
3120 and if it has not been done already, do it and set KeyIVConfig
3121 to keep track it won't have to be done again next time */
3122 hcryp->KeyIVConfig = 1U;
3123 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3126 else
3128 hcryp->SizesSum = hcryp->Size;
3131 /* Configure Key, IV and process message (header and payload) */
3132 if (DoKeyIVConfig == 1U)
3134 /* Reset CrypHeaderCount */
3135 hcryp->CrypHeaderCount = 0U;
3137 /******************************* Init phase *********************************/
3139 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3141 /* Set the key */
3142 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3144 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3145 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
3146 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
3147 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
3148 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
3150 /* Enable the CRYP peripheral */
3151 __HAL_CRYP_ENABLE(hcryp);
3153 /* just wait for hash computation */
3154 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3157 count-- ;
3158 if (count == 0U)
3160 /* Disable the CRYP peripheral clock */
3161 __HAL_CRYP_DISABLE(hcryp);
3163 /* Change state */
3164 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3165 hcryp->State = HAL_CRYP_STATE_READY;
3167 /* Process unlocked */
3168 __HAL_UNLOCK(hcryp);
3169 return HAL_ERROR;
3172 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
3174 /* Clear CCF flag */
3175 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3177 /***************************** Header phase *********************************/
3179 /* Select header phase */
3180 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3182 /* Enable computation complete flag and error interrupts */
3183 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3185 /* Enable the CRYP peripheral */
3186 __HAL_CRYP_ENABLE(hcryp);
3188 if (hcryp->Init.HeaderSize == 0U) /*header phase is skipped*/
3190 /* Set the phase */
3191 hcryp->Phase = CRYP_PHASE_PROCESS;
3193 /* Select payload phase once the header phase is performed */
3194 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
3196 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3197 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3199 /* Write the payload Input block in the IN FIFO */
3200 if (hcryp->Size == 0U)
3202 /* Disable interrupts */
3203 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3205 /* Change the CRYP state */
3206 hcryp->State = HAL_CRYP_STATE_READY;
3208 /* Process unlocked */
3209 __HAL_UNLOCK(hcryp);
3211 else if (hcryp->Size >= 16U)
3213 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3214 hcryp->CrypInCount++;
3215 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3216 hcryp->CrypInCount++;
3217 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3218 hcryp->CrypInCount++;
3219 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3220 hcryp->CrypInCount++;
3221 if (hcryp->CrypInCount == (hcryp->Size / 4U))
3223 /* Call Input transfer complete callback */
3224 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3225 /*Call registered Input complete callback*/
3226 hcryp->InCpltCallback(hcryp);
3227 #else
3228 /*Call legacy weak Input complete callback*/
3229 HAL_CRYP_InCpltCallback(hcryp);
3230 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3233 else /* Size < 16Bytes : first block is the last block*/
3235 /* Workaround not implemented for TinyAES2*/
3236 /* Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption:
3237 Workaround is implemented in polling mode, so if last block of
3238 payload <128bit do not use CRYP_Encrypt_IT otherwise TAG is incorrectly generated for GCM Encryption. */
3241 /* Compute the number of padding bytes in last block of payload */
3242 npblb = 16U - ((uint32_t)hcryp->Size);
3244 if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
3246 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3247 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3250 /* Number of valid words (lastwordsize) in last block */
3251 if ((npblb % 4U) == 0U)
3253 lastwordsize = (16U - npblb) / 4U;
3255 else
3257 lastwordsize = ((16U - npblb) / 4U) + 1U;
3260 /* last block optionally pad the data with zeros*/
3261 for (loopcounter = 0U; loopcounter < lastwordsize ; loopcounter++)
3263 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3264 hcryp->CrypInCount++;
3266 while (loopcounter < 4U)
3268 /* pad the data with zeros to have a complete block */
3269 hcryp->Instance->DINR = 0x0U;
3270 loopcounter++;
3274 else if ((hcryp->Init.HeaderSize) < 4U)
3276 for (loopcounter = 0U; loopcounter < hcryp->Init.HeaderSize ; loopcounter++)
3278 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3279 hcryp->CrypHeaderCount++ ;
3281 while (loopcounter < 4U)
3283 /* pad the data with zeros to have a complete block */
3284 hcryp->Instance->DINR = 0x0U;
3285 loopcounter++;
3287 /* Set the phase */
3288 hcryp->Phase = CRYP_PHASE_PROCESS;
3290 /* Select payload phase once the header phase is performed */
3291 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3293 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3294 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3296 /* Call Input transfer complete callback */
3297 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3298 /*Call registered Input complete callback*/
3299 hcryp->InCpltCallback(hcryp);
3300 #else
3301 /*Call legacy weak Input complete callback*/
3302 HAL_CRYP_InCpltCallback(hcryp);
3303 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3305 else
3307 /* Write the input block in the IN FIFO */
3308 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3309 hcryp->CrypHeaderCount++;
3310 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3311 hcryp->CrypHeaderCount++;
3312 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3313 hcryp->CrypHeaderCount++;
3314 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
3315 hcryp->CrypHeaderCount++;
3318 } /* end of if (DoKeyIVConfig == 1U) */
3319 else /* Key and IV have already been configured,
3320 header has already been processed;
3321 only process here message payload */
3324 /* Enable computation complete flag and error interrupts */
3325 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3327 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3328 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3330 /* Write the payload Input block in the IN FIFO */
3331 if (hcryp->Size == 0U)
3333 /* Disable interrupts */
3334 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3336 /* Change the CRYP state */
3337 hcryp->State = HAL_CRYP_STATE_READY;
3339 /* Process unlocked */
3340 __HAL_UNLOCK(hcryp);
3342 else if (hcryp->Size >= 16U)
3344 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3345 hcryp->CrypInCount++;
3346 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3347 hcryp->CrypInCount++;
3348 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3349 hcryp->CrypInCount++;
3350 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3351 hcryp->CrypInCount++;
3352 if (hcryp->CrypInCount == (hcryp->Size / 4U))
3354 /* Call Input transfer complete callback */
3355 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3356 /*Call registered Input complete callback*/
3357 hcryp->InCpltCallback(hcryp);
3358 #else
3359 /*Call legacy weak Input complete callback*/
3360 HAL_CRYP_InCpltCallback(hcryp);
3361 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3364 else /* Size < 16Bytes : first block is the last block*/
3366 /* Workaround not implemented for TinyAES2*/
3367 /* Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption:
3368 Workaround is implemented in polling mode, so if last block of
3369 payload <128bit do not use CRYP_Encrypt_IT otherwise TAG is incorrectly generated for GCM Encryption. */
3372 /* Compute the number of padding bytes in last block of payload */
3373 npblb = 16U - ((uint32_t)hcryp->Size);
3375 if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
3377 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3378 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3381 /* Number of valid words (lastwordsize) in last block */
3382 if ((npblb % 4U) == 0U)
3384 lastwordsize = (16U - npblb) / 4U;
3386 else
3388 lastwordsize = ((16U - npblb) / 4U) + 1U;
3391 /* last block optionally pad the data with zeros*/
3392 for (loopcounter = 0U; loopcounter < lastwordsize ; loopcounter++)
3394 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3395 hcryp->CrypInCount++;
3397 while (loopcounter < 4U)
3399 /* pad the data with zeros to have a complete block */
3400 hcryp->Instance->DINR = 0x0U;
3401 loopcounter++;
3406 /* Return function status */
3407 return HAL_OK;
3412 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
3413 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3414 * the configuration information for CRYP module
3415 * @retval HAL status
3417 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3419 __IO uint32_t count;
3420 uint16_t wordsize = hcryp->Size / 4U ;
3421 uint32_t index;
3422 uint32_t npblb;
3423 uint32_t lastwordsize;
3424 uint32_t temp; /* Temporary CrypOutBuff */
3425 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3427 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3429 if (hcryp->KeyIVConfig == 1U)
3431 /* If the Key and IV configuration has to be done only once
3432 and if it has already been done, skip it */
3433 DoKeyIVConfig = 0U;
3434 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3436 else
3438 /* If the Key and IV configuration has to be done only once
3439 and if it has not been done already, do it and set KeyIVConfig
3440 to keep track it won't have to be done again next time */
3441 hcryp->KeyIVConfig = 1U;
3442 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3445 else
3447 hcryp->SizesSum = hcryp->Size;
3450 if (DoKeyIVConfig == 1U)
3453 /* Reset CrypHeaderCount */
3454 hcryp->CrypHeaderCount = 0U;
3456 /*************************** Init phase ************************************/
3458 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3460 /* Set the key */
3461 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3463 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3464 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
3465 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
3466 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
3467 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
3469 /* Enable the CRYP peripheral */
3470 __HAL_CRYP_ENABLE(hcryp);
3472 /* just wait for hash computation */
3473 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3476 count-- ;
3477 if (count == 0U)
3479 /* Disable the CRYP peripheral clock */
3480 __HAL_CRYP_DISABLE(hcryp);
3482 /* Change state */
3483 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3484 hcryp->State = HAL_CRYP_STATE_READY;
3486 /* Process unlocked */
3487 __HAL_UNLOCK(hcryp);
3488 return HAL_ERROR;
3491 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
3493 /* Clear CCF flag */
3494 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3496 /************************ Header phase *************************************/
3498 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
3500 return HAL_ERROR;
3503 /************************ Payload phase ************************************/
3505 /* Set the phase */
3506 hcryp->Phase = CRYP_PHASE_PROCESS;
3508 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3509 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3511 /* Select payload phase once the header phase is performed */
3512 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3514 } /* if (DoKeyIVConfig == 1U) */
3516 if (hcryp->Size == 0U)
3518 /* Process unLocked */
3519 __HAL_UNLOCK(hcryp);
3521 /* Change the CRYP state and phase */
3522 hcryp->State = HAL_CRYP_STATE_READY;
3524 else if (hcryp->Size >= 16U)
3526 /*DMA transfer must not include the last block in case of Size is not %16 */
3527 wordsize = wordsize - (wordsize % 4U);
3529 /*DMA transfer */
3530 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
3532 else /* length of input data is < 16 */
3534 /* Compute the number of padding bytes in last block of payload */
3535 npblb = 16U - (uint32_t)hcryp->Size;
3537 /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3538 if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT)
3540 /* Specify the number of non-valid bytes using NPBLB register*/
3541 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3544 /* Enable CRYP to start the final phase */
3545 __HAL_CRYP_ENABLE(hcryp);
3547 /* Number of valid words (lastwordsize) in last block */
3548 if ((npblb % 4U) == 0U)
3550 lastwordsize = (16U - npblb) / 4U;
3552 else
3554 lastwordsize = ((16U - npblb) / 4U) + 1U;
3557 /* last block optionally pad the data with zeros*/
3558 for (index = 0U; index < lastwordsize; index ++)
3560 /* Write the last Input block in the IN FIFO */
3561 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3562 hcryp->CrypInCount++;
3564 while (index < 4U)
3566 /* pad the data with zeros to have a complete block */
3567 hcryp->Instance->DINR = 0U;
3568 index++;
3570 /* Wait for CCF flag to be raised */
3571 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
3574 count-- ;
3575 if (count == 0U)
3577 /* Disable the CRYP peripheral clock */
3578 __HAL_CRYP_DISABLE(hcryp);
3580 /* Change state */
3581 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3582 hcryp->State = HAL_CRYP_STATE_READY;
3584 /* Process unlocked */
3585 __HAL_UNLOCK(hcryp);
3586 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3587 /*Call registered error callback*/
3588 hcryp->ErrorCallback(hcryp);
3589 #else
3590 /*Call legacy weak error callback*/
3591 HAL_CRYP_ErrorCallback(hcryp);
3592 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3595 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
3597 /* Clear CCF Flag */
3598 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3600 /*Read the output block from the output FIFO */
3601 for (index = 0U; index < 4U; index++)
3603 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3604 temp = hcryp->Instance->DOUTR;
3606 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
3607 hcryp->CrypOutCount++;
3610 /* Change the CRYP state to ready */
3611 hcryp->State = HAL_CRYP_STATE_READY;
3613 /* Process unlocked */
3614 __HAL_UNLOCK(hcryp);
3617 /* Return function status */
3618 return HAL_OK;
3623 * @brief AES CCM encryption/decryption processing in polling mode
3624 * for TinyAES peripheral, no encrypt/decrypt performed, only authentication preparation.
3625 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3626 * the configuration information for CRYP module
3627 * @param Timeout Timeout duration
3628 * @retval HAL status
3630 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3632 uint32_t tickstart;
3633 uint32_t wordsize = ((uint32_t)hcryp->Size / 4U) ;
3634 uint32_t loopcounter;
3635 uint32_t npblb;
3636 uint32_t lastwordsize;
3637 uint32_t temp; /* Temporary CrypOutBuff */
3638 uint32_t incount; /* Temporary CrypInCount Value */
3639 uint32_t outcount; /* Temporary CrypOutCount Value */
3640 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3642 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3644 if (hcryp->KeyIVConfig == 1U)
3646 /* If the Key and IV configuration has to be done only once
3647 and if it has already been done, skip it */
3648 DoKeyIVConfig = 0U;
3649 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3651 else
3653 /* If the Key and IV configuration has to be done only once
3654 and if it has not been done already, do it and set KeyIVConfig
3655 to keep track it won't have to be done again next time */
3656 hcryp->KeyIVConfig = 1U;
3657 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3660 else
3662 hcryp->SizesSum = hcryp->Size;
3665 if (DoKeyIVConfig == 1U)
3667 /* Reset CrypHeaderCount */
3668 hcryp->CrypHeaderCount = 0U;
3670 /********************** Init phase ******************************************/
3672 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3674 /* Set the key */
3675 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3677 /* Set the initialization vector (IV) with B0 */
3678 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
3679 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
3680 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
3681 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
3683 /* Enable the CRYP peripheral */
3684 __HAL_CRYP_ENABLE(hcryp);
3686 /* just wait for hash computation */
3687 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3689 /* Change state */
3690 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3691 hcryp->State = HAL_CRYP_STATE_READY;
3693 /* Process unlocked & return error */
3694 __HAL_UNLOCK(hcryp);
3695 return HAL_ERROR;
3697 /* Clear CCF flag */
3698 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3700 /************************ Header phase *************************************/
3701 /* Header block(B1) : associated data length expressed in bytes concatenated
3702 with Associated Data (A)*/
3703 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
3705 return HAL_ERROR;
3708 /*************************Payload phase ************************************/
3710 /* Set the phase */
3711 hcryp->Phase = CRYP_PHASE_PROCESS;
3713 /* Select payload phase once the header phase is performed */
3714 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
3716 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3717 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3719 } /* if (DoKeyIVConfig == 1U) */
3721 if ((hcryp->Size % 16U) != 0U)
3723 /* recalculate wordsize */
3724 wordsize = ((wordsize / 4U) * 4U) ;
3726 /* Get tick */
3727 tickstart = HAL_GetTick();
3729 /* Write input data and get output data */
3730 incount = hcryp->CrypInCount;
3731 outcount = hcryp->CrypOutCount;
3732 while ((incount < wordsize) && (outcount < wordsize))
3734 /* Write plain data and get cipher data */
3735 CRYP_AES_ProcessData(hcryp, Timeout);
3737 /* Check for the Timeout */
3738 if (Timeout != HAL_MAX_DELAY)
3740 if (((HAL_GetTick() - tickstart) > Timeout) ||(Timeout == 0U))
3742 /* Disable the CRYP peripheral clock */
3743 __HAL_CRYP_DISABLE(hcryp);
3745 /* Change state */
3746 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3747 hcryp->State = HAL_CRYP_STATE_READY;
3749 /* Process unlocked */
3750 __HAL_UNLOCK(hcryp);
3751 return HAL_ERROR;
3754 incount = hcryp->CrypInCount;
3755 outcount = hcryp->CrypOutCount;
3758 if ((hcryp->Size % 16U) != 0U)
3760 /* Compute the number of padding bytes in last block of payload */
3761 npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
3763 if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT)
3765 /* Set Npblb in case of AES CCM payload decryption to get right tag */
3766 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20);
3769 /* Number of valid words (lastwordsize) in last block */
3770 if ((npblb % 4U) == 0U)
3772 lastwordsize = (16U - npblb) / 4U;
3774 else
3776 lastwordsize = ((16U - npblb) / 4U) + 1U;
3779 /* Write the last input block in the IN FIFO */
3780 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter ++)
3782 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3783 hcryp->CrypInCount++;
3786 /* Pad the data with zeros to have a complete block */
3787 while (loopcounter < 4U)
3789 hcryp->Instance->DINR = 0U;
3790 loopcounter++;
3792 /* just wait for hash computation */
3793 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
3795 /* Change state */
3796 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3797 hcryp->State = HAL_CRYP_STATE_READY;
3799 /* Process unlocked & return error */
3800 __HAL_UNLOCK(hcryp);
3801 return HAL_ERROR;
3803 /* Clear CCF flag */
3804 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3806 for (loopcounter = 0U; loopcounter < 4U; loopcounter++)
3808 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3809 temp = hcryp->Instance->DOUTR;
3811 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
3812 hcryp->CrypOutCount++;
3816 /* Return function status */
3817 return HAL_OK;
3821 * @brief AES CCM encryption/decryption process in interrupt mode
3822 * for TinyAES peripheral, no encrypt/decrypt performed, only authentication preparation.
3823 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
3824 * the configuration information for CRYP module
3825 * @retval HAL status
3827 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3829 __IO uint32_t count = 0U;
3830 uint32_t loopcounter;
3831 uint32_t lastwordsize;
3832 uint32_t npblb;
3833 uint32_t mode;
3834 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3836 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
3837 if ((hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) || (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED))
3839 CRYP_PhaseProcessingResume(hcryp);
3840 return HAL_OK;
3842 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
3844 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3846 if (hcryp->KeyIVConfig == 1U)
3848 /* If the Key and IV configuration has to be done only once
3849 and if it has already been done, skip it */
3850 DoKeyIVConfig = 0U;
3851 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3853 else
3855 /* If the Key and IV configuration has to be done only once
3856 and if it has not been done already, do it and set KeyIVConfig
3857 to keep track it won't have to be done again next time */
3858 hcryp->KeyIVConfig = 1U;
3859 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3862 else
3864 hcryp->SizesSum = hcryp->Size;
3867 /* Configure Key, IV and process message (header and payload) */
3868 if (DoKeyIVConfig == 1U)
3870 /* Reset CrypHeaderCount */
3871 hcryp->CrypHeaderCount = 0U;
3873 /********************** Init phase ******************************************/
3875 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3877 /* Set the key */
3878 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3880 /* Set the initialization vector (IV) with B0 */
3881 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
3882 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
3883 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
3884 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
3886 /* Enable the CRYP peripheral */
3887 __HAL_CRYP_ENABLE(hcryp);
3889 /* just wait for hash computation */
3890 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3893 count-- ;
3894 if (count == 0U)
3896 /* Disable the CRYP peripheral clock */
3897 __HAL_CRYP_DISABLE(hcryp);
3899 /* Change state */
3900 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3901 hcryp->State = HAL_CRYP_STATE_READY;
3903 /* Process unlocked */
3904 __HAL_UNLOCK(hcryp);
3905 return HAL_ERROR;
3908 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
3910 /* Clear CCF flag */
3911 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
3913 /***************************** Header phase *********************************/
3915 /* Select header phase */
3916 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3918 /* Enable computation complete flag and error interrupts */
3919 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3921 /* Enable the CRYP peripheral */
3922 __HAL_CRYP_ENABLE(hcryp);
3924 if (hcryp->Init.HeaderSize == 0U) /*header phase is skipped*/
3926 /* Set the phase */
3927 hcryp->Phase = CRYP_PHASE_PROCESS;
3928 /* Select payload phase once the header phase is performed */
3929 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3930 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3931 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
3933 if (hcryp->Init.Algorithm == CRYP_AES_CCM)
3935 /* Increment CrypHeaderCount to pass in CRYP_GCMCCM_SetPayloadPhase_IT */
3936 hcryp->CrypHeaderCount++;
3938 /* Write the payload Input block in the IN FIFO */
3939 if (hcryp->Size == 0U)
3941 /* Disable interrupts */
3942 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
3944 /* Change the CRYP state */
3945 hcryp->State = HAL_CRYP_STATE_READY;
3947 /* Process unlocked */
3948 __HAL_UNLOCK(hcryp);
3950 else if (hcryp->Size >= 16U)
3952 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3953 hcryp->CrypInCount++;
3954 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3955 hcryp->CrypInCount++;
3956 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3957 hcryp->CrypInCount++;
3958 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3959 hcryp->CrypInCount++;
3961 if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
3963 /* Call Input transfer complete callback */
3964 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
3965 /*Call registered Input complete callback*/
3966 hcryp->InCpltCallback(hcryp);
3967 #else
3968 /*Call legacy weak Input complete callback*/
3969 HAL_CRYP_InCpltCallback(hcryp);
3970 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3973 else /* Size < 4 words : first block is the last block*/
3975 /* Compute the number of padding bytes in last block of payload */
3976 npblb = 16U - (uint32_t)hcryp->Size;
3978 mode = hcryp->Instance->CR & AES_CR_MODE;
3979 if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
3980 ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
3982 /* Specify the number of non-valid bytes using NPBLB register*/
3983 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
3986 /* Number of valid words (lastwordsize) in last block */
3987 if ((npblb % 4U) == 0U)
3989 lastwordsize = (16U - npblb) / 4U;
3991 else
3993 lastwordsize = ((16U - npblb) / 4U) + 1U;
3996 /* Last block optionally pad the data with zeros*/
3997 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
3999 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4000 hcryp->CrypInCount++;
4002 while (loopcounter < 4U)
4004 /* Pad the data with zeros to have a complete block */
4005 hcryp->Instance->DINR = 0x0U;
4006 loopcounter++;
4010 else if ((hcryp->Init.HeaderSize) < 4U) /*HeaderSize < 4 */
4012 /* Last block optionally pad the data with zeros*/
4013 for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
4015 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4016 hcryp->CrypHeaderCount++ ;
4018 while (loopcounter < 4U)
4020 /* pad the data with zeros to have a complete block */
4021 hcryp->Instance->DINR = 0x0U;
4022 loopcounter++;
4025 else
4027 /* Write the input block in the IN FIFO */
4028 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4029 hcryp->CrypHeaderCount++;
4030 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4031 hcryp->CrypHeaderCount++;
4032 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4033 hcryp->CrypHeaderCount++;
4034 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4035 hcryp->CrypHeaderCount++;
4038 } /* end of if (DoKeyIVConfig == 1U) */
4039 else /* Key and IV have already been configured,
4040 header has already been processed;
4041 only process here message payload */
4043 /* Write the payload Input block in the IN FIFO */
4044 if (hcryp->Size == 0U)
4046 /* Disable interrupts */
4047 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
4049 /* Change the CRYP state */
4050 hcryp->State = HAL_CRYP_STATE_READY;
4052 /* Process unlocked */
4053 __HAL_UNLOCK(hcryp);
4055 else if (hcryp->Size >= 16U)
4057 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4058 hcryp->CrypInCount++;
4059 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4060 hcryp->CrypInCount++;
4061 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4062 hcryp->CrypInCount++;
4063 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4064 hcryp->CrypInCount++;
4066 if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4068 /* Call Input transfer complete callback */
4069 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4070 /*Call registered Input complete callback*/
4071 hcryp->InCpltCallback(hcryp);
4072 #else
4073 /*Call legacy weak Input complete callback*/
4074 HAL_CRYP_InCpltCallback(hcryp);
4075 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4078 else /* Size < 4 words : first block is the last block*/
4080 /* Compute the number of padding bytes in last block of payload */
4081 npblb = 16U - (uint32_t)hcryp->Size;
4083 mode = hcryp->Instance->CR & AES_CR_MODE;
4084 if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
4085 ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4087 /* Specify the number of non-valid bytes using NPBLB register*/
4088 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4091 /* Number of valid words (lastwordsize) in last block */
4092 if ((npblb % 4U) == 0U)
4094 lastwordsize = (16U - npblb) / 4U;
4096 else
4098 lastwordsize = ((16U - npblb) / 4U) + 1U;
4101 /* Last block optionally pad the data with zeros*/
4102 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4104 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4105 hcryp->CrypInCount++;
4107 while (loopcounter < 4U)
4109 /* Pad the data with zeros to have a complete block */
4110 hcryp->Instance->DINR = 0x0U;
4111 loopcounter++;
4116 /* Return function status */
4117 return HAL_OK;
4121 * @brief AES CCM encryption/decryption process in DMA mode
4122 * for TinyAES peripheral, no encrypt/decrypt performed, only authentication preparation.
4123 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4124 * the configuration information for CRYP module
4125 * @retval HAL status
4127 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
4129 __IO uint32_t count = 0U;
4130 uint16_t wordsize = hcryp->Size / 4U ;
4131 uint32_t index;
4132 uint32_t npblb;
4133 uint32_t lastwordsize;
4134 uint32_t temp; /* Temporary CrypOutBuff */
4135 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
4137 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
4139 if (hcryp->KeyIVConfig == 1U)
4141 /* If the Key and IV configuration has to be done only once
4142 and if it has already been done, skip it */
4143 DoKeyIVConfig = 0U;
4144 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
4146 else
4148 /* If the Key and IV configuration has to be done only once
4149 and if it has not been done already, do it and set KeyIVConfig
4150 to keep track it won't have to be done again next time */
4151 hcryp->KeyIVConfig = 1U;
4152 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
4155 else
4157 hcryp->SizesSum = hcryp->Size;
4160 if (DoKeyIVConfig == 1U)
4163 /* Reset CrypHeaderCount */
4164 hcryp->CrypHeaderCount = 0U;
4167 /********************** Init phase ******************************************/
4169 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
4171 /* Set the key */
4172 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
4174 /* Set the initialization vector (IV) with B0 */
4175 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0);
4176 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U);
4177 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U);
4178 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U);
4180 /* Enable the CRYP peripheral */
4181 __HAL_CRYP_ENABLE(hcryp);
4183 /* just wait for hash computation */
4184 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
4187 count-- ;
4188 if (count == 0U)
4190 /* Disable the CRYP peripheral clock */
4191 __HAL_CRYP_DISABLE(hcryp);
4193 /* Change state */
4194 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4195 hcryp->State = HAL_CRYP_STATE_READY;
4197 /* Process unlocked */
4198 __HAL_UNLOCK(hcryp);
4199 return HAL_ERROR;
4202 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
4204 /* Clear CCF flag */
4205 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4208 /********************* Header phase *****************************************/
4210 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
4212 return HAL_ERROR;
4215 /******************** Payload phase *****************************************/
4217 /* Set the phase */
4218 hcryp->Phase = CRYP_PHASE_PROCESS;
4220 /* Set to 0 the number of non-valid bytes using NPBLB register*/
4221 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
4223 /* Select payload phase once the header phase is performed */
4224 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
4226 } /* if (DoKeyIVConfig == 1U) */
4228 if (hcryp->Size == 0U)
4230 /* Process unLocked */
4231 __HAL_UNLOCK(hcryp);
4233 /* Change the CRYP state and phase */
4234 hcryp->State = HAL_CRYP_STATE_READY;
4236 else if (hcryp->Size >= 16U)
4238 /*DMA transfer must not include the last block in case of Size is not %16 */
4239 wordsize = wordsize - (wordsize % 4U);
4241 /*DMA transfer */
4242 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
4244 else /* length of input data is < 16 */
4246 /* Compute the number of padding bytes in last block of payload */
4247 npblb = 16U - (uint32_t)hcryp->Size;
4249 /* Set Npblb in case of AES CCM payload decryption to get right tag*/
4250 if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT)
4252 /* Specify the number of non-valid bytes using NPBLB register*/
4253 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4256 /* Number of valid words (lastwordsize) in last block */
4257 if ((npblb % 4U) == 0U)
4259 lastwordsize = (16U - npblb) / 4U;
4261 else
4263 lastwordsize = ((16U - npblb) / 4U) + 1U;
4266 /* last block optionally pad the data with zeros*/
4267 for (index = 0U; index < lastwordsize; index ++)
4269 /* Write the last Input block in the IN FIFO */
4270 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4271 hcryp->CrypInCount++;
4273 while (index < 4U)
4275 /* pad the data with zeros to have a complete block */
4276 hcryp->Instance->DINR = 0U;
4277 index++;
4279 /* Wait for CCF flag to be raised */
4280 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4283 count-- ;
4284 if (count == 0U)
4286 /* Disable the CRYP peripheral clock */
4287 __HAL_CRYP_DISABLE(hcryp);
4289 /* Change state */
4290 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4291 hcryp->State = HAL_CRYP_STATE_READY;
4293 /* Process unlocked */
4294 __HAL_UNLOCK(hcryp);
4295 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4296 /*Call registered error callback*/
4297 hcryp->ErrorCallback(hcryp);
4298 #else
4299 /*Call legacy weak error callback*/
4300 HAL_CRYP_ErrorCallback(hcryp);
4301 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4304 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
4306 /* Clear CCF Flag */
4307 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4309 /*Read the output block from the output FIFO */
4310 for (index = 0U; index < 4U; index++)
4312 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
4313 temp = hcryp->Instance->DOUTR;
4315 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
4316 hcryp->CrypOutCount++;
4319 /* Change the CRYP state to ready */
4320 hcryp->State = HAL_CRYP_STATE_READY;
4322 /* Process unlocked */
4323 __HAL_UNLOCK(hcryp);
4326 /* Return function status */
4327 return HAL_OK;
4331 * @brief Sets the payload phase in interrupt mode
4332 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4333 * the configuration information for CRYP module
4334 * @retval state
4336 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
4338 uint32_t loopcounter;
4339 uint32_t temp; /* Temporary CrypOutBuff */
4340 uint32_t lastwordsize;
4341 uint32_t npblb;
4342 uint32_t mode;
4343 uint16_t incount; /* Temporary CrypInCount Value */
4344 uint16_t outcount; /* Temporary CrypOutCount Value */
4346 /***************************** Payload phase *******************************/
4348 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer*/
4349 temp = hcryp->Instance->DOUTR;
4350 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
4351 hcryp->CrypOutCount++;
4352 temp = hcryp->Instance->DOUTR;
4353 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
4354 hcryp->CrypOutCount++;
4355 temp = hcryp->Instance->DOUTR;
4356 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
4357 hcryp->CrypOutCount++;
4358 temp = hcryp->Instance->DOUTR;
4359 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
4360 hcryp->CrypOutCount++;
4362 incount = hcryp->CrypInCount;
4363 outcount = hcryp->CrypOutCount;
4364 if ((outcount >= (hcryp->Size / 4U)) && ((incount * 4U) >= hcryp->Size))
4367 /* When in CCM with Key and IV configuration skipped, don't disable interruptions */
4368 if (!((hcryp->Init.Algorithm == CRYP_AES_CCM) && (hcryp->KeyIVConfig == 1U)))
4370 /* Disable computation complete flag and errors interrupts */
4371 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
4374 /* Change the CRYP state */
4375 hcryp->State = HAL_CRYP_STATE_READY;
4377 /* Process unlocked */
4378 __HAL_UNLOCK(hcryp);
4380 /* Call output transfer complete callback */
4381 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4382 /*Call registered Output complete callback*/
4383 hcryp->OutCpltCallback(hcryp);
4384 #else
4385 /*Call legacy weak Output complete callback*/
4386 HAL_CRYP_OutCpltCallback(hcryp);
4387 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4390 else if (((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U)
4393 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
4394 /* If suspension flag has been raised, suspend processing
4395 only if not already at the end of the payload */
4396 if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
4398 /* Clear CCF Flag */
4399 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4401 /* reset SuspendRequest */
4402 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
4403 /* Disable Computation Complete Flag and Errors Interrupts */
4404 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
4405 /* Change the CRYP state */
4406 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
4407 /* Mark that the payload phase is suspended */
4408 hcryp->Phase = CRYP_PHASE_PAYLOAD_SUSPENDED;
4410 /* Process Unlocked */
4411 __HAL_UNLOCK(hcryp);
4413 else
4414 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
4416 /* Write the input block in the IN FIFO */
4417 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4418 hcryp->CrypInCount++;
4419 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4420 hcryp->CrypInCount++;
4421 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4422 hcryp->CrypInCount++;
4423 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4424 hcryp->CrypInCount++;
4425 if ((hcryp->CrypInCount == hcryp->Size) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC))
4427 /* Call output transfer complete callback */
4428 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4429 /*Call registered Input complete callback*/
4430 hcryp->InCpltCallback(hcryp);
4431 #else
4432 /*Call legacy weak Input complete callback*/
4433 HAL_CRYP_InCpltCallback(hcryp);
4434 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4438 else /* Last block of payload < 128bit*/
4440 /* Compute the number of padding bytes in last block of payload */
4441 npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size);
4443 mode = hcryp->Instance->CR & AES_CR_MODE;
4444 if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
4445 ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4447 /* Specify the number of non-valid bytes using NPBLB register*/
4448 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4451 /* Number of valid words (lastwordsize) in last block */
4452 if ((npblb % 4U) == 0U)
4454 lastwordsize = (16U - npblb) / 4U;
4456 else
4458 lastwordsize = ((16U - npblb) / 4U) + 1U;
4461 /* Last block optionally pad the data with zeros*/
4462 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4464 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4465 hcryp->CrypInCount++;
4467 while (loopcounter < 4U)
4469 /* pad the data with zeros to have a complete block */
4470 hcryp->Instance->DINR = 0x0U;
4471 loopcounter++;
4478 * @brief Sets the header phase in polling mode
4479 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4480 * the configuration information for CRYP module(Header & HeaderSize)
4481 * @param Timeout Timeout value
4482 * @retval state
4484 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4486 uint32_t loopcounter;
4488 /***************************** Header phase for GCM/GMAC or CCM *********************************/
4490 if ((hcryp->Init.HeaderSize != 0U))
4492 /* Select header phase */
4493 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4495 /* Enable the CRYP peripheral */
4496 __HAL_CRYP_ENABLE(hcryp);
4498 if ((hcryp->Init.HeaderSize % 4U) == 0U)
4500 /* HeaderSize %4, no padding */
4501 for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4503 /* Write the input block in the data input register */
4504 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4505 hcryp->CrypHeaderCount++ ;
4506 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4507 hcryp->CrypHeaderCount++ ;
4508 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4509 hcryp->CrypHeaderCount++ ;
4510 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4511 hcryp->CrypHeaderCount++ ;
4513 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4515 /* Disable the CRYP peripheral clock */
4516 __HAL_CRYP_DISABLE(hcryp);
4518 /* Change state */
4519 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4520 hcryp->State = HAL_CRYP_STATE_READY;
4522 /* Process unlocked */
4523 __HAL_UNLOCK(hcryp);
4524 return HAL_ERROR;
4526 /* Clear CCF flag */
4527 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4530 else
4532 /*Write header block in the IN FIFO without last block */
4533 for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U))); loopcounter += 4U)
4535 /* Write the input block in the data input register */
4536 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4537 hcryp->CrypHeaderCount++ ;
4538 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4539 hcryp->CrypHeaderCount++ ;
4540 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4541 hcryp->CrypHeaderCount++ ;
4542 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4543 hcryp->CrypHeaderCount++ ;
4545 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4547 /* Disable the CRYP peripheral clock */
4548 __HAL_CRYP_DISABLE(hcryp);
4550 /* Change state */
4551 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4552 hcryp->State = HAL_CRYP_STATE_READY;
4554 /* Process unlocked */
4555 __HAL_UNLOCK(hcryp);
4556 return HAL_ERROR;
4558 /* Clear CCF flag */
4559 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4561 /* Last block optionally pad the data with zeros*/
4562 for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4564 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4565 hcryp->CrypHeaderCount++ ;
4567 while (loopcounter < 4U)
4569 /*Pad the data with zeros to have a complete block */
4570 hcryp->Instance->DINR = 0x0U;
4571 loopcounter++;
4574 if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
4576 /* Disable the CRYP peripheral clock */
4577 __HAL_CRYP_DISABLE(hcryp);
4579 /* Change state */
4580 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4581 hcryp->State = HAL_CRYP_STATE_READY;
4583 /* Process unlocked */
4584 __HAL_UNLOCK(hcryp);
4585 return HAL_ERROR;
4587 /* Clear CCF flag */
4588 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4591 else
4593 if (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)
4595 /*Workaround 1: only AES, before re-enabling the peripheral, datatype can be configured.*/
4596 MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE, hcryp->Init.DataType);
4598 /* Select header phase */
4599 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4601 /* Enable the CRYP peripheral */
4602 __HAL_CRYP_ENABLE(hcryp);
4605 /* Return function status */
4606 return HAL_OK;
4610 * @brief Sets the header phase when using DMA in process
4611 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4612 * the configuration information for CRYP module(Header & HeaderSize)
4613 * @retval None
4615 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
4617 __IO uint32_t count = 0U;
4618 uint32_t loopcounter;
4620 /***************************** Header phase for GCM/GMAC or CCM *********************************/
4621 if ((hcryp->Init.HeaderSize != 0U))
4623 /* Select header phase */
4624 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4626 /* Enable the CRYP peripheral */
4627 __HAL_CRYP_ENABLE(hcryp);
4629 if ((hcryp->Init.HeaderSize % 4U) == 0U)
4631 /* HeaderSize %4, no padding */
4632 for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4634 /* Write the input block in the data input register */
4635 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4636 hcryp->CrypHeaderCount++ ;
4637 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4638 hcryp->CrypHeaderCount++ ;
4639 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4640 hcryp->CrypHeaderCount++ ;
4641 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4642 hcryp->CrypHeaderCount++ ;
4644 /*Wait on CCF flag*/
4645 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4648 count-- ;
4649 if (count == 0U)
4651 /* Disable the CRYP peripheral clock */
4652 __HAL_CRYP_DISABLE(hcryp);
4654 /* Change state */
4655 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4656 hcryp->State = HAL_CRYP_STATE_READY;
4658 /* Process unlocked */
4659 __HAL_UNLOCK(hcryp);
4660 return HAL_ERROR;
4663 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
4665 /* Clear CCF flag */
4666 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4669 else
4671 /*Write header block in the IN FIFO without last block */
4672 for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U))); loopcounter += 4U)
4674 /* Write the Input block in the Data Input register */
4675 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4676 hcryp->CrypHeaderCount++ ;
4677 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4678 hcryp->CrypHeaderCount++ ;
4679 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4680 hcryp->CrypHeaderCount++ ;
4681 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4682 hcryp->CrypHeaderCount++ ;
4684 /*Wait on CCF flag*/
4685 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4688 count-- ;
4689 if (count == 0U)
4691 /* Disable the CRYP peripheral clock */
4692 __HAL_CRYP_DISABLE(hcryp);
4694 /* Change state */
4695 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4696 hcryp->State = HAL_CRYP_STATE_READY;
4698 /* Process unlocked */
4699 __HAL_UNLOCK(hcryp);
4700 return HAL_ERROR;
4703 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
4705 /* Clear CCF flag */
4706 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4708 /* Last block optionally pad the data with zeros*/
4709 for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4711 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4712 hcryp->CrypHeaderCount++ ;
4714 while (loopcounter < 4U)
4716 /* Pad the data with zeros to have a complete block */
4717 hcryp->Instance->DINR = 0x0U;
4718 loopcounter++;
4721 /*Wait on CCF flag*/
4722 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4725 count-- ;
4726 if (count == 0U)
4728 /* Disable the CRYP peripheral clock */
4729 __HAL_CRYP_DISABLE(hcryp);
4731 /* Change state */
4732 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4733 hcryp->State = HAL_CRYP_STATE_READY;
4735 /* Process unlocked */
4736 __HAL_UNLOCK(hcryp);
4737 return HAL_ERROR;
4740 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF));
4742 /* Clear CCF flag */
4743 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4746 else
4748 /* Select header phase */
4749 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4751 /* Enable the CRYP peripheral */
4752 __HAL_CRYP_ENABLE(hcryp);
4754 /* Return function status */
4755 return HAL_OK;
4759 * @brief Sets the header phase in interrupt mode
4760 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4761 * the configuration information for CRYP module(Header & HeaderSize)
4762 * @retval None
4764 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
4766 uint32_t loopcounter;
4767 uint32_t lastwordsize;
4768 uint32_t npblb;
4769 uint32_t mode;
4771 /***************************** Header phase *********************************/
4772 if (hcryp->Init.HeaderSize == hcryp->CrypHeaderCount)
4774 /* Set the phase */
4775 hcryp->Phase = CRYP_PHASE_PROCESS;
4776 /* Select payload phase */
4777 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
4778 /* Set to 0 the number of non-valid bytes using NPBLB register*/
4779 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
4781 if (hcryp->Init.Algorithm == CRYP_AES_CCM)
4783 /* Increment CrypHeaderCount to pass in CRYP_GCMCCM_SetPayloadPhase_IT */
4784 hcryp->CrypHeaderCount++;
4786 /* Write the payload Input block in the IN FIFO */
4787 if (hcryp->Size == 0U)
4789 /* Disable interrupts */
4790 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
4792 /* Change the CRYP state */
4793 hcryp->State = HAL_CRYP_STATE_READY;
4795 /* Process unlocked */
4796 __HAL_UNLOCK(hcryp);
4798 else if (hcryp->Size >= 16U)
4800 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4801 hcryp->CrypInCount++;
4802 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4803 hcryp->CrypInCount++;
4804 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4805 hcryp->CrypInCount++;
4806 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4807 hcryp->CrypInCount++;
4809 if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U))
4811 /* Call the input data transfer complete callback */
4812 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4813 /*Call registered Input complete callback*/
4814 hcryp->InCpltCallback(hcryp);
4815 #else
4816 /*Call legacy weak Input complete callback*/
4817 HAL_CRYP_InCpltCallback(hcryp);
4818 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4821 else /* Size < 4 words : first block is the last block*/
4823 /* Compute the number of padding bytes in last block of payload */
4824 npblb = 16U - ((uint32_t)hcryp->Size);
4825 mode = hcryp->Instance->CR & AES_CR_MODE;
4826 if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
4827 ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4829 /* Specify the number of non-valid bytes using NPBLB register*/
4830 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U);
4833 /* Number of valid words (lastwordsize) in last block */
4834 if ((npblb % 4U) == 0U)
4836 lastwordsize = (16U - npblb) / 4U;
4838 else
4840 lastwordsize = ((16U - npblb) / 4U) + 1U;
4843 /* Last block optionally pad the data with zeros*/
4844 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4846 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4847 hcryp->CrypInCount++;
4849 while (loopcounter < 4U)
4851 /* Pad the data with zeros to have a complete block */
4852 hcryp->Instance->DINR = 0x0U;
4853 loopcounter++;
4857 else if ((((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U))
4860 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
4861 /* If suspension flag has been raised, suspend processing
4862 only if not already at the end of the header */
4863 if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
4865 /* Clear CCF Flag */
4866 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
4868 /* reset SuspendRequest */
4869 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
4870 /* Disable Computation Complete Flag and Errors Interrupts */
4871 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
4872 /* Change the CRYP state */
4873 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
4874 /* Mark that the payload phase is suspended */
4875 hcryp->Phase = CRYP_PHASE_HEADER_SUSPENDED;
4877 /* Process Unlocked */
4878 __HAL_UNLOCK(hcryp);
4880 else
4881 #endif /* USE_HAL_CRYP_SUSPEND_RESUME */
4883 /* Write the input block in the IN FIFO */
4884 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4885 hcryp->CrypHeaderCount++;
4886 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4887 hcryp->CrypHeaderCount++;
4888 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4889 hcryp->CrypHeaderCount++;
4890 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4891 hcryp->CrypHeaderCount++;
4894 else /*HeaderSize < 4 or HeaderSize >4 & HeaderSize %4 != 0*/
4896 /* Last block optionally pad the data with zeros*/
4897 for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
4899 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4900 hcryp->CrypHeaderCount++ ;
4902 while (loopcounter < 4U)
4904 /* pad the data with zeros to have a complete block */
4905 hcryp->Instance->DINR = 0x0U;
4906 loopcounter++;
4912 * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
4913 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4914 * the configuration information for CRYP module.
4915 * @param Timeout Timeout duration.
4916 * @retval HAL status
4918 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4920 uint32_t tickstart;
4922 /* Get timeout */
4923 tickstart = HAL_GetTick();
4925 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
4927 /* Check for the Timeout */
4928 if (Timeout != HAL_MAX_DELAY)
4930 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
4932 return HAL_ERROR;
4936 return HAL_OK;
4940 #if (USE_HAL_CRYP_SUSPEND_RESUME == 1U)
4942 * @brief In case of message processing suspension, read the Initialization Vector.
4943 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4944 * the configuration information for CRYP module.
4945 * @param Output Pointer to the buffer containing the saved Initialization Vector.
4946 * @note This value has to be stored for reuse by writing the AES_IVRx registers
4947 * as soon as the suspended processing has to be resumed.
4948 * @retval None
4950 static void CRYP_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output)
4952 uint32_t outputaddr = (uint32_t)Output;
4954 *(uint32_t*)(outputaddr) = hcryp->Instance->IVR3;
4955 outputaddr+=4U;
4956 *(uint32_t*)(outputaddr) = hcryp->Instance->IVR2;
4957 outputaddr+=4U;
4958 *(uint32_t*)(outputaddr) = hcryp->Instance->IVR1;
4959 outputaddr+=4U;
4960 *(uint32_t*)(outputaddr) = hcryp->Instance->IVR0;
4964 * @brief In case of message processing resumption, rewrite the Initialization
4965 * Vector in the AES_IVRx registers.
4966 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4967 * the configuration information for CRYP module.
4968 * @param Input Pointer to the buffer containing the saved Initialization Vector to
4969 * write back in the CRYP hardware block.
4970 * @note AES must be disabled when reconfiguring the IV values.
4971 * @retval None
4973 static void CRYP_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input)
4975 uint32_t ivaddr = (uint32_t)Input;
4977 hcryp->Instance->IVR3 = *(uint32_t*)(ivaddr);
4978 ivaddr+=4U;
4979 hcryp->Instance->IVR2 = *(uint32_t*)(ivaddr);
4980 ivaddr+=4U;
4981 hcryp->Instance->IVR1 = *(uint32_t*)(ivaddr);
4982 ivaddr+=4U;
4983 hcryp->Instance->IVR0 = *(uint32_t*)(ivaddr);
4987 * @brief In case of message GCM/GMAC/CCM processing suspension,
4988 * read the Suspend Registers.
4989 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
4990 * the configuration information for CRYP module.
4991 * @param Output Pointer to the buffer containing the saved Suspend Registers.
4992 * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers
4993 * as soon as the suspended processing has to be resumed.
4994 * @retval None
4996 static void CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output)
4998 uint32_t outputaddr = (uint32_t)Output;
4999 __IO uint32_t count = 0U;
5001 /* In case of GCM payload phase encryption, check that suspension can be carried out */
5002 if (READ_BIT(hcryp->Instance->CR, (AES_CR_CHMOD|AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_AES_GCM_GMAC|AES_CR_GCMPH_1|0x0))
5005 /* Wait for BUSY flag to be cleared */
5006 count = 0xFFF;
5009 count-- ;
5010 if(count == 0U)
5012 /* Change state */
5013 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5014 hcryp->State = HAL_CRYP_STATE_READY;
5016 /* Process unlocked */
5017 __HAL_UNLOCK(hcryp);
5018 HAL_CRYP_ErrorCallback(hcryp);
5019 return;
5022 while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY));
5027 *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP7R;
5028 outputaddr+=4U;
5029 *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP6R;
5030 outputaddr+=4U;
5031 *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP5R;
5032 outputaddr+=4U;
5033 *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP4R;
5034 outputaddr+=4U;
5035 *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP3R;
5036 outputaddr+=4U;
5037 *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP2R;
5038 outputaddr+=4U;
5039 *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP1R;
5040 outputaddr+=4U;
5041 *(uint32_t*)(outputaddr) = hcryp->Instance->SUSP0R;
5045 * @brief In case of message GCM/GMAC/CCM processing resumption, rewrite the Suspend
5046 * Registers in the AES_SUSPxR registers.
5047 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5048 * the configuration information for CRYP module.
5049 * @param Input Pointer to the buffer containing the saved suspend registers to
5050 * write back in the CRYP hardware block.
5051 * @note AES must be disabled when reconfiguring the suspend registers.
5052 * @retval None
5054 static void CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input)
5056 uint32_t ivaddr = (uint32_t)Input;
5058 hcryp->Instance->SUSP7R = *(uint32_t*)(ivaddr);
5059 ivaddr+=4U;
5060 hcryp->Instance->SUSP6R = *(uint32_t*)(ivaddr);
5061 ivaddr+=4U;
5062 hcryp->Instance->SUSP5R = *(uint32_t*)(ivaddr);
5063 ivaddr+=4U;
5064 hcryp->Instance->SUSP4R = *(uint32_t*)(ivaddr);
5065 ivaddr+=4U;
5066 hcryp->Instance->SUSP3R = *(uint32_t*)(ivaddr);
5067 ivaddr+=4U;
5068 hcryp->Instance->SUSP2R = *(uint32_t*)(ivaddr);
5069 ivaddr+=4U;
5070 hcryp->Instance->SUSP1R = *(uint32_t*)(ivaddr);
5071 ivaddr+=4U;
5072 hcryp->Instance->SUSP0R = *(uint32_t*)(ivaddr);
5076 * @brief In case of message GCM/GMAC/CCM processing suspension, read the Key Registers.
5077 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5078 * the configuration information for CRYP module.
5079 * @param Output Pointer to the buffer containing the saved Key Registers.
5080 * @param KeySize Indicates the key size (128 or 256 bits).
5081 * @note These values have to be stored for reuse by writing back the AES_KEYRx registers
5082 * as soon as the suspended processing has to be resumed.
5083 * @retval None
5085 static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Output, uint32_t KeySize)
5087 uint32_t keyaddr = (uint32_t)Output;
5089 switch (KeySize)
5091 case CRYP_KEYSIZE_256B:
5092 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey);
5093 keyaddr+=4U;
5094 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 1U);
5095 keyaddr+=4U;
5096 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 2U);
5097 keyaddr+=4U;
5098 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 3U);
5099 keyaddr+=4U;
5100 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 4U);
5101 keyaddr+=4U;
5102 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 5U);
5103 keyaddr+=4U;
5104 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 6U);
5105 keyaddr+=4U;
5106 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 7U);
5107 break;
5108 case CRYP_KEYSIZE_128B:
5109 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey);
5110 keyaddr+=4U;
5111 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 1U);
5112 keyaddr+=4U;
5113 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 2U);
5114 keyaddr+=4U;
5115 *(uint32_t*)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 3U);
5116 break;
5117 default:
5118 break;
5123 * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key
5124 * Registers in the AES_KEYRx registers.
5125 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5126 * the configuration information for CRYP module.
5127 * @param Input Pointer to the buffer containing the saved key registers to
5128 * write back in the CRYP hardware block.
5129 * @param KeySize Indicates the key size (128 or 256 bits)
5130 * @note AES must be disabled when reconfiguring the Key registers.
5131 * @retval None
5133 static void CRYP_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint32_t* Input, uint32_t KeySize)
5135 uint32_t keyaddr = (uint32_t)Input;
5137 if (KeySize == CRYP_KEYSIZE_256B)
5139 hcryp->Instance->KEYR7 = *(uint32_t*)(keyaddr);
5140 keyaddr+=4;
5141 hcryp->Instance->KEYR6 = *(uint32_t*)(keyaddr);
5142 keyaddr+=4;
5143 hcryp->Instance->KEYR5 = *(uint32_t*)(keyaddr);
5144 keyaddr+=4;
5145 hcryp->Instance->KEYR4 = *(uint32_t*)(keyaddr);
5146 keyaddr+=4;
5149 hcryp->Instance->KEYR3 = *(uint32_t*)(keyaddr);
5150 keyaddr+=4;
5151 hcryp->Instance->KEYR2 = *(uint32_t*)(keyaddr);
5152 keyaddr+=4;
5153 hcryp->Instance->KEYR1 = *(uint32_t*)(keyaddr);
5154 keyaddr+=4;
5155 hcryp->Instance->KEYR0 = *(uint32_t*)(keyaddr);
5159 * @brief Authentication phase resumption in case of GCM/GMAC/CCM process in interrupt mode
5160 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
5161 * the configuration information for CRYP module(Header & HeaderSize)
5162 * @retval None
5164 static void CRYP_PhaseProcessingResume(CRYP_HandleTypeDef *hcryp)
5166 uint32_t loopcounter = 0U;
5167 uint32_t lastwordsize =0;
5168 uint32_t npblb = 0U ;
5170 /* Case of header phase resumption =================================================*/
5171 if (hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED)
5173 /* Set the phase */
5174 hcryp->Phase = CRYP_PHASE_PROCESS;
5176 /* Select header phase */
5177 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
5179 if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount) >= 4U))
5181 /* Write the input block in the IN FIFO */
5182 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount );
5183 hcryp->CrypHeaderCount++;
5184 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount );
5185 hcryp->CrypHeaderCount++;
5186 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount );
5187 hcryp->CrypHeaderCount++;
5188 hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount );
5189 hcryp->CrypHeaderCount++;
5191 else /*HeaderSize < 4 or HeaderSize >4 & HeaderSize %4 != 0*/
5193 /* Last block optionally pad the data with zeros*/
5194 for(loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize %4U ); loopcounter++)
5196 hcryp->Instance->DINR = *(uint32_t*)(hcryp->Init.Header + hcryp->CrypHeaderCount);
5197 hcryp->CrypHeaderCount++ ;
5199 while(loopcounter <4U )
5201 /* pad the data with zeros to have a complete block */
5202 hcryp->Instance->DINR = 0x0U;
5203 loopcounter++;
5207 /* Case of payload phase resumption =================================================*/
5208 else if (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED)
5211 /* Set the phase */
5212 hcryp->Phase = CRYP_PHASE_PROCESS;
5214 /* Select payload phase once the header phase is performed */
5215 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD);
5217 /* Set to 0 the number of non-valid bytes using NPBLB register*/
5218 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U);
5220 if ((hcryp->Size/4) - (hcryp->CrypInCount) >= 4U)
5222 /* Write the input block in the IN FIFO */
5223 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5224 hcryp->CrypInCount++;
5225 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5226 hcryp->CrypInCount++;
5227 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5228 hcryp->CrypInCount++;
5229 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5230 hcryp->CrypInCount++;
5231 if((hcryp->CrypInCount == hcryp->Size) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC))
5233 /* Call output transfer complete callback */
5234 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5235 /*Call registered Input complete callback*/
5236 hcryp->InCpltCallback(hcryp);
5237 #else
5238 /*Call legacy weak Input complete callback*/
5239 HAL_CRYP_InCpltCallback(hcryp);
5240 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5243 else /* Last block of payload < 128bit*/
5245 /* Compute the number of padding bytes in last block of payload */
5246 npblb = ((hcryp->Size/16U)+1U)*16U- (hcryp->Size);
5247 if((((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) ||
5248 (((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
5250 /* Specify the number of non-valid bytes using NPBLB register*/
5251 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb<< 20U);
5254 /* Number of valid words (lastwordsize) in last block */
5255 if (npblb % 4U ==0U)
5257 lastwordsize = (16U-npblb)/4U;
5259 else
5261 lastwordsize = (16U-npblb)/4U +1U;
5264 /* Last block optionally pad the data with zeros*/
5265 for(loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
5267 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount );
5268 hcryp->CrypInCount++;
5270 while(loopcounter < 4U )
5272 /* pad the data with zeros to have a complete block */
5273 hcryp->Instance->DINR = 0x0U;
5274 loopcounter++;
5279 #endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */
5281 * @}
5285 #endif /* HAL_CRYP_MODULE_ENABLED */
5287 #endif /* AES */
5289 * @}
5293 * @}
5295 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/