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
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
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
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().
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
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
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 |----------------|----------------|-----------|---------|
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
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 ------------ ---------
202 the Flags field is formatted as follows:
205 ---------- ----------------------
206 7 Reserved (always zero)
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
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
269 @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
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.
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.
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.
333 ******************************************************************************
336 * <h2><center>© 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
359 #ifdef HAL_CRYP_MODULE_ENABLED
361 /* Private typedef -----------------------------------------------------------*/
362 /* Private define ------------------------------------------------------------*/
363 /** @addtogroup CRYP_Private_Defines
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
395 /* Private macro -------------------------------------------------------------*/
396 /** @addtogroup CRYP_Private_Macros
400 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__) do{(__HANDLE__)->Instance->CR &= (uint32_t)(~AES_CR_GCMPH);\
401 (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
408 /* Private struct -------------------------------------------------------------*/
409 /* Private variables ---------------------------------------------------------*/
410 /* Private function prototypes -----------------------------------------------*/
411 /** @addtogroup CRYP_Private_Functions
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 */
453 /* Exported functions ---------------------------------------------------------*/
455 /** @addtogroup CRYP_Exported_Functions
459 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
460 * @brief Initialization and Configuration functions.
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 :
474 (+) Data Type : 32,16, 8 or 1bit
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
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
493 HAL_StatusTypeDef
HAL_CRYP_Init(CRYP_HandleTypeDef
*hcryp
)
495 /* Check the CRYP handle allocation */
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
);
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 */
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
561 HAL_StatusTypeDef
HAL_CRYP_DeInit(CRYP_HandleTypeDef
*hcryp
)
563 /* Check the CRYP handle allocation */
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
);
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
;
602 /* Return function status */
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
614 HAL_StatusTypeDef
HAL_CRYP_SetConfig(CRYP_HandleTypeDef
*hcryp
, CRYP_ConfigTypeDef
*pConf
)
616 /* Check the CRYP handle allocation */
617 if ((hcryp
== NULL
) || (pConf
== NULL
))
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
;
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 */
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 */
669 /* Process Unlocked */
672 /* Busy error code field */
673 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_BUSY
;
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
685 HAL_StatusTypeDef
HAL_CRYP_GetConfig(CRYP_HandleTypeDef
*hcryp
, CRYP_ConfigTypeDef
*pConf
)
687 /* Check the CRYP handle allocation */
688 if ((hcryp
== NULL
) || (pConf
== NULL
))
693 if (hcryp
->State
== HAL_CRYP_STATE_READY
)
695 /* Change the CRYP state */
696 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
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 */
715 /* Change the CRYP state */
716 hcryp
->State
= HAL_CRYP_STATE_READY
;
718 /* Return function status */
723 /* Process Unlocked */
726 /* Busy error code field */
727 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_BUSY
;
732 * @brief Initializes the CRYP MSP.
733 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
734 * the configuration information for CRYP module
737 __weak
void HAL_CRYP_MspInit(CRYP_HandleTypeDef
*hcryp
)
739 /* Prevent unused argument(s) compilation warning */
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
753 __weak
void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef
*hcryp
)
755 /* Prevent unused argument(s) compilation warning */
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
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
;
792 if (hcryp
->State
== HAL_CRYP_STATE_READY
)
796 case HAL_CRYP_INPUT_COMPLETE_CB_ID
:
797 hcryp
->InCpltCallback
= pCallback
;
800 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID
:
801 hcryp
->OutCpltCallback
= pCallback
;
804 case HAL_CRYP_ERROR_CB_ID
:
805 hcryp
->ErrorCallback
= pCallback
;
808 case HAL_CRYP_MSPINIT_CB_ID
:
809 hcryp
->MspInitCallback
= pCallback
;
812 case HAL_CRYP_MSPDEINIT_CB_ID
:
813 hcryp
->MspDeInitCallback
= pCallback
;
817 /* Update the error code */
818 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_INVALID_CALLBACK
;
819 /* Return error status */
824 else if (hcryp
->State
== HAL_CRYP_STATE_RESET
)
828 case HAL_CRYP_MSPINIT_CB_ID
:
829 hcryp
->MspInitCallback
= pCallback
;
832 case HAL_CRYP_MSPDEINIT_CB_ID
:
833 hcryp
->MspDeInitCallback
= pCallback
;
837 /* Update the error code */
838 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_INVALID_CALLBACK
;
839 /* Return error status */
846 /* Update the error code */
847 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_INVALID_CALLBACK
;
848 /* Return error 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
871 HAL_StatusTypeDef
HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef
*hcryp
, HAL_CRYP_CallbackIDTypeDef CallbackID
)
873 HAL_StatusTypeDef status
= HAL_OK
;
878 if (hcryp
->State
== HAL_CRYP_STATE_READY
)
882 case HAL_CRYP_INPUT_COMPLETE_CB_ID
:
883 hcryp
->InCpltCallback
= HAL_CRYP_InCpltCallback
; /* Legacy weak InCpltCallback */
886 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID
:
887 hcryp
->OutCpltCallback
= HAL_CRYP_OutCpltCallback
; /* Legacy weak OutCpltCallback */
890 case HAL_CRYP_ERROR_CB_ID
:
891 hcryp
->ErrorCallback
= HAL_CRYP_ErrorCallback
; /* Legacy weak ErrorCallback */
894 case HAL_CRYP_MSPINIT_CB_ID
:
895 hcryp
->MspInitCallback
= HAL_CRYP_MspInit
;
898 case HAL_CRYP_MSPDEINIT_CB_ID
:
899 hcryp
->MspDeInitCallback
= HAL_CRYP_MspDeInit
;
903 /* Update the error code */
904 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_INVALID_CALLBACK
;
905 /* Return error status */
910 else if (hcryp
->State
== HAL_CRYP_STATE_RESET
)
914 case HAL_CRYP_MSPINIT_CB_ID
:
915 hcryp
->MspInitCallback
= HAL_CRYP_MspInit
;
918 case HAL_CRYP_MSPDEINIT_CB_ID
:
919 hcryp
->MspDeInitCallback
= HAL_CRYP_MspDeInit
;
923 /* Update the error code */
924 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_INVALID_CALLBACK
;
925 /* Return error status */
932 /* Update the error code */
933 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_INVALID_CALLBACK
;;
934 /* Return error 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.
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.
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 */
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
);
1000 CRYP_Read_KeyRegisters(hcryp
, hcryp
->Key_saved
, hcryp
->Init
.KeySize
);
1002 CRYP_Read_IVRegisters(hcryp
, hcryp
->IV_saved
);
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
;
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 */
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
)
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
)
1110 if (HAL_CRYP_Decrypt_IT(hcryp
, hcryp
->pCrypInBuffPtr_saved
, hcryp
->Size_saved
, hcryp
->pCrypOutBuffPtr_saved
) != HAL_OK
)
1118 #endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */
1124 /** @defgroup CRYP_Exported_Functions_Group2 Encryption Decryption functions
1125 * @brief Encryption Decryption functions.
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
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
)
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 */
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;
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
;
1205 /* AES encryption */
1206 status
= CRYP_AES_Encrypt(hcryp
, Timeout
);
1209 case CRYP_AES_GCM_GMAC
:
1211 /* AES GCM encryption */
1212 status
= CRYP_AESGCM_Process(hcryp
, Timeout
) ;
1217 /* AES CCM encryption */
1218 status
= CRYP_AESCCM_Process(hcryp
, Timeout
);
1222 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_NOT_SUPPORTED
;
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
);
1238 /* Busy error code field */
1239 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_BUSY
;
1243 /* Return function 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
;
1262 if (hcryp
->State
== HAL_CRYP_STATE_READY
)
1264 /* Change state Busy */
1265 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1267 /* Process locked */
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;
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
;
1299 /* AES decryption */
1300 status
= CRYP_AES_Decrypt(hcryp
, Timeout
);
1303 case CRYP_AES_GCM_GMAC
:
1305 /* AES GCM decryption */
1306 status
= CRYP_AESGCM_Process(hcryp
, Timeout
) ;
1311 /* AES CCM decryption */
1312 status
= CRYP_AESCCM_Process(hcryp
, Timeout
);
1316 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_NOT_SUPPORTED
;
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
);
1332 /* Busy error code field */
1333 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_BUSY
;
1337 /* Return function 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
;
1355 if (hcryp
->State
== HAL_CRYP_STATE_READY
)
1357 /* Change state Busy */
1358 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1360 /* Process locked */
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
;
1375 hcryp
->CrypInCount
= 0U;
1376 hcryp
->CrypOutCount
= 0U;
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;
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
;
1412 /* AES encryption */
1413 status
= CRYP_AES_Encrypt_IT(hcryp
);
1416 case CRYP_AES_GCM_GMAC
:
1418 /* AES GCM encryption */
1419 status
= CRYP_AESGCM_Process_IT(hcryp
) ;
1424 /* AES CCM encryption */
1425 status
= CRYP_AESCCM_Process_IT(hcryp
);
1429 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_NOT_SUPPORTED
;
1436 /* Busy error code field */
1437 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_BUSY
;
1441 /* Return function 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
;
1459 if (hcryp
->State
== HAL_CRYP_STATE_READY
)
1461 /* Change state Busy */
1462 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1464 /* Process locked */
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
;
1479 hcryp
->CrypInCount
= 0U;
1480 hcryp
->CrypOutCount
= 0U;
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;
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
;
1515 /* AES decryption */
1516 status
= CRYP_AES_Decrypt_IT(hcryp
);
1519 case CRYP_AES_GCM_GMAC
:
1521 /* AES GCM decryption */
1522 status
= CRYP_AESGCM_Process_IT(hcryp
) ;
1527 /* AES CCM decryption */
1528 status
= CRYP_AESCCM_Process_IT(hcryp
);
1532 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_NOT_SUPPORTED
;
1539 /* Busy error code field */
1540 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_BUSY
;
1544 /* Return function 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
;
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 */
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;
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
;
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 */
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)
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) */
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
));
1640 case CRYP_AES_GCM_GMAC
:
1642 /* AES GCM encryption */
1643 status
= CRYP_AESGCM_Process_DMA(hcryp
) ;
1648 /* AES CCM encryption */
1649 status
= CRYP_AESCCM_Process_DMA(hcryp
);
1653 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_NOT_SUPPORTED
;
1660 /* Busy error code field */
1661 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_BUSY
;
1665 /* Return function 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
;
1683 if (hcryp
->State
== HAL_CRYP_STATE_READY
)
1686 /* Change state Busy */
1687 hcryp
->State
= HAL_CRYP_STATE_BUSY
;
1689 /* Process locked */
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;
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
;
1721 /* AES decryption */
1722 status
= CRYP_AES_Decrypt_DMA(hcryp
);
1725 case CRYP_AES_GCM_GMAC
:
1727 /* AES GCM decryption */
1728 status
= CRYP_AESGCM_Process_DMA(hcryp
) ;
1733 /* AES CCM decryption */
1734 status
= CRYP_AESCCM_Process_DMA(hcryp
);
1738 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_NOT_SUPPORTED
;
1745 /* Busy error code field */
1746 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_BUSY
;
1749 /* Return function status */
1757 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1758 * @brief CRYP IRQ handler.
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
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
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*/
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.
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.
1867 __weak
void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef
*hcryp
)
1869 /* Prevent unused argument(s) compilation warning */
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.
1883 __weak
void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef
*hcryp
)
1885 /* Prevent unused argument(s) compilation warning */
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.
1899 __weak
void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef
*hcryp
)
1901 /* Prevent unused argument(s) compilation warning */
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
1916 /* Private functions ---------------------------------------------------------*/
1917 /** @addtogroup CRYP_Private_Functions
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 */
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)
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) */
1966 hcryp
->Phase
= CRYP_PHASE_PROCESS
;
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
;
1982 __HAL_CRYP_DISABLE(hcryp
);
1984 /* Change the CRYP state */
1985 hcryp
->State
= HAL_CRYP_STATE_READY
;
1987 /* Return function status */
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 */
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)
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) */
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
);
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
++;
2057 /* Change the CRYP state */
2058 hcryp
->State
= HAL_CRYP_STATE_READY
;
2060 /* Process unlocked */
2061 __HAL_UNLOCK(hcryp
);
2064 /* Return function status */
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 */
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
);
2108 CRYP_SetKey(hcryp
, hcryp
->Init
.KeySize
);
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
);
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*/
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 */
2145 CRYP_SetKey(hcryp
, hcryp
->Init
.KeySize
);
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) */
2160 hcryp
->Phase
= CRYP_PHASE_PROCESS
;
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
;
2176 __HAL_CRYP_DISABLE(hcryp
);
2178 /* Change the CRYP state */
2179 hcryp
->State
= HAL_CRYP_STATE_READY
;
2181 /* Return function status */
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 */
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
);
2223 CRYP_SetKey(hcryp
, hcryp
->Init
.KeySize
);
2226 __HAL_CRYP_ENABLE(hcryp
);
2228 /* Wait for CCF flag to be raised */
2229 count
= CRYP_TIMEOUT_KEYPREPARATION
;
2235 /* Disable the CRYP peripheral clock */
2236 __HAL_CRYP_DISABLE(hcryp
);
2239 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
2240 hcryp
->State
= HAL_CRYP_STATE_READY
;
2242 /* Process unlocked */
2243 __HAL_UNLOCK(hcryp
);
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*/
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 */
2267 CRYP_SetKey(hcryp
, hcryp
->Init
.KeySize
);
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) */
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
);
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
++;
2303 /* Process locked */
2304 __HAL_UNLOCK(hcryp
);
2306 /* Change the CRYP state */
2307 hcryp
->State
= HAL_CRYP_STATE_READY
;
2310 /* Return function status */
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 */
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
);
2352 CRYP_SetKey(hcryp
, hcryp
->Init
.KeySize
);
2355 __HAL_CRYP_ENABLE(hcryp
);
2357 /* Wait for CCF flag to be raised */
2358 count
= CRYP_TIMEOUT_KEYPREPARATION
;
2364 /* Disable the CRYP peripheral clock */
2365 __HAL_CRYP_DISABLE(hcryp
);
2368 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
2369 hcryp
->State
= HAL_CRYP_STATE_READY
;
2371 /* Process unlocked */
2372 __HAL_UNLOCK(hcryp
);
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*/
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 */
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) */
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
));
2419 /* Process unlocked */
2420 __HAL_UNLOCK(hcryp
);
2422 /* Change the CRYP state */
2423 hcryp
->State
= HAL_CRYP_STATE_READY
;
2426 /* Return function status */
2432 * @brief DMA CRYP input data process complete callback.
2433 * @param hdma DMA handle
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
);
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
2458 static void CRYP_DMAOutCplt(DMA_HandleTypeDef
*hdma
)
2462 uint32_t lastwordsize
;
2463 uint32_t temp
; /* Temporary CrypOutBuff */
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;
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
++;
2510 /* Pad the data with zeros to have a complete block */
2511 hcryp
->Instance
->DINR
= 0x0U
;
2515 /*Wait on CCF flag*/
2516 count
= CRYP_TIMEOUT_GCMCCMHEADERPHASE
;
2522 /* Disable the CRYP peripheral clock */
2523 __HAL_CRYP_DISABLE(hcryp
);
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
);
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
);
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
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
);
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
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
);
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
);
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
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
);
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
);
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
;
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
);
2779 /*Call legacy weak Output complete callback*/
2780 HAL_CRYP_OutCpltCallback(hcryp
);
2781 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
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
);
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
);
2825 /*Call legacy weak Input complete callback*/
2826 HAL_CRYP_InCpltCallback(hcryp
);
2827 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
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
);
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.
2855 static void CRYP_SetKey(CRYP_HandleTypeDef
*hcryp
, uint32_t KeySize
)
2857 if (hcryp
->Init
.pKey
!= NULL
)
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);
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);
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
)
2894 uint32_t wordsize
= ((uint32_t)hcryp
->Size
/ 4U) ;
2896 uint32_t temp
; /* Temporary CrypOutBuff */
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 */
2910 hcryp
->SizesSum
+= hcryp
->Size
; /* Compute message total payload length */
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 */
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
);
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
)
2952 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
2953 hcryp
->State
= HAL_CRYP_STATE_READY
;
2955 /* Process unlocked & return error */
2956 __HAL_UNLOCK(hcryp
);
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
)
2969 /*************************Payload 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) ;
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
);
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;
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
++;
3049 /* pad the data with zeros to have a complete block */
3050 hcryp
->Instance
->DINR
= 0U;
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
);
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 */
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
;
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
);
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 */
3115 hcryp
->SizesSum
+= hcryp
->Size
; /* Compute message total payload length */
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 */
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
);
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
;
3160 /* Disable the CRYP peripheral clock */
3161 __HAL_CRYP_DISABLE(hcryp
);
3164 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
3165 hcryp
->State
= HAL_CRYP_STATE_READY
;
3167 /* Process unlocked */
3168 __HAL_UNLOCK(hcryp
);
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*/
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
);
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;
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
;
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
;
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
);
3301 /*Call legacy weak Input complete callback*/
3302 HAL_CRYP_InCpltCallback(hcryp
);
3303 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
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
);
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;
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
;
3406 /* Return function status */
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 ;
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 */
3434 hcryp
->SizesSum
+= hcryp
->Size
; /* Compute message total payload length */
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 */
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
);
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
;
3479 /* Disable the CRYP peripheral clock */
3480 __HAL_CRYP_DISABLE(hcryp
);
3483 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
3484 hcryp
->State
= HAL_CRYP_STATE_READY
;
3486 /* Process unlocked */
3487 __HAL_UNLOCK(hcryp
);
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
)
3503 /************************ Payload 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);
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;
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
++;
3566 /* pad the data with zeros to have a complete block */
3567 hcryp
->Instance
->DINR
= 0U;
3570 /* Wait for CCF flag to be raised */
3571 count
= CRYP_TIMEOUT_GCMCCMHEADERPHASE
;
3577 /* Disable the CRYP peripheral clock */
3578 __HAL_CRYP_DISABLE(hcryp
);
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
);
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 */
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
)
3633 uint32_t wordsize
= ((uint32_t)hcryp
->Size
/ 4U) ;
3634 uint32_t loopcounter
;
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 */
3649 hcryp
->SizesSum
+= hcryp
->Size
; /* Compute message total payload length */
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 */
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
);
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
)
3690 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
3691 hcryp
->State
= HAL_CRYP_STATE_READY
;
3693 /* Process unlocked & return error */
3694 __HAL_UNLOCK(hcryp
);
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
)
3708 /*************************Payload 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) ;
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
);
3746 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
3747 hcryp
->State
= HAL_CRYP_STATE_READY
;
3749 /* Process unlocked */
3750 __HAL_UNLOCK(hcryp
);
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;
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;
3792 /* just wait for hash computation */
3793 if (CRYP_WaitOnCCFlag(hcryp
, Timeout
) != HAL_OK
)
3796 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
3797 hcryp
->State
= HAL_CRYP_STATE_READY
;
3799 /* Process unlocked & return error */
3800 __HAL_UNLOCK(hcryp
);
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 */
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
;
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
);
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 */
3851 hcryp
->SizesSum
+= hcryp
->Size
; /* Compute message total payload length */
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 */
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
);
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
;
3896 /* Disable the CRYP peripheral clock */
3897 __HAL_CRYP_DISABLE(hcryp
);
3900 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
3901 hcryp
->State
= HAL_CRYP_STATE_READY
;
3903 /* Process unlocked */
3904 __HAL_UNLOCK(hcryp
);
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*/
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
);
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;
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
;
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
;
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
);
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;
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
;
4116 /* Return function status */
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 ;
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 */
4144 hcryp
->SizesSum
+= hcryp
->Size
; /* Compute message total payload length */
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 */
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
);
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
;
4190 /* Disable the CRYP peripheral clock */
4191 __HAL_CRYP_DISABLE(hcryp
);
4194 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
4195 hcryp
->State
= HAL_CRYP_STATE_READY
;
4197 /* Process unlocked */
4198 __HAL_UNLOCK(hcryp
);
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
)
4215 /******************** Payload 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);
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;
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
++;
4275 /* pad the data with zeros to have a complete block */
4276 hcryp
->Instance
->DINR
= 0U;
4279 /* Wait for CCF flag to be raised */
4280 count
= CRYP_TIMEOUT_GCMCCMHEADERPHASE
;
4286 /* Disable the CRYP peripheral clock */
4287 __HAL_CRYP_DISABLE(hcryp
);
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
);
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 */
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
4336 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef
*hcryp
)
4338 uint32_t loopcounter
;
4339 uint32_t temp
; /* Temporary CrypOutBuff */
4340 uint32_t lastwordsize
;
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
);
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
);
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
);
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;
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
;
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
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
);
4519 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
4520 hcryp
->State
= HAL_CRYP_STATE_READY
;
4522 /* Process unlocked */
4523 __HAL_UNLOCK(hcryp
);
4526 /* Clear CCF flag */
4527 __HAL_CRYP_CLEAR_FLAG(hcryp
, CRYP_CCF_CLEAR
);
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
);
4551 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
4552 hcryp
->State
= HAL_CRYP_STATE_READY
;
4554 /* Process unlocked */
4555 __HAL_UNLOCK(hcryp
);
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
;
4574 if (CRYP_WaitOnCCFlag(hcryp
, Timeout
) != HAL_OK
)
4576 /* Disable the CRYP peripheral clock */
4577 __HAL_CRYP_DISABLE(hcryp
);
4580 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
4581 hcryp
->State
= HAL_CRYP_STATE_READY
;
4583 /* Process unlocked */
4584 __HAL_UNLOCK(hcryp
);
4587 /* Clear CCF flag */
4588 __HAL_CRYP_CLEAR_FLAG(hcryp
, CRYP_CCF_CLEAR
);
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 */
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)
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
;
4651 /* Disable the CRYP peripheral clock */
4652 __HAL_CRYP_DISABLE(hcryp
);
4655 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
4656 hcryp
->State
= HAL_CRYP_STATE_READY
;
4658 /* Process unlocked */
4659 __HAL_UNLOCK(hcryp
);
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
);
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
;
4691 /* Disable the CRYP peripheral clock */
4692 __HAL_CRYP_DISABLE(hcryp
);
4695 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
4696 hcryp
->State
= HAL_CRYP_STATE_READY
;
4698 /* Process unlocked */
4699 __HAL_UNLOCK(hcryp
);
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
;
4721 /*Wait on CCF flag*/
4722 count
= CRYP_TIMEOUT_GCMCCMHEADERPHASE
;
4728 /* Disable the CRYP peripheral clock */
4729 __HAL_CRYP_DISABLE(hcryp
);
4732 hcryp
->ErrorCode
|= HAL_CRYP_ERROR_TIMEOUT
;
4733 hcryp
->State
= HAL_CRYP_STATE_READY
;
4735 /* Process unlocked */
4736 __HAL_UNLOCK(hcryp
);
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
);
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 */
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)
4764 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef
*hcryp
)
4766 uint32_t loopcounter
;
4767 uint32_t lastwordsize
;
4771 /***************************** Header phase *********************************/
4772 if (hcryp
->Init
.HeaderSize
== hcryp
->CrypHeaderCount
)
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
);
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;
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
;
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
);
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
;
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
)
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))
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.
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
;
4956 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->IVR2
;
4958 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->IVR1
;
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.
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
);
4979 hcryp
->Instance
->IVR2
= *(uint32_t*)(ivaddr
);
4981 hcryp
->Instance
->IVR1
= *(uint32_t*)(ivaddr
);
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.
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 */
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
);
5022 while(HAL_IS_BIT_SET(hcryp
->Instance
->SR
, AES_SR_BUSY
));
5027 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->SUSP7R
;
5029 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->SUSP6R
;
5031 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->SUSP5R
;
5033 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->SUSP4R
;
5035 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->SUSP3R
;
5037 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->SUSP2R
;
5039 *(uint32_t*)(outputaddr
) = hcryp
->Instance
->SUSP1R
;
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.
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
);
5060 hcryp
->Instance
->SUSP6R
= *(uint32_t*)(ivaddr
);
5062 hcryp
->Instance
->SUSP5R
= *(uint32_t*)(ivaddr
);
5064 hcryp
->Instance
->SUSP4R
= *(uint32_t*)(ivaddr
);
5066 hcryp
->Instance
->SUSP3R
= *(uint32_t*)(ivaddr
);
5068 hcryp
->Instance
->SUSP2R
= *(uint32_t*)(ivaddr
);
5070 hcryp
->Instance
->SUSP1R
= *(uint32_t*)(ivaddr
);
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.
5085 static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef
*hcryp
, uint32_t* Output
, uint32_t KeySize
)
5087 uint32_t keyaddr
= (uint32_t)Output
;
5091 case CRYP_KEYSIZE_256B
:
5092 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
);
5094 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 1U);
5096 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 2U);
5098 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 3U);
5100 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 4U);
5102 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 5U);
5104 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 6U);
5106 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 7U);
5108 case CRYP_KEYSIZE_128B
:
5109 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
);
5111 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 1U);
5113 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 2U);
5115 *(uint32_t*)(keyaddr
) = *(uint32_t *)(hcryp
->Init
.pKey
+ 3U);
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.
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
);
5141 hcryp
->Instance
->KEYR6
= *(uint32_t*)(keyaddr
);
5143 hcryp
->Instance
->KEYR5
= *(uint32_t*)(keyaddr
);
5145 hcryp
->Instance
->KEYR4
= *(uint32_t*)(keyaddr
);
5149 hcryp
->Instance
->KEYR3
= *(uint32_t*)(keyaddr
);
5151 hcryp
->Instance
->KEYR2
= *(uint32_t*)(keyaddr
);
5153 hcryp
->Instance
->KEYR1
= *(uint32_t*)(keyaddr
);
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)
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
)
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
;
5207 /* Case of payload phase resumption =================================================*/
5208 else if (hcryp
->Phase
== CRYP_PHASE_PAYLOAD_SUSPENDED
)
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
);
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;
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
;
5279 #endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */
5285 #endif /* HAL_CRYP_MODULE_ENABLED */
5295 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/