1 /**
2 ******************************************************************************
3 * @file stm32h5xx_hal_cryp_ex.c
4 * @author MCD Application Team
5 * @brief CRYPEx HAL module driver.
6 * This file provides firmware functions to manage the extended
7 * functionalities of the Cryptography (CRYP) peripheral.
8 *
9 ******************************************************************************
10 * @attention
11 *
12 * Copyright (c) 2023 STMicroelectronics.
13 * All rights reserved.
14 *
15 * This software is licensed under terms that can be found in the LICENSE file
16 * in the root directory of this software component.
17 * If no LICENSE file comes with this software, it is provided AS-IS.
18 *
19 ******************************************************************************
20 */
21
22 /* Includes ------------------------------------------------------------------*/
23 #include "stm32h5xx_hal.h"
24
25 /** @addtogroup STM32H5xx_HAL_Driver
26 * @{
27 */
28
29 /** @addtogroup CRYPEx
30 * @{
31 */
32
33 #if defined(AES)
34
35 #ifdef HAL_CRYP_MODULE_ENABLED
36
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private define ------------------------------------------------------------*/
39 /** @addtogroup CRYPEx_Private_Defines
40 * @{
41 */
42 #define CRYPEx_GENERAL_TIMEOUT 82U
43 #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
44 #define CRYP_PHASE_HEADER AES_CR_GCMPH_0 /*!< GCM/GMAC or CCM header phase */
45 #define CRYP_PHASE_PAYLOAD AES_CR_GCMPH_1 /*!< GCM(/CCM) payload phase */
46 #define CRYP_PHASE_FINAL AES_CR_GCMPH /*!< GCM/GMAC or CCM final phase */
47
48 #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */
49 #define CRYP_OPERATINGMODE_KEYDERIVATION AES_CR_MODE_0 /*!< Key derivation mode only used when performing ECB and CBC decryptions */
50 #define CRYP_OPERATINGMODE_DECRYPT AES_CR_MODE_1 /*!< Decryption */
51 #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT AES_CR_MODE /*!< Key derivation and decryption only used when performing ECB and CBC decryptions */
52
53 #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */
54 #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
55
56 /* CTR0 information to use in CCM algorithm */
57 #define CRYP_CCM_CTR0_0 0x07FFFFFFU
58 #define CRYP_CCM_CTR0_3 0xFFFFFF00U
59
60 /**
61 * @}
62 */
63
64 /* Private macro -------------------------------------------------------------*/
65 /* Private variables ---------------------------------------------------------*/
66 /* Private function prototypes -----------------------------------------------*/
67 static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
68 static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
69 static HAL_StatusTypeDef CRYPEx_WaitFLAG(CRYP_HandleTypeDef *hcryp, uint32_t flag, FlagStatus Status, uint32_t Timeout);
70 static HAL_StatusTypeDef CRYPEx_KeyGeneration(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
71 /* Exported functions---------------------------------------------------------*/
72 /** @addtogroup CRYPEx_Exported_Functions
73 * @{
74 */
75
76 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
77 * @brief Extended processing functions.
78 *
79 @verbatim
80 ==============================================================================
81 ##### Extended AES processing functions #####
82 ==============================================================================
83 [..] This section provides functions allowing to generate the authentication
84 TAG in Polling mode
85 (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG
86 (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG
87 they should be used after Encrypt/Decrypt operation.
88
89 @endverbatim
90 * @{
91 */
92
93 /**
94 * @brief generate the GCM authentication TAG.
95 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
96 * the configuration information for CRYP module
97 * @param pAuthTag Pointer to the authentication buffer
98 * the pAuthTag generated here is 128bits length, if the TAG length is
99 * less than 128bits, user should consider only the valid part of pAuthTag
100 * buffer which correspond exactly to TAG length.
101 * @param Timeout Timeout duration
102 * @retval HAL status
103 */
HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,const uint32_t * pAuthTag,uint32_t Timeout)104 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *pAuthTag,
105 uint32_t Timeout)
106 {
107 /* Assume first Init.HeaderSize is in words */
108 uint64_t headerlength = (uint64_t)hcryp->Init.HeaderSize * 32U; /* Header length in bits */
109 uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
110 uint32_t tagaddr = (uint32_t)pAuthTag;
111 uint32_t i;
112 uint32_t tickstart;
113
114 /* Correct headerlength if Init.HeaderSize is actually in bytes */
115 if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
116 {
117 headerlength /= 4U;
118 }
119
120 if (hcryp->State == HAL_CRYP_STATE_READY)
121 {
122 __HAL_LOCK(hcryp);
123
124 /* Change the CRYP peripheral state */
125 hcryp->State = HAL_CRYP_STATE_BUSY;
126
127 /* Check if initialization phase has already been performed */
128 if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
129 {
130 /* Check the busy flag before writing CR register */
131 if (CRYPEx_WaitFLAG(hcryp, AES_SR_BUSY, SET, CRYPEx_GENERAL_TIMEOUT) != HAL_OK)
132 {
133 hcryp->State = HAL_CRYP_STATE_READY;
134 __HAL_UNLOCK(hcryp);
135 return HAL_ERROR;
136 }
137 /* Change the CRYP phase */
138 hcryp->Phase = CRYPEx_PHASE_FINAL;
139
140 /* Select final phase */
141 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
142
143 /* Write into the AES_DINR register the number of bits in header (64 bits)
144 followed by the number of bits in the payload */
145 hcryp->Instance->DINR = 0U;
146 hcryp->Instance->DINR = (uint32_t)(headerlength);
147 hcryp->Instance->DINR = 0U;
148 hcryp->Instance->DINR = (uint32_t)(inputlength);
149
150 /* Wait for CCF flag to be raised */
151 tickstart = HAL_GetTick();
152 while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
153 {
154 /* Check for the Timeout */
155 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
156 {
157 /* Disable the CRYP peripheral clock */
158 __HAL_CRYP_DISABLE(hcryp);
159
160 /* Change state */
161 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
162 hcryp->State = HAL_CRYP_STATE_READY;
163 __HAL_UNLOCK(hcryp);
164 return HAL_ERROR;
165 }
166 }
167
168 /* Read the authentication TAG in the output FIFO */
169 for (i = 0U; i < 4U; i++)
170 {
171 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
172 tagaddr += 4U;
173 }
174
175 /* Clear CCF flag */
176 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
177
178 /* Disable the peripheral */
179 __HAL_CRYP_DISABLE(hcryp);
180
181 /* Change the CRYP peripheral state */
182 hcryp->State = HAL_CRYP_STATE_READY;
183 __HAL_UNLOCK(hcryp);
184 }
185 else /* Initialization phase has not been performed */
186 {
187 /* Disable the Peripheral */
188 __HAL_CRYP_DISABLE(hcryp);
189
190 /* Sequence error code field */
191 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
192
193 /* Change the CRYP peripheral state */
194 hcryp->State = HAL_CRYP_STATE_READY;
195 __HAL_UNLOCK(hcryp);
196 return HAL_ERROR;
197 }
198 }
199 else
200 {
201 /* Busy error code field */
202 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
203 return HAL_ERROR;
204 }
205 /* Return function status */
206 return HAL_OK;
207 }
208
209 /**
210 * @brief AES CCM Authentication TAG generation.
211 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
212 * the configuration information for CRYP module
213 * @param pAuthTag Pointer to the authentication buffer
214 * the pAuthTag generated here is 128bits length, if the TAG length is
215 * less than 128bits, user should consider only the valid part of pAuthTag
216 * buffer which correspond exactly to TAG length.
217 * @param Timeout Timeout duration
218 * @retval HAL status
219 */
HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,const uint32_t * pAuthTag,uint32_t Timeout)220 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *pAuthTag,
221 uint32_t Timeout)
222 {
223 uint32_t tagaddr = (uint32_t)pAuthTag;
224 uint32_t i;
225 uint32_t tickstart;
226
227 if (hcryp->State == HAL_CRYP_STATE_READY)
228 {
229 __HAL_LOCK(hcryp);
230
231 /* Disable interrupts in case they were kept enabled to proceed
232 a single message in several iterations */
233 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
234
235 /* Change the CRYP peripheral state */
236 hcryp->State = HAL_CRYP_STATE_BUSY;
237
238 /* Check if initialization phase has already been performed */
239 if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
240 {
241 /* Change the CRYP phase */
242 hcryp->Phase = CRYPEx_PHASE_FINAL;
243 /* Select final phase */
244 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
245
246 /* Wait for CCF flag to be raised */
247 tickstart = HAL_GetTick();
248 while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
249 {
250 /* Check for the Timeout */
251 if (Timeout != HAL_MAX_DELAY)
252 {
253 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
254 {
255 /* Disable the CRYP peripheral Clock */
256 __HAL_CRYP_DISABLE(hcryp);
257
258 /* Change state */
259 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
260 hcryp->State = HAL_CRYP_STATE_READY;
261 __HAL_UNLOCK(hcryp);
262 return HAL_ERROR;
263 }
264 }
265 }
266
267 /* Read the authentication TAG in the output FIFO */
268 for (i = 0U; i < 4U; i++)
269 {
270 *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
271 tagaddr += 4U;
272 }
273
274 /* Clear CCF Flag */
275 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
276
277 /* Change the CRYP peripheral state */
278 hcryp->State = HAL_CRYP_STATE_READY;
279 __HAL_UNLOCK(hcryp);
280
281 /* Disable CRYP */
282 __HAL_CRYP_DISABLE(hcryp);
283 }
284 else /* Initialization phase has not been performed */
285 {
286 /* Disable the peripheral */
287 __HAL_CRYP_DISABLE(hcryp);
288
289 /* Sequence error code field */
290 hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
291
292 /* Change the CRYP peripheral state */
293 hcryp->State = HAL_CRYP_STATE_READY;
294 __HAL_UNLOCK(hcryp);
295 return HAL_ERROR;
296 }
297 }
298 else
299 {
300 /* Busy error code field */
301 hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
302 return HAL_ERROR;
303 }
304 /* Return function status */
305 return HAL_OK;
306 }
307
308 /**
309 * @}
310 */
311
312
313 /** @defgroup CRYPEx_Exported_Functions_Group2 Wrap and Unwrap key functions
314 * @brief Wrap and Unwrap key functions.
315 *
316 @verbatim
317 ==============================================================================
318 ##### Wrap and Unwrap key #####
319 ==============================================================================
320 [..] This section provides API allowing to wrap (encrypt) and unwrap (decrypt)
321 key using one of the following keys, and AES Algorithm.
322 Key selection :
323 - Derived hardware unique key (DHUK)
324 - XOR of DHUK and BHK
325 - Boot hardware key (BHK)
326
327 @endverbatim
328 * @{
329 */
330
331 /**
332 * @brief Wrap (encrypt) application keys.
333 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
334 * the configuration information for CRYP module
335 * @param pInput Pointer to the Key buffer to encrypt in case of ECB or CBC
336 * @param pOutput Pointer to the Key buffer encrypted in case of ECB or CBC
337 * @param Timeout Specify Timeout value
338 * @retval HAL status
339 */
HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t * pOutput,uint32_t Timeout)340 HAL_StatusTypeDef HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t *pOutput, uint32_t Timeout)
341 {
342 HAL_StatusTypeDef status;
343 uint32_t algo;
344
345 if (hcryp->State == HAL_CRYP_STATE_READY)
346 {
347 /* Change state Busy */
348 hcryp->State = HAL_CRYP_STATE_BUSY;
349 __HAL_LOCK(hcryp);
350
351 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
352 hcryp->CrypInCount = 0U;
353 hcryp->CrypOutCount = 0U;
354 hcryp->pCrypInBuffPtr = pInput;
355 hcryp->pCrypOutBuffPtr = pOutput;
356
357 /* Disable the CRYP peripheral clock */
358 __HAL_CRYP_DISABLE(hcryp);
359
360 /* Set the operating mode*/
361 MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED);
362
363 /* Encryption operating mode(Mode 0)*/
364 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
365
366
367 /* algo get algorithm selected */
368 algo = hcryp->Instance->CR & AES_CR_CHMOD;
369
370 switch (algo)
371 {
372 case CRYP_AES_ECB:
373 case CRYP_AES_CBC:
374 /* AES decryption */
375 status = CRYPEx_KeyEncrypt(hcryp, Timeout);
376 break;
377 case CRYP_AES_CTR:
378 /* AES Key generation */
379 status = CRYPEx_KeyGeneration(hcryp, Timeout);
380 break;
381 default:
382 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
383 status = HAL_ERROR;
384 break;
385 }
386 }
387 else
388 {
389 /* Busy error code field */
390 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
391 status = HAL_ERROR;
392 }
393 /* Return function status */
394 return status;
395 }
396
397 /**
398 * @brief Unwrap (Decrypt) application keys.
399 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
400 * the configuration information for CRYP module
401 * @param pInput Pointer to the Key buffer to decrypt or generated key in case of CTR.
402 * @param Timeout Specify Timeout value
403 * @retval HAL status
404 */
HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t Timeout)405 HAL_StatusTypeDef HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t Timeout)
406 {
407 HAL_StatusTypeDef status;
408 uint32_t algo;
409
410 if (hcryp->State == HAL_CRYP_STATE_READY)
411 {
412 /* Change state Busy */
413 hcryp->State = HAL_CRYP_STATE_BUSY;
414
415 __HAL_LOCK(hcryp);
416
417 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
418 hcryp->CrypInCount = 0U;
419 hcryp->CrypOutCount = 0U;
420 hcryp->pCrypInBuffPtr = pInput;
421
422 /* Disable the CRYP peripheral clock */
423 __HAL_CRYP_DISABLE(hcryp);
424
425 /* Set the operating mode*/
426 MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED);
427
428 /* Decryption operating mode(Mode 3)*/
429 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
430
431 /* algo get algorithm selected */
432 algo = hcryp->Instance->CR & AES_CR_CHMOD;
433
434 switch (algo)
435 {
436 case CRYP_AES_ECB:
437 case CRYP_AES_CBC:
438 /* AES decryption */
439 status = CRYPEx_KeyDecrypt(hcryp, Timeout);
440 break;
441
442 case CRYP_AES_CTR:
443 /* AES Key generation */
444 status = CRYPEx_KeyGeneration(hcryp, Timeout);
445 break;
446 default:
447 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
448 status = HAL_ERROR;
449 break;
450 }
451 }
452 else
453 {
454 /* Busy error code field */
455 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
456 status = HAL_ERROR;
457 }
458 /* Return function status */
459 return status;
460 }
461
462 /**
463 * @}
464 */
465
466 /** @defgroup CRYPEx_Exported_Functions_Group3 Encrypt and Decrypt Shared key functions
467 * @brief Encrypt and Decrypt Shared key functions.
468 *
469 @verbatim
470 ==============================================================================
471 ##### Encrypt and Decrypt Shared key functions #####
472 ==============================================================================
473 [..] This section provides API allowing to Encrypt and Decrypt Shared key
474
475 @endverbatim
476 * @{
477 */
478
479 /**
480 * @brief Encrypt Shared key.
481 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
482 * the configuration information for CRYP module
483 * @param pKey Pointer to the Key buffer to share
484 * @param pOutput Pointer to the Key buffer encrypted
485 * @param ID Key share identification
486 * @param Timeout Specify Timeout value
487 * @retval HAL status
488 */
HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t * pOutput,uint32_t ID,uint32_t Timeout)489 HAL_StatusTypeDef HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t *pOutput, uint32_t ID,
490 uint32_t Timeout)
491 {
492 HAL_StatusTypeDef status;
493 uint32_t algo;
494
495 if (hcryp->State == HAL_CRYP_STATE_READY)
496 {
497 /* Change state Busy */
498 hcryp->State = HAL_CRYP_STATE_BUSY;
499 __HAL_LOCK(hcryp);
500
501 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
502 hcryp->CrypInCount = 0U;
503 hcryp->CrypOutCount = 0U;
504 hcryp->pCrypInBuffPtr = pKey;
505 hcryp->pCrypOutBuffPtr = pOutput;
506
507 /* Disable the CRYP peripheral clock */
508 __HAL_CRYP_DISABLE(hcryp);
509
510 /* Set the operating mode */
511 MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
512 /* Check the busy flag before writing CR register */
513 if (CRYPEx_WaitFLAG(hcryp, AES_SR_BUSY, SET, CRYPEx_GENERAL_TIMEOUT) != HAL_OK)
514 {
515 hcryp->State = HAL_CRYP_STATE_READY;
516 __HAL_UNLOCK(hcryp);
517 return HAL_ERROR;
518 }
519 /* Encryption operating mode(Mode 0)*/
520 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
521
522 /* algo get algorithm selected */
523 algo = hcryp->Instance->CR & AES_CR_CHMOD;
524
525 switch (algo)
526 {
527 case CRYP_AES_ECB:
528 case CRYP_AES_CBC:
529 /* AES decryption */
530 status = CRYPEx_KeyEncrypt(hcryp, Timeout);
531 break;
532 case CRYP_AES_CTR:
533 /* AES CTR key generation */
534 status = CRYPEx_KeyGeneration(hcryp, Timeout);
535 break;
536 default:
537 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
538 status = HAL_ERROR;
539 break;
540 }
541 }
542 else
543 {
544 /* Busy error code field */
545 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
546 status = HAL_ERROR;
547 }
548 /* Return function status */
549 return status;
550 }
551
552 /**
553 * @brief Decrypt Shared key.
554 * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
555 * the configuration information for CRYP module
556 * @param pKey Pointer to the Key buffer to share
557 * @param ID Key share identification
558 * @param Timeout Specify Timeout value
559 * @retval HAL status
560 */
HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t ID,uint32_t Timeout)561 HAL_StatusTypeDef HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t ID, uint32_t Timeout)
562 {
563 HAL_StatusTypeDef status;
564 uint32_t algo;
565
566 if (hcryp->State == HAL_CRYP_STATE_READY)
567 {
568 /* Change state Busy */
569 hcryp->State = HAL_CRYP_STATE_BUSY;
570 __HAL_LOCK(hcryp);
571
572 /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
573 hcryp->CrypInCount = 0U;
574 hcryp->CrypOutCount = 0U;
575 hcryp->pCrypInBuffPtr = pKey;
576
577 /* Disable the CRYP peripheral clock */
578 __HAL_CRYP_DISABLE(hcryp);
579
580 /* Set the operating mode */
581 MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
582 /* Check the busy flag before writing CR register */
583 if (CRYPEx_WaitFLAG(hcryp, AES_SR_BUSY, SET, CRYPEx_GENERAL_TIMEOUT) != HAL_OK)
584 {
585 hcryp->State = HAL_CRYP_STATE_READY;
586 __HAL_UNLOCK(hcryp);
587 return HAL_ERROR;
588 }
589 /* Decryption operating mode(Mode 3)*/
590 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
591
592 /* algo get algorithm selected */
593 algo = hcryp->Instance->CR & AES_CR_CHMOD;
594
595 switch (algo)
596 {
597 case CRYP_AES_ECB:
598 case CRYP_AES_CBC:
599 /* AES decryption */
600 status = CRYPEx_KeyDecrypt(hcryp, Timeout);
601 break;
602 case CRYP_AES_CTR:
603 /* AES CTR key generation */
604 status = CRYPEx_KeyGeneration(hcryp, Timeout);
605 break;
606 default:
607 hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
608 status = HAL_ERROR;
609 break;
610 }
611 }
612 else
613 {
614 /* Busy error code field */
615 hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
616 status = HAL_ERROR;
617 }
618 /* Return function status */
619 return status;
620 }
621
622 /**
623 * @}
624 */
625
626 /**
627 * @}
628 */
629
630 /* Private functions ---------------------------------------------------------*/
631 /** @addtogroup CRYP_Private_Functions
632 * @{
633 */
634 /**
635 * @brief Key Decryption
636 * @param hcryp pointer to a CRYP_HandleTypeDef structure
637 * @param Timeout specify Timeout value
638 * @note It is strongly recommended to select hardware secret keys
639 * @retval HAL status
640 */
CRYPEx_KeyDecrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)641 static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
642 {
643 uint32_t incount; /* Temporary CrypInCount Value */
644 uint32_t i;
645 uint32_t tickstart;
646
647 /* key preparation for decryption, operating mode 2*/
648 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
649
650 /* Enable CRYP */
651 __HAL_CRYP_ENABLE(hcryp);
652
653 /* Wait for CCF flag to be raised */
654 tickstart = HAL_GetTick();
655 while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
656 {
657 /* Check for the Timeout */
658 if (Timeout != HAL_MAX_DELAY)
659 {
660 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
661 {
662 /* Disable the CRYP peripheral clock */
663 __HAL_CRYP_DISABLE(hcryp);
664
665 /* Change state */
666 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
667 hcryp->State = HAL_CRYP_STATE_READY;
668 __HAL_UNLOCK(hcryp);
669 return HAL_ERROR;
670 }
671 }
672 }
673 /* Clear CCF Flag */
674 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
675
676 /* End of Key preparation for ECB/CBC */
677 /* Return to decryption operating mode(Mode 3)*/
678 MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
679
680 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
681 {
682 /* Set the Initialization Vector */
683 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
684 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
685 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
686 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
687 }
688 /* Enable CRYP */
689 __HAL_CRYP_ENABLE(hcryp);
690
691 /* Set the phase */
692 hcryp->Phase = CRYPEx_PHASE_PROCESS;
693
694 if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
695 {
696 incount = 4U;
697 }
698 else
699 {
700 incount = 8U;
701 }
702 while (hcryp->CrypInCount < incount)
703 {
704 /* Write four times to input the key to encrypt */
705 for (i = 0U; i < 4U; i++)
706 {
707 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
708 hcryp->CrypInCount++;
709 }
710 /* Wait for CCF flag to be raised */
711 tickstart = HAL_GetTick();
712 while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
713 {
714 /* Check for the Timeout */
715 if (Timeout != HAL_MAX_DELAY)
716 {
717 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
718 {
719 /* Disable the CRYP peripheral clock */
720 __HAL_CRYP_DISABLE(hcryp);
721
722 /* Change state */
723 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
724 hcryp->State = HAL_CRYP_STATE_READY;
725 __HAL_UNLOCK(hcryp);
726 return HAL_ERROR;
727 }
728 }
729 }
730
731 /* Clear CCF Flag */
732 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
733 }
734
735 /* Disable the CRYP peripheral clock */
736 __HAL_CRYP_DISABLE(hcryp);
737
738 /* Change the CRYP peripheral state */
739 hcryp->State = HAL_CRYP_STATE_READY;
740 __HAL_UNLOCK(hcryp);
741 return HAL_OK;
742 }
743
744 /**
745 * @brief Key Encryption
746 * @param hcryp pointer to a CRYP_HandleTypeDef structure
747 * @param Timeout specify Timeout value
748 * @retval HAL status
749 */
CRYPEx_KeyEncrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)750 static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
751 {
752 uint32_t incount; /* Temporary CrypInCount Value */
753 uint32_t i;
754 uint32_t tickstart;
755 uint32_t temp; /* Temporary CrypOutBuff */
756
757 if (hcryp->Init.Algorithm != CRYP_AES_ECB)
758 {
759 /* Set the Initialization Vector */
760 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
761 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
762 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
763 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
764 }
765
766 /* Enable CRYP */
767 __HAL_CRYP_ENABLE(hcryp);
768
769 /* Set the phase */
770 hcryp->Phase = CRYPEx_PHASE_PROCESS;
771
772 if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
773 {
774 incount = 4U;
775 }
776 else
777 {
778 incount = 8U;
779 }
780 while (hcryp->CrypInCount < incount)
781 {
782 for (i = 0U; i < 4U; i++)
783 {
784 hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
785 hcryp->CrypInCount++;
786 }
787 /* Wait for CCF flag to be raised */
788 tickstart = HAL_GetTick();
789 while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
790 {
791 /* Check for the Timeout */
792 if (Timeout != HAL_MAX_DELAY)
793 {
794 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
795 {
796 /* Disable the CRYP peripheral clock */
797 __HAL_CRYP_DISABLE(hcryp);
798
799 /* Change state */
800 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
801 hcryp->State = HAL_CRYP_STATE_READY;
802 __HAL_UNLOCK(hcryp);
803 return HAL_ERROR;
804 }
805 }
806 }
807
808 /* Clear CCF Flag */
809 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
810
811 /* Read the output block from the output FIFO and put them in temporary buffer then
812 get CrypOutBuff from temporary buffer */
813 for (i = 0U; i < 4U; i++)
814 {
815 temp = hcryp->Instance->DOUTR;
816 *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
817 hcryp->CrypOutCount++;
818 }
819 }
820
821 /* Disable the CRYP peripheral clock */
822 __HAL_CRYP_DISABLE(hcryp);
823
824 /* Change the CRYP peripheral state */
825 hcryp->State = HAL_CRYP_STATE_READY;
826 __HAL_UNLOCK(hcryp);
827 return HAL_OK;
828 }
829 /**
830 * @brief Wait Instance Flag
831 * @param hcryp cryp handle
832 * @param flag Specifies the flag to check
833 * @param Status Flag status (SET or RESET)
834 * @param Timeout Timeout duration
835 * @retval HAL status.
836 */
837
CRYPEx_WaitFLAG(CRYP_HandleTypeDef * hcryp,uint32_t flag,FlagStatus Status,uint32_t Timeout)838 static HAL_StatusTypeDef CRYPEx_WaitFLAG(CRYP_HandleTypeDef *hcryp, uint32_t flag, FlagStatus Status, uint32_t Timeout)
839 {
840 uint32_t tickstart = HAL_GetTick();
841 while (__HAL_CRYP_GET_FLAG(hcryp, flag) == Status)
842 {
843 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
844 {
845 CLEAR_BIT(hcryp->Instance->CR, AES_CR_EN);
846 /* Change state */
847 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
848 /* return error */
849 return HAL_ERROR;
850 }
851 }
852 return HAL_OK;
853 }
854 /**
855 * @brief Key Generation
856 * @param hcryp pointer to a CRYP_HandleTypeDef structure
857 * @param Timeout specify Timeout value
858 * @retval HAL status
859 */
CRYPEx_KeyGeneration(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)860 static HAL_StatusTypeDef CRYPEx_KeyGeneration(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
861 {
862 uint32_t tickstart;
863
864 /* No swap, DATATYPE must be kept to 0x0.*/
865 MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE, CRYP_NO_SWAP);
866
867 /*Writes initialization vector in IV registers*/
868 if (hcryp->Init.pInitVect != NULL)
869 {
870 /* Set the Initialization Vector*/
871 hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
872 hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
873 hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
874 /* Keeping the two least significant bit of SAES_IVR0 to 00 */
875 hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
876 hcryp->Instance->IVR0 &= 0xFFFFFFFCU ;
877 }
878 else
879 {
880 return HAL_ERROR;
881 }
882
883 /* Enable CRYP */
884 __HAL_CRYP_ENABLE(hcryp);
885
886 /* Wait for CCF flag to be raised */
887 tickstart = HAL_GetTick();
888 while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
889 {
890 /* Check for the Timeout */
891 if (Timeout != HAL_MAX_DELAY)
892 {
893 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
894 {
895 /* Disable the CRYP peripheral clock */
896 __HAL_CRYP_DISABLE(hcryp);
897
898 /* Change state */
899 hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
900 hcryp->State = HAL_CRYP_STATE_READY;
901 __HAL_UNLOCK(hcryp);
902 return HAL_ERROR;
903 }
904 }
905 }
906 /* Clear CCF Flag */
907 __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
908
909 /* Disable the CRYP peripheral clock */
910 __HAL_CRYP_DISABLE(hcryp);
911
912 /* Change the CRYP peripheral state */
913 hcryp->State = HAL_CRYP_STATE_READY;
914 __HAL_UNLOCK(hcryp);
915
916 return HAL_OK;
917 }
918
919 /**
920 * @}
921 */
922
923 /**
924 * @}
925 */
926
927 /**
928 * @}
929 */
930
931 #endif /* HAL_CRYP_MODULE_ENABLED */
932
933 #endif /* AES */
934 /**
935 * @}
936 */
937
938 /**
939 * @}
940 */
941