Merge pull request #10592 from iNavFlight/MrD_Update-parameter-description
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_cryp.c
blob2d8beb449dc94793ee23bcce8e535ea057ac66c9
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 (#) structure of message construction in GCM is defined as below :
107 (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
108 (##) The authenticated header A (also knows as Additional Authentication Data AAD)
109 this part of the message is only authenticated, not encrypted.
110 (##) The plaintext message P is both authenticated and encrypted as ciphertext.
111 GCM standard specifies that ciphertext has same bit length as the plaintext.
112 (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
113 (on 64 bits)
115 [..] This section describe The AES Counter with Cipher Block Chaining-Message
116 Authentication Code (CCM) supported by both CRYP1 IP:
117 (#) Specific parameters for CCM :
119 (##) B0 block : According to NIST Special Publication 800-38C,
120 The first block B0 is formatted as follows, where l(m) is encoded in
121 most-significant-byte first order(see below table 3)
123 (+++) Q: a bit string representation of the octet length of P (plaintext)
124 (+++) q The octet length of the binary representation of the octet length of the payload
125 (+++) A nonce (N), n The octet length of the where n+q=15.
126 (+++) Flags: most significant octet containing four flags for control information,
127 (+++) t The octet length of the MAC.
128 (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
129 the associated data length expressed in bytes (a) defined as below:
130 (+++) If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
131 (+++) If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
132 (+++) If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
133 (##) CTRx block : control blocks
134 (+++) Generation of CTR1 from first block B0 information :
135 equal to B0 with first 5 bits zeroed and most significant bits storing octet
136 length of P also zeroed, then incremented by one ( see below Table 4)
137 (+++) Generation of CTR0: same as CTR1 with bit[0] set to zero.
139 (#) Four phases are performed in CCM for CRYP1 IP:
140 (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
141 (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
142 computation only.
143 (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
144 encryption + data XORing. It works in a similar way for ciphertext (C).
145 (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
147 *** Callback registration ***
148 =============================
150 [..]
151 The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
152 allows the user to configure dynamically the driver callbacks.
153 Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
154 to register an interrupt callback.
156 [..]
157 Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
158 (+) InCpltCallback : Input FIFO transfer completed callback.
159 (+) OutCpltCallback : Output FIFO transfer completed callback.
160 (+) ErrorCallback : callback for error detection.
161 (+) MspInitCallback : CRYP MspInit.
162 (+) MspDeInitCallback : CRYP MspDeInit.
163 This function takes as parameters the HAL peripheral handle, the Callback ID
164 and a pointer to the user callback function.
166 [..]
167 Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
168 weak function.
169 @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
170 and the Callback ID.
171 This function allows to reset following callbacks:
172 (+) InCpltCallback : Input FIFO transfer completed callback.
173 (+) OutCpltCallback : Output FIFO transfer completed callback.
174 (+) ErrorCallback : callback for error detection.
175 (+) MspInitCallback : CRYP MspInit.
176 (+) MspDeInitCallback : CRYP MspDeInit.
178 [..]
179 By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
180 all callbacks are set to the corresponding weak functions :
181 examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
182 Exception done for MspInit and MspDeInit functions that are
183 reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
184 these callbacks are null (not registered beforehand).
185 if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
186 keep and use the user MspInit/MspDeInit functions (registered beforehand)
188 [..]
189 Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
190 Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
191 in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
192 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
193 In that case first register the MspInit/MspDeInit user callbacks
194 using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
195 or @ref HAL_CRYP_Init() function.
197 [..]
198 When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
199 not defined, the callback registration feature is not available and all callbacks
200 are set to the corresponding weak functions.
202 @endverbatim
204 Table 1. Initial Counter Block (ICB)
205 +-------------------------------------------------------+
206 | Initialization vector (IV) | Counter |
207 |----------------|----------------|-----------|---------|
208 127 95 63 31 0
211 Bit Number Register Contents
212 ---------- --------------- -----------
213 127 ...96 CRYP_IV1R[31:0] ICB[127:96]
214 95 ...64 CRYP_IV1L[31:0] B0[95:64]
215 63 ... 32 CRYP_IV0R[31:0] ICB[63:32]
216 31 ... 0 CRYP_IV0L[31:0] ICB[31:0], where 32-bit counter= 0x2
218 Table 2. GCM last block definition
220 +-------------------------------------------------------------------+
221 | Bit[0] | Bit[32] | Bit[64] | Bit[96] |
222 |-----------|--------------------|-----------|----------------------|
223 | 0x0 | Header length[31:0]| 0x0 | Payload length[31:0] |
224 |-----------|--------------------|-----------|----------------------|
226 Table 3. B0 block
227 Octet Number Contents
228 ------------ ---------
229 0 Flags
230 1 ... 15-q Nonce N
231 16-q ... 15 Q
233 the Flags field is formatted as follows:
235 Bit Number Contents
236 ---------- ----------------------
237 7 Reserved (always zero)
238 6 Adata
239 5 ... 3 (t-2)/2
240 2 ... 0 [q-1]3
242 Table 4. CTRx block
243 Bit Number Register Contents
244 ---------- --------------- -----------
245 127 ...96 CRYP_IV1R[31:0] B0[127:96], where Q length bits are set to 0, except for
246 bit 0 that is set to 1
247 95 ...64 CRYP_IV1L[31:0] B0[95:64]
248 63 ... 32 CRYP_IV0R[31:0] B0[63:32]
249 31 ... 0 CRYP_IV0L[31:0] B0[31:0], where flag bits set to 0
252 ******************************************************************************
253 * @attention
255 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
256 * All rights reserved.</center></h2>
258 * This software component is licensed by ST under BSD 3-Clause license,
259 * the "License"; You may not use this file except in compliance with the
260 * License. You may obtain a copy of the License at:
261 * opensource.org/licenses/BSD-3-Clause
263 ******************************************************************************
266 /* Includes ------------------------------------------------------------------*/
267 #include "stm32h7xx_hal.h"
269 /** @addtogroup STM32H7xx_HAL_Driver
270 * @{
273 #if defined (CRYP)
275 /** @defgroup CRYP CRYP
276 * @brief CRYP HAL module driver.
277 * @{
281 #ifdef HAL_CRYP_MODULE_ENABLED
283 /* Private typedef -----------------------------------------------------------*/
284 /* Private define ------------------------------------------------------------*/
285 /** @addtogroup CRYP_Private_Defines
286 * @{
288 #define CRYP_TIMEOUT_KEYPREPARATION 82U /*The latency of key preparation operation is 82 clock cycles.*/
289 #define CRYP_TIMEOUT_GCMCCMINITPHASE 299U /* The latency of GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
290 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE 290U /* The latency of GCM/CCM header phase is 290 clock cycles.*/
292 #define CRYP_PHASE_READY 0x00000001U /*!< CRYP peripheral is ready for initialization. */
293 #define CRYP_PHASE_PROCESS 0x00000002U /*!< CRYP peripheral is in processing phase */
295 #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
296 #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0 /*!< GCM/GMAC or CCM header phase */
297 #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1 /*!< GCM(/CCM) payload phase */
298 #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH /*!< GCM/GMAC or CCM final phase */
299 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */
300 #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR /*!< Decryption */
303 /* CTR1 information to use in CCM algorithm */
304 #define CRYP_CCM_CTR1_0 0x07FFFFFFU
305 #define CRYP_CCM_CTR1_1 0xFFFFFF00U
306 #define CRYP_CCM_CTR1_2 0x00000001U
309 * @}
313 /* Private macro -------------------------------------------------------------*/
314 /** @addtogroup CRYP_Private_Macros
315 * @{
318 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__) do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\
319 (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
320 }while(0)
322 #define HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRYP_CR_FFLUSH)
326 * @}
329 /* Private struct -------------------------------------------------------------*/
330 /* Private variables ---------------------------------------------------------*/
331 /* Private function prototypes -----------------------------------------------*/
332 /** @addtogroup CRYP_Private_Functions_prototypes
333 * @{
336 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
337 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
338 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
339 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
340 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
341 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
342 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
343 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
344 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
345 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
346 #if !defined (CRYP_VER_2_2)
347 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
348 #endif /*End of not defined CRYP_VER_2_2*/
349 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
350 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
351 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
352 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
353 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
354 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
355 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
356 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
357 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
358 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
359 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
360 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
361 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp);
362 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
363 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
364 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
365 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
368 * @}
371 /* Exported functions ---------------------------------------------------------*/
373 /** @defgroup CRYP_Exported_Functions CRYP Exported Functions
374 * @{
378 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
379 * @brief CRYP Initialization and Configuration functions.
381 @verbatim
382 ========================================================================================
383 ##### Initialization, de-initialization and Set and Get configuration functions #####
384 ========================================================================================
385 [..] This section provides functions allowing to:
386 (+) Initialize the CRYP
387 (+) DeInitialize the CRYP
388 (+) Initialize the CRYP MSP
389 (+) DeInitialize the CRYP MSP
390 (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
391 Parameters which are configured in This section are :
392 (++) Key size
393 (++) Data Type : 32,16, 8 or 1bit
394 (++) AlgoMode : for CRYP1 IP
395 ECB and CBC in DES/TDES Standard
396 ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
397 (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
400 @endverbatim
401 * @{
406 * @brief Initializes the CRYP according to the specified
407 * parameters in the CRYP_ConfigTypeDef and creates the associated handle.
408 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
409 * the configuration information for CRYP module
410 * @retval HAL status
412 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
414 /* Check the CRYP handle allocation */
415 if (hcryp == NULL)
417 return HAL_ERROR;
420 /* Check parameters */
421 assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
422 assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
423 assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
424 assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
426 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
427 if (hcryp->State == HAL_CRYP_STATE_RESET)
429 /* Allocate lock resource and initialize it */
430 hcryp->Lock = HAL_UNLOCKED;
432 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
433 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
434 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
436 if (hcryp->MspInitCallback == NULL)
438 hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit */
441 /* Init the low level hardware */
442 hcryp->MspInitCallback(hcryp);
444 #else
445 if (hcryp->State == HAL_CRYP_STATE_RESET)
447 /* Allocate lock resource and initialize it */
448 hcryp->Lock = HAL_UNLOCKED;
450 /* Init the low level hardware */
451 HAL_CRYP_MspInit(hcryp);
453 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
455 /* Set the key size(This bit field is ‘don’t care’ in the DES or TDES modes) data type and Algorithm */
456 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
457 hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
458 #if !defined (CRYP_VER_2_2)
459 /* Read Device ID to indicate CRYP1 IP Version */
460 hcryp->Version = HAL_GetREVID();
461 #endif /*End of not defined CRYP_VER_2_2*/
462 /* Reset Error Code field */
463 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
465 /* Reset peripheral Key and IV configuration flag */
466 hcryp->KeyIVConfig = 0U;
468 /* Change the CRYP state */
469 hcryp->State = HAL_CRYP_STATE_READY;
471 /* Set the default CRYP phase */
472 hcryp->Phase = CRYP_PHASE_READY;
474 /* Return function status */
475 return HAL_OK;
479 * @brief De-Initializes the CRYP peripheral.
480 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
481 * the configuration information for CRYP module
482 * @retval HAL status
484 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
486 /* Check the CRYP handle allocation */
487 if (hcryp == NULL)
489 return HAL_ERROR;
492 /* Set the default CRYP phase */
493 hcryp->Phase = CRYP_PHASE_READY;
495 /* Reset CrypInCount and CrypOutCount */
496 hcryp->CrypInCount = 0;
497 hcryp->CrypOutCount = 0;
498 hcryp->CrypHeaderCount = 0;
500 /* Disable the CRYP peripheral clock */
501 __HAL_CRYP_DISABLE(hcryp);
503 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
504 if (hcryp->MspDeInitCallback == NULL)
506 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit */
508 /* DeInit the low level hardware */
509 hcryp->MspDeInitCallback(hcryp);
511 #else
512 /* DeInit the low level hardware: CLOCK, NVIC.*/
513 HAL_CRYP_MspDeInit(hcryp);
514 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
516 /* Change the CRYP state */
517 hcryp->State = HAL_CRYP_STATE_RESET;
519 /* Release Lock */
520 __HAL_UNLOCK(hcryp);
522 /* Return function status */
523 return HAL_OK;
527 * @brief Configure the CRYP according to the specified
528 * parameters in the CRYP_ConfigTypeDef
529 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
530 * @param pConf: pointer to a CRYP_ConfigTypeDef structure that contains
531 * the configuration information for CRYP module
532 * @retval HAL status
534 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
536 /* Check the CRYP handle allocation */
537 if ((hcryp == NULL) || (pConf == NULL))
539 return HAL_ERROR;
542 /* Check parameters */
543 assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
544 assert_param(IS_CRYP_DATATYPE(pConf->DataType));
545 assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
547 if (hcryp->State == HAL_CRYP_STATE_READY)
549 /* Change the CRYP state */
550 hcryp->State = HAL_CRYP_STATE_BUSY;
552 /* Process locked */
553 __HAL_LOCK(hcryp);
555 /* Set CRYP parameters */
556 hcryp->Init.DataType = pConf->DataType;
557 hcryp->Init.pKey = pConf->pKey;
558 hcryp->Init.Algorithm = pConf->Algorithm;
559 hcryp->Init.KeySize = pConf->KeySize;
560 hcryp->Init.pInitVect = pConf->pInitVect;
561 hcryp->Init.Header = pConf->Header;
562 hcryp->Init.HeaderSize = pConf->HeaderSize;
563 hcryp->Init.B0 = pConf->B0;
564 hcryp->Init.DataWidthUnit = pConf->DataWidthUnit;
566 /* Set the key size(This bit field is ‘don’t care’ in the DES or TDES modes) data type, AlgoMode and operating mode*/
567 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
568 hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
570 /* Process Unlocked */
571 __HAL_UNLOCK(hcryp);
573 /* Reset Error Code field */
574 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
576 /* Change the CRYP state */
577 hcryp->State = HAL_CRYP_STATE_READY;
579 /* Set the default CRYP phase */
580 hcryp->Phase = CRYP_PHASE_READY;
582 /* Return function status */
583 return HAL_OK;
585 else
587 /* Process Unlocked */
588 __HAL_UNLOCK(hcryp);
590 /* Busy error code field */
591 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
592 return HAL_ERROR;
597 * @brief Get CRYP Configuration parameters in associated handle.
598 * @param pConf: pointer to a CRYP_ConfigTypeDef structure
599 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
600 * the configuration information for CRYP module
601 * @retval HAL status
603 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
605 /* Check the CRYP handle allocation */
606 if ((hcryp == NULL) || (pConf == NULL))
608 return HAL_ERROR;
611 if (hcryp->State == HAL_CRYP_STATE_READY)
613 /* Change the CRYP state */
614 hcryp->State = HAL_CRYP_STATE_BUSY;
616 /* Process locked */
617 __HAL_LOCK(hcryp);
619 /* Get CRYP parameters */
620 pConf->DataType = hcryp->Init.DataType;
621 pConf->pKey = hcryp->Init.pKey;
622 pConf->Algorithm = hcryp->Init.Algorithm;
623 pConf->KeySize = hcryp->Init.KeySize ;
624 pConf->pInitVect = hcryp->Init.pInitVect;
625 pConf->Header = hcryp->Init.Header ;
626 pConf->HeaderSize = hcryp->Init.HeaderSize;
627 pConf->B0 = hcryp->Init.B0;
628 pConf->DataWidthUnit = hcryp->Init.DataWidthUnit;
630 /* Process Unlocked */
631 __HAL_UNLOCK(hcryp);
633 /* Change the CRYP state */
634 hcryp->State = HAL_CRYP_STATE_READY;
636 /* Return function status */
637 return HAL_OK;
639 else
641 /* Process Unlocked */
642 __HAL_UNLOCK(hcryp);
644 /* Busy error code field */
645 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
646 return HAL_ERROR;
650 * @brief Initializes the CRYP MSP.
651 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
652 * the configuration information for CRYP module
653 * @retval None
655 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
657 /* Prevent unused argument(s) compilation warning */
658 UNUSED(hcryp);
660 /* NOTE : This function Should not be modified, when the callback is needed,
661 the HAL_CRYP_MspInit could be implemented in the user file
666 * @brief DeInitializes CRYP MSP.
667 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
668 * the configuration information for CRYP module
669 * @retval None
671 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
673 /* Prevent unused argument(s) compilation warning */
674 UNUSED(hcryp);
676 /* NOTE : This function Should not be modified, when the callback is needed,
677 the HAL_CRYP_MspDeInit could be implemented in the user file
681 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
683 * @brief Register a User CRYP Callback
684 * To be used instead of the weak predefined callback
685 * @param hcryp cryp handle
686 * @param CallbackID ID of the callback to be registered
687 * This parameter can be one of the following values:
688 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
689 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
690 * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
691 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
692 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
693 * @param pCallback pointer to the Callback function
694 * @retval status
696 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID,
697 pCRYP_CallbackTypeDef pCallback)
699 HAL_StatusTypeDef status = HAL_OK;
701 if (pCallback == NULL)
703 /* Update the error code */
704 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
706 return HAL_ERROR;
708 /* Process locked */
709 __HAL_LOCK(hcryp);
711 if (hcryp->State == HAL_CRYP_STATE_READY)
713 switch (CallbackID)
715 case HAL_CRYP_INPUT_COMPLETE_CB_ID :
716 hcryp->InCpltCallback = pCallback;
717 break;
719 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
720 hcryp->OutCpltCallback = pCallback;
721 break;
723 case HAL_CRYP_ERROR_CB_ID :
724 hcryp->ErrorCallback = pCallback;
725 break;
727 case HAL_CRYP_MSPINIT_CB_ID :
728 hcryp->MspInitCallback = pCallback;
729 break;
731 case HAL_CRYP_MSPDEINIT_CB_ID :
732 hcryp->MspDeInitCallback = pCallback;
733 break;
735 default :
736 /* Update the error code */
737 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
738 /* Return error status */
739 status = HAL_ERROR;
740 break;
743 else if (hcryp->State == HAL_CRYP_STATE_RESET)
745 switch (CallbackID)
747 case HAL_CRYP_MSPINIT_CB_ID :
748 hcryp->MspInitCallback = pCallback;
749 break;
751 case HAL_CRYP_MSPDEINIT_CB_ID :
752 hcryp->MspDeInitCallback = pCallback;
753 break;
755 default :
756 /* Update the error code */
757 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
758 /* Return error status */
759 status = HAL_ERROR;
760 break;
763 else
765 /* Update the error code */
766 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
767 /* Return error status */
768 status = HAL_ERROR;
771 /* Release Lock */
772 __HAL_UNLOCK(hcryp);
774 return status;
778 * @brief Unregister an CRYP Callback
779 * CRYP callabck is redirected to the weak predefined callback
780 * @param hcryp cryp handle
781 * @param CallbackID ID of the callback to be unregistered
782 * This parameter can be one of the following values:
783 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
784 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
785 * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
786 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
787 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
788 * @retval status
790 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
792 HAL_StatusTypeDef status = HAL_OK;
794 /* Process locked */
795 __HAL_LOCK(hcryp);
797 if (hcryp->State == HAL_CRYP_STATE_READY)
799 switch (CallbackID)
801 case HAL_CRYP_INPUT_COMPLETE_CB_ID :
802 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
803 break;
805 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
806 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
807 break;
809 case HAL_CRYP_ERROR_CB_ID :
810 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
811 break;
813 case HAL_CRYP_MSPINIT_CB_ID :
814 hcryp->MspInitCallback = HAL_CRYP_MspInit;
815 break;
817 case HAL_CRYP_MSPDEINIT_CB_ID :
818 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
819 break;
821 default :
822 /* Update the error code */
823 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
824 /* Return error status */
825 status = HAL_ERROR;
826 break;
829 else if (hcryp->State == HAL_CRYP_STATE_RESET)
831 switch (CallbackID)
833 case HAL_CRYP_MSPINIT_CB_ID :
834 hcryp->MspInitCallback = HAL_CRYP_MspInit;
835 break;
837 case HAL_CRYP_MSPDEINIT_CB_ID :
838 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
839 break;
841 default :
842 /* Update the error code */
843 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
844 /* Return error status */
845 status = HAL_ERROR;
846 break;
849 else
851 /* Update the error code */
852 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
853 /* Return error status */
854 status = HAL_ERROR;
857 /* Release Lock */
858 __HAL_UNLOCK(hcryp);
860 return status;
862 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
865 * @}
868 /** @defgroup CRYP_Exported_Functions_Group2 Encrypt Decrypt functions
869 * @brief CRYP processing functions.
871 @verbatim
872 ==============================================================================
873 ##### Encrypt Decrypt functions #####
874 ==============================================================================
875 [..] This section provides API allowing to Encrypt/Decrypt Data following
876 Standard DES/TDES or AES, and Algorithm configured by the user:
877 (+) Standard DES/TDES only supported by CRYP1 IP, below list of Algorithm supported :
878 (++) Electronic Code Book(ECB)
879 (++) Cipher Block Chaining (CBC)
880 (+) Standard AES supported by CRYP1 IP , list of Algorithm supported:
881 (++) Electronic Code Book(ECB)
882 (++) Cipher Block Chaining (CBC)
883 (++) Counter mode (CTR)
884 (++) Cipher Block Chaining (CBC)
885 (++) Counter mode (CTR)
886 (++) Galois/counter mode (GCM)
887 (++) Counter with Cipher Block Chaining-Message(CCM)
888 [..] Three processing functions are available:
889 (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
890 (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
891 (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
893 @endverbatim
894 * @{
899 * @brief Encryption mode.
900 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
901 * the configuration information for CRYP module
902 * @param Input: Pointer to the input buffer (plaintext)
903 * @param Size: Length of the plaintext buffer in word.
904 * @param Output: Pointer to the output buffer(ciphertext)
905 * @param Timeout: Specify Timeout value
906 * @retval HAL status
908 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
909 uint32_t Timeout)
911 uint32_t algo;
912 HAL_StatusTypeDef status;
914 if (hcryp->State == HAL_CRYP_STATE_READY)
916 /* Change state Busy */
917 hcryp->State = HAL_CRYP_STATE_BUSY;
919 /* Process locked */
920 __HAL_LOCK(hcryp);
922 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
923 hcryp->CrypInCount = 0U;
924 hcryp->CrypOutCount = 0U;
925 hcryp->pCrypInBuffPtr = Input;
926 hcryp->pCrypOutBuffPtr = Output;
928 /* Calculate Size parameter in Byte*/
929 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
931 hcryp->Size = Size * 4U;
933 else
935 hcryp->Size = Size;
938 /* Set Encryption operating mode*/
939 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
941 /* algo get algorithm selected */
942 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
944 switch (algo)
946 case CRYP_DES_ECB:
947 case CRYP_DES_CBC:
948 case CRYP_TDES_ECB:
949 case CRYP_TDES_CBC:
951 /*Set Key */
952 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
953 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
954 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
956 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
957 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
958 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
959 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
962 /*Set Initialization Vector (IV)*/
963 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
965 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
966 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
969 /* Flush FIFO */
970 HAL_CRYP_FIFO_FLUSH(hcryp);
972 /* Set the phase */
973 hcryp->Phase = CRYP_PHASE_PROCESS;
975 /* Statrt DES/TDES encryption process */
976 status = CRYP_TDES_Process(hcryp, Timeout);
977 break;
979 case CRYP_AES_ECB:
980 case CRYP_AES_CBC:
981 case CRYP_AES_CTR:
983 /* AES encryption */
984 status = CRYP_AES_Encrypt(hcryp, Timeout);
985 break;
987 case CRYP_AES_GCM:
989 /* AES GCM encryption */
990 status = CRYP_AESGCM_Process(hcryp, Timeout);
991 break;
993 case CRYP_AES_CCM:
995 /* AES CCM encryption */
996 status = CRYP_AESCCM_Process(hcryp, Timeout);
997 break;
999 default:
1000 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1001 status = HAL_ERROR;
1002 break;
1005 if (status == HAL_OK)
1007 /* Change the CRYP peripheral state */
1008 hcryp->State = HAL_CRYP_STATE_READY;
1010 /* Process unlocked */
1011 __HAL_UNLOCK(hcryp);
1014 else
1016 /* Process unlocked */
1017 __HAL_UNLOCK(hcryp);
1019 /* Busy error code field */
1020 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1021 status = HAL_ERROR;
1024 /* Return function status */
1025 return status ;
1029 * @brief Decryption mode.
1030 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1031 * the configuration information for CRYP module
1032 * @param Input: Pointer to the input buffer (ciphertext )
1033 * @param Size: Length of the plaintext buffer in word.
1034 * @param Output: Pointer to the output buffer(plaintext)
1035 * @param Timeout: Specify Timeout value
1036 * @retval HAL status
1038 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
1039 uint32_t Timeout)
1041 HAL_StatusTypeDef status;
1042 uint32_t algo;
1044 if (hcryp->State == HAL_CRYP_STATE_READY)
1046 /* Change state Busy */
1047 hcryp->State = HAL_CRYP_STATE_BUSY;
1049 /* Process locked */
1050 __HAL_LOCK(hcryp);
1052 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1053 hcryp->CrypInCount = 0U;
1054 hcryp->CrypOutCount = 0U;
1055 hcryp->pCrypInBuffPtr = Input;
1056 hcryp->pCrypOutBuffPtr = Output;
1058 /* Calculate Size parameter in Byte*/
1059 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1061 hcryp->Size = Size * 4U;
1063 else
1065 hcryp->Size = Size;
1068 /* Set Decryption operating mode*/
1069 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1071 /* algo get algorithm selected */
1072 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1074 switch (algo)
1076 case CRYP_DES_ECB:
1077 case CRYP_DES_CBC:
1078 case CRYP_TDES_ECB:
1079 case CRYP_TDES_CBC:
1081 /*Set Key */
1082 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1083 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1084 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1086 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1087 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1088 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1089 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1092 /*Set Initialization Vector (IV)*/
1093 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1095 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1096 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1099 /* Flush FIFO */
1100 HAL_CRYP_FIFO_FLUSH(hcryp);
1102 /* Set the phase */
1103 hcryp->Phase = CRYP_PHASE_PROCESS;
1105 /* Start DES/TDES decryption process */
1106 status = CRYP_TDES_Process(hcryp, Timeout);
1108 break;
1110 case CRYP_AES_ECB:
1111 case CRYP_AES_CBC:
1112 case CRYP_AES_CTR:
1114 /* AES decryption */
1115 status = CRYP_AES_Decrypt(hcryp, Timeout);
1116 break;
1118 case CRYP_AES_GCM:
1120 /* AES GCM decryption */
1121 status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1122 break;
1124 case CRYP_AES_CCM:
1126 /* AES CCM decryption */
1127 status = CRYP_AESCCM_Process(hcryp, Timeout);
1128 break;
1130 default:
1131 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1132 status = HAL_ERROR;
1133 break;
1136 if (status == HAL_OK)
1138 /* Change the CRYP peripheral state */
1139 hcryp->State = HAL_CRYP_STATE_READY;
1141 /* Process unlocked */
1142 __HAL_UNLOCK(hcryp);
1145 else
1147 /* Process unlocked */
1148 __HAL_UNLOCK(hcryp);
1150 /* Busy error code field */
1151 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1152 status = HAL_ERROR;
1155 /* Return function status */
1156 return status;
1160 * @brief Encryption in interrupt mode.
1161 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1162 * the configuration information for CRYP module
1163 * @param Input: Pointer to the input buffer (plaintext)
1164 * @param Size: Length of the plaintext buffer in word
1165 * @param Output: Pointer to the output buffer(ciphertext)
1166 * @retval HAL status
1168 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1170 uint32_t algo;
1171 HAL_StatusTypeDef status;
1173 if (hcryp->State == HAL_CRYP_STATE_READY)
1175 /* Change state Busy */
1176 hcryp->State = HAL_CRYP_STATE_BUSY;
1178 /* Process locked */
1179 __HAL_LOCK(hcryp);
1181 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1182 hcryp->CrypInCount = 0U;
1183 hcryp->CrypOutCount = 0U;
1184 hcryp->pCrypInBuffPtr = Input;
1185 hcryp->pCrypOutBuffPtr = Output;
1187 /* Calculate Size parameter in Byte*/
1188 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1190 hcryp->Size = Size * 4U;
1192 else
1194 hcryp->Size = Size;
1197 /* Set encryption operating mode*/
1198 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1200 /* algo get algorithm selected */
1201 algo = (hcryp->Instance->CR & CRYP_CR_ALGOMODE);
1203 switch (algo)
1205 case CRYP_DES_ECB:
1206 case CRYP_DES_CBC:
1207 case CRYP_TDES_ECB:
1208 case CRYP_TDES_CBC:
1210 /*Set Key */
1211 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1212 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1213 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1215 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1216 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1217 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1218 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1220 /* Set the Initialization Vector*/
1221 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1223 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1224 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1227 /* Flush FIFO */
1228 HAL_CRYP_FIFO_FLUSH(hcryp);
1230 /* Set the phase */
1231 hcryp->Phase = CRYP_PHASE_PROCESS;
1233 /* Enable interrupts */
1234 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1236 /* Enable CRYP to start DES/TDES process*/
1237 __HAL_CRYP_ENABLE(hcryp);
1239 status = HAL_OK;
1240 break;
1242 case CRYP_AES_ECB:
1243 case CRYP_AES_CBC:
1244 case CRYP_AES_CTR:
1246 status = CRYP_AES_Encrypt_IT(hcryp);
1247 break;
1249 case CRYP_AES_GCM:
1251 status = CRYP_AESGCM_Process_IT(hcryp) ;
1252 break;
1254 case CRYP_AES_CCM:
1256 status = CRYP_AESCCM_Process_IT(hcryp);
1257 break;
1259 default:
1260 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1261 status = HAL_ERROR;
1262 break;
1265 else
1267 /* Busy error code field */
1268 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1269 status = HAL_ERROR;
1272 /* Return function status */
1273 return status ;
1277 * @brief Decryption in itnterrupt mode.
1278 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1279 * the configuration information for CRYP module
1280 * @param Input: Pointer to the input buffer (ciphertext )
1281 * @param Size: Length of the plaintext buffer in word.
1282 * @param Output: Pointer to the output buffer(plaintext)
1283 * @retval HAL status
1285 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1287 uint32_t algo;
1288 HAL_StatusTypeDef status = HAL_OK;
1290 if (hcryp->State == HAL_CRYP_STATE_READY)
1292 /* Change state Busy */
1293 hcryp->State = HAL_CRYP_STATE_BUSY;
1295 /* Process locked */
1296 __HAL_LOCK(hcryp);
1298 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1299 hcryp->CrypInCount = 0U;
1300 hcryp->CrypOutCount = 0U;
1301 hcryp->pCrypInBuffPtr = Input;
1302 hcryp->pCrypOutBuffPtr = Output;
1304 /* Calculate Size parameter in Byte*/
1305 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1307 hcryp->Size = Size * 4U;
1309 else
1311 hcryp->Size = Size;
1314 /* Set decryption operating mode*/
1315 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1317 /* algo get algorithm selected */
1318 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1320 switch (algo)
1322 case CRYP_DES_ECB:
1323 case CRYP_DES_CBC:
1324 case CRYP_TDES_ECB:
1325 case CRYP_TDES_CBC:
1327 /*Set Key */
1328 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1329 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1330 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1332 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1333 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1334 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1335 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1338 /* Set the Initialization Vector*/
1339 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1341 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1342 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1344 /* Flush FIFO */
1345 HAL_CRYP_FIFO_FLUSH(hcryp);
1347 /* Set the phase */
1348 hcryp->Phase = CRYP_PHASE_PROCESS;
1350 /* Enable interrupts */
1351 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1353 /* Enable CRYP and start DES/TDES process*/
1354 __HAL_CRYP_ENABLE(hcryp);
1356 break;
1358 case CRYP_AES_ECB:
1359 case CRYP_AES_CBC:
1360 case CRYP_AES_CTR:
1362 /* AES decryption */
1363 status = CRYP_AES_Decrypt_IT(hcryp);
1364 break;
1366 case CRYP_AES_GCM:
1368 /* AES GCM decryption */
1369 status = CRYP_AESGCM_Process_IT(hcryp) ;
1370 break;
1372 case CRYP_AES_CCM:
1374 /* AES CCMdecryption */
1375 status = CRYP_AESCCM_Process_IT(hcryp);
1376 break;
1378 default:
1379 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1380 status = HAL_ERROR;
1381 break;
1384 else
1386 /* Busy error code field */
1387 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1388 status = HAL_ERROR;
1391 /* Return function status */
1392 return status;
1396 * @brief Encryption in DMA mode.
1397 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1398 * the configuration information for CRYP module
1399 * @param Input: Pointer to the input buffer (plaintext)
1400 * @param Size: Length of the plaintext buffer in word.
1401 * @param Output: Pointer to the output buffer(ciphertext)
1402 * @retval HAL status
1404 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1406 HAL_StatusTypeDef status = HAL_OK;
1407 uint32_t algo;
1408 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1410 if (hcryp->State == HAL_CRYP_STATE_READY)
1412 /* Change state Busy */
1413 hcryp->State = HAL_CRYP_STATE_BUSY;
1415 /* Process locked */
1416 __HAL_LOCK(hcryp);
1418 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1419 hcryp->CrypInCount = 0U;
1420 hcryp->CrypOutCount = 0U;
1421 hcryp->pCrypInBuffPtr = Input;
1422 hcryp->pCrypOutBuffPtr = Output;
1424 /* Calculate Size parameter in Byte*/
1425 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1427 hcryp->Size = Size * 4U;
1429 else
1431 hcryp->Size = Size;
1434 /* Set encryption operating mode*/
1435 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1437 /* algo get algorithm selected */
1438 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1440 switch (algo)
1442 case CRYP_DES_ECB:
1443 case CRYP_DES_CBC:
1444 case CRYP_TDES_ECB:
1445 case CRYP_TDES_CBC:
1447 /*Set Key */
1448 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1449 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1450 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1452 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1453 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1454 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1455 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1458 /* Set the Initialization Vector*/
1459 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1461 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1462 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1465 /* Flush FIFO */
1466 HAL_CRYP_FIFO_FLUSH(hcryp);
1468 /* Set the phase */
1469 hcryp->Phase = CRYP_PHASE_PROCESS;
1471 /* Start DMA process transfer for DES/TDES */
1472 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
1474 break;
1476 case CRYP_AES_ECB:
1477 case CRYP_AES_CBC:
1478 case CRYP_AES_CTR:
1480 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1482 if (hcryp->KeyIVConfig == 1U)
1484 /* If the Key and IV configuration has to be done only once
1485 and if it has already been done, skip it */
1486 DoKeyIVConfig = 0U;
1488 else
1490 /* If the Key and IV configuration has to be done only once
1491 and if it has not been done already, do it and set KeyIVConfig
1492 to keep track it won't have to be done again next time */
1493 hcryp->KeyIVConfig = 1U;
1497 if (DoKeyIVConfig == 1U)
1499 /* Set the Key*/
1500 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1502 /* Set the Initialization Vector*/
1503 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1505 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1506 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
1507 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
1508 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
1510 } /* if (DoKeyIVConfig == 1U) */
1512 /* Set the phase */
1513 hcryp->Phase = CRYP_PHASE_PROCESS;
1515 /* Start DMA process transfer for AES */
1516 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
1517 break;
1519 case CRYP_AES_GCM:
1521 /* AES GCM encryption */
1522 status = CRYP_AESGCM_Process_DMA(hcryp) ;
1523 break;
1525 case CRYP_AES_CCM:
1527 /* AES CCM encryption */
1528 status = CRYP_AESCCM_Process_DMA(hcryp);
1529 break;
1531 default:
1532 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1533 status = HAL_ERROR;
1534 break;
1537 else
1539 /* Busy error code field */
1540 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1541 status = HAL_ERROR;
1544 /* Return function status */
1545 return status;
1549 * @brief Decryption in DMA mode.
1550 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1551 * the configuration information for CRYP module
1552 * @param Input: Pointer to the input buffer (ciphertext )
1553 * @param Size: Length of the plaintext buffer in word
1554 * @param Output: Pointer to the output buffer(plaintext)
1555 * @retval HAL status
1557 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1559 uint32_t algo;
1560 HAL_StatusTypeDef status = HAL_OK;
1562 if (hcryp->State == HAL_CRYP_STATE_READY)
1564 /* Change state Busy */
1565 hcryp->State = HAL_CRYP_STATE_BUSY;
1567 /* Process locked */
1568 __HAL_LOCK(hcryp);
1570 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1571 hcryp->CrypInCount = 0U;
1572 hcryp->CrypOutCount = 0U;
1573 hcryp->pCrypInBuffPtr = Input;
1574 hcryp->pCrypOutBuffPtr = Output;
1576 /* Calculate Size parameter in Byte*/
1577 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1579 hcryp->Size = Size * 4U;
1581 else
1583 hcryp->Size = Size;
1586 /* Set decryption operating mode*/
1587 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1589 /* algo get algorithm selected */
1590 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1592 switch (algo)
1594 case CRYP_DES_ECB:
1595 case CRYP_DES_CBC:
1596 case CRYP_TDES_ECB:
1597 case CRYP_TDES_CBC:
1599 /*Set Key */
1600 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1601 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1602 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1604 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1605 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1606 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1607 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1610 /* Set the Initialization Vector*/
1611 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1613 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1614 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1617 /* Flush FIFO */
1618 HAL_CRYP_FIFO_FLUSH(hcryp);
1620 /* Set the phase */
1621 hcryp->Phase = CRYP_PHASE_PROCESS;
1623 /* Start DMA process transfer for DES/TDES */
1624 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
1625 break;
1627 case CRYP_AES_ECB:
1628 case CRYP_AES_CBC:
1629 case CRYP_AES_CTR:
1631 /* AES decryption */
1632 status = CRYP_AES_Decrypt_DMA(hcryp);
1633 break;
1635 case CRYP_AES_GCM:
1637 /* AES GCM decryption */
1638 status = CRYP_AESGCM_Process_DMA(hcryp) ;
1640 break;
1642 case CRYP_AES_CCM:
1644 /* AES CCM decryption */
1645 status = CRYP_AESCCM_Process_DMA(hcryp);
1646 break;
1648 default:
1649 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1650 status = HAL_ERROR;
1651 break;
1654 else
1656 /* Busy error code field */
1657 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1658 status = HAL_ERROR;
1661 /* Return function status */
1662 return status;
1666 * @}
1669 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1670 * @brief CRYP IRQ handler.
1672 @verbatim
1673 ==============================================================================
1674 ##### CRYP IRQ handler management #####
1675 ==============================================================================
1676 [..] This section provides CRYP IRQ handler and callback functions.
1677 (+) HAL_CRYP_IRQHandler CRYP interrupt request
1678 (+) HAL_CRYP_InCpltCallback input data transfer complete callback
1679 (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
1680 (+) HAL_CRYP_ErrorCallback CRYP error callback
1681 (+) HAL_CRYP_GetState return the CRYP state
1682 (+) HAL_CRYP_GetError return the CRYP error code
1683 @endverbatim
1684 * @{
1688 * @brief This function handles cryptographic interrupt request.
1689 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1690 * the configuration information for CRYP module
1691 * @retval None
1693 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
1695 uint32_t itstatus = hcryp->Instance->MISR;
1697 if ((itstatus & (CRYP_IT_INI | CRYP_IT_OUTI)) != 0U)
1699 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))
1701 CRYP_TDES_IT(hcryp); /* DES or TDES*/
1703 else if ((hcryp->Init.Algorithm == CRYP_AES_ECB) || (hcryp->Init.Algorithm == CRYP_AES_CBC) || (hcryp->Init.Algorithm == CRYP_AES_CTR))
1705 CRYP_AES_IT(hcryp); /*AES*/
1708 else if ((hcryp->Init.Algorithm == CRYP_AES_GCM) || (hcryp->Init.Algorithm == CRYP_CR_ALGOMODE_AES_CCM))
1710 /* if header phase */
1711 if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
1713 CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
1715 else /* if payload phase */
1717 CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
1720 else
1722 /* Nothing to do */
1728 * @brief Return the CRYP error code.
1729 * @param hcryp : pointer to a CRYP_HandleTypeDef structure that contains
1730 * the configuration information for the CRYP IP
1731 * @retval CRYP error code
1733 uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp)
1735 return hcryp->ErrorCode;
1739 * @brief Returns the CRYP state.
1740 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1741 * the configuration information for CRYP module.
1742 * @retval HAL state
1744 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp)
1746 return hcryp->State;
1750 * @brief Input FIFO transfer completed callback.
1751 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1752 * the configuration information for CRYP module.
1753 * @retval None
1755 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
1757 /* Prevent unused argument(s) compilation warning */
1758 UNUSED(hcryp);
1760 /* NOTE : This function Should not be modified, when the callback is needed,
1761 the HAL_CRYP_InCpltCallback could be implemented in the user file
1766 * @brief Output FIFO transfer completed callback.
1767 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1768 * the configuration information for CRYP module.
1769 * @retval None
1771 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
1773 /* Prevent unused argument(s) compilation warning */
1774 UNUSED(hcryp);
1776 /* NOTE : This function Should not be modified, when the callback is needed,
1777 the HAL_CRYP_OutCpltCallback could be implemented in the user file
1782 * @brief CRYP error callback.
1783 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1784 * the configuration information for CRYP module.
1785 * @retval None
1787 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
1789 /* Prevent unused argument(s) compilation warning */
1790 UNUSED(hcryp);
1792 /* NOTE : This function Should not be modified, when the callback is needed,
1793 the HAL_CRYP_ErrorCallback could be implemented in the user file
1797 * @}
1800 /* Private functions ---------------------------------------------------------*/
1801 /** @addtogroup CRYP_Private_Functions
1802 * @{
1806 * @brief Encryption in ECB/CBC Algorithm with DES/TDES standard.
1807 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1808 * the configuration information for CRYP module
1809 * @param Timeout: Timeout value
1810 * @retval HAL status
1812 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
1815 uint32_t temp; /* Temporary CrypOutBuff */
1816 uint16_t incount; /* Temporary CrypInCount Value */
1817 uint16_t outcount; /* Temporary CrypOutCount Value */
1819 /* Enable CRYP */
1820 __HAL_CRYP_ENABLE(hcryp);
1821 /*Temporary CrypOutCount Value*/
1822 outcount = hcryp->CrypOutCount;
1824 /*Start processing*/
1825 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
1827 /* Temporary CrypInCount Value */
1828 incount = hcryp->CrypInCount;
1829 /* Write plain data and get cipher data */
1830 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
1832 /* Write the input block in the IN FIFO */
1833 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1834 hcryp->CrypInCount++;
1835 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1836 hcryp->CrypInCount++;
1839 /* Wait for OFNE flag to be raised */
1840 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
1842 /* Disable the CRYP peripheral clock */
1843 __HAL_CRYP_DISABLE(hcryp);
1845 /* Change state & errorCode*/
1846 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
1847 hcryp->State = HAL_CRYP_STATE_READY;
1849 /* Process unlocked */
1850 __HAL_UNLOCK(hcryp);
1851 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1852 /*Call registered error callback*/
1853 hcryp->ErrorCallback(hcryp);
1854 #else
1855 /*Call legacy weak error callback*/
1856 HAL_CRYP_ErrorCallback(hcryp);
1857 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1860 /*Temporary CrypOutCount Value*/
1861 outcount = hcryp->CrypOutCount;
1863 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
1865 /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer */
1866 temp = hcryp->Instance->DOUT;
1867 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1868 hcryp->CrypOutCount++;
1869 temp = hcryp->Instance->DOUT;
1870 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1871 hcryp->CrypOutCount++;
1873 /*Temporary CrypOutCount Value*/
1874 outcount = hcryp->CrypOutCount;
1876 /* Disable CRYP */
1877 __HAL_CRYP_DISABLE(hcryp);
1878 /* Change the CRYP state */
1879 hcryp->State = HAL_CRYP_STATE_READY;
1881 /* Return function status */
1882 return HAL_OK;
1886 * @brief CRYP block input/output data handling under interruption with DES/TDES standard.
1887 * @note The function is called under interruption only, once
1888 * interruptions have been enabled by CRYP_Decrypt_IT() and CRYP_Encrypt_IT().
1889 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1890 * the configuration information for CRYP module.
1891 * @retval HAL status
1893 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp)
1895 uint32_t temp; /* Temporary CrypOutBuff */
1897 if (hcryp->State == HAL_CRYP_STATE_BUSY)
1899 if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI) != 0x0U)
1901 if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_INRIS) != 0x0U)
1903 /* Write input block in the IN FIFO */
1904 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1905 hcryp->CrypInCount++;
1906 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1907 hcryp->CrypInCount++;
1909 if (hcryp->CrypInCount == (hcryp->Size / 4U))
1911 /* Disable interruption */
1912 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1914 /* Call the input data transfer complete callback */
1915 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1916 /*Call registered Input complete callback*/
1917 hcryp->InCpltCallback(hcryp);
1918 #else
1919 /*Call legacy weak Input complete callback*/
1920 HAL_CRYP_InCpltCallback(hcryp);
1921 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1926 if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI) != 0x0U)
1928 if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_OUTRIS) != 0x0U)
1930 /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer */
1931 temp = hcryp->Instance->DOUT;
1932 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1933 hcryp->CrypOutCount++;
1934 temp = hcryp->Instance->DOUT;
1935 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1936 hcryp->CrypOutCount++;
1937 if (hcryp->CrypOutCount == (hcryp->Size / 4U))
1939 /* Disable interruption */
1940 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1942 /* Disable CRYP */
1943 __HAL_CRYP_DISABLE(hcryp);
1945 /* Process unlocked */
1946 __HAL_UNLOCK(hcryp);
1948 /* Change the CRYP state */
1949 hcryp->State = HAL_CRYP_STATE_READY;
1951 /* Call output transfer complete callback */
1952 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1953 /*Call registered Output complete callback*/
1954 hcryp->OutCpltCallback(hcryp);
1955 #else
1956 /*Call legacy weak Output complete callback*/
1957 HAL_CRYP_OutCpltCallback(hcryp);
1958 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1964 else
1966 /* Process unlocked */
1967 __HAL_UNLOCK(hcryp);
1968 /* Busy error code field */
1969 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1970 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1971 /*Call registered error callback*/
1972 hcryp->ErrorCallback(hcryp);
1973 #else
1974 /*Call legacy weak error callback*/
1975 HAL_CRYP_ErrorCallback(hcryp);
1976 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1981 * @brief Encryption in ECB/CBC & CTR Algorithm with AES Standard
1982 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
1983 * @param Timeout: specify Timeout value
1984 * @retval HAL status
1986 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
1988 uint16_t outcount; /* Temporary CrypOutCount Value */
1989 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1991 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1993 if (hcryp->KeyIVConfig == 1U)
1995 /* If the Key and IV configuration has to be done only once
1996 and if it has already been done, skip it */
1997 DoKeyIVConfig = 0U;
1999 else
2001 /* If the Key and IV configuration has to be done only once
2002 and if it has not been done already, do it and set KeyIVConfig
2003 to keep track it won't have to be done again next time */
2004 hcryp->KeyIVConfig = 1U;
2008 if (DoKeyIVConfig == 1U)
2010 /* Set the Key*/
2011 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2013 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2015 /* Set the Initialization Vector*/
2016 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2017 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2018 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2019 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2021 } /* if (DoKeyIVConfig == 1U) */
2023 /* Set the phase */
2024 hcryp->Phase = CRYP_PHASE_PROCESS;
2026 /* Enable CRYP */
2027 __HAL_CRYP_ENABLE(hcryp);
2028 /*Temporary CrypOutCount Value*/
2029 outcount = hcryp->CrypOutCount;
2031 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2033 /* Write plain Ddta and get cipher data */
2034 CRYP_AES_ProcessData(hcryp, Timeout);
2035 /*Temporary CrypOutCount Value*/
2036 outcount = hcryp->CrypOutCount;
2039 /* Disable CRYP */
2040 __HAL_CRYP_DISABLE(hcryp);
2042 /* Change the CRYP state */
2043 hcryp->State = HAL_CRYP_STATE_READY;
2045 /* Return function status */
2046 return HAL_OK;
2050 * @brief Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2051 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2052 * the configuration information for CRYP module
2053 * @retval HAL status
2055 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
2057 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2059 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2061 if (hcryp->KeyIVConfig == 1U)
2063 /* If the Key and IV configuration has to be done only once
2064 and if it has already been done, skip it */
2065 DoKeyIVConfig = 0U;
2067 else
2069 /* If the Key and IV configuration has to be done only once
2070 and if it has not been done already, do it and set KeyIVConfig
2071 to keep track it won't have to be done again next time */
2072 hcryp->KeyIVConfig = 1U;
2076 if (DoKeyIVConfig == 1U)
2078 /* Set the Key*/
2079 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2081 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2083 /* Set the Initialization Vector*/
2084 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2085 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2086 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2087 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2089 } /* if (DoKeyIVConfig == 1U) */
2091 /* Set the phase */
2092 hcryp->Phase = CRYP_PHASE_PROCESS;
2094 if (hcryp->Size != 0U)
2096 /* Enable interrupts */
2097 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2099 /* Enable CRYP */
2100 __HAL_CRYP_ENABLE(hcryp);
2102 else
2104 /* Change the CRYP state */
2105 hcryp->State = HAL_CRYP_STATE_READY;
2107 /* Process unlocked */
2108 __HAL_UNLOCK(hcryp);
2111 /* Return function status */
2112 return HAL_OK;
2116 * @brief Decryption in ECB/CBC & CTR mode with AES Standard
2117 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
2118 * @param Timeout: Specify Timeout value
2119 * @retval HAL status
2121 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2123 uint16_t outcount; /* Temporary CrypOutCount Value */
2124 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2126 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2128 if (hcryp->KeyIVConfig == 1U)
2130 /* If the Key and IV configuration has to be done only once
2131 and if it has already been done, skip it */
2132 DoKeyIVConfig = 0U;
2134 else
2136 /* If the Key and IV configuration has to be done only once
2137 and if it has not been done already, do it and set KeyIVConfig
2138 to keep track it won't have to be done again next time */
2139 hcryp->KeyIVConfig = 1U;
2143 if (DoKeyIVConfig == 1U)
2145 /* Key preparation for ECB/CBC */
2146 if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/
2148 /* change ALGOMODE to key preparation for decryption*/
2149 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2151 /* Set the Key*/
2152 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2154 /* Enable CRYP */
2155 __HAL_CRYP_ENABLE(hcryp);
2157 /* Wait for BUSY flag to be raised */
2158 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
2160 /* Disable the CRYP peripheral clock */
2161 __HAL_CRYP_DISABLE(hcryp);
2163 /* Change state */
2164 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2165 hcryp->State = HAL_CRYP_STATE_READY;
2167 /* Process unlocked */
2168 __HAL_UNLOCK(hcryp);
2169 return HAL_ERROR;
2171 /* Turn back to ALGOMODE of the configuration */
2172 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2174 else /*Algorithm CTR */
2176 /* Set the Key*/
2177 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2180 /* Set IV */
2181 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2183 /* Set the Initialization Vector*/
2184 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2185 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2186 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2187 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2189 } /* if (DoKeyIVConfig == 1U) */
2191 /* Set the phase */
2192 hcryp->Phase = CRYP_PHASE_PROCESS;
2194 /* Enable CRYP */
2195 __HAL_CRYP_ENABLE(hcryp);
2197 /*Temporary CrypOutCount Value*/
2198 outcount = hcryp->CrypOutCount;
2200 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2202 /* Write plain data and get cipher data */
2203 CRYP_AES_ProcessData(hcryp, Timeout);
2204 /*Temporary CrypOutCount Value*/
2205 outcount = hcryp->CrypOutCount;
2208 /* Disable CRYP */
2209 __HAL_CRYP_DISABLE(hcryp);
2211 /* Change the CRYP state */
2212 hcryp->State = HAL_CRYP_STATE_READY;
2214 /* Return function status */
2215 return HAL_OK;
2218 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2219 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2220 * the configuration information for CRYP module
2221 * @retval HAL status
2223 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
2225 __IO uint32_t count = 0U;
2226 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2228 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2230 if (hcryp->KeyIVConfig == 1U)
2232 /* If the Key and IV configuration has to be done only once
2233 and if it has already been done, skip it */
2234 DoKeyIVConfig = 0U;
2236 else
2238 /* If the Key and IV configuration has to be done only once
2239 and if it has not been done already, do it and set KeyIVConfig
2240 to keep track it won't have to be done again next time */
2241 hcryp->KeyIVConfig = 1U;
2245 if (DoKeyIVConfig == 1U)
2247 /* Key preparation for ECB/CBC */
2248 if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2250 /* change ALGOMODE to key preparation for decryption*/
2251 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2253 /* Set the Key*/
2254 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2256 /* Enable CRYP */
2257 __HAL_CRYP_ENABLE(hcryp);
2259 /* Wait for BUSY flag to be raised */
2260 count = CRYP_TIMEOUT_KEYPREPARATION;
2263 count-- ;
2264 if (count == 0U)
2266 /* Change state */
2267 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2268 hcryp->State = HAL_CRYP_STATE_READY;
2270 /* Process unlocked */
2271 __HAL_UNLOCK(hcryp);
2272 return HAL_ERROR;
2274 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2276 /* Turn back to ALGOMODE of the configuration */
2277 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2279 else /*Algorithm CTR */
2281 /* Set the Key*/
2282 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2285 /* Set IV */
2286 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2288 /* Set the Initialization Vector*/
2289 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2290 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2291 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2292 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2294 } /* if (DoKeyIVConfig == 1U) */
2296 /* Set the phase */
2297 hcryp->Phase = CRYP_PHASE_PROCESS;
2298 if (hcryp->Size != 0U)
2300 /* Enable interrupts */
2301 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2303 /* Enable CRYP */
2304 __HAL_CRYP_ENABLE(hcryp);
2306 else
2308 /* Process locked */
2309 __HAL_UNLOCK(hcryp);
2311 /* Change the CRYP state */
2312 hcryp->State = HAL_CRYP_STATE_READY;
2314 /* Return function status */
2315 return HAL_OK;
2318 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
2319 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2320 * the configuration information for CRYP module
2321 * @retval HAL status
2323 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
2325 __IO uint32_t count = 0U;
2326 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2328 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2330 if (hcryp->KeyIVConfig == 1U)
2332 /* If the Key and IV configuration has to be done only once
2333 and if it has already been done, skip it */
2334 DoKeyIVConfig = 0U;
2336 else
2338 /* If the Key and IV configuration has to be done only once
2339 and if it has not been done already, do it and set KeyIVConfig
2340 to keep track it won't have to be done again next time */
2341 hcryp->KeyIVConfig = 1U;
2345 if (DoKeyIVConfig == 1U)
2347 /* Key preparation for ECB/CBC */
2348 if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2350 /* change ALGOMODE to key preparation for decryption*/
2351 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2353 /* Set the Key*/
2354 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2356 /* Enable CRYP */
2357 __HAL_CRYP_ENABLE(hcryp);
2359 /* Wait for BUSY flag to be raised */
2360 count = CRYP_TIMEOUT_KEYPREPARATION;
2363 count-- ;
2364 if (count == 0U)
2366 /* Disable the CRYP peripheral clock */
2367 __HAL_CRYP_DISABLE(hcryp);
2369 /* Change state */
2370 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2371 hcryp->State = HAL_CRYP_STATE_READY;
2373 /* Process unlocked */
2374 __HAL_UNLOCK(hcryp);
2375 return HAL_ERROR;
2377 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2379 /* Turn back to ALGOMODE of the configuration */
2380 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2382 else /*Algorithm CTR */
2384 /* Set the Key*/
2385 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2388 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2390 /* Set the Initialization Vector*/
2391 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2392 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2393 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2394 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2396 } /* if (DoKeyIVConfig == 1U) */
2398 /* Set the phase */
2399 hcryp->Phase = CRYP_PHASE_PROCESS;
2401 if (hcryp->Size != 0U)
2403 /* Set the input and output addresses and start DMA transfer */
2404 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
2406 else
2408 /* Process unlocked */
2409 __HAL_UNLOCK(hcryp);
2411 /* Change the CRYP state */
2412 hcryp->State = HAL_CRYP_STATE_READY;
2415 /* Return function status */
2416 return HAL_OK;
2421 * @brief DMA CRYP input data process complete callback.
2422 * @param hdma: DMA handle
2423 * @retval None
2425 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
2427 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2429 /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit
2430 in the DMACR register */
2431 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
2433 /* Call input data transfer complete callback */
2434 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2435 /*Call registered Input complete callback*/
2436 hcryp->InCpltCallback(hcryp);
2437 #else
2438 /*Call legacy weak Input complete callback*/
2439 HAL_CRYP_InCpltCallback(hcryp);
2440 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2444 * @brief DMA CRYP output data process complete callback.
2445 * @param hdma: DMA handle
2446 * @retval None
2448 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
2450 uint32_t count;
2451 uint32_t npblb;
2452 uint32_t lastwordsize;
2453 uint32_t temp; /* Temporary CrypOutBuff */
2454 uint32_t temp_cr_algodir;
2455 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2458 /* Disable the DMA transfer for output FIFO */
2459 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
2461 /* Last block transfer in case of GCM or CCM with Size not %16*/
2462 if (((hcryp->Size) % 16U) != 0U)
2464 /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA */
2465 hcryp->CrypInCount = (hcryp->Size / 16U) * 4U ;
2466 hcryp->CrypOutCount = hcryp->CrypInCount;
2468 /* Compute the number of padding bytes in last block of payload */
2469 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
2471 #if !defined (CRYP_VER_2_2)
2472 if (hcryp->Version >= REV_ID_B)
2473 #endif /*End of not defined CRYP_VER_2_2*/
2475 /* Case of AES GCM payload encryption or AES CCM payload decryption to get right tag */
2476 temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
2477 if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
2478 ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
2480 /* Disable the CRYP */
2481 __HAL_CRYP_DISABLE(hcryp);
2483 /* Specify the number of non-valid bytes using NPBLB register*/
2484 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
2486 /* Enable CRYP to start the final phase */
2487 __HAL_CRYP_ENABLE(hcryp);
2491 /* Number of valid words (lastwordsize) in last block */
2492 if ((npblb % 4U) == 0U)
2494 lastwordsize = (16U - npblb) / 4U;
2496 else
2498 lastwordsize = ((16U - npblb) / 4U) + 1U;
2500 /* Write the last input block in the IN FIFO */
2501 for (count = 0U; count < lastwordsize; count ++)
2503 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2504 hcryp->CrypInCount++;
2506 /* Pad the data with zeros to have a complete block */
2507 while (count < 4U)
2509 hcryp->Instance->DIN = 0U;
2510 count++;
2512 /* Wait for OFNE flag to be raised */
2513 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
2516 count-- ;
2517 if (count == 0U)
2519 /* Disable the CRYP peripheral clock */
2520 __HAL_CRYP_DISABLE(hcryp);
2522 /* Change state */
2523 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2524 hcryp->State = HAL_CRYP_STATE_READY;
2526 /* Process unlocked */
2527 __HAL_UNLOCK(hcryp);
2528 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2529 /*Call registered error callback*/
2530 hcryp->ErrorCallback(hcryp);
2531 #else
2532 /*Call legacy weak error callback*/
2533 HAL_CRYP_ErrorCallback(hcryp);
2534 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2536 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
2538 /*Read the output block from the output FIFO */
2539 for (count = 0U; count < 4U; count++)
2541 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
2542 temp = hcryp->Instance->DOUT;
2544 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2545 hcryp->CrypOutCount++;
2547 } /*End of last block transfer in case of GCM or CCM */
2549 if ((hcryp->Init.Algorithm & CRYP_AES_GCM) != CRYP_AES_GCM)
2551 /* Disable CRYP (not allowed in GCM)*/
2552 __HAL_CRYP_DISABLE(hcryp);
2555 /* Change the CRYP state to ready */
2556 hcryp->State = HAL_CRYP_STATE_READY;
2558 /* Process unlocked */
2559 __HAL_UNLOCK(hcryp);
2561 /* Call output data transfer complete callback */
2562 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2563 /*Call registered Output complete callback*/
2564 hcryp->OutCpltCallback(hcryp);
2565 #else
2566 /*Call legacy weak Output complete callback*/
2567 HAL_CRYP_OutCpltCallback(hcryp);
2568 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2572 * @brief DMA CRYP communication error callback.
2573 * @param hdma: DMA handle
2574 * @retval None
2576 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
2578 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2580 /* Change the CRYP peripheral state */
2581 hcryp->State = HAL_CRYP_STATE_READY;
2583 /* DMA error code field */
2584 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2586 /* Call error callback */
2587 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2588 /*Call registered error callback*/
2589 hcryp->ErrorCallback(hcryp);
2590 #else
2591 /*Call legacy weak error callback*/
2592 HAL_CRYP_ErrorCallback(hcryp);
2593 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2597 * @brief Set the DMA configuration and start the DMA transfer
2598 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2599 * the configuration information for CRYP module
2600 * @param inputaddr: address of the input buffer
2601 * @param Size: size of the input buffer, must be a multiple of 16.
2602 * @param outputaddr: address of the output buffer
2603 * @retval None
2605 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2607 /* Set the CRYP DMA transfer complete callback */
2608 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2610 /* Set the DMA input error callback */
2611 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2613 /* Set the CRYP DMA transfer complete callback */
2614 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2616 /* Set the DMA output error callback */
2617 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2619 /* Enable CRYP */
2620 __HAL_CRYP_ENABLE(hcryp);
2622 /* Enable the input DMA Stream */
2623 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DIN, Size) != HAL_OK)
2625 /* DMA error code field */
2626 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2628 /* Call error callback */
2629 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2630 /*Call registered error callback*/
2631 hcryp->ErrorCallback(hcryp);
2632 #else
2633 /*Call legacy weak error callback*/
2634 HAL_CRYP_ErrorCallback(hcryp);
2635 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2638 /* Enable the output DMA Stream */
2639 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size) != HAL_OK)
2641 /* DMA error code field */
2642 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2644 /* Call error callback */
2645 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2646 /*Call registered error callback*/
2647 hcryp->ErrorCallback(hcryp);
2648 #else
2649 /*Call legacy weak error callback*/
2650 HAL_CRYP_ErrorCallback(hcryp);
2651 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2653 /* Enable In/Out DMA request */
2654 hcryp->Instance->DMACR = CRYP_DMACR_DOEN | CRYP_DMACR_DIEN;
2658 * @brief Process Data: Write Input data in polling mode and used in AES functions.
2659 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2660 * the configuration information for CRYP module
2661 * @param Timeout: Specify Timeout value
2662 * @retval None
2664 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2667 uint32_t temp[4]; /* Temporary CrypOutBuff */
2668 uint16_t incount; /* Temporary CrypInCount Value */
2669 uint16_t outcount; /* Temporary CrypOutCount Value */
2670 uint32_t i;
2672 /*Temporary CrypOutCount Value*/
2673 incount = hcryp->CrypInCount;
2675 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < ((hcryp->Size) / 4U)))
2677 /* Write the input block in the IN FIFO */
2678 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2679 hcryp->CrypInCount++;
2680 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2681 hcryp->CrypInCount++;
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++;
2688 /* Wait for OFNE flag to be raised */
2689 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
2691 /* Disable the CRYP peripheral clock */
2692 __HAL_CRYP_DISABLE(hcryp);
2694 /* Change state & error code*/
2695 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2696 hcryp->State = HAL_CRYP_STATE_READY;
2698 /* Process unlocked */
2699 __HAL_UNLOCK(hcryp);
2700 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2701 /*Call registered error callback*/
2702 hcryp->ErrorCallback(hcryp);
2703 #else
2704 /*Call legacy weak error callback*/
2705 HAL_CRYP_ErrorCallback(hcryp);
2706 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2708 /*Temporary CrypOutCount Value*/
2709 outcount = hcryp->CrypOutCount;
2711 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < ((hcryp->Size) / 4U)))
2713 /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
2714 for (i = 0U; i < 4U; i++)
2716 temp[i] = hcryp->Instance->DOUT;
2718 i = 0U;
2719 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
2721 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2722 hcryp->CrypOutCount++;
2723 i++;
2729 * @brief Handle CRYP block input/output data handling under interruption.
2730 * @note The function is called under interruption only, once
2731 * interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
2732 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2733 * the configuration information for CRYP module.
2734 * @retval HAL status
2736 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
2738 uint32_t temp[4]; /* Temporary CrypOutBuff */
2739 uint16_t incount; /* Temporary CrypInCount Value */
2740 uint16_t outcount; /* Temporary CrypOutCount Value */
2741 uint32_t i;
2743 if (hcryp->State == HAL_CRYP_STATE_BUSY)
2745 /*Temporary CrypOutCount Value*/
2746 incount = hcryp->CrypInCount;
2748 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
2750 /* Write the input block in the IN FIFO */
2751 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2752 hcryp->CrypInCount++;
2753 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2754 hcryp->CrypInCount++;
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 if (hcryp->CrypInCount == (hcryp->Size / 4U))
2761 /* Disable interrupts */
2762 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
2764 /* Call the input data transfer complete callback */
2765 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2766 /*Call registered Input complete callback*/
2767 hcryp->InCpltCallback(hcryp);
2768 #else
2769 /*Call legacy weak Input complete callback*/
2770 HAL_CRYP_InCpltCallback(hcryp);
2771 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2775 /*Temporary CrypOutCount Value*/
2776 outcount = hcryp->CrypOutCount;
2778 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
2780 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
2781 for (i = 0U; i < 4U; i++)
2783 temp[i] = hcryp->Instance->DOUT;
2785 i = 0U;
2786 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
2788 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2789 hcryp->CrypOutCount++;
2790 i++;
2792 if (hcryp->CrypOutCount == (hcryp->Size / 4U))
2794 /* Disable interrupts */
2795 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
2797 /* Change the CRYP state */
2798 hcryp->State = HAL_CRYP_STATE_READY;
2800 /* Disable CRYP */
2801 __HAL_CRYP_DISABLE(hcryp);
2803 /* Process unlocked */
2804 __HAL_UNLOCK(hcryp);
2806 /* Call output transfer complete callback */
2807 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2808 /*Call registered Output complete callback*/
2809 hcryp->OutCpltCallback(hcryp);
2810 #else
2811 /*Call legacy weak Output complete callback*/
2812 HAL_CRYP_OutCpltCallback(hcryp);
2813 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2817 else
2819 /* Process unlocked */
2820 __HAL_UNLOCK(hcryp);
2821 /* Busy error code field */
2822 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
2823 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2824 /*Call registered error callback*/
2825 hcryp->ErrorCallback(hcryp);
2826 #else
2827 /*Call legacy weak error callback*/
2828 HAL_CRYP_ErrorCallback(hcryp);
2829 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2834 * @brief Writes Key in Key registers.
2835 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2836 * the configuration information for CRYP module
2837 * @param KeySize: Size of Key
2838 * @retval None
2840 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
2842 switch (KeySize)
2844 case CRYP_KEYSIZE_256B:
2845 hcryp->Instance->K0LR = *(uint32_t *)(hcryp->Init.pKey);
2846 hcryp->Instance->K0RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2847 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2848 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2849 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2850 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2851 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 6);
2852 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 7);
2853 break;
2854 case CRYP_KEYSIZE_192B:
2855 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
2856 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2857 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2858 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2859 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2860 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2861 break;
2862 case CRYP_KEYSIZE_128B:
2863 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey);
2864 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2865 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2866 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2868 break;
2869 default:
2870 break;
2875 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
2876 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2877 * the configuration information for CRYP module
2878 * @param Timeout: Timeout duration
2879 * @retval HAL status
2881 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2883 uint32_t tickstart;
2884 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
2885 uint32_t npblb ;
2886 uint32_t temp[4]; /* Temporary CrypOutBuff */
2887 uint32_t index ;
2888 uint32_t lastwordsize ;
2889 uint16_t outcount; /* Temporary CrypOutCount Value */
2890 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2892 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2894 if (hcryp->KeyIVConfig == 1U)
2896 /* If the Key and IV configuration has to be done only once
2897 and if it has already been done, skip it */
2898 DoKeyIVConfig = 0U;
2899 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
2901 else
2903 /* If the Key and IV configuration has to be done only once
2904 and if it has not been done already, do it and set KeyIVConfig
2905 to keep track it won't have to be done again next time */
2906 hcryp->KeyIVConfig = 1U;
2907 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
2910 else
2912 hcryp->SizesSum = hcryp->Size;
2915 if (DoKeyIVConfig == 1U)
2917 /* Reset CrypHeaderCount */
2918 hcryp->CrypHeaderCount = 0U;
2920 /****************************** Init phase **********************************/
2922 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2924 /* Set the key */
2925 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2927 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
2928 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2929 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2930 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2931 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2933 /* Enable the CRYP peripheral */
2934 __HAL_CRYP_ENABLE(hcryp);
2936 /* Get tick */
2937 tickstart = HAL_GetTick();
2939 /*Wait for the CRYPEN bit to be cleared*/
2940 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2942 /* Check for the Timeout */
2943 if (Timeout != HAL_MAX_DELAY)
2945 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2947 /* Disable the CRYP peripheral clock */
2948 __HAL_CRYP_DISABLE(hcryp);
2950 /* Change state */
2951 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2952 hcryp->State = HAL_CRYP_STATE_READY;
2954 /* Process unlocked */
2955 __HAL_UNLOCK(hcryp);
2956 return HAL_ERROR;
2961 /************************ Header phase *************************************/
2963 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
2965 return HAL_ERROR;
2968 /*************************Payload phase ************************************/
2970 /* Set the phase */
2971 hcryp->Phase = CRYP_PHASE_PROCESS;
2973 /* Disable the CRYP peripheral */
2974 __HAL_CRYP_DISABLE(hcryp);
2976 #if !defined (CRYP_VER_2_2)
2977 if (hcryp->Version >= REV_ID_B)
2978 #endif /*End of not defined CRYP_VER_2_2*/
2980 /* Set to 0 the number of non-valid bytes using NPBLB register*/
2981 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
2984 /* Select payload phase once the header phase is performed */
2985 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
2987 /* Enable the CRYP peripheral */
2988 __HAL_CRYP_ENABLE(hcryp);
2989 } /* if (DoKeyIVConfig == 1U) */
2991 if ((hcryp->Size % 16U) != 0U)
2993 /* recalculate wordsize */
2994 wordsize = ((wordsize / 4U) * 4U) ;
2997 /* Get tick */
2998 tickstart = HAL_GetTick();
2999 /*Temporary CrypOutCount Value*/
3000 outcount = hcryp->CrypOutCount;
3002 /* Write input data and get output Data */
3003 while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3005 /* Write plain data and get cipher data */
3006 CRYP_AES_ProcessData(hcryp, Timeout);
3008 /*Temporary CrypOutCount Value*/
3009 outcount = hcryp->CrypOutCount;
3011 /* Check for the Timeout */
3012 if (Timeout != HAL_MAX_DELAY)
3014 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3016 /* Disable the CRYP peripheral clock */
3017 __HAL_CRYP_DISABLE(hcryp);
3019 /* Change state & error code */
3020 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3021 hcryp->State = HAL_CRYP_STATE_READY;
3023 /* Process unlocked */
3024 __HAL_UNLOCK(hcryp);
3025 return HAL_ERROR;
3030 if ((hcryp->Size % 16U) != 0U)
3033 #if !defined (CRYP_VER_2_2)
3034 if (hcryp->Version >= REV_ID_B)
3035 #endif /*End of not defined CRYP_VER_2_2*/
3037 /* Compute the number of padding bytes in last block of payload */
3038 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3040 /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3041 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3043 /* Disable the CRYP */
3044 __HAL_CRYP_DISABLE(hcryp);
3046 /* Specify the number of non-valid bytes using NPBLB register*/
3047 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3049 /* Enable CRYP to start the final phase */
3050 __HAL_CRYP_ENABLE(hcryp);
3052 /* Number of valid words (lastwordsize) in last block */
3053 if ((npblb % 4U) == 0U)
3055 lastwordsize = (16U - npblb) / 4U;
3057 else
3059 lastwordsize = ((16U - npblb) / 4U) + 1U;
3062 /* Write the last input block in the IN FIFO */
3063 for (index = 0U; index < lastwordsize; index ++)
3065 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3066 hcryp->CrypInCount++;
3069 /* Pad the data with zeros to have a complete block */
3070 while (index < 4U)
3072 hcryp->Instance->DIN = 0U;
3073 index++;
3076 /* Wait for OFNE flag to be raised */
3077 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3079 /* Disable the CRYP peripheral clock */
3080 __HAL_CRYP_DISABLE(hcryp);
3082 /* Change state */
3083 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3084 hcryp->State = HAL_CRYP_STATE_READY;
3086 /* Process Unlocked */
3087 __HAL_UNLOCK(hcryp);
3088 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3089 /*Call registered error callback*/
3090 hcryp->ErrorCallback(hcryp);
3091 #else
3092 /*Call legacy weak error callback*/
3093 HAL_CRYP_ErrorCallback(hcryp);
3094 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3097 /*Read the output block from the output FIFO */
3098 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3100 for (index = 0U; index < 4U; index++)
3102 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3103 temp[index] = hcryp->Instance->DOUT;
3105 for (index=0; index<lastwordsize; index++)
3107 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
3108 hcryp->CrypOutCount++;
3112 #if !defined (CRYP_VER_2_2)
3113 else /* Workaround to be used */
3115 /* Workaround 2 for STM32H7 below rev.B To generate correct TAG only when size of the last block of
3116 payload is inferior to 128 bits, in case of GCM encryption or CCM decryption*/
3117 CRYP_Workaround(hcryp, Timeout);
3118 } /* end of NPBLB or Workaround*/
3119 #endif /*End of not defined CRYP_VER_2_2*/
3122 /* Return function status */
3123 return HAL_OK;
3127 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
3128 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3129 * the configuration information for CRYP module
3130 * @retval HAL status
3132 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3134 __IO uint32_t count = 0U;
3135 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3137 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3139 if (hcryp->KeyIVConfig == 1U)
3141 /* If the Key and IV configuration has to be done only once
3142 and if it has already been done, skip it */
3143 DoKeyIVConfig = 0U;
3144 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3146 else
3148 /* If the Key and IV configuration has to be done only once
3149 and if it has not been done already, do it and set KeyIVConfig
3150 to keep track it won't have to be done again next time */
3151 hcryp->KeyIVConfig = 1U;
3152 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3155 else
3157 hcryp->SizesSum = hcryp->Size;
3160 /* Configure Key, IV and process message (header and payload) */
3161 if (DoKeyIVConfig == 1U)
3163 /* Reset CrypHeaderCount */
3164 hcryp->CrypHeaderCount = 0U;
3166 /******************************* Init phase *********************************/
3168 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3170 /* Set the key */
3171 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3173 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3174 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3175 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3176 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3177 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3179 /* Enable the CRYP peripheral */
3180 __HAL_CRYP_ENABLE(hcryp);
3182 /*Wait for the CRYPEN bit to be cleared*/
3183 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3186 count-- ;
3187 if (count == 0U)
3189 /* Disable the CRYP peripheral clock */
3190 __HAL_CRYP_DISABLE(hcryp);
3192 /* Change state */
3193 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3194 hcryp->State = HAL_CRYP_STATE_READY;
3196 /* Process unlocked */
3197 __HAL_UNLOCK(hcryp);
3198 return HAL_ERROR;
3200 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3202 /***************************** Header phase *********************************/
3204 /* Select header phase */
3205 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3206 } /* end of if (DoKeyIVConfig == 1U) */
3207 /* Enable interrupts */
3208 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3210 /* Enable CRYP */
3211 __HAL_CRYP_ENABLE(hcryp);
3213 /* Return function status */
3214 return HAL_OK;
3219 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
3220 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3221 * the configuration information for CRYP module
3222 * @retval HAL status
3224 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3226 __IO uint32_t count = 0U;
3227 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3228 uint32_t index;
3229 uint32_t npblb;
3230 uint32_t lastwordsize;
3231 uint32_t temp[4]; /* Temporary CrypOutBuff */
3232 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3234 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3236 if (hcryp->KeyIVConfig == 1U)
3238 /* If the Key and IV configuration has to be done only once
3239 and if it has already been done, skip it */
3240 DoKeyIVConfig = 0U;
3241 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3243 else
3245 /* If the Key and IV configuration has to be done only once
3246 and if it has not been done already, do it and set KeyIVConfig
3247 to keep track it won't have to be done again next time */
3248 hcryp->KeyIVConfig = 1U;
3249 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3252 else
3254 hcryp->SizesSum = hcryp->Size;
3257 if (DoKeyIVConfig == 1U)
3259 /* Reset CrypHeaderCount */
3260 hcryp->CrypHeaderCount = 0U;
3262 /*************************** Init phase ************************************/
3264 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3266 /* Set the key */
3267 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3269 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3270 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3271 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3272 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3273 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3275 /* Enable the CRYP peripheral */
3276 __HAL_CRYP_ENABLE(hcryp);
3278 /*Wait for the CRYPEN bit to be cleared*/
3279 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3282 count-- ;
3283 if (count == 0U)
3285 /* Disable the CRYP peripheral clock */
3286 __HAL_CRYP_DISABLE(hcryp);
3288 /* Change state */
3289 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3290 hcryp->State = HAL_CRYP_STATE_READY;
3292 /* Process unlocked */
3293 __HAL_UNLOCK(hcryp);
3294 return HAL_ERROR;
3296 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3298 /************************ Header phase *************************************/
3300 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
3302 return HAL_ERROR;
3305 /************************ Payload phase ************************************/
3307 /* Set the phase */
3308 hcryp->Phase = CRYP_PHASE_PROCESS;
3310 /* Disable the CRYP peripheral */
3311 __HAL_CRYP_DISABLE(hcryp);
3313 #if !defined (CRYP_VER_2_2)
3314 if (hcryp->Version >= REV_ID_B)
3315 #endif /*End of not defined CRYP_VER_2_2*/
3317 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3318 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3321 /* Select payload phase once the header phase is performed */
3322 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3324 } /* if (DoKeyIVConfig == 1U) */
3326 if (hcryp->Size == 0U)
3328 /* Process unLocked */
3329 __HAL_UNLOCK(hcryp);
3331 /* Change the CRYP state and phase */
3332 hcryp->State = HAL_CRYP_STATE_READY;
3334 else if (hcryp->Size >= 16U)
3336 /* for STM32H7 below rev.B : Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption:
3337 Workaround is implemented in polling mode, so if last block of payload <128bit don't use DMA mode otherwise TAG is incorrectly generated */
3339 /*DMA transfer must not include the last block in case of Size is not %16 */
3340 wordsize = wordsize - (wordsize % 4U);
3342 /*DMA transfer */
3343 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
3345 else /* length of input data is < 16 */
3347 /* Compute the number of padding bytes in last block of payload */
3348 npblb = 16U - (uint32_t)hcryp->Size;
3350 #if !defined (CRYP_VER_2_2)
3351 if (hcryp->Version >= REV_ID_B)
3352 #endif /*End of not defined CRYP_VER_2_2*/
3354 /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3355 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3357 /* Specify the number of non-valid bytes using NPBLB register*/
3358 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3361 /* Enable CRYP to start the final phase */
3362 __HAL_CRYP_ENABLE(hcryp);
3364 /* Number of valid words (lastwordsize) in last block */
3365 if ((npblb % 4U) == 0U)
3367 lastwordsize = (16U - npblb) / 4U;
3369 else
3371 lastwordsize = ((16U - npblb) / 4U) + 1U;
3374 /* Write the last input block in the IN FIFO */
3375 for (index = 0; index < lastwordsize; index ++)
3377 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3378 hcryp->CrypInCount++;
3381 /* Pad the data with zeros to have a complete block */
3382 while (index < 4U)
3384 hcryp->Instance->DIN = 0U;
3385 index++;
3388 /* Wait for OFNE flag to be raised */
3389 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
3392 count-- ;
3393 if (count == 0U)
3395 /* Disable the CRYP peripheral clock */
3396 __HAL_CRYP_DISABLE(hcryp);
3398 /* Change state */
3399 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3400 hcryp->State = HAL_CRYP_STATE_READY;
3402 /* Process unlocked */
3403 __HAL_UNLOCK(hcryp);
3404 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3405 /*Call registered error callback*/
3406 hcryp->ErrorCallback(hcryp);
3407 #else
3408 /*Call legacy weak error callback*/
3409 HAL_CRYP_ErrorCallback(hcryp);
3410 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3412 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
3414 /*Read the output block from the output FIFO */
3415 for (index = 0U; index < 4U; index++)
3417 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3418 temp[index] = hcryp->Instance->DOUT;
3420 for (index=0; index<lastwordsize; index++)
3422 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3423 hcryp->CrypOutCount++;
3426 /* Change the CRYP state to ready */
3427 hcryp->State = HAL_CRYP_STATE_READY;
3429 /* Process unlocked */
3430 __HAL_UNLOCK(hcryp);
3433 /* Return function status */
3434 return HAL_OK;
3439 * @brief AES CCM encryption/decryption processing in polling mode
3440 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3441 * the configuration information for CRYP module
3442 * @param Timeout: Timeout duration
3443 * @retval HAL status
3445 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3447 uint32_t tickstart;
3448 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
3449 uint32_t npblb ;
3450 uint32_t lastwordsize ;
3451 uint32_t temp[4] ; /* Temporary CrypOutBuff */
3452 uint32_t index ;
3453 uint16_t outcount; /* Temporary CrypOutCount Value */
3454 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3456 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3458 if (hcryp->KeyIVConfig == 1U)
3460 /* If the Key and IV configuration has to be done only once
3461 and if it has already been done, skip it */
3462 DoKeyIVConfig = 0U;
3463 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3465 else
3467 /* If the Key and IV configuration has to be done only once
3468 and if it has not been done already, do it and set KeyIVConfig
3469 to keep track it won't have to be done again next time */
3470 hcryp->KeyIVConfig = 1U;
3471 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3474 else
3476 hcryp->SizesSum = hcryp->Size;
3479 if (DoKeyIVConfig == 1U)
3481 /* Reset CrypHeaderCount */
3482 hcryp->CrypHeaderCount = 0U;
3484 /********************** Init phase ******************************************/
3486 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3488 /* Set the key */
3489 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3491 /* Set the initialization vector (IV) with CTR1 information */
3492 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3493 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3494 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3495 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
3497 /* Enable the CRYP peripheral */
3498 __HAL_CRYP_ENABLE(hcryp);
3500 #if defined (CRYP_VER_2_2)
3502 /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/
3503 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3504 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3505 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3506 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3508 #else
3509 if (hcryp->Version >= REV_ID_B)
3511 /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/
3512 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3513 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3514 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3515 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3517 else /* data has to be swapped according to the DATATYPE */
3519 if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
3521 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3522 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3523 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3524 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3526 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
3528 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3529 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3530 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3531 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3533 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
3535 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3536 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3537 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3538 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3540 else
3542 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3543 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3544 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3545 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3548 #endif
3549 /* Get tick */
3550 tickstart = HAL_GetTick();
3552 /*Wait for the CRYPEN bit to be cleared*/
3553 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
3555 /* Check for the Timeout */
3556 if (Timeout != HAL_MAX_DELAY)
3558 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3560 /* Disable the CRYP peripheral clock */
3561 __HAL_CRYP_DISABLE(hcryp);
3563 /* Change state */
3564 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3565 hcryp->State = HAL_CRYP_STATE_READY;
3567 /* Process unlocked */
3568 __HAL_UNLOCK(hcryp);
3569 return HAL_ERROR;
3574 /************************* Header phase *************************************/
3575 /* Header block(B1) : associated data length expressed in bytes concatenated
3576 with Associated Data (A)*/
3578 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
3580 return HAL_ERROR;
3582 /********************** Payload phase ***************************************/
3584 /* Set the phase */
3585 hcryp->Phase = CRYP_PHASE_PROCESS;
3587 /* Disable the CRYP peripheral */
3588 __HAL_CRYP_DISABLE(hcryp);
3589 #if !defined (CRYP_VER_2_2)
3590 if (hcryp->Version >= REV_ID_B)
3591 #endif /*End of not defined CRYP_VER_2_2*/
3593 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3594 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3597 /* Select payload phase once the header phase is performed */
3598 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3600 /* Enable the CRYP peripheral */
3601 __HAL_CRYP_ENABLE(hcryp);
3603 } /* if (DoKeyIVConfig == 1U) */
3605 if ((hcryp->Size % 16U) != 0U)
3607 /* recalculate wordsize */
3608 wordsize = ((wordsize / 4U) * 4U) ;
3610 /* Get tick */
3611 tickstart = HAL_GetTick();
3613 /*Temporary CrypOutCount Value*/
3614 outcount = hcryp->CrypOutCount;
3616 /* Write input data and get output data */
3617 while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3619 /* Write plain data and get cipher data */
3620 CRYP_AES_ProcessData(hcryp, Timeout);
3622 /*Temporary CrypOutCount Value*/
3623 outcount = hcryp->CrypOutCount;
3625 /* Check for the Timeout */
3626 if (Timeout != HAL_MAX_DELAY)
3628 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3630 /* Disable the CRYP peripheral clock */
3631 __HAL_CRYP_DISABLE(hcryp);
3633 /* Change state */
3634 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3635 hcryp->State = HAL_CRYP_STATE_READY;
3637 /* Process unlocked */
3638 __HAL_UNLOCK(hcryp);
3639 return HAL_ERROR;
3644 if ((hcryp->Size % 16U) != 0U)
3646 #if !defined (CRYP_VER_2_2)
3647 if (hcryp->Version >= REV_ID_B)
3648 #endif /*End of not defined CRYP_VER_2_2*/
3650 /* Compute the number of padding bytes in last block of payload */
3651 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3653 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
3655 /* Disable the CRYP */
3656 __HAL_CRYP_DISABLE(hcryp);
3658 /* Set Npblb in case of AES CCM payload decryption to get right tag */
3659 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3661 /* Enable CRYP to start the final phase */
3662 __HAL_CRYP_ENABLE(hcryp);
3665 /* Number of valid words (lastwordsize) in last block */
3666 if ((npblb % 4U) == 0U)
3668 lastwordsize = (16U - npblb) / 4U;
3670 else
3672 lastwordsize = ((16U - npblb) / 4U) + 1U;
3675 /* Write the last input block in the IN FIFO */
3676 for (index = 0U; index < lastwordsize; index ++)
3678 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3679 hcryp->CrypInCount++;
3682 /* Pad the data with zeros to have a complete block */
3683 while (index < 4U)
3685 hcryp->Instance->DIN = 0U;
3686 index++;
3689 /* Wait for OFNE flag to be raised */
3690 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3692 /* Disable the CRYP peripheral clock */
3693 __HAL_CRYP_DISABLE(hcryp);
3695 /* Change state */
3696 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3697 hcryp->State = HAL_CRYP_STATE_READY;
3699 /* Process Unlocked */
3700 __HAL_UNLOCK(hcryp);
3701 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3702 /*Call registered error callback*/
3703 hcryp->ErrorCallback(hcryp);
3704 #else
3705 /*Call legacy weak error callback*/
3706 HAL_CRYP_ErrorCallback(hcryp);
3707 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3710 /*Read the output block from the output FIFO */
3711 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3713 for (index = 0U; index < 4U; index++)
3715 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
3716 temp[index] = hcryp->Instance->DOUT;
3718 for (index=0; index<lastwordsize; index++)
3720 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3721 hcryp->CrypOutCount++;
3725 #if !defined (CRYP_VER_2_2)
3726 else /* No NPBLB, Workaround to be used */
3728 /* CRYP Workaround : CRYP1 generates correct TAG during CCM decryption only when ciphertext blocks size is multiple of
3729 128 bits. If lthe size of the last block of payload is inferior to 128 bits, when CCM decryption
3730 is selected, then the TAG message will be wrong.*/
3731 CRYP_Workaround(hcryp, Timeout);
3733 #endif /*End of not defined CRYP_VER_2_2*/
3736 /* Return function status */
3737 return HAL_OK;
3741 * @brief AES CCM encryption/decryption process in interrupt mode
3742 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3743 * the configuration information for CRYP module
3744 * @retval HAL status
3746 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3748 __IO uint32_t count = 0U;
3749 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3751 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3753 if (hcryp->KeyIVConfig == 1U)
3755 /* If the Key and IV configuration has to be done only once
3756 and if it has already been done, skip it */
3757 DoKeyIVConfig = 0U;
3758 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3760 else
3762 /* If the Key and IV configuration has to be done only once
3763 and if it has not been done already, do it and set KeyIVConfig
3764 to keep track it won't have to be done again next time */
3765 hcryp->KeyIVConfig = 1U;
3766 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3769 else
3771 hcryp->SizesSum = hcryp->Size;
3774 /* Configure Key, IV and process message (header and payload) */
3775 if (DoKeyIVConfig == 1U)
3777 /* Reset CrypHeaderCount */
3778 hcryp->CrypHeaderCount = 0U;
3780 /************ Init phase ************/
3782 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3784 /* Set the key */
3785 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3787 /* Set the initialization vector (IV) with CTR1 information */
3788 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3789 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3790 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3791 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
3793 /* Enable the CRYP peripheral */
3794 __HAL_CRYP_ENABLE(hcryp);
3796 /*Write the B0 packet into CRYP_DR*/
3797 #if !defined (CRYP_VER_2_2)
3798 if (hcryp->Version >= REV_ID_B)
3799 #endif /*End of not defined CRYP_VER_2_2*/
3801 /* for STM32H7 rev.B and above data has not to be swapped */
3802 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3803 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3804 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3805 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3807 #if !defined (CRYP_VER_2_2)
3808 else /* data has to be swapped according to the DATATYPE */
3810 if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
3812 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3813 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3814 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3815 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3817 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
3819 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3820 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3821 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3822 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3824 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
3826 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3827 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3828 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3829 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3831 else
3833 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3834 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3835 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3836 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3839 #endif /*End of not defined CRYP_VER_2_2*/
3840 /*Wait for the CRYPEN bit to be cleared*/
3841 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3844 count-- ;
3845 if (count == 0U)
3847 /* Disable the CRYP peripheral clock */
3848 __HAL_CRYP_DISABLE(hcryp);
3850 /* Change state */
3851 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3852 hcryp->State = HAL_CRYP_STATE_READY;
3854 /* Process unlocked */
3855 __HAL_UNLOCK(hcryp);
3856 return HAL_ERROR;
3858 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3860 /* Select header phase */
3861 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3862 } /* end of if (DoKeyIVConfig == 1U) */
3863 /* Enable interrupts */
3864 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3866 /* Enable CRYP */
3867 __HAL_CRYP_ENABLE(hcryp);
3869 /* Return function status */
3870 return HAL_OK;
3873 * @brief AES CCM encryption/decryption process in DMA mode
3874 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3875 * the configuration information for CRYP module
3876 * @retval HAL status
3878 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3880 __IO uint32_t count = 0U;
3881 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3882 uint32_t index;
3883 uint32_t npblb;
3884 uint32_t lastwordsize;
3885 uint32_t temp[4]; /* Temporary CrypOutBuff */
3886 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3888 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3890 if (hcryp->KeyIVConfig == 1U)
3892 /* If the Key and IV configuration has to be done only once
3893 and if it has already been done, skip it */
3894 DoKeyIVConfig = 0U;
3895 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3897 else
3899 /* If the Key and IV configuration has to be done only once
3900 and if it has not been done already, do it and set KeyIVConfig
3901 to keep track it won't have to be done again next time */
3902 hcryp->KeyIVConfig = 1U;
3903 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3906 else
3908 hcryp->SizesSum = hcryp->Size;
3911 if (DoKeyIVConfig == 1U)
3913 /* Reset CrypHeaderCount */
3914 hcryp->CrypHeaderCount = 0U;
3916 /************************** Init phase **************************************/
3918 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3920 /* Set the key */
3921 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3923 /* Set the initialization vector (IV) with CTR1 information */
3924 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3925 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3926 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3927 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
3929 /* Enable the CRYP peripheral */
3930 __HAL_CRYP_ENABLE(hcryp);
3932 /*Write the B0 packet into CRYP_DR*/
3933 #if !defined (CRYP_VER_2_2)
3934 if (hcryp->Version >= REV_ID_B)
3935 #endif /*End of not defined CRYP_VER_2_2*/
3937 /* for STM32H7 rev.B and above data has not to be swapped */
3938 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3939 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3940 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3941 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3943 #if !defined (CRYP_VER_2_2)
3944 else /* data has to be swapped according to the DATATYPE */
3946 if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
3948 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3949 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3950 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3951 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3953 else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
3955 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3956 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3957 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3958 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3960 else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
3962 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3963 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3964 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3965 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3967 else
3969 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3970 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3971 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3972 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3975 #endif /*End of not defined CRYP_VER_2_2*/
3976 /*Wait for the CRYPEN bit to be cleared*/
3977 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3980 count-- ;
3981 if (count == 0U)
3983 /* Disable the CRYP peripheral clock */
3984 __HAL_CRYP_DISABLE(hcryp);
3986 /* Change state */
3987 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3988 hcryp->State = HAL_CRYP_STATE_READY;
3990 /* Process unlocked */
3991 __HAL_UNLOCK(hcryp);
3992 return HAL_ERROR;
3994 } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3996 /********************* Header phase *****************************************/
3998 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
4000 return HAL_ERROR;
4003 /******************** Payload phase *****************************************/
4005 /* Set the phase */
4006 hcryp->Phase = CRYP_PHASE_PROCESS;
4008 /* Disable the CRYP peripheral */
4009 __HAL_CRYP_DISABLE(hcryp);
4010 #if !defined (CRYP_VER_2_2)
4011 if (hcryp->Version >= REV_ID_B)
4012 #endif /*End of not defined CRYP_VER_2_2*/
4014 /* Set to 0 the number of non-valid bytes using NPBLB register*/
4015 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4018 /* Select payload phase once the header phase is performed */
4019 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4020 } /* if (DoKeyIVConfig == 1U) */
4022 if (hcryp->Size == 0U)
4024 /* Process unLocked */
4025 __HAL_UNLOCK(hcryp);
4027 /* Change the CRYP state and phase */
4028 hcryp->State = HAL_CRYP_STATE_READY;
4030 else if (hcryp->Size >= 16U)
4032 /* for STM32H7 below rev.B :: Size should be %4 otherwise Tag will be incorrectly generated for CCM Decryption, Workaround is implemented in polling mode*/
4033 /*DMA transfer must not include the last block in case of Size is not %16 */
4034 wordsize = wordsize - (wordsize % 4U);
4036 /*DMA transfer */
4037 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t) wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
4039 else /* length of input data is < 16U */
4041 /* Compute the number of padding bytes in last block of payload */
4042 npblb = 16U - (uint32_t)(hcryp->Size);
4044 #if !defined (CRYP_VER_2_2)
4045 if (hcryp->Version >= REV_ID_B)
4046 #endif /*End of not defined CRYP_VER_2_2*/
4048 /* Set Npblb in case of AES CCM payload decryption to get right tag*/
4049 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4051 /* Specify the number of non-valid bytes using NPBLB register*/
4052 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4055 /* Enable CRYP to start the final phase */
4056 __HAL_CRYP_ENABLE(hcryp);
4058 /* Number of valid words (lastwordsize) in last block */
4059 if ((npblb % 4U) == 0U)
4061 lastwordsize = (16U - npblb) / 4U;
4063 else
4065 lastwordsize = ((16U - npblb) / 4U) + 1U;
4068 /* Write the last input block in the IN FIFO */
4069 for (index = 0U; index < lastwordsize; index ++)
4071 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4072 hcryp->CrypInCount++;
4075 /* Pad the data with zeros to have a complete block */
4076 while (index < 4U)
4078 hcryp->Instance->DIN = 0U;
4079 index++;
4082 /* Wait for OFNE flag to be raised */
4083 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4086 count-- ;
4087 if (count == 0U)
4089 /* Disable the CRYP peripheral clock */
4090 __HAL_CRYP_DISABLE(hcryp);
4092 /* Change state */
4093 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4094 hcryp->State = HAL_CRYP_STATE_READY;
4096 /* Process unlocked */
4097 __HAL_UNLOCK(hcryp);
4098 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4099 /*Call registered error callback*/
4100 hcryp->ErrorCallback(hcryp);
4101 #else
4102 /*Call legacy weak error callback*/
4103 HAL_CRYP_ErrorCallback(hcryp);
4104 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4106 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
4108 /*Read the output block from the output FIFO */
4109 for (index = 0U; index < 4U; index++)
4111 /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
4112 temp[index] = hcryp->Instance->DOUT;
4114 for (index=0; index<lastwordsize; index++)
4116 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
4117 hcryp->CrypOutCount++;
4120 /* Change the CRYP state to ready */
4121 hcryp->State = HAL_CRYP_STATE_READY;
4123 /* Process unlocked */
4124 __HAL_UNLOCK(hcryp);
4127 /* Return function status */
4128 return HAL_OK;
4132 * @brief Sets the payload phase in interrupt mode
4133 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4134 * the configuration information for CRYP module
4135 * @retval state
4137 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
4139 uint32_t loopcounter;
4140 uint32_t temp[4]; /* Temporary CrypOutBuff */
4141 uint32_t lastwordsize;
4142 uint32_t npblb;
4143 uint32_t temp_cr_algodir;
4144 uint8_t negative = 0U;
4145 uint32_t i;
4147 /***************************** Payload phase *******************************/
4149 if ((hcryp->Size / 4U) < hcryp->CrypInCount)
4151 negative = 1U;
4154 if (hcryp->Size == 0U)
4156 /* Disable interrupts */
4157 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4159 /* Process unlocked */
4160 __HAL_UNLOCK(hcryp);
4162 /* Change the CRYP state */
4163 hcryp->State = HAL_CRYP_STATE_READY;
4166 else if ((((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) &&
4167 (negative == 0U))
4169 if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM)!= 0x0U)
4171 /* Write the input block in the IN FIFO */
4172 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4173 hcryp->CrypInCount++;
4174 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4175 hcryp->CrypInCount++;
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 if (((hcryp->Size / 4U) == hcryp->CrypInCount) && ((hcryp->Size % 16U) == 0U))
4182 /* Disable interrupts */
4183 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4184 /* Call the input data transfer complete callback */
4185 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4186 /*Call registered Input complete callback*/
4187 hcryp->InCpltCallback(hcryp);
4188 #else
4189 /*Call legacy weak Input complete callback*/
4190 HAL_CRYP_InCpltCallback(hcryp);
4191 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4194 if (hcryp->CrypOutCount < (hcryp->Size / 4U))
4196 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4198 /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
4199 for (i = 0U; i < 4U; i++)
4201 temp[i] = hcryp->Instance->DOUT;
4203 i = 0U;
4204 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
4206 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4207 hcryp->CrypOutCount++;
4208 i++;
4210 if (((hcryp->Size / 4U) == hcryp->CrypOutCount) && ((hcryp->Size % 16U) == 0U))
4212 /* Disable interrupts */
4213 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
4215 /* Change the CRYP state */
4216 hcryp->State = HAL_CRYP_STATE_READY;
4218 /* Disable CRYP */
4219 __HAL_CRYP_DISABLE(hcryp);
4221 /* Process unlocked */
4222 __HAL_UNLOCK(hcryp);
4224 /* Call output transfer complete callback */
4225 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4226 /*Call registered Output complete callback*/
4227 hcryp->OutCpltCallback(hcryp);
4228 #else
4229 /*Call legacy weak Output complete callback*/
4230 HAL_CRYP_OutCpltCallback(hcryp);
4231 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4237 else if ((hcryp->Size % 16U) != 0U)
4239 /* Set padding only in case of input fifo interrupt */
4240 if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM)!= 0x0U)
4242 /* Compute the number of padding bytes in last block of payload */
4243 npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4245 #if !defined (CRYP_VER_2_2)
4246 if (hcryp->Version >= REV_ID_B)
4247 #endif /*End of not defined CRYP_VER_2_2*/
4249 /* Set Npblb in case of AES GCM payload encryption and CCM decryption to get right tag */
4250 temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
4252 if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
4253 ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4255 /* Disable the CRYP */
4256 __HAL_CRYP_DISABLE(hcryp);
4258 /* Specify the number of non-valid bytes using NPBLB register*/
4259 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4261 /* Enable CRYP to start the final phase */
4262 __HAL_CRYP_ENABLE(hcryp);
4266 /* Number of valid words (lastwordsize) in last block */
4267 if ((npblb % 4U) == 0U)
4269 lastwordsize = (16U - npblb) / 4U;
4271 else
4273 lastwordsize = ((16U - npblb) / 4U) + 1U;
4276 /* Write the last input block in the IN FIFO */
4277 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4279 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4280 hcryp->CrypInCount++;
4282 /* Pad the data with zeros to have a complete block */
4283 while (loopcounter < 4U)
4285 hcryp->Instance->DIN = 0U;
4286 loopcounter++;
4289 /* Disable the input FIFO Interrupt */
4290 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4293 /*Read the output block from the output FIFO */
4294 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4296 for (i = 0U; i < 4U; i++)
4298 temp[i] = hcryp->Instance->DOUT;
4300 if (( (hcryp->Size)/4U)==0U)
4302 for (i = 0U; (uint16_t)i<((hcryp->Size)%4U); i++)
4304 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4305 hcryp->CrypOutCount++;
4308 i = 0U;
4309 while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
4311 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4312 hcryp->CrypOutCount++;
4313 i++;
4317 /* Disable the output FIFO Interrupt */
4318 if (hcryp->CrypOutCount >= ((hcryp->Size) / 4U))
4320 /* Disable interrupts */
4321 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI | CRYP_IT_INI);
4323 /* Change the CRYP peripheral state */
4324 hcryp->State = HAL_CRYP_STATE_READY;
4326 /* Process unlocked */
4327 __HAL_UNLOCK(hcryp);
4329 /* Call output transfer complete callback */
4330 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4331 /*Call registered Output complete callback*/
4332 hcryp->OutCpltCallback(hcryp);
4333 #else
4334 /*Call legacy weak Output complete callback*/
4335 HAL_CRYP_OutCpltCallback(hcryp);
4336 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4339 else
4341 /* Nothing to do */
4347 * @brief Sets the header phase in polling mode
4348 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4349 * the configuration information for CRYP module(Header & HeaderSize)
4350 * @param Timeout: Timeout value
4351 * @retval state
4353 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4355 uint32_t loopcounter;
4357 /***************************** Header phase for GCM/GMAC or CCM *********************************/
4359 if ((hcryp->Init.HeaderSize != 0U))
4361 /* Select header phase */
4362 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4364 /* Enable the CRYP peripheral */
4365 __HAL_CRYP_ENABLE(hcryp);
4367 if ((hcryp->Init.HeaderSize % 4U) == 0U)
4369 /* HeaderSize %4, no padding */
4370 for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4372 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4373 hcryp->CrypHeaderCount++ ;
4374 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4375 hcryp->CrypHeaderCount++ ;
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++ ;
4381 /* Wait for IFEM to be raised */
4382 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4384 /* Disable the CRYP peripheral clock */
4385 __HAL_CRYP_DISABLE(hcryp);
4387 /* Change state */
4388 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4389 hcryp->State = HAL_CRYP_STATE_READY;
4391 /* Process unlocked */
4392 __HAL_UNLOCK(hcryp);
4393 return HAL_ERROR;
4397 else
4399 /*Write header block in the IN FIFO without last block */
4400 for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U))); loopcounter += 4U)
4402 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4403 hcryp->CrypHeaderCount++ ;
4404 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4405 hcryp->CrypHeaderCount++ ;
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++ ;
4411 /* Wait for IFEM to be raised */
4412 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4414 /* Disable the CRYP peripheral clock */
4415 __HAL_CRYP_DISABLE(hcryp);
4417 /* Change state */
4418 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4419 hcryp->State = HAL_CRYP_STATE_READY;
4421 /* Process unlocked */
4422 __HAL_UNLOCK(hcryp);
4423 return HAL_ERROR;
4426 /* Last block optionally pad the data with zeros*/
4427 for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4429 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4430 hcryp->CrypHeaderCount++ ;
4432 while (loopcounter < 4U)
4434 /* pad the data with zeros to have a complete block */
4435 hcryp->Instance->DIN = 0x0U;
4436 loopcounter++;
4438 /* Wait for CCF IFEM to be raised */
4439 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4441 /* Disable the CRYP peripheral clock */
4442 __HAL_CRYP_DISABLE(hcryp);
4444 /* Change state */
4445 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4446 hcryp->State = HAL_CRYP_STATE_READY;
4448 /* Process unlocked */
4449 __HAL_UNLOCK(hcryp);
4450 return HAL_ERROR;
4453 /* Wait until the complete message has been processed */
4454 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
4456 /* Disable the CRYP peripheral clock */
4457 __HAL_CRYP_DISABLE(hcryp);
4459 /* Change state */
4460 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4461 hcryp->State = HAL_CRYP_STATE_READY;
4463 /* Process unlocked & return error */
4464 __HAL_UNLOCK(hcryp);
4465 return HAL_ERROR;
4468 /* Return function status */
4469 return HAL_OK;
4473 * @brief Sets the header phase when using DMA in process
4474 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4475 * the configuration information for CRYP module(Header & HeaderSize)
4476 * @retval None
4478 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
4480 __IO uint32_t count = 0U;
4481 uint32_t loopcounter;
4483 /***************************** Header phase for GCM/GMAC or CCM *********************************/
4484 if ((hcryp->Init.HeaderSize != 0U))
4486 /* Select header phase */
4487 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4489 /* Enable the CRYP peripheral */
4490 __HAL_CRYP_ENABLE(hcryp);
4492 if ((hcryp->Init.HeaderSize % 4U) == 0U)
4494 /* HeaderSize %4, no padding */
4495 for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4497 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4498 hcryp->CrypHeaderCount++ ;
4499 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4500 hcryp->CrypHeaderCount++ ;
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++ ;
4506 /* Wait for IFEM to be raised */
4507 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4510 count-- ;
4511 if (count == 0U)
4513 /* Disable the CRYP peripheral clock */
4514 __HAL_CRYP_DISABLE(hcryp);
4516 /* Change state */
4517 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4518 hcryp->State = HAL_CRYP_STATE_READY;
4520 /* Process unlocked */
4521 __HAL_UNLOCK(hcryp);
4522 return HAL_ERROR;
4524 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4527 else
4529 /*Write header block in the IN FIFO without last block */
4530 for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U))); loopcounter += 4U)
4532 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4533 hcryp->CrypHeaderCount++ ;
4534 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4535 hcryp->CrypHeaderCount++ ;
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++ ;
4541 /* Wait for IFEM to be raised */
4542 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4545 count-- ;
4546 if (count == 0U)
4548 /* Disable the CRYP peripheral clock */
4549 __HAL_CRYP_DISABLE(hcryp);
4551 /* Change state */
4552 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4553 hcryp->State = HAL_CRYP_STATE_READY;
4555 /* Process unlocked */
4556 __HAL_UNLOCK(hcryp);
4557 return HAL_ERROR;
4559 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4561 /* Last block optionally pad the data with zeros*/
4562 for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4564 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4565 hcryp->CrypHeaderCount++ ;
4567 while (loopcounter < 4U)
4569 /* Pad the data with zeros to have a complete block */
4570 hcryp->Instance->DIN = 0x0U;
4571 loopcounter++;
4573 /* Wait for IFEM to be raised */
4574 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4577 count-- ;
4578 if (count == 0U)
4580 /* Disable the CRYP peripheral clock */
4581 __HAL_CRYP_DISABLE(hcryp);
4582 /* Change state */
4583 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4584 hcryp->State = HAL_CRYP_STATE_READY;
4585 /* Process unlocked */
4586 __HAL_UNLOCK(hcryp);
4587 return HAL_ERROR;
4589 } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4591 /* Wait until the complete message has been processed */
4592 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4595 count-- ;
4596 if (count == 0U)
4598 /* Disable the CRYP peripheral clock */
4599 __HAL_CRYP_DISABLE(hcryp);
4600 /* Change state */
4601 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4602 hcryp->State = HAL_CRYP_STATE_READY;
4603 /* Process unlocked */
4604 __HAL_UNLOCK(hcryp);
4605 return HAL_ERROR;
4607 } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
4610 /* Return function status */
4611 return HAL_OK;
4615 * @brief Sets the header phase in interrupt mode
4616 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4617 * the configuration information for CRYP module(Header & HeaderSize)
4618 * @retval None
4620 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
4622 uint32_t loopcounter;
4624 /***************************** Header phase *********************************/
4626 if (hcryp->Init.HeaderSize == hcryp->CrypHeaderCount)
4628 /* Disable interrupts */
4629 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4631 /* Disable the CRYP peripheral */
4632 __HAL_CRYP_DISABLE(hcryp);
4634 #if !defined (CRYP_VER_2_2)
4635 if (hcryp->Version >= REV_ID_B)
4636 #endif /*End of not defined CRYP_VER_2_2*/
4638 /* Set to 0 the number of non-valid bytes using NPBLB register*/
4639 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4642 /* Set the phase */
4643 hcryp->Phase = CRYP_PHASE_PROCESS;
4645 /* Select payload phase once the header phase is performed */
4646 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4648 /* Enable Interrupts */
4649 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4651 /* Enable the CRYP peripheral */
4652 __HAL_CRYP_ENABLE(hcryp);
4654 else if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U)
4657 /* HeaderSize %4, no padding */
4658 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4659 hcryp->CrypHeaderCount++ ;
4660 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4661 hcryp->CrypHeaderCount++ ;
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++ ;
4667 else
4669 /* Last block optionally pad the data with zeros*/
4670 for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
4672 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4673 hcryp->CrypHeaderCount++ ;
4675 while (loopcounter < 4U)
4677 /* Pad the data with zeros to have a complete block */
4678 hcryp->Instance->DIN = 0x0U;
4679 loopcounter++;
4684 #if !defined (CRYP_VER_2_2)
4686 * @brief Workaround used for GCM/CCM mode.
4687 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4688 * the configuration information for CRYP module
4689 * @param Timeout: Timeout value
4690 * @retval None
4692 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4694 uint32_t iv1temp;
4695 uint32_t temp[4] = {0};
4696 uint32_t temp2[4] = {0};
4697 uint32_t intermediate_data[4] = {0};
4698 uint32_t index;
4699 uint32_t lastwordsize;
4700 uint32_t npblb;
4702 /* Compute the number of padding bytes in last block of payload */
4703 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4705 /* Number of valid words (lastwordsize) in last block */
4706 if ((npblb % 4U) == 0U)
4708 lastwordsize = (16U - npblb) / 4U;
4710 else
4712 lastwordsize = ((16U - npblb) / 4U) + 1U;
4715 /* Workaround 2, case GCM encryption */
4716 if (hcryp->Init.Algorithm == CRYP_AES_GCM)
4718 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4720 /*Workaround in order to properly compute authentication tags while doing
4721 a GCM encryption with the last block of payload size inferior to 128 bits*/
4722 /* Disable CRYP to start the final phase */
4723 __HAL_CRYP_DISABLE(hcryp);
4725 /*Update CRYP_IV1R register and ALGOMODE*/
4726 hcryp->Instance->IV1RR = ((hcryp->Instance->CSGCMCCM7R)-1U);
4727 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
4729 /* Enable CRYP to start the final phase */
4730 __HAL_CRYP_ENABLE(hcryp);
4733 for (index = 0; index < lastwordsize ; index ++)
4735 /* Write the last input block in the IN FIFO */
4736 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4737 hcryp->CrypInCount++;
4739 while (index < 4U)
4741 /* Pad the data with zeros to have a complete block */
4742 hcryp->Instance->DIN = 0U;
4743 index++;
4745 /* Wait for OFNE flag to be raised */
4746 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4748 /* Disable the CRYP peripheral clock */
4749 __HAL_CRYP_DISABLE(hcryp);
4751 /* Change state */
4752 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4753 hcryp->State = HAL_CRYP_STATE_READY;
4755 /* Process Unlocked */
4756 __HAL_UNLOCK(hcryp);
4757 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4758 /*Call registered error callback*/
4759 hcryp->ErrorCallback(hcryp);
4760 #else
4761 /*Call legacy weak error callback*/
4762 HAL_CRYP_ErrorCallback(hcryp);
4763 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4765 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4767 for (index = 0U; index < 4U; index++)
4769 /* Read the output block from the output FIFO */
4770 intermediate_data[index] = hcryp->Instance->DOUT;
4772 /* Intermediate data buffer to be used in for the workaround*/
4773 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
4774 hcryp->CrypOutCount++;
4778 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4780 /*workaround in order to properly compute authentication tags while doing
4781 a GCM encryption with the last block of payload size inferior to 128 bits*/
4782 /* Change the AES mode to GCM mode and Select Final phase */
4783 /* configured CHMOD GCM */
4784 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_GCM);
4786 /* configured final phase */
4787 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
4789 if ( (hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_32B)
4791 if ((npblb %4U)==1U)
4793 intermediate_data[lastwordsize-1U] &= 0xFFFFFF00U;
4795 if ((npblb %4U)==2U)
4797 intermediate_data[lastwordsize-1U] &= 0xFFFF0000U;
4799 if ((npblb %4U)==3U)
4801 intermediate_data[lastwordsize-1U] &= 0xFF000000U;
4804 else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_8B)
4806 if ((npblb %4U)==1U)
4808 intermediate_data[lastwordsize-1U] &= __REV(0xFFFFFF00U);
4810 if ((npblb %4U)==2U)
4812 intermediate_data[lastwordsize-1U] &= __REV(0xFFFF0000U);
4814 if ((npblb %4U)==3U)
4816 intermediate_data[lastwordsize-1U] &= __REV(0xFF000000U);
4819 else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_DATATYPE_16B)
4821 if ((npblb %4U)==1U)
4823 intermediate_data[lastwordsize-1U] &= __ROR((0xFFFFFF00U), 16);
4825 if ((npblb %4U)==2U)
4827 intermediate_data[lastwordsize-1U] &= __ROR((0xFFFF0000U), 16);
4829 if ((npblb %4U)==3U)
4831 intermediate_data[lastwordsize-1U] &= __ROR((0xFF000000U), 16);
4834 else /*CRYP_DATATYPE_1B*/
4836 if ((npblb %4U)==1U)
4838 intermediate_data[lastwordsize-1U] &= __RBIT(0xFFFFFF00U);
4840 if ((npblb %4U)==2U)
4842 intermediate_data[lastwordsize-1U] &= __RBIT(0xFFFF0000U);
4844 if ((npblb %4U)==3U)
4846 intermediate_data[lastwordsize-1U] &= __RBIT(0xFF000000U);
4850 for (index = 0U; index < lastwordsize ; index ++)
4852 /*Write the intermediate_data in the IN FIFO */
4853 hcryp->Instance->DIN = intermediate_data[index];
4855 while (index < 4U)
4857 /* Pad the data with zeros to have a complete block */
4858 hcryp->Instance->DIN = 0x0U;
4859 index++;
4861 /* Wait for OFNE flag to be raised */
4862 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4864 /* Disable the CRYP peripheral clock */
4865 __HAL_CRYP_DISABLE(hcryp);
4867 /* Change state */
4868 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4869 hcryp->State = HAL_CRYP_STATE_READY;
4871 /* Process unlocked */
4872 __HAL_UNLOCK(hcryp);
4873 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4874 /*Call registered error callback*/
4875 hcryp->ErrorCallback(hcryp);
4876 #else
4877 /*Call legacy weak error callback*/
4878 HAL_CRYP_ErrorCallback(hcryp);
4879 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4882 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4884 for (index = 0U; index < 4U; index++)
4886 intermediate_data[index] = hcryp->Instance->DOUT;
4890 } /* End of GCM encryption */
4891 else
4893 /* Workaround 2, case CCM decryption, in order to properly compute
4894 authentication tags while doing a CCM decryption with the last block
4895 of payload size inferior to 128 bits*/
4897 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4899 iv1temp = hcryp->Instance->CSGCMCCM7R;
4901 /* Disable CRYP to start the final phase */
4902 __HAL_CRYP_DISABLE(hcryp);
4904 temp[0] = hcryp->Instance->CSGCMCCM0R;
4905 temp[1] = hcryp->Instance->CSGCMCCM1R;
4906 temp[2] = hcryp->Instance->CSGCMCCM2R;
4907 temp[3] = hcryp->Instance->CSGCMCCM3R;
4909 hcryp->Instance->IV1RR = iv1temp;
4911 /* Configured CHMOD CTR */
4912 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
4914 /* Enable CRYP to start the final phase */
4915 __HAL_CRYP_ENABLE(hcryp);
4917 /* Last block optionally pad the data with zeros*/
4918 for (index = 0U; index < lastwordsize; index ++)
4920 /* Write the last Input block in the IN FIFO */
4921 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4922 hcryp->CrypInCount++;
4924 while (index < 4U)
4926 /* Pad the data with zeros to have a complete block */
4927 hcryp->Instance->DIN = 0U;
4928 index++;
4930 /* Wait for OFNE flag to be raised */
4931 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4933 /* Disable the CRYP peripheral clock */
4934 __HAL_CRYP_DISABLE(hcryp);
4936 /* Change state */
4937 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4938 hcryp->State = HAL_CRYP_STATE_READY;
4940 /* Process Unlocked */
4941 __HAL_UNLOCK(hcryp);
4942 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4943 /*Call registered error callback*/
4944 hcryp->ErrorCallback(hcryp);
4945 #else
4946 /*Call legacy weak error callback*/
4947 HAL_CRYP_ErrorCallback(hcryp);
4948 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4951 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4953 for (index = 0U; index < 4U; index++)
4955 /* Read the Output block from the Output FIFO */
4956 intermediate_data[index] = hcryp->Instance->DOUT;
4958 /*intermediate data buffer to be used in for the workaround*/
4959 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
4960 hcryp->CrypOutCount++;
4964 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4966 temp2[0] = hcryp->Instance->CSGCMCCM0R;
4967 temp2[1] = hcryp->Instance->CSGCMCCM1R;
4968 temp2[2] = hcryp->Instance->CSGCMCCM2R;
4969 temp2[3] = hcryp->Instance->CSGCMCCM3R;
4971 /* configured CHMOD CCM */
4972 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CCM);
4974 /* configured Header phase */
4975 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_HEADER);
4977 /*set to zero the bits corresponding to the padded bits*/
4978 for (index = lastwordsize; index < 4U; index ++)
4980 intermediate_data[index] = 0U;
4983 if ((npblb % 4U) == 1U)
4985 intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
4987 if ((npblb % 4U) == 2U)
4989 intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
4991 if ((npblb % 4U) == 3U)
4993 intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
4996 for (index = 0U; index < 4U ; index ++)
4998 intermediate_data[index] ^= temp[index];
4999 intermediate_data[index] ^= temp2[index];
5001 for (index = 0U; index < 4U; index ++)
5003 /* Write the last Input block in the IN FIFO */
5004 hcryp->Instance->DIN = intermediate_data[index] ;
5007 /* Wait for BUSY flag to be raised */
5008 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
5010 /* Disable the CRYP peripheral clock */
5011 __HAL_CRYP_DISABLE(hcryp);
5013 /* Change state */
5014 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5015 hcryp->State = HAL_CRYP_STATE_READY;
5017 /* Process Unlocked */
5018 __HAL_UNLOCK(hcryp);
5019 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5020 /*Call registered error callback*/
5021 hcryp->ErrorCallback(hcryp);
5022 #else
5023 /*Call legacy weak error callback*/
5024 HAL_CRYP_ErrorCallback(hcryp);
5025 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5028 } /* End of CCM WKA*/
5030 /* Process Unlocked */
5031 __HAL_UNLOCK(hcryp);
5033 #endif /*End of not defined CRYP_VER_2_2*/
5036 * @brief Handle CRYP hardware block Timeout when waiting for IFEM flag to be raised.
5037 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5038 * the configuration information for CRYP module.
5039 * @param Timeout: Timeout duration.
5040 * @retval HAL status
5042 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5044 uint32_t tickstart;
5046 /* Get timeout */
5047 tickstart = HAL_GetTick();
5049 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
5051 /* Check for the Timeout */
5052 if (Timeout != HAL_MAX_DELAY)
5054 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5056 return HAL_ERROR;
5060 return HAL_OK;
5063 * @brief Handle CRYP hardware block Timeout when waiting for BUSY flag to be raised.
5064 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5065 * the configuration information for CRYP module.
5066 * @param Timeout: Timeout duration.
5067 * @retval HAL status
5069 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5071 uint32_t tickstart;
5073 /* Get timeout */
5074 tickstart = HAL_GetTick();
5076 while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY))
5078 /* Check for the Timeout */
5079 if (Timeout != HAL_MAX_DELAY)
5081 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5083 return HAL_ERROR;
5087 return HAL_OK;
5092 * @brief Handle CRYP hardware block Timeout when waiting for OFNE flag to be raised.
5093 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5094 * the configuration information for CRYP module.
5095 * @param Timeout: Timeout duration.
5096 * @retval HAL status
5098 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5100 uint32_t tickstart;
5102 /* Get timeout */
5103 tickstart = HAL_GetTick();
5105 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
5107 /* Check for the Timeout */
5108 if (Timeout != HAL_MAX_DELAY)
5110 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5112 return HAL_ERROR;
5116 return HAL_OK;
5121 * @}
5127 * @}
5131 * @}
5134 #endif /* HAL_CRYP_MODULE_ENABLED */
5138 * @}
5140 #endif /* CRYP */
5142 * @}
5145 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/