Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_cryp.c
blob0407c65a23bf8a3789ec342edeaa53c974e39a1a
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_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 and de-initialization functions
9 * + AES processing functions
10 * + DES processing functions
11 * + TDES processing functions
12 * + DMA callback functions
13 * + CRYP IRQ handler management
14 * + Peripheral State functions
16 @verbatim
17 ==============================================================================
18 ##### How to use this driver #####
19 ==============================================================================
20 [..]
21 The CRYP HAL driver can be used in CRYP IP as follows:
23 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
24 (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
25 (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
26 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
27 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
28 (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
29 (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
30 (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
31 (+++) Configure and enable two DMA streams one for managing data transfer from
32 memory to peripheral (input stream) and another stream for managing data
33 transfer from peripheral to memory (output stream)
34 (+++) Associate the initialized DMA handle to the CRYP DMA handle
35 using __HAL_LINKDMA()
36 (+++) Configure the priority and enable the NVIC for the transfer complete
37 interrupt on the two DMA Streams. The output stream should have higher
38 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
40 (#)Initialize the CRYP according to the specified parameters :
41 (##) The data type: 1-bit, 8-bit, 16-bit or 32-bit.
42 (##) The key size: 128, 192 or 256.
43 (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM.
44 (##) The initialization vector (counter). It is not used in ECB mode.
45 (##) The key buffer used for encryption/decryption.
46 (##) The Header used only in AES GCM and CCM Algorithm for authentication.
47 (##) The HeaderSize The size of header buffer in word.
48 (##) The B0 block is the first authentication block used only in AES CCM mode.
50 (#)Three processing (encryption/decryption) functions are available:
51 (##) Polling mode: encryption and decryption APIs are blocking functions
52 i.e. they process the data and wait till the processing is finished,
53 e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
54 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
55 i.e. they process the data under interrupt,
56 e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
57 (##) DMA mode: encryption and decryption APIs are not blocking functions
58 i.e. the data transfer is ensured by DMA,
59 e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
61 (#)When the processing function is called at first time after HAL_CRYP_Init()
62 the CRYP peripheral is configured and processes the buffer in input.
63 At second call, no need to Initialize the CRYP, user have to get current configuration via
64 HAL_CRYP_GetConfig() API, then only HAL_CRYP_SetConfig() is requested to set
65 new parametres, finally user can start encryption/decryption.
67 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
69 (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
70 without having to configure again the Key or the Initialization Vector between each API call,
71 the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
72 Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
73 or HAL_CRYP_Decrypt_DMA().
75 [..]
76 The cryptographic processor supports following standards:
77 (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 IP:
78 (##)64-bit data block processing
79 (##) chaining modes supported :
80 (+++) Electronic Code Book(ECB)
81 (+++) Cipher Block Chaining (CBC)
82 (##) keys length supported :64-bit, 128-bit and 192-bit.
83 (#) The advanced encryption standard (AES) supported by CRYP1:
84 (##)128-bit data block processing
85 (##) chaining modes supported :
86 (+++) Electronic Code Book(ECB)
87 (+++) Cipher Block Chaining (CBC)
88 (+++) Counter mode (CTR)
89 (+++) Galois/counter mode (GCM/GMAC)
90 (+++) Counter with Cipher Block Chaining-Message(CCM)
91 (##) keys length Supported :
92 (+++) for CRYP1 IP: 128-bit, 192-bit and 256-bit.
94 [..] This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 IP:
95 (#) Algorithm supported :
96 (##) Galois/counter mode (GCM)
97 (##) Galois message authentication code (GMAC) :is exactly the same as
98 GCM algorithm composed only by an header.
99 (#) Four phases are performed in GCM :
100 (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
101 (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
102 computation only.
103 (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
104 encryption + data XORing. It works in a similar way for ciphertext (C).
105 (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
106 HAL_CRYPEx_AESGCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond
107 to the Tag. user should consider only part of this 4 words, if Tag length is less than 128 bits.
108 (#) structure of message construction in GCM is defined as below :
109 (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
110 (##) The authenticated header A (also knows as Additional Authentication Data AAD)
111 this part of the message is only authenticated, not encrypted.
112 (##) The plaintext message P is both authenticated and encrypted as ciphertext.
113 GCM standard specifies that ciphertext has same bit length as the plaintext.
114 (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
115 (on 64 bits)
117 [..] This section describe The AES Counter with Cipher Block Chaining-Message
118 Authentication Code (CCM) supported by both CRYP1 IP:
119 (#) Specific parameters for CCM :
121 (##) B0 block : According to NIST Special Publication 800-38C,
122 The first block B0 is formatted as follows, where l(m) is encoded in
123 most-significant-byte first order(see below table 3)
125 (+++) Q: a bit string representation of the octet length of P (plaintext)
126 (+++) q The octet length of the binary representation of the octet length of the payload
127 (+++) A nonce (N), n The octet length of the where n+q=15.
128 (+++) Flags: most significant octet containing four flags for control information,
129 (+++) t The octet length of the MAC.
130 (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
131 the associated data length expressed in bytes (a) defined as below:
132 (+++) If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
133 (+++) If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
134 (+++) If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
135 (##) CTRx block : control blocks
136 (+++) Generation of CTR1 from first block B0 information :
137 equal to B0 with first 5 bits zeroed and most significant bits storing octet
138 length of P also zeroed, then incremented by one ( see below Table 4)
139 (+++) Generation of CTR0: same as CTR1 with bit[0] set to zero.
141 (#) Four phases are performed in CCM for CRYP1 IP:
142 (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
143 (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
144 computation only.
145 (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
146 encryption + data XORing. It works in a similar way for ciphertext (C).
147 (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
148 HAL_CRYPEx_AESCCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond to the Tag.
149 user should consider only part of this 4 words, if Tag length is less than 128 bits
151 *** Callback registration ***
152 =============================
154 [..]
155 The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
156 allows the user to configure dynamically the driver callbacks.
157 Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
158 to register an interrupt callback.
160 [..]
161 Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
162 (+) InCpltCallback : Input FIFO transfer completed callback.
163 (+) OutCpltCallback : Output FIFO transfer completed callback.
164 (+) ErrorCallback : callback for error detection.
165 (+) MspInitCallback : CRYP MspInit.
166 (+) MspDeInitCallback : CRYP MspDeInit.
167 This function takes as parameters the HAL peripheral handle, the Callback ID
168 and a pointer to the user callback function.
170 [..]
171 Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
172 weak function.
173 @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
174 and the Callback ID.
175 This function allows to reset following callbacks:
176 (+) InCpltCallback : Input FIFO transfer completed callback.
177 (+) OutCpltCallback : Output FIFO transfer completed callback.
178 (+) ErrorCallback : callback for error detection.
179 (+) MspInitCallback : CRYP MspInit.
180 (+) MspDeInitCallback : CRYP MspDeInit.
182 [..]
183 By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
184 all callbacks are set to the corresponding weak functions :
185 examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
186 Exception done for MspInit and MspDeInit functions that are
187 reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
188 these callbacks are null (not registered beforehand).
189 if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
190 keep and use the user MspInit/MspDeInit functions (registered beforehand)
192 [..]
193 Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
194 Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
195 in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
196 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
197 In that case first register the MspInit/MspDeInit user callbacks
198 using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
199 or @ref HAL_CRYP_Init() function.
201 [..]
202 When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
203 not defined, the callback registration feature is not available and all callbacks
204 are set to the corresponding weak functions.
206 @endverbatim
208 Table 1. Initial Counter Block (ICB)
209 +-------------------------------------------------------+
210 | Initialization vector (IV) | Counter |
211 |----------------|----------------|-----------|---------|
212 127 95 63 31 0
215 Bit Number Register Contents
216 ---------- --------------- -----------
217 127 ...96 CRYP_IV1R[31:0] ICB[127:96]
218 95 ...64 CRYP_IV1L[31:0] B0[95:64]
219 63 ... 32 CRYP_IV0R[31:0] ICB[63:32]
220 31 ... 0 CRYP_IV0L[31:0] ICB[31:0], where 32-bit counter= 0x2
222 Table 2. GCM last block definition
224 +-------------------------------------------------------------------+
225 | Bit[0] | Bit[32] | Bit[64] | Bit[96] |
226 |-----------|--------------------|-----------|----------------------|
227 | 0x0 | Header length[31:0]| 0x0 | Payload length[31:0] |
228 |-----------|--------------------|-----------|----------------------|
230 Table 3. B0 block
231 Octet Number Contents
232 ------------ ---------
233 0 Flags
234 1 ... 15-q Nonce N
235 16-q ... 15 Q
237 the Flags field is formatted as follows:
239 Bit Number Contents
240 ---------- ----------------------
241 7 Reserved (always zero)
242 6 Adata
243 5 ... 3 (t-2)/2
244 2 ... 0 [q-1]3
246 Table 4. CTRx block
247 Bit Number Register Contents
248 ---------- --------------- -----------
249 127 ...96 CRYP_IV1R[31:0] B0[127:96], where Q length bits are set to 0, except for
250 bit 0 that is set to 1
251 95 ...64 CRYP_IV1L[31:0] B0[95:64]
252 63 ... 32 CRYP_IV0R[31:0] B0[63:32]
253 31 ... 0 CRYP_IV0L[31:0] B0[31:0], where flag bits set to 0
256 ******************************************************************************
257 * @attention
259 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
260 * All rights reserved.</center></h2>
262 * This software component is licensed by ST under BSD 3-Clause license,
263 * the "License"; You may not use this file except in compliance with the
264 * License. You may obtain a copy of the License at:
265 * opensource.org/licenses/BSD-3-Clause
267 ******************************************************************************
270 /* Includes ------------------------------------------------------------------*/
271 #include "stm32h7xx_hal.h"
273 /** @addtogroup STM32H7xx_HAL_Driver
274 * @{
277 #if defined (CRYP)
279 /** @defgroup CRYP CRYP
280 * @brief CRYP HAL module driver.
281 * @{
285 #ifdef HAL_CRYP_MODULE_ENABLED
287 /* Private typedef -----------------------------------------------------------*/
288 /* Private define ------------------------------------------------------------*/
289 /** @addtogroup CRYP_Private_Defines
290 * @{
292 #define CRYP_TIMEOUT_KEYPREPARATION 82U /*The latency of key preparation operation is 82 clock cycles.*/
293 #define CRYP_TIMEOUT_GCMCCMINITPHASE 299U /* The latency of GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
294 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE 290U /* The latency of GCM/CCM header phase is 290 clock cycles.*/
296 #define CRYP_PHASE_READY 0x00000001U /*!< CRYP peripheral is ready for initialization. */
297 #define CRYP_PHASE_PROCESS 0x00000002U /*!< CRYP peripheral is in processing phase */
299 #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
300 #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0 /*!< GCM/GMAC or CCM header phase */
301 #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1 /*!< GCM(/CCM) payload phase */
302 #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH /*!< GCM/GMAC or CCM final phase */
303 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */
304 #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR /*!< Decryption */
307 /* CTR1 information to use in CCM algorithm */
308 #define CRYP_CCM_CTR1_0 0x07FFFFFFU
309 #define CRYP_CCM_CTR1_1 0xFFFFFF00U
310 #define CRYP_CCM_CTR1_2 0x00000001U
313 * @}
317 /* Private macro -------------------------------------------------------------*/
318 /** @addtogroup CRYP_Private_Macros
319 * @{
322 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__) do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\
323 (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
324 }while(0)
326 #define HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRYP_CR_FFLUSH)
330 * @}
333 /* Private struct -------------------------------------------------------------*/
334 /* Private variables ---------------------------------------------------------*/
335 /* Private function prototypes -----------------------------------------------*/
336 /** @addtogroup CRYP_Private_Functions_prototypes
337 * @{
340 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
341 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
342 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
343 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
344 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
345 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
346 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
347 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
348 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
349 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
350 #if !defined (CRYP_VER_2_2)
351 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
352 #endif /*End of not defined CRYP_VER_2_2*/
353 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
354 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
355 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
356 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
357 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
358 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
359 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
360 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
361 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
362 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
363 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
364 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
365 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp);
366 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
367 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
368 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
369 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
372 * @}
375 /* Exported functions ---------------------------------------------------------*/
377 /** @defgroup CRYP_Exported_Functions CRYP Exported Functions
378 * @{
382 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
383 * @brief CRYP Initialization and Configuration functions.
385 @verbatim
386 ========================================================================================
387 ##### Initialization, de-initialization and Set and Get configuration functions #####
388 ========================================================================================
389 [..] This section provides functions allowing to:
390 (+) Initialize the CRYP
391 (+) DeInitialize the CRYP
392 (+) Initialize the CRYP MSP
393 (+) DeInitialize the CRYP MSP
394 (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
395 Parameters which are configured in This section are :
396 (++) Key size
397 (++) Data Type : 32,16, 8 or 1bit
398 (++) AlgoMode : for CRYP1 IP
399 ECB and CBC in DES/TDES Standard
400 ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
401 (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
404 @endverbatim
405 * @{
410 * @brief Initializes the CRYP according to the specified
411 * parameters in the CRYP_ConfigTypeDef and creates the associated handle.
412 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
413 * the configuration information for CRYP module
414 * @retval HAL status
416 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
418 /* Check the CRYP handle allocation */
419 if (hcryp == NULL)
421 return HAL_ERROR;
424 /* Check parameters */
425 assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
426 assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
427 assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
428 assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
430 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
431 if (hcryp->State == HAL_CRYP_STATE_RESET)
433 /* Allocate lock resource and initialize it */
434 hcryp->Lock = HAL_UNLOCKED;
436 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
437 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
438 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
440 if (hcryp->MspInitCallback == NULL)
442 hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit */
445 /* Init the low level hardware */
446 hcryp->MspInitCallback(hcryp);
448 #else
449 if (hcryp->State == HAL_CRYP_STATE_RESET)
451 /* Allocate lock resource and initialize it */
452 hcryp->Lock = HAL_UNLOCKED;
454 /* Init the low level hardware */
455 HAL_CRYP_MspInit(hcryp);
457 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
459 /* Set the key size(This bit field is ‘don’t care’ in the DES or TDES modes) data type and Algorithm */
460 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
461 hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
462 #if !defined (CRYP_VER_2_2)
463 /* Read Device ID to indicate CRYP1 IP Version */
464 hcryp->Version = HAL_GetREVID();
465 #endif /*End of not defined CRYP_VER_2_2*/
466 /* Reset Error Code field */
467 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
469 /* Reset peripheral Key and IV configuration flag */
470 hcryp->KeyIVConfig = 0U;
472 /* Change the CRYP state */
473 hcryp->State = HAL_CRYP_STATE_READY;
475 /* Set the default CRYP phase */
476 hcryp->Phase = CRYP_PHASE_READY;
478 /* Return function status */
479 return HAL_OK;
483 * @brief De-Initializes the CRYP peripheral.
484 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
485 * the configuration information for CRYP module
486 * @retval HAL status
488 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
490 /* Check the CRYP handle allocation */
491 if (hcryp == NULL)
493 return HAL_ERROR;
496 /* Set the default CRYP phase */
497 hcryp->Phase = CRYP_PHASE_READY;
499 /* Reset CrypInCount and CrypOutCount */
500 hcryp->CrypInCount = 0;
501 hcryp->CrypOutCount = 0;
502 hcryp->CrypHeaderCount = 0;
504 /* Disable the CRYP peripheral clock */
505 __HAL_CRYP_DISABLE(hcryp);
507 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
508 if (hcryp->MspDeInitCallback == NULL)
510 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit */
512 /* DeInit the low level hardware */
513 hcryp->MspDeInitCallback(hcryp);
515 #else
516 /* DeInit the low level hardware: CLOCK, NVIC.*/
517 HAL_CRYP_MspDeInit(hcryp);
518 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
520 /* Change the CRYP state */
521 hcryp->State = HAL_CRYP_STATE_RESET;
523 /* Release Lock */
524 __HAL_UNLOCK(hcryp);
526 /* Return function status */
527 return HAL_OK;
531 * @brief Configure the CRYP according to the specified
532 * parameters in the CRYP_ConfigTypeDef
533 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
534 * @param pConf: pointer to a CRYP_ConfigTypeDef structure that contains
535 * the configuration information for CRYP module
536 * @retval HAL status
538 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
540 /* Check the CRYP handle allocation */
541 if ((hcryp == NULL) || (pConf == NULL))
543 return HAL_ERROR;
546 /* Check parameters */
547 assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
548 assert_param(IS_CRYP_DATATYPE(pConf->DataType));
549 assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
551 if (hcryp->State == HAL_CRYP_STATE_READY)
553 /* Change the CRYP state */
554 hcryp->State = HAL_CRYP_STATE_BUSY;
556 /* Process locked */
557 __HAL_LOCK(hcryp);
559 /* Set CRYP parameters */
560 hcryp->Init.DataType = pConf->DataType;
561 hcryp->Init.pKey = pConf->pKey;
562 hcryp->Init.Algorithm = pConf->Algorithm;
563 hcryp->Init.KeySize = pConf->KeySize;
564 hcryp->Init.pInitVect = pConf->pInitVect;
565 hcryp->Init.Header = pConf->Header;
566 hcryp->Init.HeaderSize = pConf->HeaderSize;
567 hcryp->Init.B0 = pConf->B0;
568 hcryp->Init.DataWidthUnit = pConf->DataWidthUnit;
570 /* Set the key size(This bit field is ‘don’t care’ in the DES or TDES modes) data type, AlgoMode and operating mode*/
571 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
572 hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
574 /* Process Unlocked */
575 __HAL_UNLOCK(hcryp);
577 /* Reset Error Code field */
578 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
580 /* Change the CRYP state */
581 hcryp->State = HAL_CRYP_STATE_READY;
583 /* Set the default CRYP phase */
584 hcryp->Phase = CRYP_PHASE_READY;
586 /* Return function status */
587 return HAL_OK;
589 else
591 /* Process Unlocked */
592 __HAL_UNLOCK(hcryp);
594 /* Busy error code field */
595 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
596 return HAL_ERROR;
601 * @brief Get CRYP Configuration parameters in associated handle.
602 * @param pConf: pointer to a CRYP_ConfigTypeDef structure
603 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
604 * the configuration information for CRYP module
605 * @retval HAL status
607 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
609 /* Check the CRYP handle allocation */
610 if ((hcryp == NULL) || (pConf == NULL))
612 return HAL_ERROR;
615 if (hcryp->State == HAL_CRYP_STATE_READY)
617 /* Change the CRYP state */
618 hcryp->State = HAL_CRYP_STATE_BUSY;
620 /* Process locked */
621 __HAL_LOCK(hcryp);
623 /* Get CRYP parameters */
624 pConf->DataType = hcryp->Init.DataType;
625 pConf->pKey = hcryp->Init.pKey;
626 pConf->Algorithm = hcryp->Init.Algorithm;
627 pConf->KeySize = hcryp->Init.KeySize ;
628 pConf->pInitVect = hcryp->Init.pInitVect;
629 pConf->Header = hcryp->Init.Header ;
630 pConf->HeaderSize = hcryp->Init.HeaderSize;
631 pConf->B0 = hcryp->Init.B0;
632 pConf->DataWidthUnit = hcryp->Init.DataWidthUnit;
634 /* Process Unlocked */
635 __HAL_UNLOCK(hcryp);
637 /* Change the CRYP state */
638 hcryp->State = HAL_CRYP_STATE_READY;
640 /* Return function status */
641 return HAL_OK;
643 else
645 /* Process Unlocked */
646 __HAL_UNLOCK(hcryp);
648 /* Busy error code field */
649 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
650 return HAL_ERROR;
654 * @brief Initializes the CRYP MSP.
655 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
656 * the configuration information for CRYP module
657 * @retval None
659 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
661 /* Prevent unused argument(s) compilation warning */
662 UNUSED(hcryp);
664 /* NOTE : This function Should not be modified, when the callback is needed,
665 the HAL_CRYP_MspInit could be implemented in the user file
670 * @brief DeInitializes CRYP MSP.
671 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
672 * the configuration information for CRYP module
673 * @retval None
675 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
677 /* Prevent unused argument(s) compilation warning */
678 UNUSED(hcryp);
680 /* NOTE : This function Should not be modified, when the callback is needed,
681 the HAL_CRYP_MspDeInit could be implemented in the user file
685 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
687 * @brief Register a User CRYP Callback
688 * To be used instead of the weak predefined callback
689 * @param hcryp cryp handle
690 * @param CallbackID ID of the callback to be registered
691 * This parameter can be one of the following values:
692 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
693 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
694 * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
695 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
696 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
697 * @param pCallback pointer to the Callback function
698 * @retval status
700 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID,
701 pCRYP_CallbackTypeDef pCallback)
703 HAL_StatusTypeDef status = HAL_OK;
705 if (pCallback == NULL)
707 /* Update the error code */
708 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
710 return HAL_ERROR;
712 /* Process locked */
713 __HAL_LOCK(hcryp);
715 if (hcryp->State == HAL_CRYP_STATE_READY)
717 switch (CallbackID)
719 case HAL_CRYP_INPUT_COMPLETE_CB_ID :
720 hcryp->InCpltCallback = pCallback;
721 break;
723 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
724 hcryp->OutCpltCallback = pCallback;
725 break;
727 case HAL_CRYP_ERROR_CB_ID :
728 hcryp->ErrorCallback = pCallback;
729 break;
731 case HAL_CRYP_MSPINIT_CB_ID :
732 hcryp->MspInitCallback = pCallback;
733 break;
735 case HAL_CRYP_MSPDEINIT_CB_ID :
736 hcryp->MspDeInitCallback = pCallback;
737 break;
739 default :
740 /* Update the error code */
741 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
742 /* Return error status */
743 status = HAL_ERROR;
744 break;
747 else if (hcryp->State == HAL_CRYP_STATE_RESET)
749 switch (CallbackID)
751 case HAL_CRYP_MSPINIT_CB_ID :
752 hcryp->MspInitCallback = pCallback;
753 break;
755 case HAL_CRYP_MSPDEINIT_CB_ID :
756 hcryp->MspDeInitCallback = pCallback;
757 break;
759 default :
760 /* Update the error code */
761 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
762 /* Return error status */
763 status = HAL_ERROR;
764 break;
767 else
769 /* Update the error code */
770 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
771 /* Return error status */
772 status = HAL_ERROR;
775 /* Release Lock */
776 __HAL_UNLOCK(hcryp);
778 return status;
782 * @brief Unregister an CRYP Callback
783 * CRYP callabck is redirected to the weak predefined callback
784 * @param hcryp cryp handle
785 * @param CallbackID ID of the callback to be unregistered
786 * This parameter can be one of the following values:
787 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
788 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
789 * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
790 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
791 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
792 * @retval status
794 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
796 HAL_StatusTypeDef status = HAL_OK;
798 /* Process locked */
799 __HAL_LOCK(hcryp);
801 if (hcryp->State == HAL_CRYP_STATE_READY)
803 switch (CallbackID)
805 case HAL_CRYP_INPUT_COMPLETE_CB_ID :
806 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
807 break;
809 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
810 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
811 break;
813 case HAL_CRYP_ERROR_CB_ID :
814 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
815 break;
817 case HAL_CRYP_MSPINIT_CB_ID :
818 hcryp->MspInitCallback = HAL_CRYP_MspInit;
819 break;
821 case HAL_CRYP_MSPDEINIT_CB_ID :
822 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
823 break;
825 default :
826 /* Update the error code */
827 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
828 /* Return error status */
829 status = HAL_ERROR;
830 break;
833 else if (hcryp->State == HAL_CRYP_STATE_RESET)
835 switch (CallbackID)
837 case HAL_CRYP_MSPINIT_CB_ID :
838 hcryp->MspInitCallback = HAL_CRYP_MspInit;
839 break;
841 case HAL_CRYP_MSPDEINIT_CB_ID :
842 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
843 break;
845 default :
846 /* Update the error code */
847 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
848 /* Return error status */
849 status = HAL_ERROR;
850 break;
853 else
855 /* Update the error code */
856 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
857 /* Return error status */
858 status = HAL_ERROR;
861 /* Release Lock */
862 __HAL_UNLOCK(hcryp);
864 return status;
866 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
869 * @}
872 /** @defgroup CRYP_Exported_Functions_Group2 Encrypt Decrypt functions
873 * @brief CRYP processing functions.
875 @verbatim
876 ==============================================================================
877 ##### Encrypt Decrypt functions #####
878 ==============================================================================
879 [..] This section provides API allowing to Encrypt/Decrypt Data following
880 Standard DES/TDES or AES, and Algorithm configured by the user:
881 (+) Standard DES/TDES only supported by CRYP1 IP, below list of Algorithm supported :
882 (++) Electronic Code Book(ECB)
883 (++) Cipher Block Chaining (CBC)
884 (+) Standard AES supported by CRYP1 IP , list of Algorithm supported:
885 (++) Electronic Code Book(ECB)
886 (++) Cipher Block Chaining (CBC)
887 (++) Counter mode (CTR)
888 (++) Cipher Block Chaining (CBC)
889 (++) Counter mode (CTR)
890 (++) Galois/counter mode (GCM)
891 (++) Counter with Cipher Block Chaining-Message(CCM)
892 [..] Three processing functions are available:
893 (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
894 (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
895 (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
897 @endverbatim
898 * @{
903 * @brief Encryption mode.
904 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
905 * the configuration information for CRYP module
906 * @param Input: Pointer to the input buffer (plaintext)
907 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit.
908 * @param Output: Pointer to the output buffer(ciphertext)
909 * @param Timeout: Specify Timeout value
910 * @retval HAL status
912 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
913 uint32_t Timeout)
915 uint32_t algo;
916 HAL_StatusTypeDef status;
918 if (hcryp->State == HAL_CRYP_STATE_READY)
920 /* Change state Busy */
921 hcryp->State = HAL_CRYP_STATE_BUSY;
923 /* Process locked */
924 __HAL_LOCK(hcryp);
926 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
927 hcryp->CrypInCount = 0U;
928 hcryp->CrypOutCount = 0U;
929 hcryp->pCrypInBuffPtr = Input;
930 hcryp->pCrypOutBuffPtr = Output;
932 /* Calculate Size parameter in Byte*/
933 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
935 hcryp->Size = Size * 4U;
937 else
939 hcryp->Size = Size;
942 /* Set Encryption operating mode*/
943 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
945 /* algo get algorithm selected */
946 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
948 switch (algo)
950 case CRYP_DES_ECB:
951 case CRYP_DES_CBC:
952 case CRYP_TDES_ECB:
953 case CRYP_TDES_CBC:
955 /*Set Key */
956 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
957 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
958 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
960 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
961 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
962 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
963 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
966 /*Set Initialization Vector (IV)*/
967 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
969 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
970 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
973 /* Flush FIFO */
974 HAL_CRYP_FIFO_FLUSH(hcryp);
976 /* Set the phase */
977 hcryp->Phase = CRYP_PHASE_PROCESS;
979 /* Statrt DES/TDES encryption process */
980 status = CRYP_TDES_Process(hcryp, Timeout);
981 break;
983 case CRYP_AES_ECB:
984 case CRYP_AES_CBC:
985 case CRYP_AES_CTR:
987 /* AES encryption */
988 status = CRYP_AES_Encrypt(hcryp, Timeout);
989 break;
991 case CRYP_AES_GCM:
993 /* AES GCM encryption */
994 status = CRYP_AESGCM_Process(hcryp, Timeout);
995 break;
997 case CRYP_AES_CCM:
999 /* AES CCM encryption */
1000 status = CRYP_AESCCM_Process(hcryp, Timeout);
1001 break;
1003 default:
1004 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1005 status = HAL_ERROR;
1006 break;
1009 if (status == HAL_OK)
1011 /* Change the CRYP peripheral state */
1012 hcryp->State = HAL_CRYP_STATE_READY;
1014 /* Process unlocked */
1015 __HAL_UNLOCK(hcryp);
1018 else
1020 /* Process unlocked */
1021 __HAL_UNLOCK(hcryp);
1023 /* Busy error code field */
1024 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1025 status = HAL_ERROR;
1028 /* Return function status */
1029 return status ;
1033 * @brief Decryption mode.
1034 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1035 * the configuration information for CRYP module
1036 * @param Input: Pointer to the input buffer (ciphertext )
1037 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1038 * @param Output: Pointer to the output buffer(plaintext)
1039 * @param Timeout: Specify Timeout value
1040 * @retval HAL status
1042 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
1043 uint32_t Timeout)
1045 HAL_StatusTypeDef status;
1046 uint32_t algo;
1048 if (hcryp->State == HAL_CRYP_STATE_READY)
1050 /* Change state Busy */
1051 hcryp->State = HAL_CRYP_STATE_BUSY;
1053 /* Process locked */
1054 __HAL_LOCK(hcryp);
1056 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1057 hcryp->CrypInCount = 0U;
1058 hcryp->CrypOutCount = 0U;
1059 hcryp->pCrypInBuffPtr = Input;
1060 hcryp->pCrypOutBuffPtr = Output;
1062 /* Calculate Size parameter in Byte*/
1063 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1065 hcryp->Size = Size * 4U;
1067 else
1069 hcryp->Size = Size;
1072 /* Set Decryption operating mode*/
1073 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1075 /* algo get algorithm selected */
1076 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1078 switch (algo)
1080 case CRYP_DES_ECB:
1081 case CRYP_DES_CBC:
1082 case CRYP_TDES_ECB:
1083 case CRYP_TDES_CBC:
1085 /*Set Key */
1086 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1087 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1088 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1090 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1091 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1092 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1093 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1096 /*Set Initialization Vector (IV)*/
1097 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1099 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1100 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1103 /* Flush FIFO */
1104 HAL_CRYP_FIFO_FLUSH(hcryp);
1106 /* Set the phase */
1107 hcryp->Phase = CRYP_PHASE_PROCESS;
1109 /* Start DES/TDES decryption process */
1110 status = CRYP_TDES_Process(hcryp, Timeout);
1112 break;
1114 case CRYP_AES_ECB:
1115 case CRYP_AES_CBC:
1116 case CRYP_AES_CTR:
1118 /* AES decryption */
1119 status = CRYP_AES_Decrypt(hcryp, Timeout);
1120 break;
1122 case CRYP_AES_GCM:
1124 /* AES GCM decryption */
1125 status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1126 break;
1128 case CRYP_AES_CCM:
1130 /* AES CCM decryption */
1131 status = CRYP_AESCCM_Process(hcryp, Timeout);
1132 break;
1134 default:
1135 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1136 status = HAL_ERROR;
1137 break;
1140 if (status == HAL_OK)
1142 /* Change the CRYP peripheral state */
1143 hcryp->State = HAL_CRYP_STATE_READY;
1145 /* Process unlocked */
1146 __HAL_UNLOCK(hcryp);
1149 else
1151 /* Process unlocked */
1152 __HAL_UNLOCK(hcryp);
1154 /* Busy error code field */
1155 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1156 status = HAL_ERROR;
1159 /* Return function status */
1160 return status;
1164 * @brief Encryption in interrupt mode.
1165 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1166 * the configuration information for CRYP module
1167 * @param Input: Pointer to the input buffer (plaintext)
1168 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1169 * @param Output: Pointer to the output buffer(ciphertext)
1170 * @retval HAL status
1172 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1174 uint32_t algo;
1175 HAL_StatusTypeDef status;
1177 if (hcryp->State == HAL_CRYP_STATE_READY)
1179 /* Change state Busy */
1180 hcryp->State = HAL_CRYP_STATE_BUSY;
1182 /* Process locked */
1183 __HAL_LOCK(hcryp);
1185 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1186 hcryp->CrypInCount = 0U;
1187 hcryp->CrypOutCount = 0U;
1188 hcryp->pCrypInBuffPtr = Input;
1189 hcryp->pCrypOutBuffPtr = Output;
1191 /* Calculate Size parameter in Byte*/
1192 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1194 hcryp->Size = Size * 4U;
1196 else
1198 hcryp->Size = Size;
1201 /* Set encryption operating mode*/
1202 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1204 /* algo get algorithm selected */
1205 algo = (hcryp->Instance->CR & CRYP_CR_ALGOMODE);
1207 switch (algo)
1209 case CRYP_DES_ECB:
1210 case CRYP_DES_CBC:
1211 case CRYP_TDES_ECB:
1212 case CRYP_TDES_CBC:
1214 /*Set Key */
1215 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1216 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1217 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1219 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1220 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1221 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1222 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1224 /* Set the Initialization Vector*/
1225 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1227 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1228 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1231 /* Flush FIFO */
1232 HAL_CRYP_FIFO_FLUSH(hcryp);
1234 /* Set the phase */
1235 hcryp->Phase = CRYP_PHASE_PROCESS;
1237 /* Enable interrupts */
1238 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1240 /* Enable CRYP to start DES/TDES process*/
1241 __HAL_CRYP_ENABLE(hcryp);
1243 status = HAL_OK;
1244 break;
1246 case CRYP_AES_ECB:
1247 case CRYP_AES_CBC:
1248 case CRYP_AES_CTR:
1250 status = CRYP_AES_Encrypt_IT(hcryp);
1251 break;
1253 case CRYP_AES_GCM:
1255 status = CRYP_AESGCM_Process_IT(hcryp) ;
1256 break;
1258 case CRYP_AES_CCM:
1260 status = CRYP_AESCCM_Process_IT(hcryp);
1261 break;
1263 default:
1264 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1265 status = HAL_ERROR;
1266 break;
1269 else
1271 /* Busy error code field */
1272 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1273 status = HAL_ERROR;
1276 /* Return function status */
1277 return status ;
1281 * @brief Decryption in itnterrupt mode.
1282 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1283 * the configuration information for CRYP module
1284 * @param Input: Pointer to the input buffer (ciphertext )
1285 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1286 * @param Output: Pointer to the output buffer(plaintext)
1287 * @retval HAL status
1289 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1291 uint32_t algo;
1292 HAL_StatusTypeDef status = HAL_OK;
1294 if (hcryp->State == HAL_CRYP_STATE_READY)
1296 /* Change state Busy */
1297 hcryp->State = HAL_CRYP_STATE_BUSY;
1299 /* Process locked */
1300 __HAL_LOCK(hcryp);
1302 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1303 hcryp->CrypInCount = 0U;
1304 hcryp->CrypOutCount = 0U;
1305 hcryp->pCrypInBuffPtr = Input;
1306 hcryp->pCrypOutBuffPtr = Output;
1308 /* Calculate Size parameter in Byte*/
1309 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1311 hcryp->Size = Size * 4U;
1313 else
1315 hcryp->Size = Size;
1318 /* Set decryption operating mode*/
1319 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1321 /* algo get algorithm selected */
1322 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1324 switch (algo)
1326 case CRYP_DES_ECB:
1327 case CRYP_DES_CBC:
1328 case CRYP_TDES_ECB:
1329 case CRYP_TDES_CBC:
1331 /*Set Key */
1332 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1333 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1334 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1336 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1337 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1338 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1339 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1342 /* Set the Initialization Vector*/
1343 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1345 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1346 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1348 /* Flush FIFO */
1349 HAL_CRYP_FIFO_FLUSH(hcryp);
1351 /* Set the phase */
1352 hcryp->Phase = CRYP_PHASE_PROCESS;
1354 /* Enable interrupts */
1355 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1357 /* Enable CRYP and start DES/TDES process*/
1358 __HAL_CRYP_ENABLE(hcryp);
1360 break;
1362 case CRYP_AES_ECB:
1363 case CRYP_AES_CBC:
1364 case CRYP_AES_CTR:
1366 /* AES decryption */
1367 status = CRYP_AES_Decrypt_IT(hcryp);
1368 break;
1370 case CRYP_AES_GCM:
1372 /* AES GCM decryption */
1373 status = CRYP_AESGCM_Process_IT(hcryp) ;
1374 break;
1376 case CRYP_AES_CCM:
1378 /* AES CCMdecryption */
1379 status = CRYP_AESCCM_Process_IT(hcryp);
1380 break;
1382 default:
1383 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1384 status = HAL_ERROR;
1385 break;
1388 else
1390 /* Busy error code field */
1391 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1392 status = HAL_ERROR;
1395 /* Return function status */
1396 return status;
1400 * @brief Encryption in DMA mode.
1401 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1402 * the configuration information for CRYP module
1403 * @param Input: Pointer to the input buffer (plaintext)
1404 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1405 * @param Output: Pointer to the output buffer(ciphertext)
1406 * @retval HAL status
1408 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1410 HAL_StatusTypeDef status = HAL_OK;
1411 uint32_t algo;
1412 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1414 if (hcryp->State == HAL_CRYP_STATE_READY)
1416 /* Change state Busy */
1417 hcryp->State = HAL_CRYP_STATE_BUSY;
1419 /* Process locked */
1420 __HAL_LOCK(hcryp);
1422 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1423 hcryp->CrypInCount = 0U;
1424 hcryp->CrypOutCount = 0U;
1425 hcryp->pCrypInBuffPtr = Input;
1426 hcryp->pCrypOutBuffPtr = Output;
1428 /* Calculate Size parameter in Byte*/
1429 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1431 hcryp->Size = Size * 4U;
1433 else
1435 hcryp->Size = Size;
1438 /* Set encryption operating mode*/
1439 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1441 /* algo get algorithm selected */
1442 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1444 switch (algo)
1446 case CRYP_DES_ECB:
1447 case CRYP_DES_CBC:
1448 case CRYP_TDES_ECB:
1449 case CRYP_TDES_CBC:
1451 /*Set Key */
1452 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1453 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1454 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1456 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1457 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1458 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1459 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1462 /* Set the Initialization Vector*/
1463 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1465 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1466 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1469 /* Flush FIFO */
1470 HAL_CRYP_FIFO_FLUSH(hcryp);
1472 /* Set the phase */
1473 hcryp->Phase = CRYP_PHASE_PROCESS;
1475 /* Start DMA process transfer for DES/TDES */
1476 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
1478 break;
1480 case CRYP_AES_ECB:
1481 case CRYP_AES_CBC:
1482 case CRYP_AES_CTR:
1484 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1486 if (hcryp->KeyIVConfig == 1U)
1488 /* If the Key and IV configuration has to be done only once
1489 and if it has already been done, skip it */
1490 DoKeyIVConfig = 0U;
1492 else
1494 /* If the Key and IV configuration has to be done only once
1495 and if it has not been done already, do it and set KeyIVConfig
1496 to keep track it won't have to be done again next time */
1497 hcryp->KeyIVConfig = 1U;
1501 if (DoKeyIVConfig == 1U)
1503 /* Set the Key*/
1504 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1506 /* Set the Initialization Vector*/
1507 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1509 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1510 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
1511 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
1512 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
1514 } /* if (DoKeyIVConfig == 1U) */
1516 /* Set the phase */
1517 hcryp->Phase = CRYP_PHASE_PROCESS;
1519 /* Start DMA process transfer for AES */
1520 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
1521 break;
1523 case CRYP_AES_GCM:
1525 /* AES GCM encryption */
1526 status = CRYP_AESGCM_Process_DMA(hcryp) ;
1527 break;
1529 case CRYP_AES_CCM:
1531 /* AES CCM encryption */
1532 status = CRYP_AESCCM_Process_DMA(hcryp);
1533 break;
1535 default:
1536 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1537 status = HAL_ERROR;
1538 break;
1541 else
1543 /* Busy error code field */
1544 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1545 status = HAL_ERROR;
1548 /* Return function status */
1549 return status;
1553 * @brief Decryption in DMA mode.
1554 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1555 * the configuration information for CRYP module
1556 * @param Input: Pointer to the input buffer (ciphertext )
1557 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1558 * @param Output: Pointer to the output buffer(plaintext)
1559 * @retval HAL status
1561 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1563 uint32_t algo;
1564 HAL_StatusTypeDef status = HAL_OK;
1566 if (hcryp->State == HAL_CRYP_STATE_READY)
1568 /* Change state Busy */
1569 hcryp->State = HAL_CRYP_STATE_BUSY;
1571 /* Process locked */
1572 __HAL_LOCK(hcryp);
1574 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1575 hcryp->CrypInCount = 0U;
1576 hcryp->CrypOutCount = 0U;
1577 hcryp->pCrypInBuffPtr = Input;
1578 hcryp->pCrypOutBuffPtr = Output;
1580 /* Calculate Size parameter in Byte*/
1581 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1583 hcryp->Size = Size * 4U;
1585 else
1587 hcryp->Size = Size;
1590 /* Set decryption operating mode*/
1591 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1593 /* algo get algorithm selected */
1594 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1596 switch (algo)
1598 case CRYP_DES_ECB:
1599 case CRYP_DES_CBC:
1600 case CRYP_TDES_ECB:
1601 case CRYP_TDES_CBC:
1603 /*Set Key */
1604 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1605 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1606 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1608 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1609 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1610 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1611 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1614 /* Set the Initialization Vector*/
1615 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1617 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1618 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1621 /* Flush FIFO */
1622 HAL_CRYP_FIFO_FLUSH(hcryp);
1624 /* Set the phase */
1625 hcryp->Phase = CRYP_PHASE_PROCESS;
1627 /* Start DMA process transfer for DES/TDES */
1628 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
1629 break;
1631 case CRYP_AES_ECB:
1632 case CRYP_AES_CBC:
1633 case CRYP_AES_CTR:
1635 /* AES decryption */
1636 status = CRYP_AES_Decrypt_DMA(hcryp);
1637 break;
1639 case CRYP_AES_GCM:
1641 /* AES GCM decryption */
1642 status = CRYP_AESGCM_Process_DMA(hcryp) ;
1644 break;
1646 case CRYP_AES_CCM:
1648 /* AES CCM decryption */
1649 status = CRYP_AESCCM_Process_DMA(hcryp);
1650 break;
1652 default:
1653 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1654 status = HAL_ERROR;
1655 break;
1658 else
1660 /* Busy error code field */
1661 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1662 status = HAL_ERROR;
1665 /* Return function status */
1666 return status;
1670 * @}
1673 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1674 * @brief CRYP IRQ handler.
1676 @verbatim
1677 ==============================================================================
1678 ##### CRYP IRQ handler management #####
1679 ==============================================================================
1680 [..] This section provides CRYP IRQ handler and callback functions.
1681 (+) HAL_CRYP_IRQHandler CRYP interrupt request
1682 (+) HAL_CRYP_InCpltCallback input data transfer complete callback
1683 (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
1684 (+) HAL_CRYP_ErrorCallback CRYP error callback
1685 (+) HAL_CRYP_GetState return the CRYP state
1686 (+) HAL_CRYP_GetError return the CRYP error code
1687 @endverbatim
1688 * @{
1692 * @brief This function handles cryptographic interrupt request.
1693 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1694 * the configuration information for CRYP module
1695 * @retval None
1697 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
1699 uint32_t itstatus = hcryp->Instance->MISR;
1701 if ((itstatus & (CRYP_IT_INI | CRYP_IT_OUTI)) != 0U)
1703 if ((hcryp->Init.Algorithm == CRYP_DES_ECB) || (hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1705 CRYP_TDES_IT(hcryp); /* DES or TDES*/
1707 else if ((hcryp->Init.Algorithm == CRYP_AES_ECB) || (hcryp->Init.Algorithm == CRYP_AES_CBC) || (hcryp->Init.Algorithm == CRYP_AES_CTR))
1709 CRYP_AES_IT(hcryp); /*AES*/
1712 else if ((hcryp->Init.Algorithm == CRYP_AES_GCM) || (hcryp->Init.Algorithm == CRYP_CR_ALGOMODE_AES_CCM))
1714 /* if header phase */
1715 if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
1717 CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
1719 else /* if payload phase */
1721 CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
1724 else
1726 /* Nothing to do */
1732 * @brief Return the CRYP error code.
1733 * @param hcryp : pointer to a CRYP_HandleTypeDef structure that contains
1734 * the configuration information for the CRYP IP
1735 * @retval CRYP error code
1737 uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp)
1739 return hcryp->ErrorCode;
1743 * @brief Returns the CRYP state.
1744 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1745 * the configuration information for CRYP module.
1746 * @retval HAL state
1748 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp)
1750 return hcryp->State;
1754 * @brief Input FIFO transfer completed callback.
1755 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1756 * the configuration information for CRYP module.
1757 * @retval None
1759 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
1761 /* Prevent unused argument(s) compilation warning */
1762 UNUSED(hcryp);
1764 /* NOTE : This function Should not be modified, when the callback is needed,
1765 the HAL_CRYP_InCpltCallback could be implemented in the user file
1770 * @brief Output FIFO transfer completed callback.
1771 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1772 * the configuration information for CRYP module.
1773 * @retval None
1775 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
1777 /* Prevent unused argument(s) compilation warning */
1778 UNUSED(hcryp);
1780 /* NOTE : This function Should not be modified, when the callback is needed,
1781 the HAL_CRYP_OutCpltCallback could be implemented in the user file
1786 * @brief CRYP error callback.
1787 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1788 * the configuration information for CRYP module.
1789 * @retval None
1791 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
1793 /* Prevent unused argument(s) compilation warning */
1794 UNUSED(hcryp);
1796 /* NOTE : This function Should not be modified, when the callback is needed,
1797 the HAL_CRYP_ErrorCallback could be implemented in the user file
1801 * @}
1804 /* Private functions ---------------------------------------------------------*/
1805 /** @addtogroup CRYP_Private_Functions
1806 * @{
1810 * @brief Encryption in ECB/CBC Algorithm with DES/TDES standard.
1811 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1812 * the configuration information for CRYP module
1813 * @param Timeout: Timeout value
1814 * @retval HAL status
1816 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
1819 uint32_t temp; /* Temporary CrypOutBuff */
1820 uint16_t incount; /* Temporary CrypInCount Value */
1821 uint16_t outcount; /* Temporary CrypOutCount Value */
1823 /* Enable CRYP */
1824 __HAL_CRYP_ENABLE(hcryp);
1825 /*Temporary CrypOutCount Value*/
1826 outcount = hcryp->CrypOutCount;
1828 /*Start processing*/
1829 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
1831 /* Temporary CrypInCount Value */
1832 incount = hcryp->CrypInCount;
1833 /* Write plain data and get cipher data */
1834 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
1836 /* Write the input block in the IN FIFO */
1837 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1838 hcryp->CrypInCount++;
1839 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1840 hcryp->CrypInCount++;
1843 /* Wait for OFNE flag to be raised */
1844 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
1846 /* Disable the CRYP peripheral clock */
1847 __HAL_CRYP_DISABLE(hcryp);
1849 /* Change state & errorCode*/
1850 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
1851 hcryp->State = HAL_CRYP_STATE_READY;
1853 /* Process unlocked */
1854 __HAL_UNLOCK(hcryp);
1855 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1856 /*Call registered error callback*/
1857 hcryp->ErrorCallback(hcryp);
1858 #else
1859 /*Call legacy weak error callback*/
1860 HAL_CRYP_ErrorCallback(hcryp);
1861 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1864 /*Temporary CrypOutCount Value*/
1865 outcount = hcryp->CrypOutCount;
1867 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
1869 /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer */
1870 temp = hcryp->Instance->DOUT;
1871 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1872 hcryp->CrypOutCount++;
1873 temp = hcryp->Instance->DOUT;
1874 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1875 hcryp->CrypOutCount++;
1877 /*Temporary CrypOutCount Value*/
1878 outcount = hcryp->CrypOutCount;
1880 /* Disable CRYP */
1881 __HAL_CRYP_DISABLE(hcryp);
1882 /* Change the CRYP state */
1883 hcryp->State = HAL_CRYP_STATE_READY;
1885 /* Return function status */
1886 return HAL_OK;
1890 * @brief CRYP block input/output data handling under interruption with DES/TDES standard.
1891 * @note The function is called under interruption only, once
1892 * interruptions have been enabled by CRYP_Decrypt_IT() and CRYP_Encrypt_IT().
1893 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1894 * the configuration information for CRYP module.
1895 * @retval HAL status
1897 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp)
1899 uint32_t temp; /* Temporary CrypOutBuff */
1901 if (hcryp->State == HAL_CRYP_STATE_BUSY)
1903 if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI) != 0x0U)
1905 if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_INRIS) != 0x0U)
1907 /* Write input block in the IN FIFO */
1908 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1909 hcryp->CrypInCount++;
1910 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1911 hcryp->CrypInCount++;
1913 if (hcryp->CrypInCount == (hcryp->Size / 4U))
1915 /* Disable interruption */
1916 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1918 /* Call the input data transfer complete callback */
1919 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1920 /*Call registered Input complete callback*/
1921 hcryp->InCpltCallback(hcryp);
1922 #else
1923 /*Call legacy weak Input complete callback*/
1924 HAL_CRYP_InCpltCallback(hcryp);
1925 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1930 if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI) != 0x0U)
1932 if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_OUTRIS) != 0x0U)
1934 /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer */
1935 temp = hcryp->Instance->DOUT;
1936 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1937 hcryp->CrypOutCount++;
1938 temp = hcryp->Instance->DOUT;
1939 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1940 hcryp->CrypOutCount++;
1941 if (hcryp->CrypOutCount == (hcryp->Size / 4U))
1943 /* Disable interruption */
1944 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1946 /* Disable CRYP */
1947 __HAL_CRYP_DISABLE(hcryp);
1949 /* Process unlocked */
1950 __HAL_UNLOCK(hcryp);
1952 /* Change the CRYP state */
1953 hcryp->State = HAL_CRYP_STATE_READY;
1955 /* Call output transfer complete callback */
1956 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1957 /*Call registered Output complete callback*/
1958 hcryp->OutCpltCallback(hcryp);
1959 #else
1960 /*Call legacy weak Output complete callback*/
1961 HAL_CRYP_OutCpltCallback(hcryp);
1962 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1968 else
1970 /* Process unlocked */
1971 __HAL_UNLOCK(hcryp);
1972 /* Busy error code field */
1973 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1974 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1975 /*Call registered error callback*/
1976 hcryp->ErrorCallback(hcryp);
1977 #else
1978 /*Call legacy weak error callback*/
1979 HAL_CRYP_ErrorCallback(hcryp);
1980 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1985 * @brief Encryption in ECB/CBC & CTR Algorithm with AES Standard
1986 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
1987 * @param Timeout: specify Timeout value
1988 * @retval HAL status
1990 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
1992 uint16_t outcount; /* Temporary CrypOutCount Value */
1993 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1995 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1997 if (hcryp->KeyIVConfig == 1U)
1999 /* If the Key and IV configuration has to be done only once
2000 and if it has already been done, skip it */
2001 DoKeyIVConfig = 0U;
2003 else
2005 /* If the Key and IV configuration has to be done only once
2006 and if it has not been done already, do it and set KeyIVConfig
2007 to keep track it won't have to be done again next time */
2008 hcryp->KeyIVConfig = 1U;
2012 if (DoKeyIVConfig == 1U)
2014 /* Set the Key*/
2015 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2017 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2019 /* Set the Initialization Vector*/
2020 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2021 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2022 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2023 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2025 } /* if (DoKeyIVConfig == 1U) */
2027 /* Set the phase */
2028 hcryp->Phase = CRYP_PHASE_PROCESS;
2030 /* Enable CRYP */
2031 __HAL_CRYP_ENABLE(hcryp);
2032 /*Temporary CrypOutCount Value*/
2033 outcount = hcryp->CrypOutCount;
2035 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2037 /* Write plain Ddta and get cipher data */
2038 CRYP_AES_ProcessData(hcryp, Timeout);
2039 /*Temporary CrypOutCount Value*/
2040 outcount = hcryp->CrypOutCount;
2043 /* Disable CRYP */
2044 __HAL_CRYP_DISABLE(hcryp);
2046 /* Change the CRYP state */
2047 hcryp->State = HAL_CRYP_STATE_READY;
2049 /* Return function status */
2050 return HAL_OK;
2054 * @brief Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2055 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2056 * the configuration information for CRYP module
2057 * @retval HAL status
2059 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
2061 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2063 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2065 if (hcryp->KeyIVConfig == 1U)
2067 /* If the Key and IV configuration has to be done only once
2068 and if it has already been done, skip it */
2069 DoKeyIVConfig = 0U;
2071 else
2073 /* If the Key and IV configuration has to be done only once
2074 and if it has not been done already, do it and set KeyIVConfig
2075 to keep track it won't have to be done again next time */
2076 hcryp->KeyIVConfig = 1U;
2080 if (DoKeyIVConfig == 1U)
2082 /* Set the Key*/
2083 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2085 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2087 /* Set the Initialization Vector*/
2088 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2089 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2090 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2091 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2093 } /* if (DoKeyIVConfig == 1U) */
2095 /* Set the phase */
2096 hcryp->Phase = CRYP_PHASE_PROCESS;
2098 if (hcryp->Size != 0U)
2100 /* Enable interrupts */
2101 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2103 /* Enable CRYP */
2104 __HAL_CRYP_ENABLE(hcryp);
2106 else
2108 /* Change the CRYP state */
2109 hcryp->State = HAL_CRYP_STATE_READY;
2111 /* Process unlocked */
2112 __HAL_UNLOCK(hcryp);
2115 /* Return function status */
2116 return HAL_OK;
2120 * @brief Decryption in ECB/CBC & CTR mode with AES Standard
2121 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
2122 * @param Timeout: Specify Timeout value
2123 * @retval HAL status
2125 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2127 uint16_t outcount; /* Temporary CrypOutCount Value */
2128 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2130 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2132 if (hcryp->KeyIVConfig == 1U)
2134 /* If the Key and IV configuration has to be done only once
2135 and if it has already been done, skip it */
2136 DoKeyIVConfig = 0U;
2138 else
2140 /* If the Key and IV configuration has to be done only once
2141 and if it has not been done already, do it and set KeyIVConfig
2142 to keep track it won't have to be done again next time */
2143 hcryp->KeyIVConfig = 1U;
2147 if (DoKeyIVConfig == 1U)
2149 /* Key preparation for ECB/CBC */
2150 if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/
2152 /* change ALGOMODE to key preparation for decryption*/
2153 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2155 /* Set the Key*/
2156 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2158 /* Enable CRYP */
2159 __HAL_CRYP_ENABLE(hcryp);
2161 /* Wait for BUSY flag to be raised */
2162 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
2164 /* Disable the CRYP peripheral clock */
2165 __HAL_CRYP_DISABLE(hcryp);
2167 /* Change state */
2168 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2169 hcryp->State = HAL_CRYP_STATE_READY;
2171 /* Process unlocked */
2172 __HAL_UNLOCK(hcryp);
2173 return HAL_ERROR;
2175 /* Turn back to ALGOMODE of the configuration */
2176 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2178 else /*Algorithm CTR */
2180 /* Set the Key*/
2181 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2184 /* Set IV */
2185 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2187 /* Set the Initialization Vector*/
2188 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2189 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2190 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2191 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2193 } /* if (DoKeyIVConfig == 1U) */
2195 /* Set the phase */
2196 hcryp->Phase = CRYP_PHASE_PROCESS;
2198 /* Enable CRYP */
2199 __HAL_CRYP_ENABLE(hcryp);
2201 /*Temporary CrypOutCount Value*/
2202 outcount = hcryp->CrypOutCount;
2204 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2206 /* Write plain data and get cipher data */
2207 CRYP_AES_ProcessData(hcryp, Timeout);
2208 /*Temporary CrypOutCount Value*/
2209 outcount = hcryp->CrypOutCount;
2212 /* Disable CRYP */
2213 __HAL_CRYP_DISABLE(hcryp);
2215 /* Change the CRYP state */
2216 hcryp->State = HAL_CRYP_STATE_READY;
2218 /* Return function status */
2219 return HAL_OK;
2222 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2223 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2224 * the configuration information for CRYP module
2225 * @retval HAL status
2227 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
2229 __IO uint32_t count = 0U;
2230 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2232 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2234 if (hcryp->KeyIVConfig == 1U)
2236 /* If the Key and IV configuration has to be done only once
2237 and if it has already been done, skip it */
2238 DoKeyIVConfig = 0U;
2240 else
2242 /* If the Key and IV configuration has to be done only once
2243 and if it has not been done already, do it and set KeyIVConfig
2244 to keep track it won't have to be done again next time */
2245 hcryp->KeyIVConfig = 1U;
2249 if (DoKeyIVConfig == 1U)
2251 /* Key preparation for ECB/CBC */
2252 if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2254 /* change ALGOMODE to key preparation for decryption*/
2255 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2257 /* Set the Key*/
2258 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2260 /* Enable CRYP */
2261 __HAL_CRYP_ENABLE(hcryp);
2263 /* Wait for BUSY flag to be raised */
2264 count = CRYP_TIMEOUT_KEYPREPARATION;
2267 count-- ;
2268 if (count == 0U)
2270 /* Change state */
2271 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2272 hcryp->State = HAL_CRYP_STATE_READY;
2274 /* Process unlocked */
2275 __HAL_UNLOCK(hcryp);
2276 return HAL_ERROR;
2278 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2280 /* Turn back to ALGOMODE of the configuration */
2281 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2283 else /*Algorithm CTR */
2285 /* Set the Key*/
2286 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2289 /* Set IV */
2290 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2292 /* Set the Initialization Vector*/
2293 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2294 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2295 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2296 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2298 } /* if (DoKeyIVConfig == 1U) */
2300 /* Set the phase */
2301 hcryp->Phase = CRYP_PHASE_PROCESS;
2302 if (hcryp->Size != 0U)
2304 /* Enable interrupts */
2305 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2307 /* Enable CRYP */
2308 __HAL_CRYP_ENABLE(hcryp);
2310 else
2312 /* Process locked */
2313 __HAL_UNLOCK(hcryp);
2315 /* Change the CRYP state */
2316 hcryp->State = HAL_CRYP_STATE_READY;
2318 /* Return function status */
2319 return HAL_OK;
2322 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
2323 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2324 * the configuration information for CRYP module
2325 * @retval HAL status
2327 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
2329 __IO uint32_t count = 0U;
2330 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2332 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2334 if (hcryp->KeyIVConfig == 1U)
2336 /* If the Key and IV configuration has to be done only once
2337 and if it has already been done, skip it */
2338 DoKeyIVConfig = 0U;
2340 else
2342 /* If the Key and IV configuration has to be done only once
2343 and if it has not been done already, do it and set KeyIVConfig
2344 to keep track it won't have to be done again next time */
2345 hcryp->KeyIVConfig = 1U;
2349 if (DoKeyIVConfig == 1U)
2351 /* Key preparation for ECB/CBC */
2352 if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2354 /* change ALGOMODE to key preparation for decryption*/
2355 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2357 /* Set the Key*/
2358 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2360 /* Enable CRYP */
2361 __HAL_CRYP_ENABLE(hcryp);
2363 /* Wait for BUSY flag to be raised */
2364 count = CRYP_TIMEOUT_KEYPREPARATION;
2367 count-- ;
2368 if (count == 0U)
2370 /* Disable the CRYP peripheral clock */
2371 __HAL_CRYP_DISABLE(hcryp);
2373 /* Change state */
2374 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2375 hcryp->State = HAL_CRYP_STATE_READY;
2377 /* Process unlocked */
2378 __HAL_UNLOCK(hcryp);
2379 return HAL_ERROR;
2381 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2383 /* Turn back to ALGOMODE of the configuration */
2384 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2386 else /*Algorithm CTR */
2388 /* Set the Key*/
2389 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2392 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2394 /* Set the Initialization Vector*/
2395 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2396 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2397 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2398 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2400 } /* if (DoKeyIVConfig == 1U) */
2402 /* Set the phase */
2403 hcryp->Phase = CRYP_PHASE_PROCESS;
2405 if (hcryp->Size != 0U)
2407 /* Set the input and output addresses and start DMA transfer */
2408 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
2410 else
2412 /* Process unlocked */
2413 __HAL_UNLOCK(hcryp);
2415 /* Change the CRYP state */
2416 hcryp->State = HAL_CRYP_STATE_READY;
2419 /* Return function status */
2420 return HAL_OK;
2425 * @brief DMA CRYP input data process complete callback.
2426 * @param hdma: DMA handle
2427 * @retval None
2429 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
2431 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2433 /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit
2434 in the DMACR register */
2435 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
2437 /* Call input data transfer complete callback */
2438 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2439 /*Call registered Input complete callback*/
2440 hcryp->InCpltCallback(hcryp);
2441 #else
2442 /*Call legacy weak Input complete callback*/
2443 HAL_CRYP_InCpltCallback(hcryp);
2444 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2448 * @brief DMA CRYP output data process complete callback.
2449 * @param hdma: DMA handle
2450 * @retval None
2452 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
2454 uint32_t count;
2455 uint32_t npblb;
2456 uint32_t lastwordsize;
2457 uint32_t temp; /* Temporary CrypOutBuff */
2458 uint32_t temp_cr_algodir;
2459 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2462 /* Disable the DMA transfer for output FIFO */
2463 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
2465 /* Last block transfer in case of GCM or CCM with Size not %16*/
2466 if (((hcryp->Size) % 16U) != 0U)
2468 /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA */
2469 hcryp->CrypInCount = (hcryp->Size / 16U) * 4U ;
2470 hcryp->CrypOutCount = hcryp->CrypInCount;
2472 /* Compute the number of padding bytes in last block of payload */
2473 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
2475 #if !defined (CRYP_VER_2_2)
2476 if (hcryp->Version >= REV_ID_B)
2477 #endif /*End of not defined CRYP_VER_2_2*/
2479 /* Case of AES GCM payload encryption or AES CCM payload decryption to get right tag */
2480 temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
2481 if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
2482 ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
2484 /* Disable the CRYP */
2485 __HAL_CRYP_DISABLE(hcryp);
2487 /* Specify the number of non-valid bytes using NPBLB register*/
2488 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
2490 /* Enable CRYP to start the final phase */
2491 __HAL_CRYP_ENABLE(hcryp);
2495 /* Number of valid words (lastwordsize) in last block */
2496 if ((npblb % 4U) == 0U)
2498 lastwordsize = (16U - npblb) / 4U;
2500 else
2502 lastwordsize = ((16U - npblb) / 4U) + 1U;
2504 /* Write the last input block in the IN FIFO */
2505 for (count = 0U; count < lastwordsize; count ++)
2507 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2508 hcryp->CrypInCount++;
2510 /* Pad the data with zeros to have a complete block */
2511 while (count < 4U)
2513 hcryp->Instance->DIN = 0U;
2514 count++;
2516 /* Wait for OFNE flag to be raised */
2517 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
2520 count-- ;
2521 if (count == 0U)
2523 /* Disable the CRYP peripheral clock */
2524 __HAL_CRYP_DISABLE(hcryp);
2526 /* Change state */
2527 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2528 hcryp->State = HAL_CRYP_STATE_READY;
2530 /* Process unlocked */
2531 __HAL_UNLOCK(hcryp);
2532 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2533 /*Call registered error callback*/
2534 hcryp->ErrorCallback(hcryp);
2535 #else
2536 /*Call legacy weak error callback*/
2537 HAL_CRYP_ErrorCallback(hcryp);
2538 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2540 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
2542 /*Read the output block from the output FIFO */
2543 for (count = 0U; count < 4U; count++)
2545 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
2546 temp = hcryp->Instance->DOUT;
2548 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2549 hcryp->CrypOutCount++;
2551 } /*End of last block transfer in case of GCM or CCM */
2553 if ((hcryp->Init.Algorithm & CRYP_AES_GCM) != CRYP_AES_GCM)
2555 /* Disable CRYP (not allowed in GCM)*/
2556 __HAL_CRYP_DISABLE(hcryp);
2559 /* Change the CRYP state to ready */
2560 hcryp->State = HAL_CRYP_STATE_READY;
2562 /* Process unlocked */
2563 __HAL_UNLOCK(hcryp);
2565 /* Call output data transfer complete callback */
2566 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2567 /*Call registered Output complete callback*/
2568 hcryp->OutCpltCallback(hcryp);
2569 #else
2570 /*Call legacy weak Output complete callback*/
2571 HAL_CRYP_OutCpltCallback(hcryp);
2572 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2576 * @brief DMA CRYP communication error callback.
2577 * @param hdma: DMA handle
2578 * @retval None
2580 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
2582 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2584 /* Change the CRYP peripheral state */
2585 hcryp->State = HAL_CRYP_STATE_READY;
2587 /* DMA error code field */
2588 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2590 /* Call error callback */
2591 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2592 /*Call registered error callback*/
2593 hcryp->ErrorCallback(hcryp);
2594 #else
2595 /*Call legacy weak error callback*/
2596 HAL_CRYP_ErrorCallback(hcryp);
2597 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2601 * @brief Set the DMA configuration and start the DMA transfer
2602 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2603 * the configuration information for CRYP module
2604 * @param inputaddr: address of the input buffer
2605 * @param Size: size of the input buffer, must be a multiple of 16.
2606 * @param outputaddr: address of the output buffer
2607 * @retval None
2609 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2611 /* Set the CRYP DMA transfer complete callback */
2612 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2614 /* Set the DMA input error callback */
2615 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2617 /* Set the CRYP DMA transfer complete callback */
2618 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2620 /* Set the DMA output error callback */
2621 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2623 /* Enable CRYP */
2624 __HAL_CRYP_ENABLE(hcryp);
2626 /* Enable the input DMA Stream */
2627 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DIN, Size) != HAL_OK)
2629 /* DMA error code field */
2630 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2632 /* Call error callback */
2633 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2634 /*Call registered error callback*/
2635 hcryp->ErrorCallback(hcryp);
2636 #else
2637 /*Call legacy weak error callback*/
2638 HAL_CRYP_ErrorCallback(hcryp);
2639 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2642 /* Enable the output DMA Stream */
2643 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size) != HAL_OK)
2645 /* DMA error code field */
2646 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2648 /* Call error callback */
2649 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2650 /*Call registered error callback*/
2651 hcryp->ErrorCallback(hcryp);
2652 #else
2653 /*Call legacy weak error callback*/
2654 HAL_CRYP_ErrorCallback(hcryp);
2655 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2657 /* Enable In/Out DMA request */
2658 hcryp->Instance->DMACR = CRYP_DMACR_DOEN | CRYP_DMACR_DIEN;
2662 * @brief Process Data: Write Input data in polling mode and used in AES functions.
2663 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2664 * the configuration information for CRYP module
2665 * @param Timeout: Specify Timeout value
2666 * @retval None
2668 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2671 uint32_t temp[4]; /* Temporary CrypOutBuff */
2672 uint16_t incount; /* Temporary CrypInCount Value */
2673 uint16_t outcount; /* Temporary CrypOutCount Value */
2674 uint32_t i;
2676 /*Temporary CrypOutCount Value*/
2677 incount = hcryp->CrypInCount;
2679 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < ((hcryp->Size) / 4U)))
2681 /* Write the input block in the IN FIFO */
2682 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2683 hcryp->CrypInCount++;
2684 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2685 hcryp->CrypInCount++;
2686 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2687 hcryp->CrypInCount++;
2688 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2689 hcryp->CrypInCount++;
2692 /* Wait for OFNE flag to be raised */
2693 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
2695 /* Disable the CRYP peripheral clock */
2696 __HAL_CRYP_DISABLE(hcryp);
2698 /* Change state & error code*/
2699 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2700 hcryp->State = HAL_CRYP_STATE_READY;
2702 /* Process unlocked */
2703 __HAL_UNLOCK(hcryp);
2704 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2705 /*Call registered error callback*/
2706 hcryp->ErrorCallback(hcryp);
2707 #else
2708 /*Call legacy weak error callback*/
2709 HAL_CRYP_ErrorCallback(hcryp);
2710 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2712 /*Temporary CrypOutCount Value*/
2713 outcount = hcryp->CrypOutCount;
2715 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < ((hcryp->Size) / 4U)))
2717 /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
2718 for (i = 0U; i < 4U; i++)
2720 temp[i] = hcryp->Instance->DOUT;
2722 i = 0U;
2723 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
2725 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2726 hcryp->CrypOutCount++;
2727 i++;
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[4]; /* Temporary CrypOutBuff */
2743 uint16_t incount; /* Temporary CrypInCount Value */
2744 uint16_t outcount; /* Temporary CrypOutCount Value */
2745 uint32_t i;
2747 if (hcryp->State == HAL_CRYP_STATE_BUSY)
2749 /*Temporary CrypOutCount Value*/
2750 incount = hcryp->CrypInCount;
2752 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
2754 /* Write the input block in the IN FIFO */
2755 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2756 hcryp->CrypInCount++;
2757 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2758 hcryp->CrypInCount++;
2759 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2760 hcryp->CrypInCount++;
2761 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2762 hcryp->CrypInCount++;
2763 if (hcryp->CrypInCount == (hcryp->Size / 4U))
2765 /* Disable interrupts */
2766 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
2768 /* Call the input data transfer complete callback */
2769 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2770 /*Call registered Input complete callback*/
2771 hcryp->InCpltCallback(hcryp);
2772 #else
2773 /*Call legacy weak Input complete callback*/
2774 HAL_CRYP_InCpltCallback(hcryp);
2775 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2779 /*Temporary CrypOutCount Value*/
2780 outcount = hcryp->CrypOutCount;
2782 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
2784 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
2785 for (i = 0U; i < 4U; i++)
2787 temp[i] = hcryp->Instance->DOUT;
2789 i = 0U;
2790 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
2792 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2793 hcryp->CrypOutCount++;
2794 i++;
2796 if (hcryp->CrypOutCount == (hcryp->Size / 4U))
2798 /* Disable interrupts */
2799 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
2801 /* Change the CRYP state */
2802 hcryp->State = HAL_CRYP_STATE_READY;
2804 /* Disable CRYP */
2805 __HAL_CRYP_DISABLE(hcryp);
2807 /* Process unlocked */
2808 __HAL_UNLOCK(hcryp);
2810 /* Call output transfer complete callback */
2811 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2812 /*Call registered Output complete callback*/
2813 hcryp->OutCpltCallback(hcryp);
2814 #else
2815 /*Call legacy weak Output complete callback*/
2816 HAL_CRYP_OutCpltCallback(hcryp);
2817 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2821 else
2823 /* Process unlocked */
2824 __HAL_UNLOCK(hcryp);
2825 /* Busy error code field */
2826 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
2827 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2828 /*Call registered error callback*/
2829 hcryp->ErrorCallback(hcryp);
2830 #else
2831 /*Call legacy weak error callback*/
2832 HAL_CRYP_ErrorCallback(hcryp);
2833 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2838 * @brief Writes Key in Key registers.
2839 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2840 * the configuration information for CRYP module
2841 * @param KeySize: Size of Key
2842 * @retval None
2844 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
2846 switch (KeySize)
2848 case CRYP_KEYSIZE_256B:
2849 hcryp->Instance->K0LR = *(uint32_t *)(hcryp->Init.pKey);
2850 hcryp->Instance->K0RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2851 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2852 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2853 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2854 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2855 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 6);
2856 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 7);
2857 break;
2858 case CRYP_KEYSIZE_192B:
2859 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
2860 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2861 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2862 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2863 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2864 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2865 break;
2866 case CRYP_KEYSIZE_128B:
2867 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey);
2868 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2869 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2870 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2872 break;
2873 default:
2874 break;
2879 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
2880 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2881 * the configuration information for CRYP module
2882 * @param Timeout: Timeout duration
2883 * @retval HAL status
2885 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2887 uint32_t tickstart;
2888 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
2889 uint32_t npblb ;
2890 uint32_t temp[4]; /* Temporary CrypOutBuff */
2891 uint32_t index ;
2892 uint32_t lastwordsize ;
2893 uint16_t outcount; /* Temporary CrypOutCount Value */
2894 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2896 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2898 if (hcryp->KeyIVConfig == 1U)
2900 /* If the Key and IV configuration has to be done only once
2901 and if it has already been done, skip it */
2902 DoKeyIVConfig = 0U;
2903 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
2905 else
2907 /* If the Key and IV configuration has to be done only once
2908 and if it has not been done already, do it and set KeyIVConfig
2909 to keep track it won't have to be done again next time */
2910 hcryp->KeyIVConfig = 1U;
2911 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
2914 else
2916 hcryp->SizesSum = hcryp->Size;
2919 if (DoKeyIVConfig == 1U)
2921 /* Reset CrypHeaderCount */
2922 hcryp->CrypHeaderCount = 0U;
2924 /****************************** Init phase **********************************/
2926 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2928 /* Set the key */
2929 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2931 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
2932 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2933 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2934 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2935 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2937 /* Enable the CRYP peripheral */
2938 __HAL_CRYP_ENABLE(hcryp);
2940 /* Get tick */
2941 tickstart = HAL_GetTick();
2943 /*Wait for the CRYPEN bit to be cleared*/
2944 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2946 /* Check for the Timeout */
2947 if (Timeout != HAL_MAX_DELAY)
2949 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2951 /* Disable the CRYP peripheral clock */
2952 __HAL_CRYP_DISABLE(hcryp);
2954 /* Change state */
2955 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2956 hcryp->State = HAL_CRYP_STATE_READY;
2958 /* Process unlocked */
2959 __HAL_UNLOCK(hcryp);
2960 return HAL_ERROR;
2965 /************************ Header phase *************************************/
2967 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
2969 return HAL_ERROR;
2972 /*************************Payload phase ************************************/
2974 /* Set the phase */
2975 hcryp->Phase = CRYP_PHASE_PROCESS;
2977 /* Disable the CRYP peripheral */
2978 __HAL_CRYP_DISABLE(hcryp);
2980 #if !defined (CRYP_VER_2_2)
2981 if (hcryp->Version >= REV_ID_B)
2982 #endif /*End of not defined CRYP_VER_2_2*/
2984 /* Set to 0 the number of non-valid bytes using NPBLB register*/
2985 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
2988 /* Select payload phase once the header phase is performed */
2989 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2991 /* Enable the CRYP peripheral */
2992 __HAL_CRYP_ENABLE(hcryp);
2993 } /* if (DoKeyIVConfig == 1U) */
2995 if ((hcryp->Size % 16U) != 0U)
2997 /* recalculate wordsize */
2998 wordsize = ((wordsize / 4U) * 4U) ;
3001 /* Get tick */
3002 tickstart = HAL_GetTick();
3003 /*Temporary CrypOutCount Value*/
3004 outcount = hcryp->CrypOutCount;
3006 /* Write input data and get output Data */
3007 while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3009 /* Write plain data and get cipher data */
3010 CRYP_AES_ProcessData(hcryp, Timeout);
3012 /*Temporary CrypOutCount Value*/
3013 outcount = hcryp->CrypOutCount;
3015 /* Check for the Timeout */
3016 if (Timeout != HAL_MAX_DELAY)
3018 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3020 /* Disable the CRYP peripheral clock */
3021 __HAL_CRYP_DISABLE(hcryp);
3023 /* Change state & error code */
3024 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3025 hcryp->State = HAL_CRYP_STATE_READY;
3027 /* Process unlocked */
3028 __HAL_UNLOCK(hcryp);
3029 return HAL_ERROR;
3034 if ((hcryp->Size % 16U) != 0U)
3037 #if !defined (CRYP_VER_2_2)
3038 if (hcryp->Version >= REV_ID_B)
3039 #endif /*End of not defined CRYP_VER_2_2*/
3041 /* Compute the number of padding bytes in last block of payload */
3042 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3044 /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3045 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3047 /* Disable the CRYP */
3048 __HAL_CRYP_DISABLE(hcryp);
3050 /* Specify the number of non-valid bytes using NPBLB register*/
3051 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3053 /* Enable CRYP to start the final phase */
3054 __HAL_CRYP_ENABLE(hcryp);
3056 /* Number of valid words (lastwordsize) in last block */
3057 if ((npblb % 4U) == 0U)
3059 lastwordsize = (16U - npblb) / 4U;
3061 else
3063 lastwordsize = ((16U - npblb) / 4U) + 1U;
3066 /* Write the last input block in the IN FIFO */
3067 for (index = 0U; index < lastwordsize; index ++)
3069 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3070 hcryp->CrypInCount++;
3073 /* Pad the data with zeros to have a complete block */
3074 while (index < 4U)
3076 hcryp->Instance->DIN = 0U;
3077 index++;
3080 /* Wait for OFNE flag to be raised */
3081 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3083 /* Disable the CRYP peripheral clock */
3084 __HAL_CRYP_DISABLE(hcryp);
3086 /* Change state */
3087 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3088 hcryp->State = HAL_CRYP_STATE_READY;
3090 /* Process Unlocked */
3091 __HAL_UNLOCK(hcryp);
3092 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3093 /*Call registered error callback*/
3094 hcryp->ErrorCallback(hcryp);
3095 #else
3096 /*Call legacy weak error callback*/
3097 HAL_CRYP_ErrorCallback(hcryp);
3098 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3101 /*Read the output block from the output FIFO */
3102 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3104 for (index = 0U; index < 4U; index++)
3106 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3107 temp[index] = hcryp->Instance->DOUT;
3109 for (index=0; index<lastwordsize; index++)
3111 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
3112 hcryp->CrypOutCount++;
3116 #if !defined (CRYP_VER_2_2)
3117 else /* Workaround to be used */
3119 /* Workaround 2 for STM32H7 below rev.B To generate correct TAG only when size of the last block of
3120 payload is inferior to 128 bits, in case of GCM encryption or CCM decryption*/
3121 CRYP_Workaround(hcryp, Timeout);
3122 } /* end of NPBLB or Workaround*/
3123 #endif /*End of not defined CRYP_VER_2_2*/
3126 /* Return function status */
3127 return HAL_OK;
3131 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
3132 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3133 * the configuration information for CRYP module
3134 * @retval HAL status
3136 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3138 __IO uint32_t count = 0U;
3139 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3141 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3143 if (hcryp->KeyIVConfig == 1U)
3145 /* If the Key and IV configuration has to be done only once
3146 and if it has already been done, skip it */
3147 DoKeyIVConfig = 0U;
3148 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3150 else
3152 /* If the Key and IV configuration has to be done only once
3153 and if it has not been done already, do it and set KeyIVConfig
3154 to keep track it won't have to be done again next time */
3155 hcryp->KeyIVConfig = 1U;
3156 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3159 else
3161 hcryp->SizesSum = hcryp->Size;
3164 /* Configure Key, IV and process message (header and payload) */
3165 if (DoKeyIVConfig == 1U)
3167 /* Reset CrypHeaderCount */
3168 hcryp->CrypHeaderCount = 0U;
3170 /******************************* Init phase *********************************/
3172 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3174 /* Set the key */
3175 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3177 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3178 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3179 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3180 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3181 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3183 /* Enable the CRYP peripheral */
3184 __HAL_CRYP_ENABLE(hcryp);
3186 /*Wait for the CRYPEN bit to be cleared*/
3187 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3190 count-- ;
3191 if (count == 0U)
3193 /* Disable the CRYP peripheral clock */
3194 __HAL_CRYP_DISABLE(hcryp);
3196 /* Change state */
3197 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3198 hcryp->State = HAL_CRYP_STATE_READY;
3200 /* Process unlocked */
3201 __HAL_UNLOCK(hcryp);
3202 return HAL_ERROR;
3204 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3206 /***************************** Header phase *********************************/
3208 /* Select header phase */
3209 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3210 } /* end of if (DoKeyIVConfig == 1U) */
3211 /* Enable interrupts */
3212 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3214 /* Enable CRYP */
3215 __HAL_CRYP_ENABLE(hcryp);
3217 /* Return function status */
3218 return HAL_OK;
3223 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
3224 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3225 * the configuration information for CRYP module
3226 * @retval HAL status
3228 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3230 __IO uint32_t count = 0U;
3231 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3232 uint32_t index;
3233 uint32_t npblb;
3234 uint32_t lastwordsize;
3235 uint32_t temp[4]; /* Temporary CrypOutBuff */
3236 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3238 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3240 if (hcryp->KeyIVConfig == 1U)
3242 /* If the Key and IV configuration has to be done only once
3243 and if it has already been done, skip it */
3244 DoKeyIVConfig = 0U;
3245 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3247 else
3249 /* If the Key and IV configuration has to be done only once
3250 and if it has not been done already, do it and set KeyIVConfig
3251 to keep track it won't have to be done again next time */
3252 hcryp->KeyIVConfig = 1U;
3253 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3256 else
3258 hcryp->SizesSum = hcryp->Size;
3261 if (DoKeyIVConfig == 1U)
3263 /* Reset CrypHeaderCount */
3264 hcryp->CrypHeaderCount = 0U;
3266 /*************************** Init phase ************************************/
3268 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3270 /* Set the key */
3271 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3273 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3274 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3275 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3276 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3277 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3279 /* Enable the CRYP peripheral */
3280 __HAL_CRYP_ENABLE(hcryp);
3282 /*Wait for the CRYPEN bit to be cleared*/
3283 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3286 count-- ;
3287 if (count == 0U)
3289 /* Disable the CRYP peripheral clock */
3290 __HAL_CRYP_DISABLE(hcryp);
3292 /* Change state */
3293 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3294 hcryp->State = HAL_CRYP_STATE_READY;
3296 /* Process unlocked */
3297 __HAL_UNLOCK(hcryp);
3298 return HAL_ERROR;
3300 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3302 /************************ Header phase *************************************/
3304 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
3306 return HAL_ERROR;
3309 /************************ Payload phase ************************************/
3311 /* Set the phase */
3312 hcryp->Phase = CRYP_PHASE_PROCESS;
3314 /* Disable the CRYP peripheral */
3315 __HAL_CRYP_DISABLE(hcryp);
3317 #if !defined (CRYP_VER_2_2)
3318 if (hcryp->Version >= REV_ID_B)
3319 #endif /*End of not defined CRYP_VER_2_2*/
3321 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3322 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3325 /* Select payload phase once the header phase is performed */
3326 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3328 } /* if (DoKeyIVConfig == 1U) */
3330 if (hcryp->Size == 0U)
3332 /* Process unLocked */
3333 __HAL_UNLOCK(hcryp);
3335 /* Change the CRYP state and phase */
3336 hcryp->State = HAL_CRYP_STATE_READY;
3338 else if (hcryp->Size >= 16U)
3340 /* for STM32H7 below rev.B : Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption:
3341 Workaround is implemented in polling mode, so if last block of payload <128bit don't use DMA mode otherwise TAG is incorrectly generated */
3343 /*DMA transfer must not include the last block in case of Size is not %16 */
3344 wordsize = wordsize - (wordsize % 4U);
3346 /*DMA transfer */
3347 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
3349 else /* length of input data is < 16 */
3351 /* Compute the number of padding bytes in last block of payload */
3352 npblb = 16U - (uint32_t)hcryp->Size;
3354 #if !defined (CRYP_VER_2_2)
3355 if (hcryp->Version >= REV_ID_B)
3356 #endif /*End of not defined CRYP_VER_2_2*/
3358 /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3359 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3361 /* Specify the number of non-valid bytes using NPBLB register*/
3362 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3365 /* Enable CRYP to start the final phase */
3366 __HAL_CRYP_ENABLE(hcryp);
3368 /* Number of valid words (lastwordsize) in last block */
3369 if ((npblb % 4U) == 0U)
3371 lastwordsize = (16U - npblb) / 4U;
3373 else
3375 lastwordsize = ((16U - npblb) / 4U) + 1U;
3378 /* Write the last input block in the IN FIFO */
3379 for (index = 0; index < lastwordsize; index ++)
3381 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3382 hcryp->CrypInCount++;
3385 /* Pad the data with zeros to have a complete block */
3386 while (index < 4U)
3388 hcryp->Instance->DIN = 0U;
3389 index++;
3392 /* Wait for OFNE flag to be raised */
3393 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
3396 count-- ;
3397 if (count == 0U)
3399 /* Disable the CRYP peripheral clock */
3400 __HAL_CRYP_DISABLE(hcryp);
3402 /* Change state */
3403 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3404 hcryp->State = HAL_CRYP_STATE_READY;
3406 /* Process unlocked */
3407 __HAL_UNLOCK(hcryp);
3408 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3409 /*Call registered error callback*/
3410 hcryp->ErrorCallback(hcryp);
3411 #else
3412 /*Call legacy weak error callback*/
3413 HAL_CRYP_ErrorCallback(hcryp);
3414 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3416 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
3418 /*Read the output block from the output FIFO */
3419 for (index = 0U; index < 4U; index++)
3421 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3422 temp[index] = hcryp->Instance->DOUT;
3424 for (index=0; index<lastwordsize; index++)
3426 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3427 hcryp->CrypOutCount++;
3430 /* Change the CRYP state to ready */
3431 hcryp->State = HAL_CRYP_STATE_READY;
3433 /* Process unlocked */
3434 __HAL_UNLOCK(hcryp);
3437 /* Return function status */
3438 return HAL_OK;
3443 * @brief AES CCM encryption/decryption processing in polling mode
3444 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3445 * the configuration information for CRYP module
3446 * @param Timeout: Timeout duration
3447 * @retval HAL status
3449 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3451 uint32_t tickstart;
3452 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
3453 uint32_t npblb ;
3454 uint32_t lastwordsize ;
3455 uint32_t temp[4] ; /* Temporary CrypOutBuff */
3456 uint32_t index ;
3457 uint16_t outcount; /* Temporary CrypOutCount Value */
3458 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3460 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3462 if (hcryp->KeyIVConfig == 1U)
3464 /* If the Key and IV configuration has to be done only once
3465 and if it has already been done, skip it */
3466 DoKeyIVConfig = 0U;
3467 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3469 else
3471 /* If the Key and IV configuration has to be done only once
3472 and if it has not been done already, do it and set KeyIVConfig
3473 to keep track it won't have to be done again next time */
3474 hcryp->KeyIVConfig = 1U;
3475 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3478 else
3480 hcryp->SizesSum = hcryp->Size;
3483 if (DoKeyIVConfig == 1U)
3485 /* Reset CrypHeaderCount */
3486 hcryp->CrypHeaderCount = 0U;
3488 /********************** Init phase ******************************************/
3490 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3492 /* Set the key */
3493 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3495 /* Set the initialization vector (IV) with CTR1 information */
3496 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3497 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3498 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3499 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
3501 /* Enable the CRYP peripheral */
3502 __HAL_CRYP_ENABLE(hcryp);
3504 #if defined (CRYP_VER_2_2)
3506 /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/
3507 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3508 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3509 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3510 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3512 #else
3513 if (hcryp->Version >= REV_ID_B)
3515 /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/
3516 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3517 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3518 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3519 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3521 else /* data has to be swapped according to the DATATYPE */
3523 if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
3525 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3526 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3527 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3528 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3530 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
3532 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3533 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3534 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3535 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3537 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
3539 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3540 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3541 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3542 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3544 else
3546 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3547 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3548 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3549 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3552 #endif
3553 /* Get tick */
3554 tickstart = HAL_GetTick();
3556 /*Wait for the CRYPEN bit to be cleared*/
3557 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
3559 /* Check for the Timeout */
3560 if (Timeout != HAL_MAX_DELAY)
3562 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3564 /* Disable the CRYP peripheral clock */
3565 __HAL_CRYP_DISABLE(hcryp);
3567 /* Change state */
3568 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3569 hcryp->State = HAL_CRYP_STATE_READY;
3571 /* Process unlocked */
3572 __HAL_UNLOCK(hcryp);
3573 return HAL_ERROR;
3578 /************************* Header phase *************************************/
3579 /* Header block(B1) : associated data length expressed in bytes concatenated
3580 with Associated Data (A)*/
3582 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
3584 return HAL_ERROR;
3586 /********************** Payload phase ***************************************/
3588 /* Set the phase */
3589 hcryp->Phase = CRYP_PHASE_PROCESS;
3591 /* Disable the CRYP peripheral */
3592 __HAL_CRYP_DISABLE(hcryp);
3593 #if !defined (CRYP_VER_2_2)
3594 if (hcryp->Version >= REV_ID_B)
3595 #endif /*End of not defined CRYP_VER_2_2*/
3597 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3598 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3601 /* Select payload phase once the header phase is performed */
3602 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3604 /* Enable the CRYP peripheral */
3605 __HAL_CRYP_ENABLE(hcryp);
3607 } /* if (DoKeyIVConfig == 1U) */
3609 if ((hcryp->Size % 16U) != 0U)
3611 /* recalculate wordsize */
3612 wordsize = ((wordsize / 4U) * 4U) ;
3614 /* Get tick */
3615 tickstart = HAL_GetTick();
3617 /*Temporary CrypOutCount Value*/
3618 outcount = hcryp->CrypOutCount;
3620 /* Write input data and get output data */
3621 while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3623 /* Write plain data and get cipher data */
3624 CRYP_AES_ProcessData(hcryp, Timeout);
3626 /*Temporary CrypOutCount Value*/
3627 outcount = hcryp->CrypOutCount;
3629 /* Check for the Timeout */
3630 if (Timeout != HAL_MAX_DELAY)
3632 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3634 /* Disable the CRYP peripheral clock */
3635 __HAL_CRYP_DISABLE(hcryp);
3637 /* Change state */
3638 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3639 hcryp->State = HAL_CRYP_STATE_READY;
3641 /* Process unlocked */
3642 __HAL_UNLOCK(hcryp);
3643 return HAL_ERROR;
3648 if ((hcryp->Size % 16U) != 0U)
3650 #if !defined (CRYP_VER_2_2)
3651 if (hcryp->Version >= REV_ID_B)
3652 #endif /*End of not defined CRYP_VER_2_2*/
3654 /* Compute the number of padding bytes in last block of payload */
3655 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3657 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
3659 /* Disable the CRYP */
3660 __HAL_CRYP_DISABLE(hcryp);
3662 /* Set Npblb in case of AES CCM payload decryption to get right tag */
3663 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3665 /* Enable CRYP to start the final phase */
3666 __HAL_CRYP_ENABLE(hcryp);
3669 /* Number of valid words (lastwordsize) in last block */
3670 if ((npblb % 4U) == 0U)
3672 lastwordsize = (16U - npblb) / 4U;
3674 else
3676 lastwordsize = ((16U - npblb) / 4U) + 1U;
3679 /* Write the last input block in the IN FIFO */
3680 for (index = 0U; index < lastwordsize; index ++)
3682 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3683 hcryp->CrypInCount++;
3686 /* Pad the data with zeros to have a complete block */
3687 while (index < 4U)
3689 hcryp->Instance->DIN = 0U;
3690 index++;
3693 /* Wait for OFNE flag to be raised */
3694 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3696 /* Disable the CRYP peripheral clock */
3697 __HAL_CRYP_DISABLE(hcryp);
3699 /* Change state */
3700 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3701 hcryp->State = HAL_CRYP_STATE_READY;
3703 /* Process Unlocked */
3704 __HAL_UNLOCK(hcryp);
3705 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3706 /*Call registered error callback*/
3707 hcryp->ErrorCallback(hcryp);
3708 #else
3709 /*Call legacy weak error callback*/
3710 HAL_CRYP_ErrorCallback(hcryp);
3711 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3714 /*Read the output block from the output FIFO */
3715 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3717 for (index = 0U; index < 4U; index++)
3719 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3720 temp[index] = hcryp->Instance->DOUT;
3722 for (index=0; index<lastwordsize; index++)
3724 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3725 hcryp->CrypOutCount++;
3729 #if !defined (CRYP_VER_2_2)
3730 else /* No NPBLB, Workaround to be used */
3732 /* CRYP Workaround : CRYP1 generates correct TAG during CCM decryption only when ciphertext blocks size is multiple of
3733 128 bits. If lthe size of the last block of payload is inferior to 128 bits, when CCM decryption
3734 is selected, then the TAG message will be wrong.*/
3735 CRYP_Workaround(hcryp, Timeout);
3737 #endif /*End of not defined CRYP_VER_2_2*/
3740 /* Return function status */
3741 return HAL_OK;
3745 * @brief AES CCM encryption/decryption process in interrupt mode
3746 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3747 * the configuration information for CRYP module
3748 * @retval HAL status
3750 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3752 __IO uint32_t count = 0U;
3753 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3755 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3757 if (hcryp->KeyIVConfig == 1U)
3759 /* If the Key and IV configuration has to be done only once
3760 and if it has already been done, skip it */
3761 DoKeyIVConfig = 0U;
3762 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3764 else
3766 /* If the Key and IV configuration has to be done only once
3767 and if it has not been done already, do it and set KeyIVConfig
3768 to keep track it won't have to be done again next time */
3769 hcryp->KeyIVConfig = 1U;
3770 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3773 else
3775 hcryp->SizesSum = hcryp->Size;
3778 /* Configure Key, IV and process message (header and payload) */
3779 if (DoKeyIVConfig == 1U)
3781 /* Reset CrypHeaderCount */
3782 hcryp->CrypHeaderCount = 0U;
3784 /************ Init phase ************/
3786 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3788 /* Set the key */
3789 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3791 /* Set the initialization vector (IV) with CTR1 information */
3792 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3793 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3794 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3795 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
3797 /* Enable the CRYP peripheral */
3798 __HAL_CRYP_ENABLE(hcryp);
3800 /*Write the B0 packet into CRYP_DR*/
3801 #if !defined (CRYP_VER_2_2)
3802 if (hcryp->Version >= REV_ID_B)
3803 #endif /*End of not defined CRYP_VER_2_2*/
3805 /* for STM32H7 rev.B and above data has not to be swapped */
3806 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3807 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3808 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3809 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3811 #if !defined (CRYP_VER_2_2)
3812 else /* data has to be swapped according to the DATATYPE */
3814 if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
3816 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3817 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3818 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3819 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3821 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
3823 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3824 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3825 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3826 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3828 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
3830 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3831 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3832 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3833 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3835 else
3837 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3838 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3839 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3840 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3843 #endif /*End of not defined CRYP_VER_2_2*/
3844 /*Wait for the CRYPEN bit to be cleared*/
3845 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3848 count-- ;
3849 if (count == 0U)
3851 /* Disable the CRYP peripheral clock */
3852 __HAL_CRYP_DISABLE(hcryp);
3854 /* Change state */
3855 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3856 hcryp->State = HAL_CRYP_STATE_READY;
3858 /* Process unlocked */
3859 __HAL_UNLOCK(hcryp);
3860 return HAL_ERROR;
3862 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3864 /* Select header phase */
3865 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3866 } /* end of if (DoKeyIVConfig == 1U) */
3867 /* Enable interrupts */
3868 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3870 /* Enable CRYP */
3871 __HAL_CRYP_ENABLE(hcryp);
3873 /* Return function status */
3874 return HAL_OK;
3877 * @brief AES CCM encryption/decryption process in DMA mode
3878 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3879 * the configuration information for CRYP module
3880 * @retval HAL status
3882 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3884 __IO uint32_t count = 0U;
3885 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3886 uint32_t index;
3887 uint32_t npblb;
3888 uint32_t lastwordsize;
3889 uint32_t temp[4]; /* Temporary CrypOutBuff */
3890 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3892 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3894 if (hcryp->KeyIVConfig == 1U)
3896 /* If the Key and IV configuration has to be done only once
3897 and if it has already been done, skip it */
3898 DoKeyIVConfig = 0U;
3899 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3901 else
3903 /* If the Key and IV configuration has to be done only once
3904 and if it has not been done already, do it and set KeyIVConfig
3905 to keep track it won't have to be done again next time */
3906 hcryp->KeyIVConfig = 1U;
3907 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3910 else
3912 hcryp->SizesSum = hcryp->Size;
3915 if (DoKeyIVConfig == 1U)
3917 /* Reset CrypHeaderCount */
3918 hcryp->CrypHeaderCount = 0U;
3920 /************************** Init phase **************************************/
3922 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3924 /* Set the key */
3925 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3927 /* Set the initialization vector (IV) with CTR1 information */
3928 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3929 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3930 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3931 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
3933 /* Enable the CRYP peripheral */
3934 __HAL_CRYP_ENABLE(hcryp);
3936 /*Write the B0 packet into CRYP_DR*/
3937 #if !defined (CRYP_VER_2_2)
3938 if (hcryp->Version >= REV_ID_B)
3939 #endif /*End of not defined CRYP_VER_2_2*/
3941 /* for STM32H7 rev.B and above data has not to be swapped */
3942 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3943 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3944 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3945 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3947 #if !defined (CRYP_VER_2_2)
3948 else /* data has to be swapped according to the DATATYPE */
3950 if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
3952 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3953 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3954 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3955 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3957 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
3959 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3960 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3961 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3962 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3964 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
3966 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3967 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3968 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3969 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3971 else
3973 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3974 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3975 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3976 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3979 #endif /*End of not defined CRYP_VER_2_2*/
3980 /*Wait for the CRYPEN bit to be cleared*/
3981 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3984 count-- ;
3985 if (count == 0U)
3987 /* Disable the CRYP peripheral clock */
3988 __HAL_CRYP_DISABLE(hcryp);
3990 /* Change state */
3991 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3992 hcryp->State = HAL_CRYP_STATE_READY;
3994 /* Process unlocked */
3995 __HAL_UNLOCK(hcryp);
3996 return HAL_ERROR;
3998 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
4000 /********************* Header phase *****************************************/
4002 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
4004 return HAL_ERROR;
4007 /******************** Payload phase *****************************************/
4009 /* Set the phase */
4010 hcryp->Phase = CRYP_PHASE_PROCESS;
4012 /* Disable the CRYP peripheral */
4013 __HAL_CRYP_DISABLE(hcryp);
4014 #if !defined (CRYP_VER_2_2)
4015 if (hcryp->Version >= REV_ID_B)
4016 #endif /*End of not defined CRYP_VER_2_2*/
4018 /* Set to 0 the number of non-valid bytes using NPBLB register*/
4019 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4022 /* Select payload phase once the header phase is performed */
4023 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4024 } /* if (DoKeyIVConfig == 1U) */
4026 if (hcryp->Size == 0U)
4028 /* Process unLocked */
4029 __HAL_UNLOCK(hcryp);
4031 /* Change the CRYP state and phase */
4032 hcryp->State = HAL_CRYP_STATE_READY;
4034 else if (hcryp->Size >= 16U)
4036 /* for STM32H7 below rev.B :: Size should be %4 otherwise Tag will be incorrectly generated for CCM Decryption, Workaround is implemented in polling mode*/
4037 /*DMA transfer must not include the last block in case of Size is not %16 */
4038 wordsize = wordsize - (wordsize % 4U);
4040 /*DMA transfer */
4041 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t) wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
4043 else /* length of input data is < 16U */
4045 /* Compute the number of padding bytes in last block of payload */
4046 npblb = 16U - (uint32_t)(hcryp->Size);
4048 #if !defined (CRYP_VER_2_2)
4049 if (hcryp->Version >= REV_ID_B)
4050 #endif /*End of not defined CRYP_VER_2_2*/
4052 /* Set Npblb in case of AES CCM payload decryption to get right tag*/
4053 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4055 /* Specify the number of non-valid bytes using NPBLB register*/
4056 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4059 /* Enable CRYP to start the final phase */
4060 __HAL_CRYP_ENABLE(hcryp);
4062 /* Number of valid words (lastwordsize) in last block */
4063 if ((npblb % 4U) == 0U)
4065 lastwordsize = (16U - npblb) / 4U;
4067 else
4069 lastwordsize = ((16U - npblb) / 4U) + 1U;
4072 /* Write the last input block in the IN FIFO */
4073 for (index = 0U; index < lastwordsize; index ++)
4075 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4076 hcryp->CrypInCount++;
4079 /* Pad the data with zeros to have a complete block */
4080 while (index < 4U)
4082 hcryp->Instance->DIN = 0U;
4083 index++;
4086 /* Wait for OFNE flag to be raised */
4087 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4090 count-- ;
4091 if (count == 0U)
4093 /* Disable the CRYP peripheral clock */
4094 __HAL_CRYP_DISABLE(hcryp);
4096 /* Change state */
4097 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4098 hcryp->State = HAL_CRYP_STATE_READY;
4100 /* Process unlocked */
4101 __HAL_UNLOCK(hcryp);
4102 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4103 /*Call registered error callback*/
4104 hcryp->ErrorCallback(hcryp);
4105 #else
4106 /*Call legacy weak error callback*/
4107 HAL_CRYP_ErrorCallback(hcryp);
4108 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4110 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
4112 /*Read the output block from the output FIFO */
4113 for (index = 0U; index < 4U; index++)
4115 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
4116 temp[index] = hcryp->Instance->DOUT;
4118 for (index=0; index<lastwordsize; index++)
4120 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
4121 hcryp->CrypOutCount++;
4124 /* Change the CRYP state to ready */
4125 hcryp->State = HAL_CRYP_STATE_READY;
4127 /* Process unlocked */
4128 __HAL_UNLOCK(hcryp);
4131 /* Return function status */
4132 return HAL_OK;
4136 * @brief Sets the payload phase in interrupt mode
4137 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4138 * the configuration information for CRYP module
4139 * @retval state
4141 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
4143 uint32_t loopcounter;
4144 uint32_t temp[4]; /* Temporary CrypOutBuff */
4145 uint32_t lastwordsize;
4146 uint32_t npblb;
4147 uint32_t temp_cr_algodir;
4148 uint8_t negative = 0U;
4149 uint32_t i;
4151 /***************************** Payload phase *******************************/
4153 if ((hcryp->Size / 4U) < hcryp->CrypInCount)
4155 negative = 1U;
4158 if (hcryp->Size == 0U)
4160 /* Disable interrupts */
4161 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4163 /* Process unlocked */
4164 __HAL_UNLOCK(hcryp);
4166 /* Change the CRYP state */
4167 hcryp->State = HAL_CRYP_STATE_READY;
4170 else if ((((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) &&
4171 (negative == 0U))
4173 if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM)!= 0x0U)
4175 /* Write the input block in the IN FIFO */
4176 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4177 hcryp->CrypInCount++;
4178 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4179 hcryp->CrypInCount++;
4180 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4181 hcryp->CrypInCount++;
4182 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4183 hcryp->CrypInCount++;
4184 if (((hcryp->Size / 4U) == hcryp->CrypInCount) && ((hcryp->Size % 16U) == 0U))
4186 /* Disable interrupts */
4187 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4188 /* Call the input data transfer complete callback */
4189 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4190 /*Call registered Input complete callback*/
4191 hcryp->InCpltCallback(hcryp);
4192 #else
4193 /*Call legacy weak Input complete callback*/
4194 HAL_CRYP_InCpltCallback(hcryp);
4195 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4198 if (hcryp->CrypOutCount < (hcryp->Size / 4U))
4200 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4202 /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
4203 for (i = 0U; i < 4U; i++)
4205 temp[i] = hcryp->Instance->DOUT;
4207 i = 0U;
4208 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
4210 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4211 hcryp->CrypOutCount++;
4212 i++;
4214 if (((hcryp->Size / 4U) == hcryp->CrypOutCount) && ((hcryp->Size % 16U) == 0U))
4216 /* Disable interrupts */
4217 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
4219 /* Change the CRYP state */
4220 hcryp->State = HAL_CRYP_STATE_READY;
4222 /* Disable CRYP */
4223 __HAL_CRYP_DISABLE(hcryp);
4225 /* Process unlocked */
4226 __HAL_UNLOCK(hcryp);
4228 /* Call output transfer complete callback */
4229 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4230 /*Call registered Output complete callback*/
4231 hcryp->OutCpltCallback(hcryp);
4232 #else
4233 /*Call legacy weak Output complete callback*/
4234 HAL_CRYP_OutCpltCallback(hcryp);
4235 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4241 else if ((hcryp->Size % 16U) != 0U)
4243 /* Set padding only in case of input fifo interrupt */
4244 if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM)!= 0x0U)
4246 /* Compute the number of padding bytes in last block of payload */
4247 npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4249 #if !defined (CRYP_VER_2_2)
4250 if (hcryp->Version >= REV_ID_B)
4251 #endif /*End of not defined CRYP_VER_2_2*/
4253 /* Set Npblb in case of AES GCM payload encryption and CCM decryption to get right tag */
4254 temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
4256 if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
4257 ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4259 /* Disable the CRYP */
4260 __HAL_CRYP_DISABLE(hcryp);
4262 /* Specify the number of non-valid bytes using NPBLB register*/
4263 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4265 /* Enable CRYP to start the final phase */
4266 __HAL_CRYP_ENABLE(hcryp);
4270 /* Number of valid words (lastwordsize) in last block */
4271 if ((npblb % 4U) == 0U)
4273 lastwordsize = (16U - npblb) / 4U;
4275 else
4277 lastwordsize = ((16U - npblb) / 4U) + 1U;
4280 /* Write the last input block in the IN FIFO */
4281 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4283 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4284 hcryp->CrypInCount++;
4286 /* Pad the data with zeros to have a complete block */
4287 while (loopcounter < 4U)
4289 hcryp->Instance->DIN = 0U;
4290 loopcounter++;
4293 /* Disable the input FIFO Interrupt */
4294 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4297 /*Read the output block from the output FIFO */
4298 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4300 for (i = 0U; i < 4U; i++)
4302 temp[i] = hcryp->Instance->DOUT;
4304 if (( (hcryp->Size)/4U)==0U)
4306 for (i = 0U; (uint16_t)i<((hcryp->Size)%4U); i++)
4308 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4309 hcryp->CrypOutCount++;
4312 i = 0U;
4313 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
4315 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4316 hcryp->CrypOutCount++;
4317 i++;
4321 /* Disable the output FIFO Interrupt */
4322 if (hcryp->CrypOutCount >= ((hcryp->Size) / 4U))
4324 /* Disable interrupts */
4325 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI | CRYP_IT_INI);
4327 /* Change the CRYP peripheral state */
4328 hcryp->State = HAL_CRYP_STATE_READY;
4330 /* Process unlocked */
4331 __HAL_UNLOCK(hcryp);
4333 /* Call output transfer complete callback */
4334 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4335 /*Call registered Output complete callback*/
4336 hcryp->OutCpltCallback(hcryp);
4337 #else
4338 /*Call legacy weak Output complete callback*/
4339 HAL_CRYP_OutCpltCallback(hcryp);
4340 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4343 else
4345 /* Nothing to do */
4351 * @brief Sets the header phase in polling mode
4352 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4353 * the configuration information for CRYP module(Header & HeaderSize)
4354 * @param Timeout: Timeout value
4355 * @retval state
4357 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4359 uint32_t loopcounter;
4361 /***************************** Header phase for GCM/GMAC or CCM *********************************/
4363 if ((hcryp->Init.HeaderSize != 0U))
4365 /* Select header phase */
4366 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4368 /* Enable the CRYP peripheral */
4369 __HAL_CRYP_ENABLE(hcryp);
4371 if ((hcryp->Init.HeaderSize % 4U) == 0U)
4373 /* HeaderSize %4, no padding */
4374 for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4376 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4377 hcryp->CrypHeaderCount++ ;
4378 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4379 hcryp->CrypHeaderCount++ ;
4380 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4381 hcryp->CrypHeaderCount++ ;
4382 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4383 hcryp->CrypHeaderCount++ ;
4385 /* Wait for IFEM to be raised */
4386 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4388 /* Disable the CRYP peripheral clock */
4389 __HAL_CRYP_DISABLE(hcryp);
4391 /* Change state */
4392 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4393 hcryp->State = HAL_CRYP_STATE_READY;
4395 /* Process unlocked */
4396 __HAL_UNLOCK(hcryp);
4397 return HAL_ERROR;
4401 else
4403 /*Write header block in the IN FIFO without last block */
4404 for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U))); loopcounter += 4U)
4406 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4407 hcryp->CrypHeaderCount++ ;
4408 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4409 hcryp->CrypHeaderCount++ ;
4410 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4411 hcryp->CrypHeaderCount++ ;
4412 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4413 hcryp->CrypHeaderCount++ ;
4415 /* Wait for IFEM to be raised */
4416 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4418 /* Disable the CRYP peripheral clock */
4419 __HAL_CRYP_DISABLE(hcryp);
4421 /* Change state */
4422 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4423 hcryp->State = HAL_CRYP_STATE_READY;
4425 /* Process unlocked */
4426 __HAL_UNLOCK(hcryp);
4427 return HAL_ERROR;
4430 /* Last block optionally pad the data with zeros*/
4431 for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4433 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4434 hcryp->CrypHeaderCount++ ;
4436 while (loopcounter < 4U)
4438 /* pad the data with zeros to have a complete block */
4439 hcryp->Instance->DIN = 0x0U;
4440 loopcounter++;
4442 /* Wait for CCF IFEM to be raised */
4443 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4445 /* Disable the CRYP peripheral clock */
4446 __HAL_CRYP_DISABLE(hcryp);
4448 /* Change state */
4449 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4450 hcryp->State = HAL_CRYP_STATE_READY;
4452 /* Process unlocked */
4453 __HAL_UNLOCK(hcryp);
4454 return HAL_ERROR;
4457 /* Wait until the complete message has been processed */
4458 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
4460 /* Disable the CRYP peripheral clock */
4461 __HAL_CRYP_DISABLE(hcryp);
4463 /* Change state */
4464 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4465 hcryp->State = HAL_CRYP_STATE_READY;
4467 /* Process unlocked & return error */
4468 __HAL_UNLOCK(hcryp);
4469 return HAL_ERROR;
4472 /* Return function status */
4473 return HAL_OK;
4477 * @brief Sets the header phase when using DMA in process
4478 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4479 * the configuration information for CRYP module(Header & HeaderSize)
4480 * @retval None
4482 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
4484 __IO uint32_t count = 0U;
4485 uint32_t loopcounter;
4487 /***************************** Header phase for GCM/GMAC or CCM *********************************/
4488 if ((hcryp->Init.HeaderSize != 0U))
4490 /* Select header phase */
4491 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4493 /* Enable the CRYP peripheral */
4494 __HAL_CRYP_ENABLE(hcryp);
4496 if ((hcryp->Init.HeaderSize % 4U) == 0U)
4498 /* HeaderSize %4, no padding */
4499 for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4501 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4502 hcryp->CrypHeaderCount++ ;
4503 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4504 hcryp->CrypHeaderCount++ ;
4505 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4506 hcryp->CrypHeaderCount++ ;
4507 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4508 hcryp->CrypHeaderCount++ ;
4510 /* Wait for IFEM to be raised */
4511 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4514 count-- ;
4515 if (count == 0U)
4517 /* Disable the CRYP peripheral clock */
4518 __HAL_CRYP_DISABLE(hcryp);
4520 /* Change state */
4521 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4522 hcryp->State = HAL_CRYP_STATE_READY;
4524 /* Process unlocked */
4525 __HAL_UNLOCK(hcryp);
4526 return HAL_ERROR;
4528 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4531 else
4533 /*Write header block in the IN FIFO without last block */
4534 for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U))); loopcounter += 4U)
4536 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4537 hcryp->CrypHeaderCount++ ;
4538 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4539 hcryp->CrypHeaderCount++ ;
4540 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4541 hcryp->CrypHeaderCount++ ;
4542 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4543 hcryp->CrypHeaderCount++ ;
4545 /* Wait for IFEM to be raised */
4546 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4549 count-- ;
4550 if (count == 0U)
4552 /* Disable the CRYP peripheral clock */
4553 __HAL_CRYP_DISABLE(hcryp);
4555 /* Change state */
4556 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4557 hcryp->State = HAL_CRYP_STATE_READY;
4559 /* Process unlocked */
4560 __HAL_UNLOCK(hcryp);
4561 return HAL_ERROR;
4563 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4565 /* Last block optionally pad the data with zeros*/
4566 for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4568 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4569 hcryp->CrypHeaderCount++ ;
4571 while (loopcounter < 4U)
4573 /* Pad the data with zeros to have a complete block */
4574 hcryp->Instance->DIN = 0x0U;
4575 loopcounter++;
4577 /* Wait for IFEM to be raised */
4578 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4581 count-- ;
4582 if (count == 0U)
4584 /* Disable the CRYP peripheral clock */
4585 __HAL_CRYP_DISABLE(hcryp);
4586 /* Change state */
4587 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4588 hcryp->State = HAL_CRYP_STATE_READY;
4589 /* Process unlocked */
4590 __HAL_UNLOCK(hcryp);
4591 return HAL_ERROR;
4593 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4595 /* Wait until the complete message has been processed */
4596 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4599 count-- ;
4600 if (count == 0U)
4602 /* Disable the CRYP peripheral clock */
4603 __HAL_CRYP_DISABLE(hcryp);
4604 /* Change state */
4605 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4606 hcryp->State = HAL_CRYP_STATE_READY;
4607 /* Process unlocked */
4608 __HAL_UNLOCK(hcryp);
4609 return HAL_ERROR;
4611 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
4614 /* Return function status */
4615 return HAL_OK;
4619 * @brief Sets the header phase in interrupt mode
4620 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4621 * the configuration information for CRYP module(Header & HeaderSize)
4622 * @retval None
4624 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
4626 uint32_t loopcounter;
4628 /***************************** Header phase *********************************/
4630 if (hcryp->Init.HeaderSize == hcryp->CrypHeaderCount)
4632 /* Disable interrupts */
4633 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4635 /* Disable the CRYP peripheral */
4636 __HAL_CRYP_DISABLE(hcryp);
4638 #if !defined (CRYP_VER_2_2)
4639 if (hcryp->Version >= REV_ID_B)
4640 #endif /*End of not defined CRYP_VER_2_2*/
4642 /* Set to 0 the number of non-valid bytes using NPBLB register*/
4643 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4646 /* Set the phase */
4647 hcryp->Phase = CRYP_PHASE_PROCESS;
4649 /* Select payload phase once the header phase is performed */
4650 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4652 /* Enable Interrupts */
4653 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4655 /* Enable the CRYP peripheral */
4656 __HAL_CRYP_ENABLE(hcryp);
4658 else if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U)
4661 /* HeaderSize %4, no padding */
4662 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4663 hcryp->CrypHeaderCount++ ;
4664 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4665 hcryp->CrypHeaderCount++ ;
4666 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4667 hcryp->CrypHeaderCount++ ;
4668 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4669 hcryp->CrypHeaderCount++ ;
4671 else
4673 /* Last block optionally pad the data with zeros*/
4674 for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
4676 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4677 hcryp->CrypHeaderCount++ ;
4679 while (loopcounter < 4U)
4681 /* Pad the data with zeros to have a complete block */
4682 hcryp->Instance->DIN = 0x0U;
4683 loopcounter++;
4688 #if !defined (CRYP_VER_2_2)
4690 * @brief Workaround used for GCM/CCM mode.
4691 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4692 * the configuration information for CRYP module
4693 * @param Timeout: Timeout value
4694 * @retval None
4696 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4698 uint32_t iv1temp;
4699 uint32_t temp[4] = {0};
4700 uint32_t temp2[4] = {0};
4701 uint32_t intermediate_data[4] = {0};
4702 uint32_t index;
4703 uint32_t lastwordsize;
4704 uint32_t npblb;
4706 /* Compute the number of padding bytes in last block of payload */
4707 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4709 /* Number of valid words (lastwordsize) in last block */
4710 if ((npblb % 4U) == 0U)
4712 lastwordsize = (16U - npblb) / 4U;
4714 else
4716 lastwordsize = ((16U - npblb) / 4U) + 1U;
4719 /* Workaround 2, case GCM encryption */
4720 if (hcryp->Init.Algorithm == CRYP_AES_GCM)
4722 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4724 /*Workaround in order to properly compute authentication tags while doing
4725 a GCM encryption with the last block of payload size inferior to 128 bits*/
4726 /* Disable CRYP to start the final phase */
4727 __HAL_CRYP_DISABLE(hcryp);
4729 /*Update CRYP_IV1R register and ALGOMODE*/
4730 hcryp->Instance->IV1RR = ((hcryp->Instance->CSGCMCCM7R)-1U);
4731 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
4733 /* Enable CRYP to start the final phase */
4734 __HAL_CRYP_ENABLE(hcryp);
4737 for (index = 0; index < lastwordsize ; index ++)
4739 /* Write the last input block in the IN FIFO */
4740 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4741 hcryp->CrypInCount++;
4743 while (index < 4U)
4745 /* Pad the data with zeros to have a complete block */
4746 hcryp->Instance->DIN = 0U;
4747 index++;
4749 /* Wait for OFNE flag to be raised */
4750 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4752 /* Disable the CRYP peripheral clock */
4753 __HAL_CRYP_DISABLE(hcryp);
4755 /* Change state */
4756 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4757 hcryp->State = HAL_CRYP_STATE_READY;
4759 /* Process Unlocked */
4760 __HAL_UNLOCK(hcryp);
4761 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4762 /*Call registered error callback*/
4763 hcryp->ErrorCallback(hcryp);
4764 #else
4765 /*Call legacy weak error callback*/
4766 HAL_CRYP_ErrorCallback(hcryp);
4767 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4769 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4771 for (index = 0U; index < 4U; index++)
4773 /* Read the output block from the output FIFO */
4774 intermediate_data[index] = hcryp->Instance->DOUT;
4776 /* Intermediate data buffer to be used in for the workaround*/
4777 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
4778 hcryp->CrypOutCount++;
4782 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4784 /*workaround in order to properly compute authentication tags while doing
4785 a GCM encryption with the last block of payload size inferior to 128 bits*/
4786 /* Change the AES mode to GCM mode and Select Final phase */
4787 /* configured CHMOD GCM */
4788 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_GCM);
4790 /* configured final phase */
4791 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
4793 if ( (hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_32B)
4795 if ((npblb %4U)==1U)
4797 intermediate_data[lastwordsize-1U] &= 0xFFFFFF00U;
4799 if ((npblb %4U)==2U)
4801 intermediate_data[lastwordsize-1U] &= 0xFFFF0000U;
4803 if ((npblb %4U)==3U)
4805 intermediate_data[lastwordsize-1U] &= 0xFF000000U;
4808 else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_8B)
4810 if ((npblb %4U)==1U)
4812 intermediate_data[lastwordsize-1U] &= __REV(0xFFFFFF00U);
4814 if ((npblb %4U)==2U)
4816 intermediate_data[lastwordsize-1U] &= __REV(0xFFFF0000U);
4818 if ((npblb %4U)==3U)
4820 intermediate_data[lastwordsize-1U] &= __REV(0xFF000000U);
4823 else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_16B)
4825 if ((npblb %4U)==1U)
4827 intermediate_data[lastwordsize-1U] &= __ROR((0xFFFFFF00U), 16);
4829 if ((npblb %4U)==2U)
4831 intermediate_data[lastwordsize-1U] &= __ROR((0xFFFF0000U), 16);
4833 if ((npblb %4U)==3U)
4835 intermediate_data[lastwordsize-1U] &= __ROR((0xFF000000U), 16);
4838 else /*CRYP_DATATYPE_1B*/
4840 if ((npblb %4U)==1U)
4842 intermediate_data[lastwordsize-1U] &= __RBIT(0xFFFFFF00U);
4844 if ((npblb %4U)==2U)
4846 intermediate_data[lastwordsize-1U] &= __RBIT(0xFFFF0000U);
4848 if ((npblb %4U)==3U)
4850 intermediate_data[lastwordsize-1U] &= __RBIT(0xFF000000U);
4854 for (index = 0U; index < lastwordsize ; index ++)
4856 /*Write the intermediate_data in the IN FIFO */
4857 hcryp->Instance->DIN = intermediate_data[index];
4859 while (index < 4U)
4861 /* Pad the data with zeros to have a complete block */
4862 hcryp->Instance->DIN = 0x0U;
4863 index++;
4865 /* Wait for OFNE flag to be raised */
4866 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4868 /* Disable the CRYP peripheral clock */
4869 __HAL_CRYP_DISABLE(hcryp);
4871 /* Change state */
4872 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4873 hcryp->State = HAL_CRYP_STATE_READY;
4875 /* Process unlocked */
4876 __HAL_UNLOCK(hcryp);
4877 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4878 /*Call registered error callback*/
4879 hcryp->ErrorCallback(hcryp);
4880 #else
4881 /*Call legacy weak error callback*/
4882 HAL_CRYP_ErrorCallback(hcryp);
4883 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4886 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4888 for (index = 0U; index < 4U; index++)
4890 intermediate_data[index] = hcryp->Instance->DOUT;
4894 } /* End of GCM encryption */
4895 else
4897 /* Workaround 2, case CCM decryption, in order to properly compute
4898 authentication tags while doing a CCM decryption with the last block
4899 of payload size inferior to 128 bits*/
4901 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4903 iv1temp = hcryp->Instance->CSGCMCCM7R;
4905 /* Disable CRYP to start the final phase */
4906 __HAL_CRYP_DISABLE(hcryp);
4908 temp[0] = hcryp->Instance->CSGCMCCM0R;
4909 temp[1] = hcryp->Instance->CSGCMCCM1R;
4910 temp[2] = hcryp->Instance->CSGCMCCM2R;
4911 temp[3] = hcryp->Instance->CSGCMCCM3R;
4913 hcryp->Instance->IV1RR = iv1temp;
4915 /* Configured CHMOD CTR */
4916 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
4918 /* Enable CRYP to start the final phase */
4919 __HAL_CRYP_ENABLE(hcryp);
4921 /* Last block optionally pad the data with zeros*/
4922 for (index = 0U; index < lastwordsize; index ++)
4924 /* Write the last Input block in the IN FIFO */
4925 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4926 hcryp->CrypInCount++;
4928 while (index < 4U)
4930 /* Pad the data with zeros to have a complete block */
4931 hcryp->Instance->DIN = 0U;
4932 index++;
4934 /* Wait for OFNE flag to be raised */
4935 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4937 /* Disable the CRYP peripheral clock */
4938 __HAL_CRYP_DISABLE(hcryp);
4940 /* Change state */
4941 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4942 hcryp->State = HAL_CRYP_STATE_READY;
4944 /* Process Unlocked */
4945 __HAL_UNLOCK(hcryp);
4946 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4947 /*Call registered error callback*/
4948 hcryp->ErrorCallback(hcryp);
4949 #else
4950 /*Call legacy weak error callback*/
4951 HAL_CRYP_ErrorCallback(hcryp);
4952 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4955 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4957 for (index = 0U; index < 4U; index++)
4959 /* Read the Output block from the Output FIFO */
4960 intermediate_data[index] = hcryp->Instance->DOUT;
4962 /*intermediate data buffer to be used in for the workaround*/
4963 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
4964 hcryp->CrypOutCount++;
4968 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4970 temp2[0] = hcryp->Instance->CSGCMCCM0R;
4971 temp2[1] = hcryp->Instance->CSGCMCCM1R;
4972 temp2[2] = hcryp->Instance->CSGCMCCM2R;
4973 temp2[3] = hcryp->Instance->CSGCMCCM3R;
4975 /* configured CHMOD CCM */
4976 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CCM);
4978 /* configured Header phase */
4979 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_HEADER);
4981 /*set to zero the bits corresponding to the padded bits*/
4982 for (index = lastwordsize; index < 4U; index ++)
4984 intermediate_data[index] = 0U;
4987 if ((npblb % 4U) == 1U)
4989 intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
4991 if ((npblb % 4U) == 2U)
4993 intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
4995 if ((npblb % 4U) == 3U)
4997 intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
5000 for (index = 0U; index < 4U ; index ++)
5002 intermediate_data[index] ^= temp[index];
5003 intermediate_data[index] ^= temp2[index];
5005 for (index = 0U; index < 4U; index ++)
5007 /* Write the last Input block in the IN FIFO */
5008 hcryp->Instance->DIN = intermediate_data[index] ;
5011 /* Wait for BUSY flag to be raised */
5012 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
5014 /* Disable the CRYP peripheral clock */
5015 __HAL_CRYP_DISABLE(hcryp);
5017 /* Change state */
5018 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5019 hcryp->State = HAL_CRYP_STATE_READY;
5021 /* Process Unlocked */
5022 __HAL_UNLOCK(hcryp);
5023 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5024 /*Call registered error callback*/
5025 hcryp->ErrorCallback(hcryp);
5026 #else
5027 /*Call legacy weak error callback*/
5028 HAL_CRYP_ErrorCallback(hcryp);
5029 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5032 } /* End of CCM WKA*/
5034 /* Process Unlocked */
5035 __HAL_UNLOCK(hcryp);
5037 #endif /*End of not defined CRYP_VER_2_2*/
5040 * @brief Handle CRYP hardware block Timeout when waiting for IFEM flag to be raised.
5041 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5042 * the configuration information for CRYP module.
5043 * @param Timeout: Timeout duration.
5044 * @retval HAL status
5046 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5048 uint32_t tickstart;
5050 /* Get timeout */
5051 tickstart = HAL_GetTick();
5053 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
5055 /* Check for the Timeout */
5056 if (Timeout != HAL_MAX_DELAY)
5058 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5060 return HAL_ERROR;
5064 return HAL_OK;
5067 * @brief Handle CRYP hardware block Timeout when waiting for BUSY flag to be raised.
5068 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5069 * the configuration information for CRYP module.
5070 * @param Timeout: Timeout duration.
5071 * @retval HAL status
5073 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5075 uint32_t tickstart;
5077 /* Get timeout */
5078 tickstart = HAL_GetTick();
5080 while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY))
5082 /* Check for the Timeout */
5083 if (Timeout != HAL_MAX_DELAY)
5085 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5087 return HAL_ERROR;
5091 return HAL_OK;
5096 * @brief Handle CRYP hardware block Timeout when waiting for OFNE flag to be raised.
5097 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5098 * the configuration information for CRYP module.
5099 * @param Timeout: Timeout duration.
5100 * @retval HAL status
5102 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5104 uint32_t tickstart;
5106 /* Get timeout */
5107 tickstart = HAL_GetTick();
5109 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
5111 /* Check for the Timeout */
5112 if (Timeout != HAL_MAX_DELAY)
5114 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5116 return HAL_ERROR;
5120 return HAL_OK;
5125 * @}
5131 * @}
5135 * @}
5138 #endif /* HAL_CRYP_MODULE_ENABLED */
5142 * @}
5144 #endif /* CRYP */
5146 * @}
5149 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/