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
15 *
16 ******************************************************************************
17 * @attention
18 *
19 * Copyright (c) 2017 STMicroelectronics.
20 * All rights reserved.
21 *
22 * This software is licensed under terms that can be found in the LICENSE file
23 * in the root directory of this software component.
24 * If no LICENSE file comes with this software, it is provided AS-IS.
25 *
26 ******************************************************************************
27 @verbatim
28 ==============================================================================
29 ##### How to use this driver #####
30 ==============================================================================
31 [..]
32 The CRYP HAL driver can be used in CRYP IP as follows:
33
34 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
35 (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
36 (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
37 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
38 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
39 (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
40 (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
41 (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
42 (+++) Configure and enable two DMA streams one for managing data transfer from
43 memory to peripheral (input stream) and another stream for managing data
44 transfer from peripheral to memory (output stream)
45 (+++) Associate the initialized DMA handle to the CRYP DMA handle
46 using __HAL_LINKDMA()
47 (+++) Configure the priority and enable the NVIC for the transfer complete
48 interrupt on the two DMA Streams. The output stream should have higher
49 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
50
51 (#)Initialize the CRYP according to the specified parameters :
52 (##) The data type: bit swap(1-bit data), byte swap(8-bit data), half word swap(16-bit data)
53 or no swap(32-bit data).
54 (##) The key size: 128, 192 or 256.
55 (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM.
56 (##) The initialization vector (counter). It is not used in ECB mode.
57 (##) The key buffer used for encryption/decryption.
58 (##) The Header used only in AES GCM and CCM Algorithm for authentication.
59 (##) The HeaderSize The size of header buffer in word.
60 (##) The B0 block is the first authentication block used only in AES CCM mode.
61
62 (#)Three processing (encryption/decryption) functions are available:
63 (##) Polling mode: encryption and decryption APIs are blocking functions
64 i.e. they process the data and wait till the processing is finished,
65 e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
66 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
67 i.e. they process the data under interrupt,
68 e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
69 (##) DMA mode: encryption and decryption APIs are not blocking functions
70 i.e. the data transfer is ensured by DMA,
71 e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
72
73 (#)When the processing function is called at first time after HAL_CRYP_Init()
74 the CRYP peripheral is configured and processes the buffer in input.
75 At second call, no need to Initialize the CRYP, user have to get current configuration via
76 HAL_CRYP_GetConfig() API, then only HAL_CRYP_SetConfig() is requested to set
77 new parameters, finally user can start encryption/decryption.
78
79 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
80
81 (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
82 without having to configure again the Key or the Initialization Vector between each API call,
83 the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
84 Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
85 or HAL_CRYP_Decrypt_DMA().
86
87 [..]
88 The cryptographic processor supports following standards:
89 (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 IP:
90 (##)64-bit data block processing
91 (##) chaining modes supported :
92 (+++) Electronic Code Book(ECB)
93 (+++) Cipher Block Chaining (CBC)
94 (##) keys length supported :64-bit, 128-bit and 192-bit.
95 (#) The advanced encryption standard (AES) supported by CRYP1:
96 (##)128-bit data block processing
97 (##) chaining modes supported :
98 (+++) Electronic Code Book(ECB)
99 (+++) Cipher Block Chaining (CBC)
100 (+++) Counter mode (CTR)
101 (+++) Galois/counter mode (GCM/GMAC)
102 (+++) Counter with Cipher Block Chaining-Message(CCM)
103 (##) keys length Supported :
104 (+++) for CRYP1 IP: 128-bit, 192-bit and 256-bit.
105
106 [..] This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 IP:
107 (#) Algorithm supported :
108 (##) Galois/counter mode (GCM)
109 (##) Galois message authentication code (GMAC) :is exactly the same as
110 GCM algorithm composed only by an header.
111 (#) Four phases are performed in GCM :
112 (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
113 (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
114 computation only.
115 (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
116 encryption + data XORing. It works in a similar way for ciphertext (C).
117 (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
118 HAL_CRYPEx_AESGCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond
119 to the Tag. user should consider only part of this 4 words, if Tag length is less than 128 bits.
120 (#) structure of message construction in GCM is defined as below :
121 (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
122 (##) The authenticated header A (also knows as Additional Authentication Data AAD)
123 this part of the message is only authenticated, not encrypted.
124 (##) The plaintext message P is both authenticated and encrypted as ciphertext.
125 GCM standard specifies that ciphertext has same bit length as the plaintext.
126 (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
127 (on 64 bits)
128
129 [..] This section describe The AES Counter with Cipher Block Chaining-Message
130 Authentication Code (CCM) supported by both CRYP1 IP:
131 (#) Specific parameters for CCM :
132
133 (##) B0 block : According to NIST Special Publication 800-38C,
134 The first block B0 is formatted as follows, where l(m) is encoded in
135 most-significant-byte first order(see below table 3)
136
137 (+++) Q: a bit string representation of the octet length of P (plaintext)
138 (+++) q The octet length of the binary representation of the octet length of the payload
139 (+++) A nonce (N), n The octet length of the where n+q=15.
140 (+++) Flags: most significant octet containing four flags for control information,
141 (+++) t The octet length of the MAC.
142 (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
143 the associated data length expressed in bytes (a) defined as below:
144 (+++) If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
145 (+++) If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
146 (+++) If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
147 (##) CTRx block : control blocks
148 (+++) Generation of CTR1 from first block B0 information :
149 equal to B0 with first 5 bits zeroed and most significant bits storing octet
150 length of P also zeroed, then incremented by one ( see below Table 4)
151 (+++) Generation of CTR0: same as CTR1 with bit[0] set to zero.
152
153 (#) Four phases are performed in CCM for CRYP1 IP:
154 (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
155 (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
156 computation only.
157 (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
158 encryption + data XORing. It works in a similar way for ciphertext (C).
159 (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
160 HAL_CRYPEx_AESCCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond to the Tag.
161 user should consider only part of this 4 words, if Tag length is less than 128 bits
162
163 *** Callback registration ***
164 =============================
165
166 [..]
167 The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
168 allows the user to configure dynamically the driver callbacks.
169 Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
170 to register an interrupt callback.
171
172 [..]
173 Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
174 (+) InCpltCallback : Input FIFO transfer completed callback.
175 (+) OutCpltCallback : Output FIFO transfer completed callback.
176 (+) ErrorCallback : callback for error detection.
177 (+) MspInitCallback : CRYP MspInit.
178 (+) MspDeInitCallback : CRYP MspDeInit.
179 This function takes as parameters the HAL peripheral handle, the Callback ID
180 and a pointer to the user callback function.
181
182 [..]
183 Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
184 weak function.
185 @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
186 and the Callback ID.
187 This function allows to reset following callbacks:
188 (+) InCpltCallback : Input FIFO transfer completed callback.
189 (+) OutCpltCallback : Output FIFO transfer completed callback.
190 (+) ErrorCallback : callback for error detection.
191 (+) MspInitCallback : CRYP MspInit.
192 (+) MspDeInitCallback : CRYP MspDeInit.
193
194 [..]
195 By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
196 all callbacks are set to the corresponding weak functions :
197 examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
198 Exception done for MspInit and MspDeInit functions that are
199 reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
200 these callbacks are null (not registered beforehand).
201 if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
202 keep and use the user MspInit/MspDeInit functions (registered beforehand)
203
204 [..]
205 Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
206 Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
207 in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
208 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
209 In that case first register the MspInit/MspDeInit user callbacks
210 using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
211 or @ref HAL_CRYP_Init() function.
212
213 [..]
214 When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
215 not defined, the callback registration feature is not available and all callbacks
216 are set to the corresponding weak functions.
217
218 @endverbatim
219
220 Table 1. Initial Counter Block (ICB)
221 +-------------------------------------------------------+
222 | Initialization vector (IV) | Counter |
223 |----------------|----------------|-----------|---------|
224 127 95 63 31 0
225
226
227 Bit Number Register Contents
228 ---------- --------------- -----------
229 127 ...96 CRYP_IV1R[31:0] ICB[127:96]
230 95 ...64 CRYP_IV1L[31:0] B0[95:64]
231 63 ... 32 CRYP_IV0R[31:0] ICB[63:32]
232 31 ... 0 CRYP_IV0L[31:0] ICB[31:0], where 32-bit counter= 0x2
233
234 Table 2. GCM last block definition
235
236 +-------------------------------------------------------------------+
237 | Bit[0] | Bit[32] | Bit[64] | Bit[96] |
238 |-----------|--------------------|-----------|----------------------|
239 | 0x0 | Header length[31:0]| 0x0 | Payload length[31:0] |
240 |-----------|--------------------|-----------|----------------------|
241
242 Table 3. B0 block
243 Octet Number Contents
244 ------------ ---------
245 0 Flags
246 1 ... 15-q Nonce N
247 16-q ... 15 Q
248
249 the Flags field is formatted as follows:
250
251 Bit Number Contents
252 ---------- ----------------------
253 7 Reserved (always zero)
254 6 Adata
255 5 ... 3 (t-2)/2
256 2 ... 0 [q-1]3
257
258 Table 4. CTRx block
259 Bit Number Register Contents
260 ---------- --------------- -----------
261 127 ...96 CRYP_IV1R[31:0] B0[127:96], where Q length bits are set to 0, except for
262 bit 0 that is set to 1
263 95 ...64 CRYP_IV1L[31:0] B0[95:64]
264 63 ... 32 CRYP_IV0R[31:0] B0[63:32]
265 31 ... 0 CRYP_IV0L[31:0] B0[31:0], where flag bits set to 0
266 */
267
268 /* Includes ------------------------------------------------------------------*/
269 #include "stm32h7xx_hal.h"
270
271 /** @addtogroup STM32H7xx_HAL_Driver
272 * @{
273 */
274
275 #if defined (CRYP)
276
277 /** @defgroup CRYP CRYP
278 * @brief CRYP HAL module driver.
279 * @{
280 */
281
282
283 #ifdef HAL_CRYP_MODULE_ENABLED
284
285 /* Private typedef -----------------------------------------------------------*/
286 /* Private define ------------------------------------------------------------*/
287 /** @addtogroup CRYP_Private_Defines
288 * @{
289 */
290 #define CRYP_TIMEOUT_KEYPREPARATION 82U /*!< The latency of key preparation operation is 82 clock cycles.*/
291 #define CRYP_TIMEOUT_GCMCCMINITPHASE 299U /*!< The latency of GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
292 #define CRYP_TIMEOUT_GCMCCMHEADERPHASE 290U /*!< The latency of GCM/CCM header phase is 290 clock cycles.*/
293
294 #define CRYP_PHASE_READY 0x00000001U /*!< CRYP peripheral is ready for initialization. */
295 #define CRYP_PHASE_PROCESS 0x00000002U /*!< CRYP peripheral is in processing phase */
296
297 #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
298 #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0 /*!< GCM/GMAC or CCM header phase */
299 #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1 /*!< GCM(/CCM) payload phase */
300 #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH /*!< GCM/GMAC or CCM final phase */
301 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */
302 #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR /*!< Decryption */
303
304
305 /* CTR1 information to use in CCM algorithm */
306 #define CRYP_CCM_CTR1_0 0x07FFFFFFU
307 #define CRYP_CCM_CTR1_1 0xFFFFFF00U
308 #define CRYP_CCM_CTR1_2 0x00000001U
309
310 /**
311 * @}
312 */
313
314
315 /* Private macro -------------------------------------------------------------*/
316 /** @addtogroup CRYP_Private_Macros
317 * @{
318 */
319
320 #define CRYP_SET_PHASE(__HANDLE__, __PHASE__) do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\
321 (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
322 }while(0)
323
324 #define HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRYP_CR_FFLUSH)
325
326
327 /**
328 * @}
329 */
330
331 /* Private struct -------------------------------------------------------------*/
332 /* Private variables ---------------------------------------------------------*/
333 /* Private function prototypes -----------------------------------------------*/
334 /** @addtogroup CRYP_Private_Functions_Prototypes
335 * @{
336 */
337
338 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
339 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
340 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
341 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
342 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
343 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
344 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
345 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
346 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
347 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
348 #if !defined (CRYP_VER_2_2)
349 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
350 #endif /*End of not defined CRYP_VER_2_2*/
351 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
352 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
353 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
354 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
355 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
356 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
357 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
358 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
359 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
360 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
361 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
362 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
363 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp);
364 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
365 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
366 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
367 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
368
369 /**
370 * @}
371 */
372
373 /* Exported functions ---------------------------------------------------------*/
374
375 /** @defgroup CRYP_Exported_Functions CRYP Exported Functions
376 * @{
377 */
378
379
380 /** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
381 * @brief CRYP Initialization and Configuration functions.
382 *
383 @verbatim
384 ========================================================================================
385 ##### Initialization, de-initialization and Set and Get configuration functions #####
386 ========================================================================================
387 [..] This section provides functions allowing to:
388 (+) Initialize the CRYP
389 (+) DeInitialize the CRYP
390 (+) Initialize the CRYP MSP
391 (+) DeInitialize the CRYP MSP
392 (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
393 Parameters which are configured in This section are :
394 (++) Key size
395 (++) Data Type : 32,16, 8 or 1bit
396 (++) AlgoMode : for CRYP1 IP
397 ECB and CBC in DES/TDES Standard
398 ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
399 (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
400
401
402 @endverbatim
403 * @{
404 */
405
406
407 /**
408 * @brief Initializes the CRYP according to the specified
409 * parameters in the CRYP_ConfigTypeDef and creates the associated handle.
410 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
411 * the configuration information for CRYP module
412 * @retval HAL status
413 */
HAL_CRYP_Init(CRYP_HandleTypeDef * hcryp)414 HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
415 {
416 /* Check the CRYP handle allocation */
417 if (hcryp == NULL)
418 {
419 return HAL_ERROR;
420 }
421
422 /* Check parameters */
423 assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
424 assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
425 assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
426 assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
427
428 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
429 if (hcryp->State == HAL_CRYP_STATE_RESET)
430 {
431 /* Allocate lock resource and initialize it */
432 hcryp->Lock = HAL_UNLOCKED;
433
434 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
435 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
436 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
437
438 if (hcryp->MspInitCallback == NULL)
439 {
440 hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit */
441 }
442
443 /* Init the low level hardware */
444 hcryp->MspInitCallback(hcryp);
445 }
446 #else
447 if (hcryp->State == HAL_CRYP_STATE_RESET)
448 {
449 /* Allocate lock resource and initialize it */
450 hcryp->Lock = HAL_UNLOCKED;
451
452 /* Init the low level hardware */
453 HAL_CRYP_MspInit(hcryp);
454 }
455 #endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
456
457 /* Set the key size(This bit field is don't care in the DES or TDES modes) data type and Algorithm */
458 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
459 hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
460 #if !defined (CRYP_VER_2_2)
461 /* Read Device ID to indicate CRYP1 IP Version */
462 hcryp->Version = HAL_GetREVID();
463 #endif /*End of not defined CRYP_VER_2_2*/
464 /* Reset Error Code field */
465 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
466
467 /* Reset peripheral Key and IV configuration flag */
468 hcryp->KeyIVConfig = 0U;
469
470 /* Change the CRYP state */
471 hcryp->State = HAL_CRYP_STATE_READY;
472
473 /* Set the default CRYP phase */
474 hcryp->Phase = CRYP_PHASE_READY;
475
476 /* Return function status */
477 return HAL_OK;
478 }
479
480 /**
481 * @brief De-Initializes the CRYP peripheral.
482 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
483 * the configuration information for CRYP module
484 * @retval HAL status
485 */
HAL_CRYP_DeInit(CRYP_HandleTypeDef * hcryp)486 HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
487 {
488 /* Check the CRYP handle allocation */
489 if (hcryp == NULL)
490 {
491 return HAL_ERROR;
492 }
493
494 /* Set the default CRYP phase */
495 hcryp->Phase = CRYP_PHASE_READY;
496
497 /* Reset CrypInCount and CrypOutCount */
498 hcryp->CrypInCount = 0;
499 hcryp->CrypOutCount = 0;
500 hcryp->CrypHeaderCount = 0;
501
502 /* Disable the CRYP peripheral clock */
503 __HAL_CRYP_DISABLE(hcryp);
504
505 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
506 if (hcryp->MspDeInitCallback == NULL)
507 {
508 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit */
509 }
510 /* DeInit the low level hardware */
511 hcryp->MspDeInitCallback(hcryp);
512
513 #else
514 /* DeInit the low level hardware: CLOCK, NVIC.*/
515 HAL_CRYP_MspDeInit(hcryp);
516 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
517
518 /* Change the CRYP state */
519 hcryp->State = HAL_CRYP_STATE_RESET;
520
521 /* Release Lock */
522 __HAL_UNLOCK(hcryp);
523
524 /* Return function status */
525 return HAL_OK;
526 }
527
528 /**
529 * @brief Configure the CRYP according to the specified
530 * parameters in the CRYP_ConfigTypeDef
531 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
532 * @param pConf: pointer to a CRYP_ConfigTypeDef structure that contains
533 * the configuration information for CRYP module
534 * @retval HAL status
535 */
HAL_CRYP_SetConfig(CRYP_HandleTypeDef * hcryp,CRYP_ConfigTypeDef * pConf)536 HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
537 {
538 /* Check the CRYP handle allocation */
539 if ((hcryp == NULL) || (pConf == NULL))
540 {
541 return HAL_ERROR;
542 }
543
544 /* Check parameters */
545 assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
546 assert_param(IS_CRYP_DATATYPE(pConf->DataType));
547 assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
548
549 if (hcryp->State == HAL_CRYP_STATE_READY)
550 {
551 /* Change the CRYP state */
552 hcryp->State = HAL_CRYP_STATE_BUSY;
553
554 /* Process locked */
555 __HAL_LOCK(hcryp);
556
557 /* Set CRYP parameters */
558 hcryp->Init.DataType = pConf->DataType;
559 hcryp->Init.pKey = pConf->pKey;
560 hcryp->Init.Algorithm = pConf->Algorithm;
561 hcryp->Init.KeySize = pConf->KeySize;
562 hcryp->Init.pInitVect = pConf->pInitVect;
563 hcryp->Init.Header = pConf->Header;
564 hcryp->Init.HeaderSize = pConf->HeaderSize;
565 hcryp->Init.B0 = pConf->B0;
566 hcryp->Init.DataWidthUnit = pConf->DataWidthUnit;
567 hcryp->Init.HeaderWidthUnit = pConf->HeaderWidthUnit;
568 hcryp->Init.KeyIVConfigSkip = pConf->KeyIVConfigSkip;
569
570 /* Set the key size(This bit field is don't care in the DES or TDES modes) data type, AlgoMode and operating mode*/
571 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
572 hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
573
574 /* Process Unlocked */
575 __HAL_UNLOCK(hcryp);
576
577 /* Reset Error Code field */
578 hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
579
580 /* Change the CRYP state */
581 hcryp->State = HAL_CRYP_STATE_READY;
582
583 /* Set the default CRYP phase */
584 hcryp->Phase = CRYP_PHASE_READY;
585
586 /* Return function status */
587 return HAL_OK;
588 }
589 else
590 {
591 /* Process Unlocked */
592 __HAL_UNLOCK(hcryp);
593
594 /* Busy error code field */
595 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
596 return HAL_ERROR;
597 }
598 }
599
600 /**
601 * @brief Get CRYP Configuration parameters in associated handle.
602 * @param pConf: pointer to a CRYP_ConfigTypeDef structure
603 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
604 * the configuration information for CRYP module
605 * @retval HAL status
606 */
HAL_CRYP_GetConfig(CRYP_HandleTypeDef * hcryp,CRYP_ConfigTypeDef * pConf)607 HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
608 {
609 /* Check the CRYP handle allocation */
610 if ((hcryp == NULL) || (pConf == NULL))
611 {
612 return HAL_ERROR;
613 }
614
615 if (hcryp->State == HAL_CRYP_STATE_READY)
616 {
617 /* Change the CRYP state */
618 hcryp->State = HAL_CRYP_STATE_BUSY;
619
620 /* Process locked */
621 __HAL_LOCK(hcryp);
622
623 /* Get CRYP parameters */
624 pConf->DataType = hcryp->Init.DataType;
625 pConf->pKey = hcryp->Init.pKey;
626 pConf->Algorithm = hcryp->Init.Algorithm;
627 pConf->KeySize = hcryp->Init.KeySize ;
628 pConf->pInitVect = hcryp->Init.pInitVect;
629 pConf->Header = hcryp->Init.Header ;
630 pConf->HeaderSize = hcryp->Init.HeaderSize;
631 pConf->B0 = hcryp->Init.B0;
632 pConf->DataWidthUnit = hcryp->Init.DataWidthUnit;
633 pConf->HeaderWidthUnit = hcryp->Init.HeaderWidthUnit;
634 pConf->KeyIVConfigSkip = hcryp->Init.KeyIVConfigSkip;
635
636 /* Process Unlocked */
637 __HAL_UNLOCK(hcryp);
638
639 /* Change the CRYP state */
640 hcryp->State = HAL_CRYP_STATE_READY;
641
642 /* Return function status */
643 return HAL_OK;
644 }
645 else
646 {
647 /* Process Unlocked */
648 __HAL_UNLOCK(hcryp);
649
650 /* Busy error code field */
651 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
652 return HAL_ERROR;
653 }
654 }
655 /**
656 * @brief Initializes the CRYP MSP.
657 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
658 * the configuration information for CRYP module
659 * @retval None
660 */
HAL_CRYP_MspInit(CRYP_HandleTypeDef * hcryp)661 __weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
662 {
663 /* Prevent unused argument(s) compilation warning */
664 UNUSED(hcryp);
665
666 /* NOTE : This function Should not be modified, when the callback is needed,
667 the HAL_CRYP_MspInit could be implemented in the user file
668 */
669 }
670
671 /**
672 * @brief DeInitializes CRYP MSP.
673 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
674 * the configuration information for CRYP module
675 * @retval None
676 */
HAL_CRYP_MspDeInit(CRYP_HandleTypeDef * hcryp)677 __weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
678 {
679 /* Prevent unused argument(s) compilation warning */
680 UNUSED(hcryp);
681
682 /* NOTE : This function Should not be modified, when the callback is needed,
683 the HAL_CRYP_MspDeInit could be implemented in the user file
684 */
685 }
686
687 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
688 /**
689 * @brief Register a User CRYP Callback
690 * To be used instead of the weak predefined callback
691 * @param hcryp cryp handle
692 * @param CallbackID ID of the callback to be registered
693 * This parameter can be one of the following values:
694 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
695 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
696 * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
697 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
698 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
699 * @param pCallback pointer to the Callback function
700 * @retval status
701 */
HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef * hcryp,HAL_CRYP_CallbackIDTypeDef CallbackID,pCRYP_CallbackTypeDef pCallback)702 HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID,
703 pCRYP_CallbackTypeDef pCallback)
704 {
705 HAL_StatusTypeDef status = HAL_OK;
706
707 if (pCallback == NULL)
708 {
709 /* Update the error code */
710 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
711
712 return HAL_ERROR;
713 }
714 /* Process locked */
715 __HAL_LOCK(hcryp);
716
717 if (hcryp->State == HAL_CRYP_STATE_READY)
718 {
719 switch (CallbackID)
720 {
721 case HAL_CRYP_INPUT_COMPLETE_CB_ID :
722 hcryp->InCpltCallback = pCallback;
723 break;
724
725 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
726 hcryp->OutCpltCallback = pCallback;
727 break;
728
729 case HAL_CRYP_ERROR_CB_ID :
730 hcryp->ErrorCallback = pCallback;
731 break;
732
733 case HAL_CRYP_MSPINIT_CB_ID :
734 hcryp->MspInitCallback = pCallback;
735 break;
736
737 case HAL_CRYP_MSPDEINIT_CB_ID :
738 hcryp->MspDeInitCallback = pCallback;
739 break;
740
741 default :
742 /* Update the error code */
743 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
744 /* Return error status */
745 status = HAL_ERROR;
746 break;
747 }
748 }
749 else if (hcryp->State == HAL_CRYP_STATE_RESET)
750 {
751 switch (CallbackID)
752 {
753 case HAL_CRYP_MSPINIT_CB_ID :
754 hcryp->MspInitCallback = pCallback;
755 break;
756
757 case HAL_CRYP_MSPDEINIT_CB_ID :
758 hcryp->MspDeInitCallback = pCallback;
759 break;
760
761 default :
762 /* Update the error code */
763 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
764 /* Return error status */
765 status = HAL_ERROR;
766 break;
767 }
768 }
769 else
770 {
771 /* Update the error code */
772 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
773 /* Return error status */
774 status = HAL_ERROR;
775 }
776
777 /* Release Lock */
778 __HAL_UNLOCK(hcryp);
779
780 return status;
781 }
782
783 /**
784 * @brief Unregister an CRYP Callback
785 * CRYP callback is redirected to the weak predefined callback
786 * @param hcryp cryp handle
787 * @param CallbackID ID of the callback to be unregistered
788 * This parameter can be one of the following values:
789 * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
790 * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
791 * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
792 * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
793 * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
794 * @retval status
795 */
HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef * hcryp,HAL_CRYP_CallbackIDTypeDef CallbackID)796 HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
797 {
798 HAL_StatusTypeDef status = HAL_OK;
799
800 /* Process locked */
801 __HAL_LOCK(hcryp);
802
803 if (hcryp->State == HAL_CRYP_STATE_READY)
804 {
805 switch (CallbackID)
806 {
807 case HAL_CRYP_INPUT_COMPLETE_CB_ID :
808 hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
809 break;
810
811 case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
812 hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
813 break;
814
815 case HAL_CRYP_ERROR_CB_ID :
816 hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
817 break;
818
819 case HAL_CRYP_MSPINIT_CB_ID :
820 hcryp->MspInitCallback = HAL_CRYP_MspInit;
821 break;
822
823 case HAL_CRYP_MSPDEINIT_CB_ID :
824 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
825 break;
826
827 default :
828 /* Update the error code */
829 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
830 /* Return error status */
831 status = HAL_ERROR;
832 break;
833 }
834 }
835 else if (hcryp->State == HAL_CRYP_STATE_RESET)
836 {
837 switch (CallbackID)
838 {
839 case HAL_CRYP_MSPINIT_CB_ID :
840 hcryp->MspInitCallback = HAL_CRYP_MspInit;
841 break;
842
843 case HAL_CRYP_MSPDEINIT_CB_ID :
844 hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
845 break;
846
847 default :
848 /* Update the error code */
849 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
850 /* Return error status */
851 status = HAL_ERROR;
852 break;
853 }
854 }
855 else
856 {
857 /* Update the error code */
858 hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
859 /* Return error status */
860 status = HAL_ERROR;
861 }
862
863 /* Release Lock */
864 __HAL_UNLOCK(hcryp);
865
866 return status;
867 }
868 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
869
870 /**
871 * @}
872 */
873
874 /** @defgroup CRYP_Exported_Functions_Group2 Encrypt Decrypt functions
875 * @brief CRYP processing functions.
876 *
877 @verbatim
878 ==============================================================================
879 ##### Encrypt Decrypt functions #####
880 ==============================================================================
881 [..] This section provides API allowing to Encrypt/Decrypt Data following
882 Standard DES/TDES or AES, and Algorithm configured by the user:
883 (+) Standard DES/TDES only supported by CRYP1 IP, below list of Algorithm supported :
884 (++) Electronic Code Book(ECB)
885 (++) Cipher Block Chaining (CBC)
886 (+) Standard AES supported by CRYP1 IP , list of Algorithm supported:
887 (++) Electronic Code Book(ECB)
888 (++) Cipher Block Chaining (CBC)
889 (++) Counter mode (CTR)
890 (++) Cipher Block Chaining (CBC)
891 (++) Counter mode (CTR)
892 (++) Galois/counter mode (GCM)
893 (++) Counter with Cipher Block Chaining-Message(CCM)
894 [..] Three processing functions are available:
895 (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
896 (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
897 (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
898
899 @endverbatim
900 * @{
901 */
902
903
904 /**
905 * @brief Encryption mode.
906 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
907 * the configuration information for CRYP module
908 * @param Input: Pointer to the input buffer (plaintext)
909 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit.
910 * @param Output: Pointer to the output buffer(ciphertext)
911 * @param Timeout: Specify Timeout value
912 * @retval HAL status
913 */
HAL_CRYP_Encrypt(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output,uint32_t Timeout)914 HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
915 uint32_t Timeout)
916 {
917 uint32_t algo;
918 HAL_StatusTypeDef status;
919
920 if (hcryp->State == HAL_CRYP_STATE_READY)
921 {
922 /* Change state Busy */
923 hcryp->State = HAL_CRYP_STATE_BUSY;
924
925 /* Process locked */
926 __HAL_LOCK(hcryp);
927
928 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
929 hcryp->CrypInCount = 0U;
930 hcryp->CrypOutCount = 0U;
931 hcryp->pCrypInBuffPtr = Input;
932 hcryp->pCrypOutBuffPtr = Output;
933
934 /* Calculate Size parameter in Byte*/
935 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
936 {
937 hcryp->Size = Size * 4U;
938 }
939 else
940 {
941 hcryp->Size = Size;
942 }
943
944 /* Set Encryption operating mode*/
945 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
946
947 /* algo get algorithm selected */
948 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
949
950 switch (algo)
951 {
952 case CRYP_DES_ECB:
953 case CRYP_DES_CBC:
954 case CRYP_TDES_ECB:
955 case CRYP_TDES_CBC:
956
957 /*Set Key */
958 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
959 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
960 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
961 {
962 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
963 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
964 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
965 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
966 }
967
968 /*Set Initialization Vector (IV)*/
969 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
970 {
971 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
972 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
973 }
974
975 /* Flush FIFO */
976 HAL_CRYP_FIFO_FLUSH(hcryp);
977
978 /* Set the phase */
979 hcryp->Phase = CRYP_PHASE_PROCESS;
980
981 /* Start DES/TDES encryption process */
982 status = CRYP_TDES_Process(hcryp, Timeout);
983 break;
984
985 case CRYP_AES_ECB:
986 case CRYP_AES_CBC:
987 case CRYP_AES_CTR:
988
989 /* AES encryption */
990 status = CRYP_AES_Encrypt(hcryp, Timeout);
991 break;
992
993 case CRYP_AES_GCM:
994
995 /* AES GCM encryption */
996 status = CRYP_AESGCM_Process(hcryp, Timeout);
997 break;
998
999 case CRYP_AES_CCM:
1000
1001 /* AES CCM encryption */
1002 status = CRYP_AESCCM_Process(hcryp, Timeout);
1003 break;
1004
1005 default:
1006 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1007 status = HAL_ERROR;
1008 break;
1009 }
1010
1011 if (status == HAL_OK)
1012 {
1013 /* Change the CRYP peripheral state */
1014 hcryp->State = HAL_CRYP_STATE_READY;
1015
1016 /* Process unlocked */
1017 __HAL_UNLOCK(hcryp);
1018 }
1019 }
1020 else
1021 {
1022 /* Process unlocked */
1023 __HAL_UNLOCK(hcryp);
1024
1025 /* Busy error code field */
1026 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1027 status = HAL_ERROR;
1028 }
1029
1030 /* Return function status */
1031 return status ;
1032 }
1033
1034 /**
1035 * @brief Decryption mode.
1036 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1037 * the configuration information for CRYP module
1038 * @param Input: Pointer to the input buffer (ciphertext )
1039 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1040 * @param Output: Pointer to the output buffer(plaintext)
1041 * @param Timeout: Specify Timeout value
1042 * @retval HAL status
1043 */
HAL_CRYP_Decrypt(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output,uint32_t Timeout)1044 HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
1045 uint32_t Timeout)
1046 {
1047 HAL_StatusTypeDef status;
1048 uint32_t algo;
1049
1050 if (hcryp->State == HAL_CRYP_STATE_READY)
1051 {
1052 /* Change state Busy */
1053 hcryp->State = HAL_CRYP_STATE_BUSY;
1054
1055 /* Process locked */
1056 __HAL_LOCK(hcryp);
1057
1058 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1059 hcryp->CrypInCount = 0U;
1060 hcryp->CrypOutCount = 0U;
1061 hcryp->pCrypInBuffPtr = Input;
1062 hcryp->pCrypOutBuffPtr = Output;
1063
1064 /* Calculate Size parameter in Byte*/
1065 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1066 {
1067 hcryp->Size = Size * 4U;
1068 }
1069 else
1070 {
1071 hcryp->Size = Size;
1072 }
1073
1074 /* Set Decryption operating mode*/
1075 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1076
1077 /* algo get algorithm selected */
1078 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1079
1080 switch (algo)
1081 {
1082 case CRYP_DES_ECB:
1083 case CRYP_DES_CBC:
1084 case CRYP_TDES_ECB:
1085 case CRYP_TDES_CBC:
1086
1087 /*Set Key */
1088 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1089 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1090 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1091 {
1092 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1093 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1094 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1095 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1096 }
1097
1098 /*Set Initialization Vector (IV)*/
1099 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1100 {
1101 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1102 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1103 }
1104
1105 /* Flush FIFO */
1106 HAL_CRYP_FIFO_FLUSH(hcryp);
1107
1108 /* Set the phase */
1109 hcryp->Phase = CRYP_PHASE_PROCESS;
1110
1111 /* Start DES/TDES decryption process */
1112 status = CRYP_TDES_Process(hcryp, Timeout);
1113
1114 break;
1115
1116 case CRYP_AES_ECB:
1117 case CRYP_AES_CBC:
1118 case CRYP_AES_CTR:
1119
1120 /* AES decryption */
1121 status = CRYP_AES_Decrypt(hcryp, Timeout);
1122 break;
1123
1124 case CRYP_AES_GCM:
1125
1126 /* AES GCM decryption */
1127 status = CRYP_AESGCM_Process(hcryp, Timeout) ;
1128 break;
1129
1130 case CRYP_AES_CCM:
1131
1132 /* AES CCM decryption */
1133 status = CRYP_AESCCM_Process(hcryp, Timeout);
1134 break;
1135
1136 default:
1137 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1138 status = HAL_ERROR;
1139 break;
1140 }
1141
1142 if (status == HAL_OK)
1143 {
1144 /* Change the CRYP peripheral state */
1145 hcryp->State = HAL_CRYP_STATE_READY;
1146
1147 /* Process unlocked */
1148 __HAL_UNLOCK(hcryp);
1149 }
1150 }
1151 else
1152 {
1153 /* Process unlocked */
1154 __HAL_UNLOCK(hcryp);
1155
1156 /* Busy error code field */
1157 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1158 status = HAL_ERROR;
1159 }
1160
1161 /* Return function status */
1162 return status;
1163 }
1164
1165 /**
1166 * @brief Encryption in interrupt mode.
1167 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1168 * the configuration information for CRYP module
1169 * @param Input: Pointer to the input buffer (plaintext)
1170 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1171 * @param Output: Pointer to the output buffer(ciphertext)
1172 * @retval HAL status
1173 */
HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1174 HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1175 {
1176 uint32_t algo;
1177 HAL_StatusTypeDef status;
1178
1179 if (hcryp->State == HAL_CRYP_STATE_READY)
1180 {
1181 /* Change state Busy */
1182 hcryp->State = HAL_CRYP_STATE_BUSY;
1183
1184 /* Process locked */
1185 __HAL_LOCK(hcryp);
1186
1187 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1188 hcryp->CrypInCount = 0U;
1189 hcryp->CrypOutCount = 0U;
1190 hcryp->pCrypInBuffPtr = Input;
1191 hcryp->pCrypOutBuffPtr = Output;
1192
1193 /* Calculate Size parameter in Byte*/
1194 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1195 {
1196 hcryp->Size = Size * 4U;
1197 }
1198 else
1199 {
1200 hcryp->Size = Size;
1201 }
1202
1203 /* Set encryption operating mode*/
1204 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1205
1206 /* algo get algorithm selected */
1207 algo = (hcryp->Instance->CR & CRYP_CR_ALGOMODE);
1208
1209 switch (algo)
1210 {
1211 case CRYP_DES_ECB:
1212 case CRYP_DES_CBC:
1213 case CRYP_TDES_ECB:
1214 case CRYP_TDES_CBC:
1215
1216 /*Set Key */
1217 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1218 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1219 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1220 {
1221 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1222 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1223 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1224 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1225 }
1226 /* Set the Initialization Vector*/
1227 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1228 {
1229 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1230 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1231 }
1232
1233 /* Flush FIFO */
1234 HAL_CRYP_FIFO_FLUSH(hcryp);
1235
1236 /* Set the phase */
1237 hcryp->Phase = CRYP_PHASE_PROCESS;
1238
1239 /* Enable interrupts */
1240 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1241
1242 /* Enable CRYP to start DES/TDES process*/
1243 __HAL_CRYP_ENABLE(hcryp);
1244
1245 status = HAL_OK;
1246 break;
1247
1248 case CRYP_AES_ECB:
1249 case CRYP_AES_CBC:
1250 case CRYP_AES_CTR:
1251
1252 status = CRYP_AES_Encrypt_IT(hcryp);
1253 break;
1254
1255 case CRYP_AES_GCM:
1256
1257 status = CRYP_AESGCM_Process_IT(hcryp) ;
1258 break;
1259
1260 case CRYP_AES_CCM:
1261
1262 status = CRYP_AESCCM_Process_IT(hcryp);
1263 break;
1264
1265 default:
1266 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1267 status = HAL_ERROR;
1268 break;
1269 }
1270 }
1271 else
1272 {
1273 /* Busy error code field */
1274 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1275 status = HAL_ERROR;
1276 }
1277
1278 /* Return function status */
1279 return status ;
1280 }
1281
1282 /**
1283 * @brief Decryption in itnterrupt mode.
1284 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1285 * the configuration information for CRYP module
1286 * @param Input: Pointer to the input buffer (ciphertext )
1287 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1288 * @param Output: Pointer to the output buffer(plaintext)
1289 * @retval HAL status
1290 */
HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1291 HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1292 {
1293 uint32_t algo;
1294 HAL_StatusTypeDef status = HAL_OK;
1295
1296 if (hcryp->State == HAL_CRYP_STATE_READY)
1297 {
1298 /* Change state Busy */
1299 hcryp->State = HAL_CRYP_STATE_BUSY;
1300
1301 /* Process locked */
1302 __HAL_LOCK(hcryp);
1303
1304 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1305 hcryp->CrypInCount = 0U;
1306 hcryp->CrypOutCount = 0U;
1307 hcryp->pCrypInBuffPtr = Input;
1308 hcryp->pCrypOutBuffPtr = Output;
1309
1310 /* Calculate Size parameter in Byte*/
1311 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1312 {
1313 hcryp->Size = Size * 4U;
1314 }
1315 else
1316 {
1317 hcryp->Size = Size;
1318 }
1319
1320 /* Set decryption operating mode*/
1321 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1322
1323 /* algo get algorithm selected */
1324 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1325
1326 switch (algo)
1327 {
1328 case CRYP_DES_ECB:
1329 case CRYP_DES_CBC:
1330 case CRYP_TDES_ECB:
1331 case CRYP_TDES_CBC:
1332
1333 /*Set Key */
1334 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1335 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1336 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1337 {
1338 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1339 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1340 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1341 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1342 }
1343
1344 /* Set the Initialization Vector*/
1345 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1346 {
1347 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1348 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1349 }
1350 /* Flush FIFO */
1351 HAL_CRYP_FIFO_FLUSH(hcryp);
1352
1353 /* Set the phase */
1354 hcryp->Phase = CRYP_PHASE_PROCESS;
1355
1356 /* Enable interrupts */
1357 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
1358
1359 /* Enable CRYP and start DES/TDES process*/
1360 __HAL_CRYP_ENABLE(hcryp);
1361
1362 break;
1363
1364 case CRYP_AES_ECB:
1365 case CRYP_AES_CBC:
1366 case CRYP_AES_CTR:
1367
1368 /* AES decryption */
1369 status = CRYP_AES_Decrypt_IT(hcryp);
1370 break;
1371
1372 case CRYP_AES_GCM:
1373
1374 /* AES GCM decryption */
1375 status = CRYP_AESGCM_Process_IT(hcryp) ;
1376 break;
1377
1378 case CRYP_AES_CCM:
1379
1380 /* AES CCMdecryption */
1381 status = CRYP_AESCCM_Process_IT(hcryp);
1382 break;
1383
1384 default:
1385 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1386 status = HAL_ERROR;
1387 break;
1388 }
1389 }
1390 else
1391 {
1392 /* Busy error code field */
1393 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1394 status = HAL_ERROR;
1395 }
1396
1397 /* Return function status */
1398 return status;
1399 }
1400
1401 /**
1402 * @brief Encryption in DMA mode.
1403 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1404 * the configuration information for CRYP module
1405 * @param Input: Pointer to the input buffer (plaintext)
1406 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1407 * @param Output: Pointer to the output buffer(ciphertext)
1408 * @retval HAL status
1409 */
HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1410 HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1411 {
1412 HAL_StatusTypeDef status = HAL_OK;
1413 uint32_t algo;
1414 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
1415
1416 if (hcryp->State == HAL_CRYP_STATE_READY)
1417 {
1418 /* Change state Busy */
1419 hcryp->State = HAL_CRYP_STATE_BUSY;
1420
1421 /* Process locked */
1422 __HAL_LOCK(hcryp);
1423
1424 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1425 hcryp->CrypInCount = 0U;
1426 hcryp->CrypOutCount = 0U;
1427 hcryp->pCrypInBuffPtr = Input;
1428 hcryp->pCrypOutBuffPtr = Output;
1429
1430 /* Calculate Size parameter in Byte*/
1431 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1432 {
1433 hcryp->Size = Size * 4U;
1434 }
1435 else
1436 {
1437 hcryp->Size = Size;
1438 }
1439
1440 /* Set encryption operating mode*/
1441 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
1442
1443 /* algo get algorithm selected */
1444 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1445
1446 switch (algo)
1447 {
1448 case CRYP_DES_ECB:
1449 case CRYP_DES_CBC:
1450 case CRYP_TDES_ECB:
1451 case CRYP_TDES_CBC:
1452
1453 /*Set Key */
1454 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1455 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1456 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1457 {
1458 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1459 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1460 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1461 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1462 }
1463
1464 /* Set the Initialization Vector*/
1465 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1466 {
1467 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1468 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1469 }
1470
1471 /* Flush FIFO */
1472 HAL_CRYP_FIFO_FLUSH(hcryp);
1473
1474 /* Set the phase */
1475 hcryp->Phase = CRYP_PHASE_PROCESS;
1476
1477 /* Start DMA process transfer for DES/TDES */
1478 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1479 (uint32_t)(hcryp->pCrypOutBuffPtr));
1480
1481 break;
1482
1483 case CRYP_AES_ECB:
1484 case CRYP_AES_CBC:
1485 case CRYP_AES_CTR:
1486
1487 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
1488 {
1489 if (hcryp->KeyIVConfig == 1U)
1490 {
1491 /* If the Key and IV configuration has to be done only once
1492 and if it has already been done, skip it */
1493 DoKeyIVConfig = 0U;
1494 }
1495 else
1496 {
1497 /* If the Key and IV configuration has to be done only once
1498 and if it has not been done already, do it and set KeyIVConfig
1499 to keep track it won't have to be done again next time */
1500 hcryp->KeyIVConfig = 1U;
1501 }
1502 }
1503
1504 if (DoKeyIVConfig == 1U)
1505 {
1506 /* Set the Key*/
1507 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
1508
1509 /* Set the Initialization Vector*/
1510 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
1511 {
1512 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1513 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
1514 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
1515 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
1516 }
1517 } /* if (DoKeyIVConfig == 1U) */
1518
1519 /* Set the phase */
1520 hcryp->Phase = CRYP_PHASE_PROCESS;
1521
1522 /* Start DMA process transfer for AES */
1523 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1524 (uint32_t)(hcryp->pCrypOutBuffPtr));
1525 break;
1526
1527 case CRYP_AES_GCM:
1528
1529 /* AES GCM encryption */
1530 status = CRYP_AESGCM_Process_DMA(hcryp) ;
1531 break;
1532
1533 case CRYP_AES_CCM:
1534
1535 /* AES CCM encryption */
1536 status = CRYP_AESCCM_Process_DMA(hcryp);
1537 break;
1538
1539 default:
1540 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1541 status = HAL_ERROR;
1542 break;
1543 }
1544 }
1545 else
1546 {
1547 /* Busy error code field */
1548 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1549 status = HAL_ERROR;
1550 }
1551
1552 /* Return function status */
1553 return status;
1554 }
1555
1556 /**
1557 * @brief Decryption in DMA mode.
1558 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1559 * the configuration information for CRYP module
1560 * @param Input: Pointer to the input buffer (ciphertext )
1561 * @param Size: Length of the plaintext buffer either in word or in byte, according to DataWidthUnit
1562 * @param Output: Pointer to the output buffer(plaintext)
1563 * @retval HAL status
1564 */
HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef * hcryp,uint32_t * Input,uint16_t Size,uint32_t * Output)1565 HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
1566 {
1567 uint32_t algo;
1568 HAL_StatusTypeDef status = HAL_OK;
1569
1570 if (hcryp->State == HAL_CRYP_STATE_READY)
1571 {
1572 /* Change state Busy */
1573 hcryp->State = HAL_CRYP_STATE_BUSY;
1574
1575 /* Process locked */
1576 __HAL_LOCK(hcryp);
1577
1578 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
1579 hcryp->CrypInCount = 0U;
1580 hcryp->CrypOutCount = 0U;
1581 hcryp->pCrypInBuffPtr = Input;
1582 hcryp->pCrypOutBuffPtr = Output;
1583
1584 /* Calculate Size parameter in Byte*/
1585 if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
1586 {
1587 hcryp->Size = Size * 4U;
1588 }
1589 else
1590 {
1591 hcryp->Size = Size;
1592 }
1593
1594 /* Set decryption operating mode*/
1595 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
1596
1597 /* algo get algorithm selected */
1598 algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
1599
1600 switch (algo)
1601 {
1602 case CRYP_DES_ECB:
1603 case CRYP_DES_CBC:
1604 case CRYP_TDES_ECB:
1605 case CRYP_TDES_CBC:
1606
1607 /*Set Key */
1608 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
1609 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
1610 if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1611 {
1612 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
1613 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
1614 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
1615 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
1616 }
1617
1618 /* Set the Initialization Vector*/
1619 if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1620 {
1621 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
1622 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
1623 }
1624
1625 /* Flush FIFO */
1626 HAL_CRYP_FIFO_FLUSH(hcryp);
1627
1628 /* Set the phase */
1629 hcryp->Phase = CRYP_PHASE_PROCESS;
1630
1631 /* Start DMA process transfer for DES/TDES */
1632 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
1633 (uint32_t)(hcryp->pCrypOutBuffPtr));
1634 break;
1635
1636 case CRYP_AES_ECB:
1637 case CRYP_AES_CBC:
1638 case CRYP_AES_CTR:
1639
1640 /* AES decryption */
1641 status = CRYP_AES_Decrypt_DMA(hcryp);
1642 break;
1643
1644 case CRYP_AES_GCM:
1645
1646 /* AES GCM decryption */
1647 status = CRYP_AESGCM_Process_DMA(hcryp) ;
1648
1649 break;
1650
1651 case CRYP_AES_CCM:
1652
1653 /* AES CCM decryption */
1654 status = CRYP_AESCCM_Process_DMA(hcryp);
1655 break;
1656
1657 default:
1658 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
1659 status = HAL_ERROR;
1660 break;
1661 }
1662 }
1663 else
1664 {
1665 /* Busy error code field */
1666 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1667 status = HAL_ERROR;
1668 }
1669
1670 /* Return function status */
1671 return status;
1672 }
1673
1674 /**
1675 * @}
1676 */
1677
1678 /** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
1679 * @brief CRYP IRQ handler.
1680 *
1681 @verbatim
1682 ==============================================================================
1683 ##### CRYP IRQ handler management #####
1684 ==============================================================================
1685 [..] This section provides CRYP IRQ handler and callback functions.
1686 (+) HAL_CRYP_IRQHandler CRYP interrupt request
1687 (+) HAL_CRYP_InCpltCallback input data transfer complete callback
1688 (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
1689 (+) HAL_CRYP_ErrorCallback CRYP error callback
1690 (+) HAL_CRYP_GetState return the CRYP state
1691 (+) HAL_CRYP_GetError return the CRYP error code
1692 @endverbatim
1693 * @{
1694 */
1695
1696 /**
1697 * @brief This function handles cryptographic interrupt request.
1698 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1699 * the configuration information for CRYP module
1700 * @retval None
1701 */
HAL_CRYP_IRQHandler(CRYP_HandleTypeDef * hcryp)1702 void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
1703 {
1704 uint32_t itstatus = hcryp->Instance->MISR;
1705
1706 if ((itstatus & (CRYP_IT_INI | CRYP_IT_OUTI)) != 0U)
1707 {
1708 if ((hcryp->Init.Algorithm == CRYP_DES_ECB) || (hcryp->Init.Algorithm == CRYP_DES_CBC) ||
1709 (hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
1710 {
1711 CRYP_TDES_IT(hcryp); /* DES or TDES*/
1712 }
1713 else if ((hcryp->Init.Algorithm == CRYP_AES_ECB) || (hcryp->Init.Algorithm == CRYP_AES_CBC) ||
1714 (hcryp->Init.Algorithm == CRYP_AES_CTR))
1715 {
1716 CRYP_AES_IT(hcryp); /*AES*/
1717 }
1718
1719 else if ((hcryp->Init.Algorithm == CRYP_AES_GCM) || (hcryp->Init.Algorithm == CRYP_CR_ALGOMODE_AES_CCM))
1720 {
1721 /* if header phase */
1722 if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
1723 {
1724 CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
1725 }
1726 else /* if payload phase */
1727 {
1728 CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
1729 }
1730 }
1731 else
1732 {
1733 /* Nothing to do */
1734 }
1735 }
1736 }
1737
1738 /**
1739 * @brief Return the CRYP error code.
1740 * @param hcryp : pointer to a CRYP_HandleTypeDef structure that contains
1741 * the configuration information for the CRYP IP
1742 * @retval CRYP error code
1743 */
HAL_CRYP_GetError(const CRYP_HandleTypeDef * hcryp)1744 uint32_t HAL_CRYP_GetError(const CRYP_HandleTypeDef *hcryp)
1745 {
1746 return hcryp->ErrorCode;
1747 }
1748
1749 /**
1750 * @brief Returns the CRYP state.
1751 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1752 * the configuration information for CRYP module.
1753 * @retval HAL state
1754 */
HAL_CRYP_GetState(const CRYP_HandleTypeDef * hcryp)1755 HAL_CRYP_STATETypeDef HAL_CRYP_GetState(const CRYP_HandleTypeDef *hcryp)
1756 {
1757 return hcryp->State;
1758 }
1759
1760 /**
1761 * @brief Input FIFO transfer completed callback.
1762 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1763 * the configuration information for CRYP module.
1764 * @retval None
1765 */
HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef * hcryp)1766 __weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
1767 {
1768 /* Prevent unused argument(s) compilation warning */
1769 UNUSED(hcryp);
1770
1771 /* NOTE : This function Should not be modified, when the callback is needed,
1772 the HAL_CRYP_InCpltCallback could be implemented in the user file
1773 */
1774 }
1775
1776 /**
1777 * @brief Output FIFO transfer completed callback.
1778 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1779 * the configuration information for CRYP module.
1780 * @retval None
1781 */
HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef * hcryp)1782 __weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
1783 {
1784 /* Prevent unused argument(s) compilation warning */
1785 UNUSED(hcryp);
1786
1787 /* NOTE : This function Should not be modified, when the callback is needed,
1788 the HAL_CRYP_OutCpltCallback could be implemented in the user file
1789 */
1790 }
1791
1792 /**
1793 * @brief CRYP error callback.
1794 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1795 * the configuration information for CRYP module.
1796 * @retval None
1797 */
HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef * hcryp)1798 __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
1799 {
1800 /* Prevent unused argument(s) compilation warning */
1801 UNUSED(hcryp);
1802
1803 /* NOTE : This function Should not be modified, when the callback is needed,
1804 the HAL_CRYP_ErrorCallback could be implemented in the user file
1805 */
1806 }
1807 /**
1808 * @}
1809 */
1810 /**
1811 * @}
1812 */
1813
1814 /* Private functions ---------------------------------------------------------*/
1815 /** @addtogroup CRYP_Private_Functions
1816 * @{
1817 */
1818
1819 /**
1820 * @brief Encryption in ECB/CBC Algorithm with DES/TDES standard.
1821 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1822 * the configuration information for CRYP module
1823 * @param Timeout: Timeout value
1824 * @retval HAL status
1825 */
CRYP_TDES_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)1826 static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
1827 {
1828
1829 uint32_t temp; /* Temporary CrypOutBuff */
1830 uint16_t incount; /* Temporary CrypInCount Value */
1831 uint16_t outcount; /* Temporary CrypOutCount Value */
1832
1833 /* Enable CRYP */
1834 __HAL_CRYP_ENABLE(hcryp);
1835 /*Temporary CrypOutCount Value*/
1836 outcount = hcryp->CrypOutCount;
1837
1838 /*Start processing*/
1839 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
1840 {
1841 /* Temporary CrypInCount Value */
1842 incount = hcryp->CrypInCount;
1843 /* Write plain data and get cipher data */
1844 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
1845 {
1846 /* Write the input block in the IN FIFO */
1847 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1848 hcryp->CrypInCount++;
1849 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1850 hcryp->CrypInCount++;
1851 }
1852
1853 /* Wait for OFNE flag to be raised */
1854 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
1855 {
1856 /* Disable the CRYP peripheral clock */
1857 __HAL_CRYP_DISABLE(hcryp);
1858
1859 /* Change state & errorCode*/
1860 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
1861 hcryp->State = HAL_CRYP_STATE_READY;
1862
1863 /* Process unlocked */
1864 __HAL_UNLOCK(hcryp);
1865 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1866 /*Call registered error callback*/
1867 hcryp->ErrorCallback(hcryp);
1868 #else
1869 /*Call legacy weak error callback*/
1870 HAL_CRYP_ErrorCallback(hcryp);
1871 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1872 }
1873
1874 /*Temporary CrypOutCount Value*/
1875 outcount = hcryp->CrypOutCount;
1876
1877 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
1878 {
1879 /* Read the output block from the Output FIFO and put them in temporary Buffer
1880 then get CrypOutBuff from temporary buffer */
1881 temp = hcryp->Instance->DOUT;
1882 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1883 hcryp->CrypOutCount++;
1884 temp = hcryp->Instance->DOUT;
1885 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1886 hcryp->CrypOutCount++;
1887 }
1888 /*Temporary CrypOutCount Value*/
1889 outcount = hcryp->CrypOutCount;
1890 }
1891 /* Disable CRYP */
1892 __HAL_CRYP_DISABLE(hcryp);
1893 /* Change the CRYP state */
1894 hcryp->State = HAL_CRYP_STATE_READY;
1895
1896 /* Return function status */
1897 return HAL_OK;
1898 }
1899
1900 /**
1901 * @brief CRYP block input/output data handling under interruption with DES/TDES standard.
1902 * @note The function is called under interruption only, once
1903 * interruptions have been enabled by CRYP_Decrypt_IT() and CRYP_Encrypt_IT().
1904 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
1905 * the configuration information for CRYP module.
1906 * @retval HAL status
1907 */
CRYP_TDES_IT(CRYP_HandleTypeDef * hcryp)1908 static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp)
1909 {
1910 uint32_t temp; /* Temporary CrypOutBuff */
1911
1912 if (hcryp->State == HAL_CRYP_STATE_BUSY)
1913 {
1914 if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI) != 0x0U)
1915 {
1916 if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_INRIS) != 0x0U)
1917 {
1918 /* Write input block in the IN FIFO */
1919 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1920 hcryp->CrypInCount++;
1921 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
1922 hcryp->CrypInCount++;
1923
1924 if (hcryp->CrypInCount == (hcryp->Size / 4U))
1925 {
1926 /* Disable interruption */
1927 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
1928
1929 /* Call the input data transfer complete callback */
1930 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1931 /*Call registered Input complete callback*/
1932 hcryp->InCpltCallback(hcryp);
1933 #else
1934 /*Call legacy weak Input complete callback*/
1935 HAL_CRYP_InCpltCallback(hcryp);
1936 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1937 }
1938 }
1939 }
1940
1941 if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI) != 0x0U)
1942 {
1943 if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_OUTRIS) != 0x0U)
1944 {
1945 /* Read the output block from the Output FIFO and put them in temporary Buffer
1946 then get CrypOutBuff from temporary buffer */
1947 temp = hcryp->Instance->DOUT;
1948 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1949 hcryp->CrypOutCount++;
1950 temp = hcryp->Instance->DOUT;
1951 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
1952 hcryp->CrypOutCount++;
1953 if (hcryp->CrypOutCount == (hcryp->Size / 4U))
1954 {
1955 /* Disable interruption */
1956 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
1957
1958 /* Disable CRYP */
1959 __HAL_CRYP_DISABLE(hcryp);
1960
1961 /* Process unlocked */
1962 __HAL_UNLOCK(hcryp);
1963
1964 /* Change the CRYP state */
1965 hcryp->State = HAL_CRYP_STATE_READY;
1966
1967 /* Call output transfer complete callback */
1968 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1969 /*Call registered Output complete callback*/
1970 hcryp->OutCpltCallback(hcryp);
1971 #else
1972 /*Call legacy weak Output complete callback*/
1973 HAL_CRYP_OutCpltCallback(hcryp);
1974 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1975
1976 }
1977 }
1978 }
1979 }
1980 else
1981 {
1982 /* Process unlocked */
1983 __HAL_UNLOCK(hcryp);
1984 /* Busy error code field */
1985 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
1986 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
1987 /*Call registered error callback*/
1988 hcryp->ErrorCallback(hcryp);
1989 #else
1990 /*Call legacy weak error callback*/
1991 HAL_CRYP_ErrorCallback(hcryp);
1992 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
1993 }
1994 }
1995
1996 /**
1997 * @brief Encryption in ECB/CBC & CTR Algorithm with AES Standard
1998 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
1999 * @param Timeout: specify Timeout value
2000 * @retval HAL status
2001 */
CRYP_AES_Encrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2002 static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2003 {
2004 uint16_t outcount; /* Temporary CrypOutCount Value */
2005 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2006
2007 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2008 {
2009 if (hcryp->KeyIVConfig == 1U)
2010 {
2011 /* If the Key and IV configuration has to be done only once
2012 and if it has already been done, skip it */
2013 DoKeyIVConfig = 0U;
2014 }
2015 else
2016 {
2017 /* If the Key and IV configuration has to be done only once
2018 and if it has not been done already, do it and set KeyIVConfig
2019 to keep track it won't have to be done again next time */
2020 hcryp->KeyIVConfig = 1U;
2021 }
2022 }
2023
2024 if (DoKeyIVConfig == 1U)
2025 {
2026 /* Set the Key*/
2027 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2028
2029 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2030 {
2031 /* Set the Initialization Vector*/
2032 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2033 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2034 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2035 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2036 }
2037 } /* if (DoKeyIVConfig == 1U) */
2038
2039 /* Set the phase */
2040 hcryp->Phase = CRYP_PHASE_PROCESS;
2041
2042 /* Enable CRYP */
2043 __HAL_CRYP_ENABLE(hcryp);
2044 /*Temporary CrypOutCount Value*/
2045 outcount = hcryp->CrypOutCount;
2046
2047 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2048 {
2049 /* Write plain Ddta and get cipher data */
2050 CRYP_AES_ProcessData(hcryp, Timeout);
2051 /*Temporary CrypOutCount Value*/
2052 outcount = hcryp->CrypOutCount;
2053 }
2054
2055 /* Disable CRYP */
2056 __HAL_CRYP_DISABLE(hcryp);
2057
2058 /* Change the CRYP state */
2059 hcryp->State = HAL_CRYP_STATE_READY;
2060
2061 /* Return function status */
2062 return HAL_OK;
2063 }
2064
2065 /**
2066 * @brief Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2067 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2068 * the configuration information for CRYP module
2069 * @retval HAL status
2070 */
CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef * hcryp)2071 static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
2072 {
2073 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2074
2075 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2076 {
2077 if (hcryp->KeyIVConfig == 1U)
2078 {
2079 /* If the Key and IV configuration has to be done only once
2080 and if it has already been done, skip it */
2081 DoKeyIVConfig = 0U;
2082 }
2083 else
2084 {
2085 /* If the Key and IV configuration has to be done only once
2086 and if it has not been done already, do it and set KeyIVConfig
2087 to keep track it won't have to be done again next time */
2088 hcryp->KeyIVConfig = 1U;
2089 }
2090 }
2091
2092 if (DoKeyIVConfig == 1U)
2093 {
2094 /* Set the Key*/
2095 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2096
2097 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2098 {
2099 /* Set the Initialization Vector*/
2100 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2101 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
2102 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
2103 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
2104 }
2105 } /* if (DoKeyIVConfig == 1U) */
2106
2107 /* Set the phase */
2108 hcryp->Phase = CRYP_PHASE_PROCESS;
2109
2110 if (hcryp->Size != 0U)
2111 {
2112 /* Enable interrupts */
2113 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2114
2115 /* Enable CRYP */
2116 __HAL_CRYP_ENABLE(hcryp);
2117 }
2118 else
2119 {
2120 /* Change the CRYP state */
2121 hcryp->State = HAL_CRYP_STATE_READY;
2122
2123 /* Process unlocked */
2124 __HAL_UNLOCK(hcryp);
2125 }
2126
2127 /* Return function status */
2128 return HAL_OK;
2129 }
2130
2131 /**
2132 * @brief Decryption in ECB/CBC & CTR mode with AES Standard
2133 * @param hcryp: pointer to a CRYP_HandleTypeDef structure
2134 * @param Timeout: Specify Timeout value
2135 * @retval HAL status
2136 */
CRYP_AES_Decrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2137 static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2138 {
2139 uint16_t outcount; /* Temporary CrypOutCount Value */
2140 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2141
2142 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2143 {
2144 if (hcryp->KeyIVConfig == 1U)
2145 {
2146 /* If the Key and IV configuration has to be done only once
2147 and if it has already been done, skip it */
2148 DoKeyIVConfig = 0U;
2149 }
2150 else
2151 {
2152 /* If the Key and IV configuration has to be done only once
2153 and if it has not been done already, do it and set KeyIVConfig
2154 to keep track it won't have to be done again next time */
2155 hcryp->KeyIVConfig = 1U;
2156 }
2157 }
2158
2159 if (DoKeyIVConfig == 1U)
2160 {
2161 /* Key preparation for ECB/CBC */
2162 if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/
2163 {
2164 /* change ALGOMODE to key preparation for decryption*/
2165 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2166
2167 /* Set the Key*/
2168 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2169
2170 /* Enable CRYP */
2171 __HAL_CRYP_ENABLE(hcryp);
2172
2173 /* Wait for BUSY flag to be raised */
2174 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
2175 {
2176 /* Disable the CRYP peripheral clock */
2177 __HAL_CRYP_DISABLE(hcryp);
2178
2179 /* Change state */
2180 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2181 hcryp->State = HAL_CRYP_STATE_READY;
2182
2183 /* Process unlocked */
2184 __HAL_UNLOCK(hcryp);
2185 return HAL_ERROR;
2186 }
2187 /* Turn back to ALGOMODE of the configuration */
2188 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2189 }
2190 else /*Algorithm CTR */
2191 {
2192 /* Set the Key*/
2193 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2194 }
2195
2196 /* Set IV */
2197 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2198 {
2199 /* Set the Initialization Vector*/
2200 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2201 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2202 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2203 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2204 }
2205 } /* if (DoKeyIVConfig == 1U) */
2206
2207 /* Set the phase */
2208 hcryp->Phase = CRYP_PHASE_PROCESS;
2209
2210 /* Enable CRYP */
2211 __HAL_CRYP_ENABLE(hcryp);
2212
2213 /*Temporary CrypOutCount Value*/
2214 outcount = hcryp->CrypOutCount;
2215
2216 while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
2217 {
2218 /* Write plain data and get cipher data */
2219 CRYP_AES_ProcessData(hcryp, Timeout);
2220 /*Temporary CrypOutCount Value*/
2221 outcount = hcryp->CrypOutCount;
2222 }
2223
2224 /* Disable CRYP */
2225 __HAL_CRYP_DISABLE(hcryp);
2226
2227 /* Change the CRYP state */
2228 hcryp->State = HAL_CRYP_STATE_READY;
2229
2230 /* Return function status */
2231 return HAL_OK;
2232 }
2233 /**
2234 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
2235 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2236 * the configuration information for CRYP module
2237 * @retval HAL status
2238 */
CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef * hcryp)2239 static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
2240 {
2241 __IO uint32_t count = 0U;
2242 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2243
2244 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2245 {
2246 if (hcryp->KeyIVConfig == 1U)
2247 {
2248 /* If the Key and IV configuration has to be done only once
2249 and if it has already been done, skip it */
2250 DoKeyIVConfig = 0U;
2251 }
2252 else
2253 {
2254 /* If the Key and IV configuration has to be done only once
2255 and if it has not been done already, do it and set KeyIVConfig
2256 to keep track it won't have to be done again next time */
2257 hcryp->KeyIVConfig = 1U;
2258 }
2259 }
2260
2261 if (DoKeyIVConfig == 1U)
2262 {
2263 /* Key preparation for ECB/CBC */
2264 if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2265 {
2266 /* change ALGOMODE to key preparation for decryption*/
2267 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2268
2269 /* Set the Key*/
2270 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2271
2272 /* Enable CRYP */
2273 __HAL_CRYP_ENABLE(hcryp);
2274
2275 /* Wait for BUSY flag to be raised */
2276 count = CRYP_TIMEOUT_KEYPREPARATION;
2277 do
2278 {
2279 count-- ;
2280 if (count == 0U)
2281 {
2282 /* Change state */
2283 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2284 hcryp->State = HAL_CRYP_STATE_READY;
2285
2286 /* Process unlocked */
2287 __HAL_UNLOCK(hcryp);
2288 return HAL_ERROR;
2289 }
2290 }
2291 while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2292
2293 /* Turn back to ALGOMODE of the configuration */
2294 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2295 }
2296 else /*Algorithm CTR */
2297 {
2298 /* Set the Key*/
2299 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2300 }
2301
2302 /* Set IV */
2303 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2304 {
2305 /* Set the Initialization Vector*/
2306 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2307 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2308 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2309 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2310 }
2311 } /* if (DoKeyIVConfig == 1U) */
2312
2313 /* Set the phase */
2314 hcryp->Phase = CRYP_PHASE_PROCESS;
2315 if (hcryp->Size != 0U)
2316 {
2317 /* Enable interrupts */
2318 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
2319
2320 /* Enable CRYP */
2321 __HAL_CRYP_ENABLE(hcryp);
2322 }
2323 else
2324 {
2325 /* Process locked */
2326 __HAL_UNLOCK(hcryp);
2327
2328 /* Change the CRYP state */
2329 hcryp->State = HAL_CRYP_STATE_READY;
2330 }
2331 /* Return function status */
2332 return HAL_OK;
2333 }
2334 /**
2335 * @brief Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
2336 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2337 * the configuration information for CRYP module
2338 * @retval HAL status
2339 */
CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef * hcryp)2340 static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
2341 {
2342 __IO uint32_t count = 0U;
2343 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2344
2345 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2346 {
2347 if (hcryp->KeyIVConfig == 1U)
2348 {
2349 /* If the Key and IV configuration has to be done only once
2350 and if it has already been done, skip it */
2351 DoKeyIVConfig = 0U;
2352 }
2353 else
2354 {
2355 /* If the Key and IV configuration has to be done only once
2356 and if it has not been done already, do it and set KeyIVConfig
2357 to keep track it won't have to be done again next time */
2358 hcryp->KeyIVConfig = 1U;
2359 }
2360 }
2361
2362 if (DoKeyIVConfig == 1U)
2363 {
2364 /* Key preparation for ECB/CBC */
2365 if (hcryp->Init.Algorithm != CRYP_AES_CTR)
2366 {
2367 /* change ALGOMODE to key preparation for decryption*/
2368 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
2369
2370 /* Set the Key*/
2371 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2372
2373 /* Enable CRYP */
2374 __HAL_CRYP_ENABLE(hcryp);
2375
2376 /* Wait for BUSY flag to be raised */
2377 count = CRYP_TIMEOUT_KEYPREPARATION;
2378 do
2379 {
2380 count-- ;
2381 if (count == 0U)
2382 {
2383 /* Disable the CRYP peripheral clock */
2384 __HAL_CRYP_DISABLE(hcryp);
2385
2386 /* Change state */
2387 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2388 hcryp->State = HAL_CRYP_STATE_READY;
2389
2390 /* Process unlocked */
2391 __HAL_UNLOCK(hcryp);
2392 return HAL_ERROR;
2393 }
2394 }
2395 while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
2396
2397 /* Turn back to ALGOMODE of the configuration */
2398 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
2399 }
2400 else /*Algorithm CTR */
2401 {
2402 /* Set the Key*/
2403 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2404 }
2405
2406 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
2407 {
2408 /* Set the Initialization Vector*/
2409 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2410 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2411 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2412 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2413 }
2414 } /* if (DoKeyIVConfig == 1U) */
2415
2416 /* Set the phase */
2417 hcryp->Phase = CRYP_PHASE_PROCESS;
2418
2419 if (hcryp->Size != 0U)
2420 {
2421 /* Set the input and output addresses and start DMA transfer */
2422 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U),
2423 (uint32_t)(hcryp->pCrypOutBuffPtr));
2424 }
2425 else
2426 {
2427 /* Process unlocked */
2428 __HAL_UNLOCK(hcryp);
2429
2430 /* Change the CRYP state */
2431 hcryp->State = HAL_CRYP_STATE_READY;
2432 }
2433
2434 /* Return function status */
2435 return HAL_OK;
2436 }
2437
2438
2439 /**
2440 * @brief DMA CRYP input data process complete callback.
2441 * @param hdma: DMA handle
2442 * @retval None
2443 */
CRYP_DMAInCplt(DMA_HandleTypeDef * hdma)2444 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
2445 {
2446 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2447
2448 /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit
2449 in the DMACR register */
2450 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
2451
2452 /* Call input data transfer complete callback */
2453 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2454 /*Call registered Input complete callback*/
2455 hcryp->InCpltCallback(hcryp);
2456 #else
2457 /*Call legacy weak Input complete callback*/
2458 HAL_CRYP_InCpltCallback(hcryp);
2459 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2460 }
2461
2462 /**
2463 * @brief DMA CRYP output data process complete callback.
2464 * @param hdma: DMA handle
2465 * @retval None
2466 */
CRYP_DMAOutCplt(DMA_HandleTypeDef * hdma)2467 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
2468 {
2469 uint32_t count;
2470 uint32_t npblb;
2471 uint32_t lastwordsize;
2472 uint32_t temp; /* Temporary CrypOutBuff */
2473 uint32_t temp_cr_algodir;
2474 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2475
2476
2477 /* Disable the DMA transfer for output FIFO */
2478 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
2479
2480 /* Last block transfer in case of GCM or CCM with Size not %16*/
2481 if (((hcryp->Size) % 16U) != 0U)
2482 {
2483 /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA */
2484 hcryp->CrypInCount = (hcryp->Size / 16U) * 4U ;
2485 hcryp->CrypOutCount = hcryp->CrypInCount;
2486
2487 /* Compute the number of padding bytes in last block of payload */
2488 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
2489
2490 #if !defined (CRYP_VER_2_2)
2491 if (hcryp->Version >= REV_ID_B)
2492 #endif /*End of not defined CRYP_VER_2_2*/
2493 {
2494 /* Case of AES GCM payload encryption or AES CCM payload decryption to get right tag */
2495 temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
2496 if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
2497 ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
2498 {
2499 /* Disable the CRYP */
2500 __HAL_CRYP_DISABLE(hcryp);
2501
2502 /* Specify the number of non-valid bytes using NPBLB register*/
2503 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
2504
2505 /* Enable CRYP to start the final phase */
2506 __HAL_CRYP_ENABLE(hcryp);
2507 }
2508 }
2509
2510 /* Number of valid words (lastwordsize) in last block */
2511 if ((npblb % 4U) == 0U)
2512 {
2513 lastwordsize = (16U - npblb) / 4U;
2514 }
2515 else
2516 {
2517 lastwordsize = ((16U - npblb) / 4U) + 1U;
2518 }
2519 /* Write the last input block in the IN FIFO */
2520 for (count = 0U; count < lastwordsize; count ++)
2521 {
2522 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2523 hcryp->CrypInCount++;
2524 }
2525 /* Pad the data with zeros to have a complete block */
2526 while (count < 4U)
2527 {
2528 hcryp->Instance->DIN = 0U;
2529 count++;
2530 }
2531 /* Wait for OFNE flag to be raised */
2532 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
2533 do
2534 {
2535 count-- ;
2536 if (count == 0U)
2537 {
2538 /* Disable the CRYP peripheral clock */
2539 __HAL_CRYP_DISABLE(hcryp);
2540
2541 /* Change state */
2542 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2543 hcryp->State = HAL_CRYP_STATE_READY;
2544
2545 /* Process unlocked */
2546 __HAL_UNLOCK(hcryp);
2547 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2548 /*Call registered error callback*/
2549 hcryp->ErrorCallback(hcryp);
2550 #else
2551 /*Call legacy weak error callback*/
2552 HAL_CRYP_ErrorCallback(hcryp);
2553 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2554 }
2555 }
2556 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
2557
2558 /*Read the output block from the output FIFO */
2559 for (count = 0U; count < 4U; count++)
2560 {
2561 /* Read the output block from the output FIFO and put them in temporary buffer
2562 then get CrypOutBuff from temporary buffer */
2563 temp = hcryp->Instance->DOUT;
2564
2565 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
2566 hcryp->CrypOutCount++;
2567 }
2568 } /*End of last block transfer in case of GCM or CCM */
2569
2570 if ((hcryp->Init.Algorithm & CRYP_AES_GCM) != CRYP_AES_GCM)
2571 {
2572 /* Disable CRYP (not allowed in GCM)*/
2573 __HAL_CRYP_DISABLE(hcryp);
2574 }
2575
2576 /* Change the CRYP state to ready */
2577 hcryp->State = HAL_CRYP_STATE_READY;
2578
2579 /* Process unlocked */
2580 __HAL_UNLOCK(hcryp);
2581
2582 /* Call output data transfer complete callback */
2583 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2584 /*Call registered Output complete callback*/
2585 hcryp->OutCpltCallback(hcryp);
2586 #else
2587 /*Call legacy weak Output complete callback*/
2588 HAL_CRYP_OutCpltCallback(hcryp);
2589 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2590 }
2591
2592 /**
2593 * @brief DMA CRYP communication error callback.
2594 * @param hdma: DMA handle
2595 * @retval None
2596 */
CRYP_DMAError(DMA_HandleTypeDef * hdma)2597 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
2598 {
2599 CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2600
2601 /* Change the CRYP peripheral state */
2602 hcryp->State = HAL_CRYP_STATE_READY;
2603
2604 /* DMA error code field */
2605 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2606
2607 /* Call error callback */
2608 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2609 /*Call registered error callback*/
2610 hcryp->ErrorCallback(hcryp);
2611 #else
2612 /*Call legacy weak error callback*/
2613 HAL_CRYP_ErrorCallback(hcryp);
2614 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2615 }
2616
2617 /**
2618 * @brief Set the DMA configuration and start the DMA transfer
2619 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2620 * the configuration information for CRYP module
2621 * @param inputaddr: address of the input buffer
2622 * @param Size: size of the input buffer, must be a multiple of 16.
2623 * @param outputaddr: address of the output buffer
2624 * @retval None
2625 */
CRYP_SetDMAConfig(CRYP_HandleTypeDef * hcryp,uint32_t inputaddr,uint16_t Size,uint32_t outputaddr)2626 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
2627 {
2628 /* Set the CRYP DMA transfer complete callback */
2629 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
2630
2631 /* Set the DMA input error callback */
2632 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
2633
2634 /* Set the CRYP DMA transfer complete callback */
2635 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
2636
2637 /* Set the DMA output error callback */
2638 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
2639
2640 /* Enable CRYP */
2641 __HAL_CRYP_ENABLE(hcryp);
2642
2643 /* Enable the input DMA Stream */
2644 if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DIN, Size) != HAL_OK)
2645 {
2646 /* DMA error code field */
2647 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2648
2649 /* Call error callback */
2650 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2651 /*Call registered error callback*/
2652 hcryp->ErrorCallback(hcryp);
2653 #else
2654 /*Call legacy weak error callback*/
2655 HAL_CRYP_ErrorCallback(hcryp);
2656 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2657 }
2658
2659 /* Enable the output DMA Stream */
2660 if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size) != HAL_OK)
2661 {
2662 /* DMA error code field */
2663 hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
2664
2665 /* Call error callback */
2666 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2667 /*Call registered error callback*/
2668 hcryp->ErrorCallback(hcryp);
2669 #else
2670 /*Call legacy weak error callback*/
2671 HAL_CRYP_ErrorCallback(hcryp);
2672 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2673 }
2674 /* Enable In/Out DMA request */
2675 hcryp->Instance->DMACR = CRYP_DMACR_DOEN | CRYP_DMACR_DIEN;
2676 }
2677
2678 /**
2679 * @brief Process Data: Write Input data in polling mode and used in AES functions.
2680 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2681 * the configuration information for CRYP module
2682 * @param Timeout: Specify Timeout value
2683 * @retval None
2684 */
CRYP_AES_ProcessData(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2685 static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2686 {
2687
2688 uint32_t temp[4]; /* Temporary CrypOutBuff */
2689 uint16_t incount; /* Temporary CrypInCount Value */
2690 uint16_t outcount; /* Temporary CrypOutCount Value */
2691 uint32_t i;
2692
2693 /*Temporary CrypOutCount Value*/
2694 incount = hcryp->CrypInCount;
2695
2696 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < ((hcryp->Size) / 4U)))
2697 {
2698 /* Write the input block in the IN FIFO */
2699 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2700 hcryp->CrypInCount++;
2701 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2702 hcryp->CrypInCount++;
2703 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2704 hcryp->CrypInCount++;
2705 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2706 hcryp->CrypInCount++;
2707 }
2708
2709 /* Wait for OFNE flag to be raised */
2710 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
2711 {
2712 /* Disable the CRYP peripheral clock */
2713 __HAL_CRYP_DISABLE(hcryp);
2714
2715 /* Change state & error code*/
2716 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2717 hcryp->State = HAL_CRYP_STATE_READY;
2718
2719 /* Process unlocked */
2720 __HAL_UNLOCK(hcryp);
2721 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2722 /*Call registered error callback*/
2723 hcryp->ErrorCallback(hcryp);
2724 #else
2725 /*Call legacy weak error callback*/
2726 HAL_CRYP_ErrorCallback(hcryp);
2727 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2728 }
2729 /*Temporary CrypOutCount Value*/
2730 outcount = hcryp->CrypOutCount;
2731
2732 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < ((hcryp->Size) / 4U)))
2733 {
2734 /* Read the output block from the Output FIFO and put them in temporary buffer
2735 then get CrypOutBuff from temporary buffer */
2736 for (i = 0U; i < 4U; i++)
2737 {
2738 temp[i] = hcryp->Instance->DOUT;
2739 }
2740 i = 0U;
2741 while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
2742 {
2743 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2744 hcryp->CrypOutCount++;
2745 i++;
2746 }
2747 }
2748 }
2749
2750 /**
2751 * @brief Handle CRYP block input/output data handling under interruption.
2752 * @note The function is called under interruption only, once
2753 * interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
2754 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2755 * the configuration information for CRYP module.
2756 * @retval HAL status
2757 */
CRYP_AES_IT(CRYP_HandleTypeDef * hcryp)2758 static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
2759 {
2760 uint32_t temp[4]; /* Temporary CrypOutBuff */
2761 uint16_t incount; /* Temporary CrypInCount Value */
2762 uint16_t outcount; /* Temporary CrypOutCount Value */
2763 uint32_t i;
2764
2765 if (hcryp->State == HAL_CRYP_STATE_BUSY)
2766 {
2767 /*Temporary CrypOutCount Value*/
2768 incount = hcryp->CrypInCount;
2769
2770 if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
2771 {
2772 /* Write the input block in the IN FIFO */
2773 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2774 hcryp->CrypInCount++;
2775 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2776 hcryp->CrypInCount++;
2777 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2778 hcryp->CrypInCount++;
2779 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
2780 hcryp->CrypInCount++;
2781 if (hcryp->CrypInCount == (hcryp->Size / 4U))
2782 {
2783 /* Disable interrupts */
2784 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
2785
2786 /* Call the input data transfer complete callback */
2787 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2788 /*Call registered Input complete callback*/
2789 hcryp->InCpltCallback(hcryp);
2790 #else
2791 /*Call legacy weak Input complete callback*/
2792 HAL_CRYP_InCpltCallback(hcryp);
2793 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2794 }
2795 }
2796
2797 /*Temporary CrypOutCount Value*/
2798 outcount = hcryp->CrypOutCount;
2799
2800 if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
2801 {
2802 /* Read the output block from the output FIFO and put them in temporary buffer
2803 then get CrypOutBuff from temporary buffer */
2804 for (i = 0U; i < 4U; i++)
2805 {
2806 temp[i] = hcryp->Instance->DOUT;
2807 }
2808 i = 0U;
2809 while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
2810 {
2811 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
2812 hcryp->CrypOutCount++;
2813 i++;
2814 }
2815 if (hcryp->CrypOutCount == (hcryp->Size / 4U))
2816 {
2817 /* Disable interrupts */
2818 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
2819
2820 /* Change the CRYP state */
2821 hcryp->State = HAL_CRYP_STATE_READY;
2822
2823 /* Disable CRYP */
2824 __HAL_CRYP_DISABLE(hcryp);
2825
2826 /* Process unlocked */
2827 __HAL_UNLOCK(hcryp);
2828
2829 /* Call output transfer complete callback */
2830 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2831 /*Call registered Output complete callback*/
2832 hcryp->OutCpltCallback(hcryp);
2833 #else
2834 /*Call legacy weak Output complete callback*/
2835 HAL_CRYP_OutCpltCallback(hcryp);
2836 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2837 }
2838 }
2839 }
2840 else
2841 {
2842 /* Process unlocked */
2843 __HAL_UNLOCK(hcryp);
2844 /* Busy error code field */
2845 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
2846 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
2847 /*Call registered error callback*/
2848 hcryp->ErrorCallback(hcryp);
2849 #else
2850 /*Call legacy weak error callback*/
2851 HAL_CRYP_ErrorCallback(hcryp);
2852 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
2853 }
2854 }
2855
2856 /**
2857 * @brief Writes Key in Key registers.
2858 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2859 * the configuration information for CRYP module
2860 * @param KeySize: Size of Key
2861 * @retval None
2862 */
CRYP_SetKey(CRYP_HandleTypeDef * hcryp,uint32_t KeySize)2863 static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
2864 {
2865 switch (KeySize)
2866 {
2867 case CRYP_KEYSIZE_256B:
2868 hcryp->Instance->K0LR = *(uint32_t *)(hcryp->Init.pKey);
2869 hcryp->Instance->K0RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2870 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2871 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2872 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2873 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2874 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 6);
2875 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 7);
2876 break;
2877 case CRYP_KEYSIZE_192B:
2878 hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
2879 hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2880 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2881 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2882 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
2883 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
2884 break;
2885 case CRYP_KEYSIZE_128B:
2886 hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey);
2887 hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 1);
2888 hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 2);
2889 hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 3);
2890
2891 break;
2892 default:
2893 break;
2894 }
2895 }
2896
2897 /**
2898 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
2899 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
2900 * the configuration information for CRYP module
2901 * @param Timeout: Timeout duration
2902 * @retval HAL status
2903 */
CRYP_AESGCM_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)2904 static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
2905 {
2906 uint32_t tickstart;
2907 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
2908 uint32_t npblb ;
2909 uint32_t temp[4]; /* Temporary CrypOutBuff */
2910 uint32_t index ;
2911 uint32_t lastwordsize ;
2912 uint32_t nolastpaddingbytes;
2913 uint8_t *pval;
2914 uint16_t outcount; /* Temporary CrypOutCount Value */
2915 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
2916
2917 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
2918 {
2919 if (hcryp->KeyIVConfig == 1U)
2920 {
2921 /* If the Key and IV configuration has to be done only once
2922 and if it has already been done, skip it */
2923 DoKeyIVConfig = 0U;
2924 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
2925 }
2926 else
2927 {
2928 /* If the Key and IV configuration has to be done only once
2929 and if it has not been done already, do it and set KeyIVConfig
2930 to keep track it won't have to be done again next time */
2931 hcryp->KeyIVConfig = 1U;
2932 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
2933 }
2934 }
2935 else
2936 {
2937 hcryp->SizesSum = hcryp->Size;
2938 }
2939
2940 if (DoKeyIVConfig == 1U)
2941 {
2942 /* Reset CrypHeaderCount */
2943 hcryp->CrypHeaderCount = 0U;
2944
2945 /****************************** Init phase **********************************/
2946
2947 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
2948
2949 /* Set the key */
2950 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
2951
2952 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
2953 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
2954 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
2955 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
2956 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
2957
2958 /* Enable the CRYP peripheral */
2959 __HAL_CRYP_ENABLE(hcryp);
2960
2961 /* Get tick */
2962 tickstart = HAL_GetTick();
2963
2964 /*Wait for the CRYPEN bit to be cleared*/
2965 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
2966 {
2967 /* Check for the Timeout */
2968 if (Timeout != HAL_MAX_DELAY)
2969 {
2970 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2971 {
2972 /* Disable the CRYP peripheral clock */
2973 __HAL_CRYP_DISABLE(hcryp);
2974
2975 /* Change state */
2976 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
2977 hcryp->State = HAL_CRYP_STATE_READY;
2978
2979 /* Process unlocked */
2980 __HAL_UNLOCK(hcryp);
2981 return HAL_ERROR;
2982 }
2983 }
2984 }
2985
2986 /************************ Header phase *************************************/
2987
2988 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
2989 {
2990 return HAL_ERROR;
2991 }
2992
2993 /*************************Payload phase ************************************/
2994
2995 /* Set the phase */
2996 hcryp->Phase = CRYP_PHASE_PROCESS;
2997
2998 /* Disable the CRYP peripheral */
2999 __HAL_CRYP_DISABLE(hcryp);
3000
3001 #if !defined (CRYP_VER_2_2)
3002 if (hcryp->Version >= REV_ID_B)
3003 #endif /*End of not defined CRYP_VER_2_2*/
3004 {
3005 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3006 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3007 }
3008
3009 /* Select payload phase once the header phase is performed */
3010 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3011
3012 /* Enable the CRYP peripheral */
3013 __HAL_CRYP_ENABLE(hcryp);
3014 } /* if (DoKeyIVConfig == 1U) */
3015
3016 if ((hcryp->Size % 16U) != 0U)
3017 {
3018 /* recalculate wordsize */
3019 wordsize = ((wordsize / 4U) * 4U) ;
3020 }
3021
3022 /* Get tick */
3023 tickstart = HAL_GetTick();
3024 /*Temporary CrypOutCount Value*/
3025 outcount = hcryp->CrypOutCount;
3026
3027 /* Write input data and get output Data */
3028 while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3029 {
3030 /* Write plain data and get cipher data */
3031 CRYP_AES_ProcessData(hcryp, Timeout);
3032
3033 /*Temporary CrypOutCount Value*/
3034 outcount = hcryp->CrypOutCount;
3035
3036 /* Check for the Timeout */
3037 if (Timeout != HAL_MAX_DELAY)
3038 {
3039 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3040 {
3041 /* Disable the CRYP peripheral clock */
3042 __HAL_CRYP_DISABLE(hcryp);
3043
3044 /* Change state & error code */
3045 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3046 hcryp->State = HAL_CRYP_STATE_READY;
3047
3048 /* Process unlocked */
3049 __HAL_UNLOCK(hcryp);
3050 return HAL_ERROR;
3051 }
3052 }
3053 }
3054
3055 if ((hcryp->Size % 16U) != 0U)
3056 {
3057
3058 #if !defined (CRYP_VER_2_2)
3059 if (hcryp->Version >= REV_ID_B)
3060 #endif /*End of not defined CRYP_VER_2_2*/
3061 {
3062 /* Compute the number of padding bytes in last block of payload */
3063 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3064
3065 /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3066 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3067 {
3068 /* Disable the CRYP */
3069 __HAL_CRYP_DISABLE(hcryp);
3070
3071 /* Specify the number of non-valid bytes using NPBLB register*/
3072 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3073
3074 /* Enable CRYP to start the final phase */
3075 __HAL_CRYP_ENABLE(hcryp);
3076 }
3077 /* Number of valid words (lastwordsize) in last block */
3078 if ((npblb % 4U) == 0U)
3079 {
3080 lastwordsize = (16U - npblb) / 4U;
3081 }
3082 else
3083 {
3084 lastwordsize = ((16U - npblb) / 4U) + 1U;
3085 }
3086
3087 /* Write the last input block in the IN FIFO */
3088 for (index = 0U; index < lastwordsize; index ++)
3089 {
3090 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3091 hcryp->CrypInCount++;
3092 }
3093
3094 /* Pad the data with zeros to have a complete block */
3095 while (index < 4U)
3096 {
3097 hcryp->Instance->DIN = 0U;
3098 index++;
3099 }
3100
3101 /* Wait for OFNE flag to be raised */
3102 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3103 {
3104 /* Disable the CRYP peripheral clock */
3105 __HAL_CRYP_DISABLE(hcryp);
3106
3107 /* Change state */
3108 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3109 hcryp->State = HAL_CRYP_STATE_READY;
3110
3111 /* Process Unlocked */
3112 __HAL_UNLOCK(hcryp);
3113 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3114 /*Call registered error callback*/
3115 hcryp->ErrorCallback(hcryp);
3116 #else
3117 /*Call legacy weak error callback*/
3118 HAL_CRYP_ErrorCallback(hcryp);
3119 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3120 }
3121
3122 /*Read the output block from the output FIFO */
3123 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3124 {
3125 for (index = 0U; index < 4U; index++)
3126 {
3127 /* Read the output block from the output FIFO and put them in temporary buffer
3128 then get CrypOutBuff from temporary buffer */
3129 temp[index] = hcryp->Instance->DOUT;
3130 }
3131
3132 for (index = 0U; index < lastwordsize; index++)
3133 {
3134 pval = (uint8_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount));
3135
3136 if (index == (lastwordsize - 1U))
3137 {
3138 nolastpaddingbytes = npblb % 4U;
3139
3140 switch (nolastpaddingbytes)
3141 {
3142 case 1:
3143 *(pval) = (uint8_t)(temp[index]);
3144 pval++;
3145 *(pval) = (uint8_t)(temp[index] >> 8U);
3146 pval++;
3147 *(pval) = (uint8_t)(temp[index] >> 16U);
3148 break;
3149 case 2:
3150 *(pval) = (uint8_t)(temp[index]);
3151 pval++;
3152 *(pval) = (uint8_t)(temp[index] >> 8U);
3153 break;
3154 case 3:
3155 *(pval) = (uint8_t)(temp[index]);
3156 break;
3157 default:
3158 *(pval) = (uint8_t)(temp[index]);
3159 pval++;
3160 *(pval) = (uint8_t)(temp[index] >> 8U);
3161 pval++;
3162 *(pval) = (uint8_t)(temp[index] >> 16U);
3163 pval++;
3164 *(pval) = (uint8_t)(temp[index] >> 24U);
3165 break;
3166 }
3167 }
3168 else
3169 {
3170 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
3171 }
3172
3173 hcryp->CrypOutCount++;
3174 }
3175 }
3176 }
3177 #if !defined (CRYP_VER_2_2)
3178 else /* Workaround to be used */
3179 {
3180 /* Workaround 2 for STM32H7 below rev.B To generate correct TAG only when size of the last block of
3181 payload is inferior to 128 bits, in case of GCM encryption or CCM decryption*/
3182 CRYP_Workaround(hcryp, Timeout);
3183 } /* end of NPBLB or Workaround*/
3184 #endif /*End of not defined CRYP_VER_2_2*/
3185 }
3186
3187 /* Return function status */
3188 return HAL_OK;
3189 }
3190
3191 /**
3192 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
3193 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3194 * the configuration information for CRYP module
3195 * @retval HAL status
3196 */
CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef * hcryp)3197 static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3198 {
3199 __IO uint32_t count = 0U;
3200 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3201
3202 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3203 {
3204 if (hcryp->KeyIVConfig == 1U)
3205 {
3206 /* If the Key and IV configuration has to be done only once
3207 and if it has already been done, skip it */
3208 DoKeyIVConfig = 0U;
3209 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3210 }
3211 else
3212 {
3213 /* If the Key and IV configuration has to be done only once
3214 and if it has not been done already, do it and set KeyIVConfig
3215 to keep track it won't have to be done again next time */
3216 hcryp->KeyIVConfig = 1U;
3217 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3218 }
3219 }
3220 else
3221 {
3222 hcryp->SizesSum = hcryp->Size;
3223 }
3224
3225 /* Configure Key, IV and process message (header and payload) */
3226 if (DoKeyIVConfig == 1U)
3227 {
3228 /* Reset CrypHeaderCount */
3229 hcryp->CrypHeaderCount = 0U;
3230
3231 /******************************* Init phase *********************************/
3232
3233 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3234
3235 /* Set the key */
3236 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3237
3238 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3239 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3240 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3241 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3242 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3243
3244 /* Enable the CRYP peripheral */
3245 __HAL_CRYP_ENABLE(hcryp);
3246
3247 /*Wait for the CRYPEN bit to be cleared*/
3248 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3249 do
3250 {
3251 count-- ;
3252 if (count == 0U)
3253 {
3254 /* Disable the CRYP peripheral clock */
3255 __HAL_CRYP_DISABLE(hcryp);
3256
3257 /* Change state */
3258 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3259 hcryp->State = HAL_CRYP_STATE_READY;
3260
3261 /* Process unlocked */
3262 __HAL_UNLOCK(hcryp);
3263 return HAL_ERROR;
3264 }
3265 }
3266 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3267
3268 /***************************** Header phase *********************************/
3269
3270 /* Select header phase */
3271 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3272 } /* end of if (DoKeyIVConfig == 1U) */
3273 /* Enable interrupts */
3274 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3275
3276 /* Enable CRYP */
3277 __HAL_CRYP_ENABLE(hcryp);
3278
3279 /* Return function status */
3280 return HAL_OK;
3281 }
3282
3283
3284 /**
3285 * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
3286 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3287 * the configuration information for CRYP module
3288 * @retval HAL status
3289 */
CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef * hcryp)3290 static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3291 {
3292 __IO uint32_t count = 0U;
3293 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3294 uint32_t index;
3295 uint32_t npblb;
3296 uint32_t lastwordsize;
3297 uint32_t temp[4]; /* Temporary CrypOutBuff */
3298 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3299
3300 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3301 {
3302 if (hcryp->KeyIVConfig == 1U)
3303 {
3304 /* If the Key and IV configuration has to be done only once
3305 and if it has already been done, skip it */
3306 DoKeyIVConfig = 0U;
3307 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3308 }
3309 else
3310 {
3311 /* If the Key and IV configuration has to be done only once
3312 and if it has not been done already, do it and set KeyIVConfig
3313 to keep track it won't have to be done again next time */
3314 hcryp->KeyIVConfig = 1U;
3315 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3316 }
3317 }
3318 else
3319 {
3320 hcryp->SizesSum = hcryp->Size;
3321 }
3322
3323 if (DoKeyIVConfig == 1U)
3324 {
3325 /* Reset CrypHeaderCount */
3326 hcryp->CrypHeaderCount = 0U;
3327
3328 /*************************** Init phase ************************************/
3329
3330 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3331
3332 /* Set the key */
3333 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3334
3335 /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
3336 hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
3337 hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
3338 hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
3339 hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
3340
3341 /* Enable the CRYP peripheral */
3342 __HAL_CRYP_ENABLE(hcryp);
3343
3344 /*Wait for the CRYPEN bit to be cleared*/
3345 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3346 do
3347 {
3348 count-- ;
3349 if (count == 0U)
3350 {
3351 /* Disable the CRYP peripheral clock */
3352 __HAL_CRYP_DISABLE(hcryp);
3353
3354 /* Change state */
3355 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3356 hcryp->State = HAL_CRYP_STATE_READY;
3357
3358 /* Process unlocked */
3359 __HAL_UNLOCK(hcryp);
3360 return HAL_ERROR;
3361 }
3362 }
3363 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3364
3365 /************************ Header phase *************************************/
3366
3367 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
3368 {
3369 return HAL_ERROR;
3370 }
3371
3372 /************************ Payload phase ************************************/
3373
3374 /* Set the phase */
3375 hcryp->Phase = CRYP_PHASE_PROCESS;
3376
3377 /* Disable the CRYP peripheral */
3378 __HAL_CRYP_DISABLE(hcryp);
3379
3380 #if !defined (CRYP_VER_2_2)
3381 if (hcryp->Version >= REV_ID_B)
3382 #endif /*End of not defined CRYP_VER_2_2*/
3383 {
3384 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3385 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3386 }
3387
3388 /* Select payload phase once the header phase is performed */
3389 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3390
3391 } /* if (DoKeyIVConfig == 1U) */
3392
3393 if (hcryp->Size == 0U)
3394 {
3395 /* Process unLocked */
3396 __HAL_UNLOCK(hcryp);
3397
3398 /* Change the CRYP state and phase */
3399 hcryp->State = HAL_CRYP_STATE_READY;
3400 }
3401 else if (hcryp->Size >= 16U)
3402 {
3403 /* for STM32H7 below rev.B : Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption:
3404 Workaround is implemented in polling mode, so if last block of payload <128bit don't use DMA mode otherwise
3405 TAG is incorrectly generated */
3406
3407 /*DMA transfer must not include the last block in case of Size is not %16 */
3408 wordsize = wordsize - (wordsize % 4U);
3409
3410 /*DMA transfer */
3411 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)wordsize,
3412 (uint32_t)(hcryp->pCrypOutBuffPtr));
3413 }
3414 else /* length of input data is < 16 */
3415 {
3416 /* Compute the number of padding bytes in last block of payload */
3417 npblb = 16U - (uint32_t)hcryp->Size;
3418
3419 #if !defined (CRYP_VER_2_2)
3420 if (hcryp->Version >= REV_ID_B)
3421 #endif /*End of not defined CRYP_VER_2_2*/
3422 {
3423 /* Set Npblb in case of AES GCM payload encryption to get right tag*/
3424 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
3425 {
3426 /* Specify the number of non-valid bytes using NPBLB register*/
3427 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3428 }
3429 }
3430 /* Enable CRYP to start the final phase */
3431 __HAL_CRYP_ENABLE(hcryp);
3432
3433 /* Number of valid words (lastwordsize) in last block */
3434 if ((npblb % 4U) == 0U)
3435 {
3436 lastwordsize = (16U - npblb) / 4U;
3437 }
3438 else
3439 {
3440 lastwordsize = ((16U - npblb) / 4U) + 1U;
3441 }
3442
3443 /* Write the last input block in the IN FIFO */
3444 for (index = 0; index < lastwordsize; index ++)
3445 {
3446 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3447 hcryp->CrypInCount++;
3448 }
3449
3450 /* Pad the data with zeros to have a complete block */
3451 while (index < 4U)
3452 {
3453 hcryp->Instance->DIN = 0U;
3454 index++;
3455 }
3456
3457 /* Wait for OFNE flag to be raised */
3458 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
3459 do
3460 {
3461 count-- ;
3462 if (count == 0U)
3463 {
3464 /* Disable the CRYP peripheral clock */
3465 __HAL_CRYP_DISABLE(hcryp);
3466
3467 /* Change state */
3468 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3469 hcryp->State = HAL_CRYP_STATE_READY;
3470
3471 /* Process unlocked */
3472 __HAL_UNLOCK(hcryp);
3473 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3474 /*Call registered error callback*/
3475 hcryp->ErrorCallback(hcryp);
3476 #else
3477 /*Call legacy weak error callback*/
3478 HAL_CRYP_ErrorCallback(hcryp);
3479 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3480 }
3481 }
3482 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
3483
3484 /*Read the output block from the output FIFO */
3485 for (index = 0U; index < 4U; index++)
3486 {
3487 /* Read the output block from the output FIFO and put them in temporary buffer
3488 then get CrypOutBuff from temporary buffer */
3489 temp[index] = hcryp->Instance->DOUT;
3490 }
3491 for (index = 0; index < lastwordsize; index++)
3492 {
3493 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3494 hcryp->CrypOutCount++;
3495 }
3496
3497 /* Change the CRYP state to ready */
3498 hcryp->State = HAL_CRYP_STATE_READY;
3499
3500 /* Process unlocked */
3501 __HAL_UNLOCK(hcryp);
3502 }
3503
3504 /* Return function status */
3505 return HAL_OK;
3506 }
3507
3508
3509 /**
3510 * @brief AES CCM encryption/decryption processing in polling mode
3511 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3512 * the configuration information for CRYP module
3513 * @param Timeout: Timeout duration
3514 * @retval HAL status
3515 */
CRYP_AESCCM_Process(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)3516 static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
3517 {
3518 uint32_t tickstart;
3519 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
3520 uint32_t npblb ;
3521 uint32_t lastwordsize ;
3522 uint32_t temp[4] ; /* Temporary CrypOutBuff */
3523 uint32_t index ;
3524 uint16_t outcount; /* Temporary CrypOutCount Value */
3525 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3526
3527 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3528 {
3529 if (hcryp->KeyIVConfig == 1U)
3530 {
3531 /* If the Key and IV configuration has to be done only once
3532 and if it has already been done, skip it */
3533 DoKeyIVConfig = 0U;
3534 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3535 }
3536 else
3537 {
3538 /* If the Key and IV configuration has to be done only once
3539 and if it has not been done already, do it and set KeyIVConfig
3540 to keep track it won't have to be done again next time */
3541 hcryp->KeyIVConfig = 1U;
3542 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3543 }
3544 }
3545 else
3546 {
3547 hcryp->SizesSum = hcryp->Size;
3548 }
3549
3550 if (DoKeyIVConfig == 1U)
3551 {
3552 /* Reset CrypHeaderCount */
3553 hcryp->CrypHeaderCount = 0U;
3554
3555 /********************** Init phase ******************************************/
3556
3557 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3558
3559 /* Set the key */
3560 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3561
3562 /* Set the initialization vector (IV) with CTR1 information */
3563 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3564 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3565 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3566 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
3567
3568 /* Enable the CRYP peripheral */
3569 __HAL_CRYP_ENABLE(hcryp);
3570
3571 #if defined (CRYP_VER_2_2)
3572 {
3573 /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/
3574 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3575 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3576 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3577 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3578 }
3579 #else
3580 if (hcryp->Version >= REV_ID_B)
3581 {
3582 /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/
3583 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3584 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3585 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3586 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3587 }
3588 else /* data has to be swapped according to the DATATYPE */
3589 {
3590 if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
3591 {
3592 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3593 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3594 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3595 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3596 }
3597 else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
3598 {
3599 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3600 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3601 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3602 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3603 }
3604 else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
3605 {
3606 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3607 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3608 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3609 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3610 }
3611 else
3612 {
3613 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3614 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3615 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3616 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3617 }
3618 }
3619 #endif /* CRYP_VER_2_2 */
3620 /* Get tick */
3621 tickstart = HAL_GetTick();
3622
3623 /*Wait for the CRYPEN bit to be cleared*/
3624 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
3625 {
3626 /* Check for the Timeout */
3627 if (Timeout != HAL_MAX_DELAY)
3628 {
3629 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3630 {
3631 /* Disable the CRYP peripheral clock */
3632 __HAL_CRYP_DISABLE(hcryp);
3633
3634 /* Change state */
3635 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3636 hcryp->State = HAL_CRYP_STATE_READY;
3637
3638 /* Process unlocked */
3639 __HAL_UNLOCK(hcryp);
3640 return HAL_ERROR;
3641 }
3642 }
3643 }
3644
3645 /************************* Header phase *************************************/
3646 /* Header block(B1) : associated data length expressed in bytes concatenated
3647 with Associated Data (A)*/
3648
3649 if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
3650 {
3651 return HAL_ERROR;
3652 }
3653 /********************** Payload phase ***************************************/
3654
3655 /* Set the phase */
3656 hcryp->Phase = CRYP_PHASE_PROCESS;
3657
3658 /* Disable the CRYP peripheral */
3659 __HAL_CRYP_DISABLE(hcryp);
3660 #if !defined (CRYP_VER_2_2)
3661 if (hcryp->Version >= REV_ID_B)
3662 #endif /*End of not defined CRYP_VER_2_2*/
3663 {
3664 /* Set to 0 the number of non-valid bytes using NPBLB register*/
3665 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
3666 }
3667
3668 /* Select payload phase once the header phase is performed */
3669 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
3670
3671 /* Enable the CRYP peripheral */
3672 __HAL_CRYP_ENABLE(hcryp);
3673
3674 } /* if (DoKeyIVConfig == 1U) */
3675
3676 if ((hcryp->Size % 16U) != 0U)
3677 {
3678 /* recalculate wordsize */
3679 wordsize = ((wordsize / 4U) * 4U) ;
3680 }
3681 /* Get tick */
3682 tickstart = HAL_GetTick();
3683
3684 /*Temporary CrypOutCount Value*/
3685 outcount = hcryp->CrypOutCount;
3686
3687 /* Write input data and get output data */
3688 while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
3689 {
3690 /* Write plain data and get cipher data */
3691 CRYP_AES_ProcessData(hcryp, Timeout);
3692
3693 /*Temporary CrypOutCount Value*/
3694 outcount = hcryp->CrypOutCount;
3695
3696 /* Check for the Timeout */
3697 if (Timeout != HAL_MAX_DELAY)
3698 {
3699 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3700 {
3701 /* Disable the CRYP peripheral clock */
3702 __HAL_CRYP_DISABLE(hcryp);
3703
3704 /* Change state */
3705 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3706 hcryp->State = HAL_CRYP_STATE_READY;
3707
3708 /* Process unlocked */
3709 __HAL_UNLOCK(hcryp);
3710 return HAL_ERROR;
3711 }
3712 }
3713 }
3714
3715 if ((hcryp->Size % 16U) != 0U)
3716 {
3717 #if !defined (CRYP_VER_2_2)
3718 if (hcryp->Version >= REV_ID_B)
3719 #endif /*End of not defined CRYP_VER_2_2*/
3720 {
3721 /* Compute the number of padding bytes in last block of payload */
3722 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
3723
3724 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
3725 {
3726 /* Disable the CRYP */
3727 __HAL_CRYP_DISABLE(hcryp);
3728
3729 /* Set Npblb in case of AES CCM payload decryption to get right tag */
3730 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
3731
3732 /* Enable CRYP to start the final phase */
3733 __HAL_CRYP_ENABLE(hcryp);
3734 }
3735
3736 /* Number of valid words (lastwordsize) in last block */
3737 if ((npblb % 4U) == 0U)
3738 {
3739 lastwordsize = (16U - npblb) / 4U;
3740 }
3741 else
3742 {
3743 lastwordsize = ((16U - npblb) / 4U) + 1U;
3744 }
3745
3746 /* Write the last input block in the IN FIFO */
3747 for (index = 0U; index < lastwordsize; index ++)
3748 {
3749 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
3750 hcryp->CrypInCount++;
3751 }
3752
3753 /* Pad the data with zeros to have a complete block */
3754 while (index < 4U)
3755 {
3756 hcryp->Instance->DIN = 0U;
3757 index++;
3758 }
3759
3760 /* Wait for OFNE flag to be raised */
3761 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
3762 {
3763 /* Disable the CRYP peripheral clock */
3764 __HAL_CRYP_DISABLE(hcryp);
3765
3766 /* Change state */
3767 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3768 hcryp->State = HAL_CRYP_STATE_READY;
3769
3770 /* Process Unlocked */
3771 __HAL_UNLOCK(hcryp);
3772 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
3773 /*Call registered error callback*/
3774 hcryp->ErrorCallback(hcryp);
3775 #else
3776 /*Call legacy weak error callback*/
3777 HAL_CRYP_ErrorCallback(hcryp);
3778 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
3779 }
3780
3781 /*Read the output block from the output FIFO */
3782 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
3783 {
3784 for (index = 0U; index < 4U; index++)
3785 {
3786 /* Read the output block from the output FIFO and put them in temporary buffer
3787 then get CrypOutBuff from temporary buffer */
3788 temp[index] = hcryp->Instance->DOUT;
3789 }
3790 for (index = 0; index < lastwordsize; index++)
3791 {
3792 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
3793 hcryp->CrypOutCount++;
3794 }
3795 }
3796 }
3797 #if !defined (CRYP_VER_2_2)
3798 else /* No NPBLB, Workaround to be used */
3799 {
3800 /* CRYP Workaround : CRYP1 generates correct TAG during CCM decryption only when ciphertext
3801 blocks size is multiple of 128 bits. If lthe size of the last block of payload is inferior to 128 bits,
3802 when CCM decryption is selected, then the TAG message will be wrong.*/
3803 CRYP_Workaround(hcryp, Timeout);
3804 }
3805 #endif /*End of not defined CRYP_VER_2_2*/
3806 }
3807
3808 /* Return function status */
3809 return HAL_OK;
3810 }
3811
3812 /**
3813 * @brief AES CCM encryption/decryption process in interrupt mode
3814 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3815 * the configuration information for CRYP module
3816 * @retval HAL status
3817 */
CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef * hcryp)3818 static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
3819 {
3820 __IO uint32_t count = 0U;
3821 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3822
3823 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3824 {
3825 if (hcryp->KeyIVConfig == 1U)
3826 {
3827 /* If the Key and IV configuration has to be done only once
3828 and if it has already been done, skip it */
3829 DoKeyIVConfig = 0U;
3830 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3831 }
3832 else
3833 {
3834 /* If the Key and IV configuration has to be done only once
3835 and if it has not been done already, do it and set KeyIVConfig
3836 to keep track it won't have to be done again next time */
3837 hcryp->KeyIVConfig = 1U;
3838 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3839 }
3840 }
3841 else
3842 {
3843 hcryp->SizesSum = hcryp->Size;
3844 }
3845
3846 /* Configure Key, IV and process message (header and payload) */
3847 if (DoKeyIVConfig == 1U)
3848 {
3849 /* Reset CrypHeaderCount */
3850 hcryp->CrypHeaderCount = 0U;
3851
3852 /************ Init phase ************/
3853
3854 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3855
3856 /* Set the key */
3857 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3858
3859 /* Set the initialization vector (IV) with CTR1 information */
3860 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3861 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3862 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
3863 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
3864
3865 /* Enable the CRYP peripheral */
3866 __HAL_CRYP_ENABLE(hcryp);
3867
3868 /*Write the B0 packet into CRYP_DR*/
3869 #if !defined (CRYP_VER_2_2)
3870 if (hcryp->Version >= REV_ID_B)
3871 #endif /*End of not defined CRYP_VER_2_2*/
3872 {
3873 /* for STM32H7 rev.B and above data has not to be swapped */
3874 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3875 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3876 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3877 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3878 }
3879 #if !defined (CRYP_VER_2_2)
3880 else /* data has to be swapped according to the DATATYPE */
3881 {
3882 if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
3883 {
3884 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
3885 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
3886 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
3887 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
3888 }
3889 else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
3890 {
3891 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
3892 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
3893 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
3894 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
3895 }
3896 else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
3897 {
3898 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
3899 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
3900 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
3901 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
3902 }
3903 else
3904 {
3905 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
3906 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
3907 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
3908 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
3909 }
3910 }
3911 #endif /*End of not defined CRYP_VER_2_2*/
3912 /*Wait for the CRYPEN bit to be cleared*/
3913 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
3914 do
3915 {
3916 count-- ;
3917 if (count == 0U)
3918 {
3919 /* Disable the CRYP peripheral clock */
3920 __HAL_CRYP_DISABLE(hcryp);
3921
3922 /* Change state */
3923 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
3924 hcryp->State = HAL_CRYP_STATE_READY;
3925
3926 /* Process unlocked */
3927 __HAL_UNLOCK(hcryp);
3928 return HAL_ERROR;
3929 }
3930 }
3931 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
3932
3933 /* Select header phase */
3934 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
3935 } /* end of if (DoKeyIVConfig == 1U) */
3936 /* Enable interrupts */
3937 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
3938
3939 /* Enable CRYP */
3940 __HAL_CRYP_ENABLE(hcryp);
3941
3942 /* Return function status */
3943 return HAL_OK;
3944 }
3945 /**
3946 * @brief AES CCM encryption/decryption process in DMA mode
3947 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
3948 * the configuration information for CRYP module
3949 * @retval HAL status
3950 */
CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef * hcryp)3951 static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
3952 {
3953 __IO uint32_t count = 0U;
3954 uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
3955 uint32_t index;
3956 uint32_t npblb;
3957 uint32_t lastwordsize;
3958 uint32_t temp[4]; /* Temporary CrypOutBuff */
3959 uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
3960
3961 if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
3962 {
3963 if (hcryp->KeyIVConfig == 1U)
3964 {
3965 /* If the Key and IV configuration has to be done only once
3966 and if it has already been done, skip it */
3967 DoKeyIVConfig = 0U;
3968 hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
3969 }
3970 else
3971 {
3972 /* If the Key and IV configuration has to be done only once
3973 and if it has not been done already, do it and set KeyIVConfig
3974 to keep track it won't have to be done again next time */
3975 hcryp->KeyIVConfig = 1U;
3976 hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
3977 }
3978 }
3979 else
3980 {
3981 hcryp->SizesSum = hcryp->Size;
3982 }
3983
3984 if (DoKeyIVConfig == 1U)
3985 {
3986 /* Reset CrypHeaderCount */
3987 hcryp->CrypHeaderCount = 0U;
3988
3989 /************************** Init phase **************************************/
3990
3991 CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
3992
3993 /* Set the key */
3994 CRYP_SetKey(hcryp, hcryp->Init.KeySize);
3995
3996 /* Set the initialization vector (IV) with CTR1 information */
3997 hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
3998 hcryp->Instance->IV0RR = hcryp->Init.B0[1];
3999 hcryp->Instance->IV1LR = hcryp->Init.B0[2];
4000 hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
4001
4002 /* Enable the CRYP peripheral */
4003 __HAL_CRYP_ENABLE(hcryp);
4004
4005 /*Write the B0 packet into CRYP_DR*/
4006 #if !defined (CRYP_VER_2_2)
4007 if (hcryp->Version >= REV_ID_B)
4008 #endif /*End of not defined CRYP_VER_2_2*/
4009 {
4010 /* for STM32H7 rev.B and above data has not to be swapped */
4011 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
4012 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
4013 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
4014 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
4015 }
4016 #if !defined (CRYP_VER_2_2)
4017 else /* data has to be swapped according to the DATATYPE */
4018 {
4019 if (hcryp->Init.DataType == CRYP_BYTE_SWAP)
4020 {
4021 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
4022 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
4023 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
4024 hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
4025 }
4026 else if (hcryp->Init.DataType == CRYP_HALFWORD_SWAP)
4027 {
4028 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
4029 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
4030 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
4031 hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
4032 }
4033 else if (hcryp->Init.DataType == CRYP_BIT_SWAP)
4034 {
4035 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
4036 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
4037 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
4038 hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
4039 }
4040 else
4041 {
4042 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
4043 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
4044 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
4045 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
4046 }
4047 }
4048 #endif /*End of not defined CRYP_VER_2_2*/
4049 /*Wait for the CRYPEN bit to be cleared*/
4050 count = CRYP_TIMEOUT_GCMCCMINITPHASE;
4051 do
4052 {
4053 count-- ;
4054 if (count == 0U)
4055 {
4056 /* Disable the CRYP peripheral clock */
4057 __HAL_CRYP_DISABLE(hcryp);
4058
4059 /* Change state */
4060 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4061 hcryp->State = HAL_CRYP_STATE_READY;
4062
4063 /* Process unlocked */
4064 __HAL_UNLOCK(hcryp);
4065 return HAL_ERROR;
4066 }
4067 }
4068 while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
4069
4070 /********************* Header phase *****************************************/
4071
4072 if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
4073 {
4074 return HAL_ERROR;
4075 }
4076
4077 /******************** Payload phase *****************************************/
4078
4079 /* Set the phase */
4080 hcryp->Phase = CRYP_PHASE_PROCESS;
4081
4082 /* Disable the CRYP peripheral */
4083 __HAL_CRYP_DISABLE(hcryp);
4084 #if !defined (CRYP_VER_2_2)
4085 if (hcryp->Version >= REV_ID_B)
4086 #endif /*End of not defined CRYP_VER_2_2*/
4087 {
4088 /* Set to 0 the number of non-valid bytes using NPBLB register*/
4089 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4090 }
4091
4092 /* Select payload phase once the header phase is performed */
4093 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4094 } /* if (DoKeyIVConfig == 1U) */
4095
4096 if (hcryp->Size == 0U)
4097 {
4098 /* Process unLocked */
4099 __HAL_UNLOCK(hcryp);
4100
4101 /* Change the CRYP state and phase */
4102 hcryp->State = HAL_CRYP_STATE_READY;
4103 }
4104 else if (hcryp->Size >= 16U)
4105 {
4106 /* for STM32H7 below rev.B :: Size should be %4 otherwise Tag will be incorrectly generated for CCM Decryption,
4107 Workaround is implemented in polling mode*/
4108 /*DMA transfer must not include the last block in case of Size is not %16 */
4109 wordsize = wordsize - (wordsize % 4U);
4110
4111 /*DMA transfer */
4112 CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t) wordsize,
4113 (uint32_t)(hcryp->pCrypOutBuffPtr));
4114 }
4115 else /* length of input data is < 16U */
4116 {
4117 /* Compute the number of padding bytes in last block of payload */
4118 npblb = 16U - (uint32_t)(hcryp->Size);
4119
4120 #if !defined (CRYP_VER_2_2)
4121 if (hcryp->Version >= REV_ID_B)
4122 #endif /*End of not defined CRYP_VER_2_2*/
4123 {
4124 /* Set Npblb in case of AES CCM payload decryption to get right tag*/
4125 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
4126 {
4127 /* Specify the number of non-valid bytes using NPBLB register*/
4128 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4129 }
4130 }
4131 /* Enable CRYP to start the final phase */
4132 __HAL_CRYP_ENABLE(hcryp);
4133
4134 /* Number of valid words (lastwordsize) in last block */
4135 if ((npblb % 4U) == 0U)
4136 {
4137 lastwordsize = (16U - npblb) / 4U;
4138 }
4139 else
4140 {
4141 lastwordsize = ((16U - npblb) / 4U) + 1U;
4142 }
4143
4144 /* Write the last input block in the IN FIFO */
4145 for (index = 0U; index < lastwordsize; index ++)
4146 {
4147 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4148 hcryp->CrypInCount++;
4149 }
4150
4151 /* Pad the data with zeros to have a complete block */
4152 while (index < 4U)
4153 {
4154 hcryp->Instance->DIN = 0U;
4155 index++;
4156 }
4157
4158 /* Wait for OFNE flag to be raised */
4159 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4160 do
4161 {
4162 count-- ;
4163 if (count == 0U)
4164 {
4165 /* Disable the CRYP peripheral clock */
4166 __HAL_CRYP_DISABLE(hcryp);
4167
4168 /* Change state */
4169 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4170 hcryp->State = HAL_CRYP_STATE_READY;
4171
4172 /* Process unlocked */
4173 __HAL_UNLOCK(hcryp);
4174 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4175 /*Call registered error callback*/
4176 hcryp->ErrorCallback(hcryp);
4177 #else
4178 /*Call legacy weak error callback*/
4179 HAL_CRYP_ErrorCallback(hcryp);
4180 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4181 }
4182 }
4183 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
4184
4185 /*Read the output block from the output FIFO */
4186 for (index = 0U; index < 4U; index++)
4187 {
4188 /* Read the output block from the output FIFO and put them in temporary buffer
4189 then get CrypOutBuff from temporary buffer */
4190 temp[index] = hcryp->Instance->DOUT;
4191 }
4192 for (index = 0; index < lastwordsize; index++)
4193 {
4194 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
4195 hcryp->CrypOutCount++;
4196 }
4197
4198 /* Change the CRYP state to ready */
4199 hcryp->State = HAL_CRYP_STATE_READY;
4200
4201 /* Process unlocked */
4202 __HAL_UNLOCK(hcryp);
4203 }
4204
4205 /* Return function status */
4206 return HAL_OK;
4207 }
4208
4209 /**
4210 * @brief Sets the payload phase in interrupt mode
4211 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4212 * the configuration information for CRYP module
4213 * @retval state
4214 */
CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef * hcryp)4215 static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
4216 {
4217 uint32_t loopcounter;
4218 uint32_t temp[4]; /* Temporary CrypOutBuff */
4219 uint32_t lastwordsize;
4220 uint32_t npblb;
4221 uint32_t temp_cr_algodir;
4222 uint8_t negative = 0U;
4223 uint32_t i;
4224
4225 /***************************** Payload phase *******************************/
4226
4227 if ((hcryp->Size / 4U) < hcryp->CrypInCount)
4228 {
4229 negative = 1U;
4230 }
4231
4232 if (hcryp->Size == 0U)
4233 {
4234 /* Disable interrupts */
4235 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4236
4237 /* Process unlocked */
4238 __HAL_UNLOCK(hcryp);
4239
4240 /* Change the CRYP state */
4241 hcryp->State = HAL_CRYP_STATE_READY;
4242 }
4243
4244 else if ((((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) &&
4245 (negative == 0U))
4246 {
4247 if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM) != 0x0U)
4248 {
4249 /* Write the input block in the IN FIFO */
4250 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4251 hcryp->CrypInCount++;
4252 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4253 hcryp->CrypInCount++;
4254 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4255 hcryp->CrypInCount++;
4256 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4257 hcryp->CrypInCount++;
4258 if (((hcryp->Size / 4U) == hcryp->CrypInCount) && ((hcryp->Size % 16U) == 0U))
4259 {
4260 /* Disable interrupts */
4261 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4262 /* Call the input data transfer complete callback */
4263 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4264 /*Call registered Input complete callback*/
4265 hcryp->InCpltCallback(hcryp);
4266 #else
4267 /*Call legacy weak Input complete callback*/
4268 HAL_CRYP_InCpltCallback(hcryp);
4269 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4270 }
4271
4272 if (hcryp->CrypOutCount < (hcryp->Size / 4U))
4273 {
4274 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4275 {
4276 /* Read the output block from the Output FIFO and put them in temporary buffer
4277 then get CrypOutBuff from temporary buffer */
4278 for (i = 0U; i < 4U; i++)
4279 {
4280 temp[i] = hcryp->Instance->DOUT;
4281 }
4282 i = 0U;
4283 while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
4284 {
4285 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4286 hcryp->CrypOutCount++;
4287 i++;
4288 }
4289 if (((hcryp->Size / 4U) == hcryp->CrypOutCount) && ((hcryp->Size % 16U) == 0U))
4290 {
4291 /* Disable interrupts */
4292 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
4293
4294 /* Change the CRYP state */
4295 hcryp->State = HAL_CRYP_STATE_READY;
4296
4297 /* Disable CRYP */
4298 __HAL_CRYP_DISABLE(hcryp);
4299
4300 /* Process unlocked */
4301 __HAL_UNLOCK(hcryp);
4302
4303 /* Call output transfer complete callback */
4304 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4305 /*Call registered Output complete callback*/
4306 hcryp->OutCpltCallback(hcryp);
4307 #else
4308 /*Call legacy weak Output complete callback*/
4309 HAL_CRYP_OutCpltCallback(hcryp);
4310 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4311 }
4312 }
4313 }
4314 }
4315 }
4316 else if ((hcryp->Size % 16U) != 0U)
4317 {
4318 /* Set padding only in case of input fifo interrupt */
4319 if ((hcryp->Instance->IMSCR & CRYP_IMSCR_INIM) != 0x0U)
4320 {
4321 /* Compute the number of padding bytes in last block of payload */
4322 npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4323
4324 #if !defined (CRYP_VER_2_2)
4325 if (hcryp->Version >= REV_ID_B)
4326 #endif /*End of not defined CRYP_VER_2_2*/
4327 {
4328 /* Set Npblb in case of AES GCM payload encryption and CCM decryption to get right tag */
4329 temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
4330
4331 if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
4332 ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
4333 {
4334 /* Disable the CRYP */
4335 __HAL_CRYP_DISABLE(hcryp);
4336
4337 /* Specify the number of non-valid bytes using NPBLB register*/
4338 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
4339
4340 /* Enable CRYP to start the final phase */
4341 __HAL_CRYP_ENABLE(hcryp);
4342 }
4343 }
4344
4345 /* Number of valid words (lastwordsize) in last block */
4346 if ((npblb % 4U) == 0U)
4347 {
4348 lastwordsize = (16U - npblb) / 4U;
4349 }
4350 else
4351 {
4352 lastwordsize = ((16U - npblb) / 4U) + 1U;
4353 }
4354
4355 /* Write the last input block in the IN FIFO */
4356 for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++)
4357 {
4358 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4359 hcryp->CrypInCount++;
4360 }
4361 /* Pad the data with zeros to have a complete block */
4362 while (loopcounter < 4U)
4363 {
4364 hcryp->Instance->DIN = 0U;
4365 loopcounter++;
4366 }
4367
4368 /* Disable the input FIFO Interrupt */
4369 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4370 }
4371
4372 /*Read the output block from the output FIFO */
4373 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4374 {
4375 for (i = 0U; i < 4U; i++)
4376 {
4377 temp[i] = hcryp->Instance->DOUT;
4378 }
4379 if (((hcryp->Size) / 4U) == 0U)
4380 {
4381 for (i = 0U; (uint16_t)i < ((hcryp->Size) % 4U); i++)
4382 {
4383 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4384 hcryp->CrypOutCount++;
4385 }
4386 }
4387 i = 0U;
4388 while (((hcryp->CrypOutCount < ((hcryp->Size) / 4U))) && (i < 4U))
4389 {
4390 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
4391 hcryp->CrypOutCount++;
4392 i++;
4393 }
4394 }
4395
4396 /* Disable the output FIFO Interrupt */
4397 if (hcryp->CrypOutCount >= ((hcryp->Size) / 4U))
4398 {
4399 /* Disable interrupts */
4400 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI | CRYP_IT_INI);
4401
4402 /* Change the CRYP peripheral state */
4403 hcryp->State = HAL_CRYP_STATE_READY;
4404
4405 /* Process unlocked */
4406 __HAL_UNLOCK(hcryp);
4407
4408 /* Call output transfer complete callback */
4409 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4410 /*Call registered Output complete callback*/
4411 hcryp->OutCpltCallback(hcryp);
4412 #else
4413 /*Call legacy weak Output complete callback*/
4414 HAL_CRYP_OutCpltCallback(hcryp);
4415 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4416 }
4417 }
4418 else
4419 {
4420 /* Nothing to do */
4421 }
4422 }
4423
4424
4425 /**
4426 * @brief Sets the header phase in polling mode
4427 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4428 * the configuration information for CRYP module(Header & HeaderSize)
4429 * @param Timeout: Timeout value
4430 * @retval state
4431 */
CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)4432 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4433 {
4434 uint32_t loopcounter;
4435 uint32_t size_in_bytes;
4436 uint32_t tmp;
4437 const uint32_t mask[4] = {0x0U, 0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
4438
4439 /***************************** Header phase for GCM/GMAC or CCM *********************************/
4440
4441
4442 if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD)
4443 {
4444 size_in_bytes = hcryp->Init.HeaderSize * 4U;
4445 }
4446 else
4447 {
4448 size_in_bytes = hcryp->Init.HeaderSize;
4449 }
4450
4451 if ((size_in_bytes != 0U))
4452 {
4453 /* Select header phase */
4454 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4455
4456 /* Enable the CRYP peripheral */
4457 __HAL_CRYP_ENABLE(hcryp);
4458
4459 /* If size_in_bytes is a multiple of blocks (a multiple of four 32-bits words ) */
4460 if ((size_in_bytes % 16U) == 0U)
4461 {
4462 /* No padding */
4463 for (loopcounter = 0U; (loopcounter < (size_in_bytes / 4U)); loopcounter += 4U)
4464
4465 {
4466 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4467 hcryp->CrypHeaderCount++ ;
4468 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4469 hcryp->CrypHeaderCount++ ;
4470 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4471 hcryp->CrypHeaderCount++ ;
4472 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4473 hcryp->CrypHeaderCount++ ;
4474
4475 /* Wait for IFEM to be raised */
4476 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4477 {
4478 /* Disable the CRYP peripheral clock */
4479 __HAL_CRYP_DISABLE(hcryp);
4480
4481 /* Change state */
4482 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4483 hcryp->State = HAL_CRYP_STATE_READY;
4484
4485 /* Process unlocked */
4486 __HAL_UNLOCK(hcryp);
4487 return HAL_ERROR;
4488 }
4489 }
4490 }
4491 else
4492 {
4493 /* Write header block in the IN FIFO without last block */
4494 for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 16U) * 4U)); loopcounter += 4U)
4495 {
4496 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4497 hcryp->CrypHeaderCount++ ;
4498 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4499 hcryp->CrypHeaderCount++ ;
4500 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4501 hcryp->CrypHeaderCount++ ;
4502 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4503 hcryp->CrypHeaderCount++ ;
4504
4505 /* Wait for IFEM to be raised */
4506 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4507 {
4508 /* Disable the CRYP peripheral clock */
4509 __HAL_CRYP_DISABLE(hcryp);
4510
4511 /* Change state */
4512 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4513 hcryp->State = HAL_CRYP_STATE_READY;
4514
4515 /* Process unlocked */
4516 __HAL_UNLOCK(hcryp);
4517 return HAL_ERROR;
4518 }
4519 }
4520 /* Last block optionally pad the data with zeros*/
4521 for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 4U) % 4U)); loopcounter++)
4522 {
4523 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4524 hcryp->CrypHeaderCount++ ;
4525 }
4526 /* If the header size is a multiple of words */
4527 if ((size_in_bytes % 4U) == 0U)
4528 {
4529 /* Pad the data with zeros to have a complete block */
4530 while (loopcounter < 4U)
4531 {
4532 hcryp->Instance->DIN = 0x0U;
4533 loopcounter++;
4534 }
4535 }
4536 else
4537 {
4538 /* Enter last bytes, padded with zeroes */
4539 tmp = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4540 tmp &= mask[size_in_bytes % 4U];
4541 hcryp->Instance->DIN = tmp;
4542 loopcounter++;
4543 /* Pad the data with zeros to have a complete block */
4544 while (loopcounter < 4U)
4545 {
4546 hcryp->Instance->DIN = 0x0U;
4547 loopcounter++;
4548 }
4549 }
4550 /* Wait for CCF IFEM to be raised */
4551 if (CRYP_WaitOnIFEMFlag(hcryp, Timeout) != HAL_OK)
4552 {
4553 /* Disable the CRYP peripheral clock */
4554 __HAL_CRYP_DISABLE(hcryp);
4555
4556 /* Change state */
4557 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4558 hcryp->State = HAL_CRYP_STATE_READY;
4559
4560 /* Process unlocked */
4561 __HAL_UNLOCK(hcryp);
4562 return HAL_ERROR;
4563 }
4564 }
4565 /* Wait until the complete message has been processed */
4566 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
4567 {
4568 /* Disable the CRYP peripheral clock */
4569 __HAL_CRYP_DISABLE(hcryp);
4570
4571 /* Change state */
4572 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4573 hcryp->State = HAL_CRYP_STATE_READY;
4574
4575 /* Process unlocked & return error */
4576 __HAL_UNLOCK(hcryp);
4577 return HAL_ERROR;
4578 }
4579 }
4580 /* Return function status */
4581 return HAL_OK;
4582 }
4583
4584 /**
4585 * @brief Sets the header phase when using DMA in process
4586 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4587 * the configuration information for CRYP module(Header & HeaderSize)
4588 * @retval None
4589 */
CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef * hcryp)4590 static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp)
4591 {
4592 __IO uint32_t count = 0U;
4593 uint32_t loopcounter;
4594
4595 /***************************** Header phase for GCM/GMAC or CCM *********************************/
4596 if ((hcryp->Init.HeaderSize != 0U))
4597 {
4598 /* Select header phase */
4599 CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
4600
4601 /* Enable the CRYP peripheral */
4602 __HAL_CRYP_ENABLE(hcryp);
4603
4604 if ((hcryp->Init.HeaderSize % 4U) == 0U)
4605 {
4606 /* HeaderSize %4, no padding */
4607 for (loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter += 4U)
4608 {
4609 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4610 hcryp->CrypHeaderCount++ ;
4611 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4612 hcryp->CrypHeaderCount++ ;
4613 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4614 hcryp->CrypHeaderCount++ ;
4615 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4616 hcryp->CrypHeaderCount++ ;
4617
4618 /* Wait for IFEM to be raised */
4619 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4620 do
4621 {
4622 count-- ;
4623 if (count == 0U)
4624 {
4625 /* Disable the CRYP peripheral clock */
4626 __HAL_CRYP_DISABLE(hcryp);
4627
4628 /* Change state */
4629 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4630 hcryp->State = HAL_CRYP_STATE_READY;
4631
4632 /* Process unlocked */
4633 __HAL_UNLOCK(hcryp);
4634 return HAL_ERROR;
4635 }
4636 }
4637 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4638 }
4639 }
4640 else
4641 {
4642 /*Write header block in the IN FIFO without last block */
4643 for (loopcounter = 0U; (loopcounter < ((hcryp->Init.HeaderSize) - (hcryp->Init.HeaderSize % 4U)));
4644 loopcounter += 4U)
4645 {
4646 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4647 hcryp->CrypHeaderCount++ ;
4648 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4649 hcryp->CrypHeaderCount++ ;
4650 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4651 hcryp->CrypHeaderCount++ ;
4652 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4653 hcryp->CrypHeaderCount++ ;
4654
4655 /* Wait for IFEM to be raised */
4656 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4657 do
4658 {
4659 count-- ;
4660 if (count == 0U)
4661 {
4662 /* Disable the CRYP peripheral clock */
4663 __HAL_CRYP_DISABLE(hcryp);
4664
4665 /* Change state */
4666 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4667 hcryp->State = HAL_CRYP_STATE_READY;
4668
4669 /* Process unlocked */
4670 __HAL_UNLOCK(hcryp);
4671 return HAL_ERROR;
4672 }
4673 }
4674 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4675 }
4676 /* Last block optionally pad the data with zeros*/
4677 for (loopcounter = 0U; (loopcounter < (hcryp->Init.HeaderSize % 4U)); loopcounter++)
4678 {
4679 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4680 hcryp->CrypHeaderCount++ ;
4681 }
4682 while (loopcounter < 4U)
4683 {
4684 /* Pad the data with zeros to have a complete block */
4685 hcryp->Instance->DIN = 0x0U;
4686 loopcounter++;
4687 }
4688 /* Wait for IFEM to be raised */
4689 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4690 do
4691 {
4692 count-- ;
4693 if (count == 0U)
4694 {
4695 /* Disable the CRYP peripheral clock */
4696 __HAL_CRYP_DISABLE(hcryp);
4697 /* Change state */
4698 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4699 hcryp->State = HAL_CRYP_STATE_READY;
4700 /* Process unlocked */
4701 __HAL_UNLOCK(hcryp);
4702 return HAL_ERROR;
4703 }
4704 }
4705 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM));
4706 }
4707 /* Wait until the complete message has been processed */
4708 count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
4709 do
4710 {
4711 count-- ;
4712 if (count == 0U)
4713 {
4714 /* Disable the CRYP peripheral clock */
4715 __HAL_CRYP_DISABLE(hcryp);
4716 /* Change state */
4717 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4718 hcryp->State = HAL_CRYP_STATE_READY;
4719 /* Process unlocked */
4720 __HAL_UNLOCK(hcryp);
4721 return HAL_ERROR;
4722 }
4723 }
4724 while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
4725 }
4726
4727 /* Return function status */
4728 return HAL_OK;
4729 }
4730
4731 /**
4732 * @brief Sets the header phase in interrupt mode
4733 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4734 * the configuration information for CRYP module(Header & HeaderSize)
4735 * @retval None
4736 */
CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef * hcryp)4737 static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp)
4738 {
4739 uint32_t loopcounter;
4740
4741 /***************************** Header phase *********************************/
4742
4743 if (hcryp->Init.HeaderSize == hcryp->CrypHeaderCount)
4744 {
4745 /* Disable interrupts */
4746 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
4747
4748 /* Disable the CRYP peripheral */
4749 __HAL_CRYP_DISABLE(hcryp);
4750
4751 #if !defined (CRYP_VER_2_2)
4752 if (hcryp->Version >= REV_ID_B)
4753 #endif /*End of not defined CRYP_VER_2_2*/
4754 {
4755 /* Set to 0 the number of non-valid bytes using NPBLB register*/
4756 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
4757 }
4758
4759 /* Set the phase */
4760 hcryp->Phase = CRYP_PHASE_PROCESS;
4761
4762 /* Select payload phase once the header phase is performed */
4763 CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
4764
4765 /* Enable Interrupts */
4766 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
4767
4768 /* Enable the CRYP peripheral */
4769 __HAL_CRYP_ENABLE(hcryp);
4770 }
4771 else if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount)) >= 4U)
4772
4773 {
4774 /* HeaderSize %4, no padding */
4775 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4776 hcryp->CrypHeaderCount++ ;
4777 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4778 hcryp->CrypHeaderCount++ ;
4779 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4780 hcryp->CrypHeaderCount++ ;
4781 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4782 hcryp->CrypHeaderCount++ ;
4783 }
4784 else
4785 {
4786 /* Last block optionally pad the data with zeros*/
4787 for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++)
4788 {
4789 hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount);
4790 hcryp->CrypHeaderCount++ ;
4791 }
4792 while (loopcounter < 4U)
4793 {
4794 /* Pad the data with zeros to have a complete block */
4795 hcryp->Instance->DIN = 0x0U;
4796 loopcounter++;
4797 }
4798 }
4799 }
4800
4801 #if !defined (CRYP_VER_2_2)
4802 /**
4803 * @brief Workaround used for GCM/CCM mode.
4804 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
4805 * the configuration information for CRYP module
4806 * @param Timeout: Timeout value
4807 * @retval None
4808 */
CRYP_Workaround(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)4809 static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
4810 {
4811 uint32_t iv1temp;
4812 uint32_t temp[4] = {0};
4813 uint32_t temp2[4] = {0};
4814 uint32_t intermediate_data[4] = {0};
4815 uint32_t index;
4816 uint32_t lastwordsize;
4817 uint32_t npblb;
4818
4819 /* Compute the number of padding bytes in last block of payload */
4820 npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
4821
4822 /* Number of valid words (lastwordsize) in last block */
4823 if ((npblb % 4U) == 0U)
4824 {
4825 lastwordsize = (16U - npblb) / 4U;
4826 }
4827 else
4828 {
4829 lastwordsize = ((16U - npblb) / 4U) + 1U;
4830 }
4831
4832 /* Workaround 2, case GCM encryption */
4833 if (hcryp->Init.Algorithm == CRYP_AES_GCM)
4834 {
4835 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4836 {
4837 /*Workaround in order to properly compute authentication tags while doing
4838 a GCM encryption with the last block of payload size inferior to 128 bits*/
4839 /* Disable CRYP to start the final phase */
4840 __HAL_CRYP_DISABLE(hcryp);
4841
4842 /*Update CRYP_IV1R register and ALGOMODE*/
4843 hcryp->Instance->IV1RR = ((hcryp->Instance->CSGCMCCM7R) - 1U);
4844 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
4845
4846 /* Enable CRYP to start the final phase */
4847 __HAL_CRYP_ENABLE(hcryp);
4848 }
4849
4850 for (index = 0; index < lastwordsize ; index ++)
4851 {
4852 /* Write the last input block in the IN FIFO */
4853 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
4854 hcryp->CrypInCount++;
4855 }
4856 while (index < 4U)
4857 {
4858 /* Pad the data with zeros to have a complete block */
4859 hcryp->Instance->DIN = 0U;
4860 index++;
4861 }
4862 /* Wait for OFNE flag to be raised */
4863 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4864 {
4865 /* Disable the CRYP peripheral clock */
4866 __HAL_CRYP_DISABLE(hcryp);
4867
4868 /* Change state */
4869 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4870 hcryp->State = HAL_CRYP_STATE_READY;
4871
4872 /* Process Unlocked */
4873 __HAL_UNLOCK(hcryp);
4874 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
4875 /*Call registered error callback*/
4876 hcryp->ErrorCallback(hcryp);
4877 #else
4878 /*Call legacy weak error callback*/
4879 HAL_CRYP_ErrorCallback(hcryp);
4880 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4881 }
4882 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
4883 {
4884 for (index = 0U; index < 4U; index++)
4885 {
4886 /* Read the output block from the output FIFO */
4887 intermediate_data[index] = hcryp->Instance->DOUT;
4888
4889 /* Intermediate data buffer to be used in for the workaround*/
4890 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
4891 hcryp->CrypOutCount++;
4892 }
4893 }
4894
4895 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
4896 {
4897 /*workaround in order to properly compute authentication tags while doing
4898 a GCM encryption with the last block of payload size inferior to 128 bits*/
4899 /* Change the AES mode to GCM mode and Select Final phase */
4900 /* configured CHMOD GCM */
4901 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_GCM);
4902
4903 /* configured final phase */
4904 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
4905
4906 if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_NO_SWAP)
4907 {
4908 if ((npblb % 4U) == 1U)
4909 {
4910 intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
4911 }
4912 if ((npblb % 4U) == 2U)
4913 {
4914 intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
4915 }
4916 if ((npblb % 4U) == 3U)
4917 {
4918 intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
4919 }
4920 }
4921 else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_BYTE_SWAP)
4922 {
4923 if ((npblb % 4U) == 1U)
4924 {
4925 intermediate_data[lastwordsize - 1U] &= __REV(0xFFFFFF00U);
4926 }
4927 if ((npblb % 4U) == 2U)
4928 {
4929 intermediate_data[lastwordsize - 1U] &= __REV(0xFFFF0000U);
4930 }
4931 if ((npblb % 4U) == 3U)
4932 {
4933 intermediate_data[lastwordsize - 1U] &= __REV(0xFF000000U);
4934 }
4935 }
4936 else if ((hcryp->Instance->CR & CRYP_CR_DATATYPE) == CRYP_HALFWORD_SWAP)
4937 {
4938 if ((npblb % 4U) == 1U)
4939 {
4940 intermediate_data[lastwordsize - 1U] &= __ROR((0xFFFFFF00U), 16);
4941 }
4942 if ((npblb % 4U) == 2U)
4943 {
4944 intermediate_data[lastwordsize - 1U] &= __ROR((0xFFFF0000U), 16);
4945 }
4946 if ((npblb % 4U) == 3U)
4947 {
4948 intermediate_data[lastwordsize - 1U] &= __ROR((0xFF000000U), 16);
4949 }
4950 }
4951 else /*CRYP_BIT_SWAP*/
4952 {
4953 if ((npblb % 4U) == 1U)
4954 {
4955 intermediate_data[lastwordsize - 1U] &= __RBIT(0xFFFFFF00U);
4956 }
4957 if ((npblb % 4U) == 2U)
4958 {
4959 intermediate_data[lastwordsize - 1U] &= __RBIT(0xFFFF0000U);
4960 }
4961 if ((npblb % 4U) == 3U)
4962 {
4963 intermediate_data[lastwordsize - 1U] &= __RBIT(0xFF000000U);
4964 }
4965 }
4966
4967 for (index = 0U; index < lastwordsize ; index ++)
4968 {
4969 /*Write the intermediate_data in the IN FIFO */
4970 hcryp->Instance->DIN = intermediate_data[index];
4971 }
4972 while (index < 4U)
4973 {
4974 /* Pad the data with zeros to have a complete block */
4975 hcryp->Instance->DIN = 0x0U;
4976 index++;
4977 }
4978 /* Wait for OFNE flag to be raised */
4979 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
4980 {
4981 /* Disable the CRYP peripheral clock */
4982 __HAL_CRYP_DISABLE(hcryp);
4983
4984 /* Change state */
4985 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
4986 hcryp->State = HAL_CRYP_STATE_READY;
4987
4988 /* Process unlocked */
4989 __HAL_UNLOCK(hcryp);
4990 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U)
4991 /*Call registered error callback*/
4992 hcryp->ErrorCallback(hcryp);
4993 #else
4994 /*Call legacy weak error callback*/
4995 HAL_CRYP_ErrorCallback(hcryp);
4996 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
4997 }
4998
4999 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
5000 {
5001 for (index = 0U; index < 4U; index++)
5002 {
5003 intermediate_data[index] = hcryp->Instance->DOUT;
5004 }
5005 }
5006 }
5007 } /* End of GCM encryption */
5008 else
5009 {
5010 /* Workaround 2, case CCM decryption, in order to properly compute
5011 authentication tags while doing a CCM decryption with the last block
5012 of payload size inferior to 128 bits*/
5013
5014 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
5015 {
5016 iv1temp = hcryp->Instance->CSGCMCCM7R;
5017
5018 /* Disable CRYP to start the final phase */
5019 __HAL_CRYP_DISABLE(hcryp);
5020
5021 temp[0] = hcryp->Instance->CSGCMCCM0R;
5022 temp[1] = hcryp->Instance->CSGCMCCM1R;
5023 temp[2] = hcryp->Instance->CSGCMCCM2R;
5024 temp[3] = hcryp->Instance->CSGCMCCM3R;
5025
5026 hcryp->Instance->IV1RR = iv1temp;
5027
5028 /* Configured CHMOD CTR */
5029 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CTR);
5030
5031 /* Enable CRYP to start the final phase */
5032 __HAL_CRYP_ENABLE(hcryp);
5033 }
5034 /* Last block optionally pad the data with zeros*/
5035 for (index = 0U; index < lastwordsize; index ++)
5036 {
5037 /* Write the last Input block in the IN FIFO */
5038 hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
5039 hcryp->CrypInCount++;
5040 }
5041 while (index < 4U)
5042 {
5043 /* Pad the data with zeros to have a complete block */
5044 hcryp->Instance->DIN = 0U;
5045 index++;
5046 }
5047 /* Wait for OFNE flag to be raised */
5048 if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
5049 {
5050 /* Disable the CRYP peripheral clock */
5051 __HAL_CRYP_DISABLE(hcryp);
5052
5053 /* Change state */
5054 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5055 hcryp->State = HAL_CRYP_STATE_READY;
5056
5057 /* Process Unlocked */
5058 __HAL_UNLOCK(hcryp);
5059 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5060 /*Call registered error callback*/
5061 hcryp->ErrorCallback(hcryp);
5062 #else
5063 /*Call legacy weak error callback*/
5064 HAL_CRYP_ErrorCallback(hcryp);
5065 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5066 }
5067
5068 if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
5069 {
5070 for (index = 0U; index < 4U; index++)
5071 {
5072 /* Read the Output block from the Output FIFO */
5073 intermediate_data[index] = hcryp->Instance->DOUT;
5074
5075 /*intermediate data buffer to be used in for the workaround*/
5076 *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = intermediate_data[index];
5077 hcryp->CrypOutCount++;
5078 }
5079 }
5080
5081 if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
5082 {
5083 temp2[0] = hcryp->Instance->CSGCMCCM0R;
5084 temp2[1] = hcryp->Instance->CSGCMCCM1R;
5085 temp2[2] = hcryp->Instance->CSGCMCCM2R;
5086 temp2[3] = hcryp->Instance->CSGCMCCM3R;
5087
5088 /* configured CHMOD CCM */
5089 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_AES_CCM);
5090
5091 /* configured Header phase */
5092 MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_HEADER);
5093
5094 /*set to zero the bits corresponding to the padded bits*/
5095 for (index = lastwordsize; index < 4U; index ++)
5096 {
5097 intermediate_data[index] = 0U;
5098 }
5099
5100 if ((npblb % 4U) == 1U)
5101 {
5102 intermediate_data[lastwordsize - 1U] &= 0xFFFFFF00U;
5103 }
5104 if ((npblb % 4U) == 2U)
5105 {
5106 intermediate_data[lastwordsize - 1U] &= 0xFFFF0000U;
5107 }
5108 if ((npblb % 4U) == 3U)
5109 {
5110 intermediate_data[lastwordsize - 1U] &= 0xFF000000U;
5111 }
5112
5113 for (index = 0U; index < 4U ; index ++)
5114 {
5115 intermediate_data[index] ^= temp[index];
5116 intermediate_data[index] ^= temp2[index];
5117 }
5118 for (index = 0U; index < 4U; index ++)
5119 {
5120 /* Write the last Input block in the IN FIFO */
5121 hcryp->Instance->DIN = intermediate_data[index] ;
5122 }
5123
5124 /* Wait for BUSY flag to be raised */
5125 if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
5126 {
5127 /* Disable the CRYP peripheral clock */
5128 __HAL_CRYP_DISABLE(hcryp);
5129
5130 /* Change state */
5131 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
5132 hcryp->State = HAL_CRYP_STATE_READY;
5133
5134 /* Process Unlocked */
5135 __HAL_UNLOCK(hcryp);
5136 #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
5137 /*Call registered error callback*/
5138 hcryp->ErrorCallback(hcryp);
5139 #else
5140 /*Call legacy weak error callback*/
5141 HAL_CRYP_ErrorCallback(hcryp);
5142 #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
5143 }
5144 }
5145 } /* End of CCM WKA*/
5146
5147 /* Process Unlocked */
5148 __HAL_UNLOCK(hcryp);
5149 }
5150 #endif /*End of not defined CRYP_VER_2_2*/
5151
5152 /**
5153 * @brief Handle CRYP hardware block Timeout when waiting for IFEM flag to be raised.
5154 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5155 * the configuration information for CRYP module.
5156 * @param Timeout: Timeout duration.
5157 * @retval HAL status
5158 */
CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5159 static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5160 {
5161 uint32_t tickstart;
5162
5163 /* Get timeout */
5164 tickstart = HAL_GetTick();
5165
5166 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
5167 {
5168 /* Check for the Timeout */
5169 if (Timeout != HAL_MAX_DELAY)
5170 {
5171 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5172 {
5173 return HAL_ERROR;
5174 }
5175 }
5176 }
5177 return HAL_OK;
5178 }
5179 /**
5180 * @brief Handle CRYP hardware block Timeout when waiting for BUSY flag to be raised.
5181 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5182 * the configuration information for CRYP module.
5183 * @param Timeout: Timeout duration.
5184 * @retval HAL status
5185 */
CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5186 static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5187 {
5188 uint32_t tickstart;
5189
5190 /* Get timeout */
5191 tickstart = HAL_GetTick();
5192
5193 while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY))
5194 {
5195 /* Check for the Timeout */
5196 if (Timeout != HAL_MAX_DELAY)
5197 {
5198 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5199 {
5200 return HAL_ERROR;
5201 }
5202 }
5203 }
5204 return HAL_OK;
5205 }
5206
5207
5208 /**
5209 * @brief Handle CRYP hardware block Timeout when waiting for OFNE flag to be raised.
5210 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
5211 * the configuration information for CRYP module.
5212 * @param Timeout: Timeout duration.
5213 * @retval HAL status
5214 */
CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef * hcryp,uint32_t Timeout)5215 static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
5216 {
5217 uint32_t tickstart;
5218
5219 /* Get timeout */
5220 tickstart = HAL_GetTick();
5221
5222 while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
5223 {
5224 /* Check for the Timeout */
5225 if (Timeout != HAL_MAX_DELAY)
5226 {
5227 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
5228 {
5229 return HAL_ERROR;
5230 }
5231 }
5232 }
5233 return HAL_OK;
5234 }
5235
5236
5237 /**
5238 * @}
5239 */
5240
5241
5242
5243 /**
5244 * @}
5245 */
5246
5247 #endif /* HAL_CRYP_MODULE_ENABLED */
5248
5249
5250 /**
5251 * @}
5252 */
5253 #endif /* CRYP */
5254 /**
5255 * @}
5256 */
5257
5258