1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_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) 2021 STMicroelectronics.
13   * All rights reserved.
14   *
15   * This software component is licensed by ST under BSD 3-Clause license,
16   * the "License"; You may not use this file except in compliance with the
17   * License. You may obtain a copy of the License at:
18   *                        opensource.org/licenses/BSD-3-Clause
19   *
20   ******************************************************************************
21   */
22 
23 /* Includes ------------------------------------------------------------------*/
24 #include "stm32u5xx_hal.h"
25 
26 /** @addtogroup STM32U5xx_HAL_Driver
27   * @{
28   */
29 
30 /** @addtogroup CRYPEx
31   * @{
32   */
33 
34 #if defined(AES)
35 
36 #ifdef HAL_CRYP_MODULE_ENABLED
37 
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private define ------------------------------------------------------------*/
40 /** @addtogroup CRYPEx_Private_Defines
41   * @{
42   */
43 
44 #define CRYP_PHASE_INIT                              0x00000000U             /*!< GCM/GMAC (or CCM) init phase */
45 #define CRYP_PHASE_HEADER                            AES_CR_GCMPH_0          /*!< GCM/GMAC or CCM header phase */
46 #define CRYP_PHASE_PAYLOAD                           AES_CR_GCMPH_1          /*!< GCM(/CCM) payload phase   */
47 #define CRYP_PHASE_FINAL                             AES_CR_GCMPH            /*!< GCM/GMAC or CCM  final phase  */
48 
49 #define CRYP_OPERATINGMODE_ENCRYPT                   0x00000000U             /*!< Encryption mode   */
50 #define CRYP_OPERATINGMODE_KEYDERIVATION             AES_CR_MODE_0           /*!< Key derivation mode  only used when performing ECB and CBC decryptions  */
51 #define CRYP_OPERATINGMODE_DECRYPT                   AES_CR_MODE_1           /*!< Decryption       */
52 #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT     AES_CR_MODE             /*!< Key derivation and decryption only used when performing ECB and CBC decryptions  */
53 
54 #define  CRYPEx_PHASE_PROCESS       0x02U     /*!< CRYP peripheral is in processing phase */
55 #define  CRYPEx_PHASE_FINAL         0x03U     /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
56 
57 /*  CTR0 information to use in CCM algorithm */
58 #define CRYP_CCM_CTR0_0            0x07FFFFFFU
59 #define CRYP_CCM_CTR0_3            0xFFFFFF00U
60 
61 /**
62   * @}
63   */
64 
65 /* Private macro -------------------------------------------------------------*/
66 /* Private variables ---------------------------------------------------------*/
67 /* Private function prototypes -----------------------------------------------*/
68 static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
69 static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
70 static void CRYPEx_SetKey(const CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
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,uint32_t * pAuthTag,uint32_t Timeout)104 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *pAuthTag, uint32_t Timeout)
105 {
106   /* Assume first Init.HeaderSize is in words */
107   uint64_t headerlength = (uint64_t)hcryp->Init.HeaderSize * 32U; /* Header length in bits */
108   uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
109   uint32_t tagaddr = (uint32_t)pAuthTag;
110   uint32_t i;
111   uint32_t tickstart;
112 
113   /* Correct headerlength if Init.HeaderSize is actually in bytes */
114   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
115   {
116     headerlength /= 4U;
117   }
118 
119   if (hcryp->State == HAL_CRYP_STATE_READY)
120   {
121     __HAL_LOCK(hcryp);
122 
123     /* Change the CRYP peripheral state */
124     hcryp->State = HAL_CRYP_STATE_BUSY;
125 
126     /* Check if initialization phase has already been performed */
127     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
128     {
129       /* Change the CRYP phase */
130       hcryp->Phase = CRYPEx_PHASE_FINAL;
131 
132       /* Select final phase */
133       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
134 
135       /* Set the encrypt operating mode */
136       MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
137 
138       /* Write into the AES_DINR register the number of bits in header (64 bits)
139       followed by the number of bits in the payload */
140       hcryp->Instance->DINR = 0U;
141       hcryp->Instance->DINR = (uint32_t)(headerlength);
142       hcryp->Instance->DINR = 0U;
143       hcryp->Instance->DINR = (uint32_t)(inputlength);
144 
145       /* Wait for CCF flag to be raised */
146       tickstart = HAL_GetTick();
147       while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
148       {
149         /* Check for the Timeout */
150         if (Timeout != HAL_MAX_DELAY)
151         {
152           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
153           {
154             /* Disable the CRYP peripheral clock */
155             __HAL_CRYP_DISABLE(hcryp);
156 
157             /* Change state */
158             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
159             hcryp->State = HAL_CRYP_STATE_READY;
160             __HAL_UNLOCK(hcryp);
161             return HAL_ERROR;
162           }
163         }
164       }
165 
166       /* Read the authentication TAG in the output FIFO */
167       for (i = 0U; i < 4U; i++)
168       {
169         *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
170         tagaddr += 4U;
171       }
172 
173       /* Clear CCF flag */
174       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
175 
176       /* Disable the peripheral */
177       __HAL_CRYP_DISABLE(hcryp);
178 
179       /* Change the CRYP peripheral state */
180       hcryp->State = HAL_CRYP_STATE_READY;
181       __HAL_UNLOCK(hcryp);
182     }
183     else /* Initialization phase has not been performed */
184     {
185       /* Disable the Peripheral */
186       __HAL_CRYP_DISABLE(hcryp);
187 
188       /* Sequence error code field */
189       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
190 
191       /* Change the CRYP peripheral state */
192       hcryp->State = HAL_CRYP_STATE_READY;
193       __HAL_UNLOCK(hcryp);
194       return HAL_ERROR;
195     }
196   }
197   else
198   {
199     /* Busy error code field */
200     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
201     return HAL_ERROR;
202   }
203   /* Return function status */
204   return HAL_OK;
205 }
206 
207 /**
208   * @brief  AES CCM Authentication TAG generation.
209   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
210   *         the configuration information for CRYP module
211   * @param  pAuthTag Pointer to the authentication buffer
212   *         the pAuthTag generated here is 128bits length, if the TAG length is
213   *         less than 128bits, user should consider only the valid part of pAuthTag
214   *         buffer which correspond exactly to TAG length.
215   * @param  Timeout Timeout duration
216   * @retval HAL status
217   */
HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,uint32_t * pAuthTag,uint32_t Timeout)218 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *pAuthTag, uint32_t Timeout)
219 {
220   uint32_t tagaddr = (uint32_t)pAuthTag;
221   uint32_t i;
222   uint32_t tickstart;
223 
224   if (hcryp->State == HAL_CRYP_STATE_READY)
225   {
226     __HAL_LOCK(hcryp);
227 
228     /* Disable interrupts in case they were kept enabled to proceed
229        a single message in several iterations */
230     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
231 
232     /* Change the CRYP peripheral state */
233     hcryp->State = HAL_CRYP_STATE_BUSY;
234 
235     /* Check if initialization phase has already been performed */
236     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
237     {
238       /* Change the CRYP phase */
239       hcryp->Phase = CRYPEx_PHASE_FINAL;
240       /* Select final phase */
241       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
242 
243       /* Set encrypt  operating mode */
244       MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
245 
246       /* Wait for CCF flag to be raised */
247       tickstart = HAL_GetTick();
248       while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_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            - Key registers AES_KEYx
327 
328 @endverbatim
329   * @{
330   */
331 
332 /**
333   * @brief  Wrap (encrypt) application keys.
334   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
335   *         the configuration information for CRYP module
336   * @param  pInput Pointer to the Key buffer to encrypt
337   * @param  pOutput Pointer to the Key buffer encrypted
338   * @param  Timeout Specify Timeout value
339   * @retval HAL status
340   */
HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t * pOutput,uint32_t Timeout)341 HAL_StatusTypeDef HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t *pOutput, uint32_t Timeout)
342 {
343   HAL_StatusTypeDef status;
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     status = CRYPEx_KeyEncrypt(hcryp, Timeout);
364   }
365   else
366   {
367     /* Busy error code field */
368     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
369     status = HAL_ERROR;
370   }
371   /* Return function status */
372   return status;
373 }
374 
375 /**
376   * @brief  Unwrap (Decrypt) application keys.
377   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
378   *         the configuration information for CRYP module
379   * @param  pInput Pointer to the Key buffer to decrypt
380   * @param  Timeout Specify Timeout value
381   * @retval HAL status
382   */
HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t Timeout)383 HAL_StatusTypeDef HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t Timeout)
384 {
385   HAL_StatusTypeDef status;
386 
387   if (hcryp->State == HAL_CRYP_STATE_READY)
388   {
389     /* Change state Busy */
390     hcryp->State = HAL_CRYP_STATE_BUSY;
391 
392     __HAL_LOCK(hcryp);
393 
394     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
395     hcryp->CrypInCount = 0U;
396     hcryp->CrypOutCount = 0U;
397     hcryp->pCrypInBuffPtr = pInput;
398 
399     /* Disable the CRYP peripheral clock */
400     __HAL_CRYP_DISABLE(hcryp);
401 
402     /* Set the operating mode*/
403     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED);
404 
405     status = CRYPEx_KeyDecrypt(hcryp, Timeout);
406   }
407   else
408   {
409     /* Busy error code field */
410     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
411     status = HAL_ERROR;
412   }
413   /* Return function status */
414   return status;
415 }
416 
417 /**
418   * @}
419   */
420 
421 /** @defgroup CRYPEx_Exported_Functions_Group3 Encrypt/Decrypt Shared key functions
422   * @brief    Encrypt/Decrypt Shared key functions.
423   *
424 @verbatim
425   ==============================================================================
426                       ##### Encrypt/Decrypt Shared key functions #####
427   ==============================================================================
428     [..]  This section provides API allowing to Encrypt/Decrypt Shared key
429 
430 @endverbatim
431   * @{
432   */
433 
434 /**
435   * @brief  Encrypt Shared key.
436   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
437   *         the configuration information for CRYP module
438   * @param  pKey Pointer to the Key buffer to share
439   * @param  pOutput Pointer to the Key buffer encrypted
440   * @param  ID Key share identification
441   * @param  Timeout Specify Timeout value
442   * @retval HAL status
443   */
HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t * pOutput,uint32_t ID,uint32_t Timeout)444 HAL_StatusTypeDef HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t *pOutput, uint32_t ID,
445                                               uint32_t Timeout)
446 {
447   HAL_StatusTypeDef status;
448 
449   if (hcryp->State == HAL_CRYP_STATE_READY)
450   {
451     /* Change state Busy */
452     hcryp->State = HAL_CRYP_STATE_BUSY;
453     __HAL_LOCK(hcryp);
454 
455     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
456     hcryp->CrypInCount = 0U;
457     hcryp->CrypOutCount = 0U;
458     hcryp->pCrypInBuffPtr = pKey;
459     hcryp->pCrypOutBuffPtr = pOutput;
460 
461     /* Disable the CRYP peripheral clock */
462     __HAL_CRYP_DISABLE(hcryp);
463 
464     /* Set the operating mode */
465     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
466 
467     status = CRYPEx_KeyEncrypt(hcryp, Timeout);
468   }
469   else
470   {
471     /* Busy error code field */
472     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
473     status = HAL_ERROR;
474   }
475   /* Return function status */
476   return status;
477 }
478 
479 /**
480   * @brief  Decrypt 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  ID Key share identification
485   * @param  Timeout Specify Timeout value
486   * @retval HAL status
487   */
HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t ID,uint32_t Timeout)488 HAL_StatusTypeDef HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t ID, uint32_t Timeout)
489 {
490   HAL_StatusTypeDef status;
491 
492   if (hcryp->State == HAL_CRYP_STATE_READY)
493   {
494     /* Change state Busy */
495     hcryp->State = HAL_CRYP_STATE_BUSY;
496     __HAL_LOCK(hcryp);
497 
498     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
499     hcryp->CrypInCount = 0U;
500     hcryp->CrypOutCount = 0U;
501     hcryp->pCrypInBuffPtr = pKey;
502 
503     /* Disable the CRYP peripheral clock */
504     __HAL_CRYP_DISABLE(hcryp);
505 
506     /* Set the operating mode */
507     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
508 
509     status = CRYPEx_KeyDecrypt(hcryp, Timeout);
510   }
511   else
512   {
513     /* Busy error code field */
514     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
515     status = HAL_ERROR;
516   }
517   /* Return function status */
518   return status;
519 }
520 
521 /**
522   * @}
523   */
524 
525 /**
526   * @}
527   */
528 
529 /* Private functions ---------------------------------------------------------*/
530 /** @addtogroup CRYP_Private_Functions
531   * @{
532   */
533 /**
534   * @brief  Key Decryption
535   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
536   * @param  Timeout specify Timeout value
537   * @note   It is strongly recommended to select hardware secret keys
538   * @retval HAL status
539   */
CRYPEx_KeyDecrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)540 static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
541 {
542   uint32_t incount; /* Temporary CrypInCount Value */
543   uint32_t i;
544   uint32_t tickstart;
545 
546   /* key preparation for decryption, operating mode 2*/
547   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
548 
549   /* It is strongly recommended to select hardware secret keys */
550   if (hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL)
551   {
552     /* Set the Key */
553     CRYPEx_SetKey(hcryp, hcryp->Init.KeySize);
554   }
555   /* Enable CRYP */
556   __HAL_CRYP_ENABLE(hcryp);
557 
558   /* Wait for CCF flag to be raised */
559   tickstart = HAL_GetTick();
560   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
561   {
562     /* Check for the Timeout */
563     if (Timeout != HAL_MAX_DELAY)
564     {
565       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
566       {
567         /* Disable the CRYP peripheral clock */
568         __HAL_CRYP_DISABLE(hcryp);
569 
570         /* Change state */
571         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
572         hcryp->State = HAL_CRYP_STATE_READY;
573         __HAL_UNLOCK(hcryp);
574         return HAL_ERROR;
575       }
576     }
577   }
578   /* Clear CCF Flag */
579   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
580 
581   /*  End of Key preparation for ECB/CBC */
582   /* Return to decryption operating mode(Mode 3)*/
583   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
584 
585   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
586   {
587     /* Set the Initialization Vector */
588     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
589     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
590     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
591     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
592   }
593   /* Enable CRYP */
594   __HAL_CRYP_ENABLE(hcryp);
595 
596   /* Set the phase */
597   hcryp->Phase = CRYPEx_PHASE_PROCESS;
598 
599   if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
600   {
601     incount = 4U;
602   }
603   else
604   {
605     incount = 8U;
606   }
607   while (hcryp->CrypInCount < incount)
608   {
609     /* Write four times to input the key to encrypt */
610     for (i = 0U; i < 4U; i++)
611     {
612       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
613       hcryp->CrypInCount++;
614     }
615     /* Wait for CCF flag to be raised */
616     tickstart = HAL_GetTick();
617     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
618     {
619       /* Check for the Timeout */
620       if (Timeout != HAL_MAX_DELAY)
621       {
622         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
623         {
624           /* Disable the CRYP peripheral clock */
625           __HAL_CRYP_DISABLE(hcryp);
626 
627           /* Change state */
628           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
629           hcryp->State = HAL_CRYP_STATE_READY;
630           __HAL_UNLOCK(hcryp);
631           return HAL_ERROR;
632         }
633       }
634     }
635 
636     /* Clear CCF Flag */
637     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
638   }
639 
640   /* Disable the CRYP peripheral clock */
641   __HAL_CRYP_DISABLE(hcryp);
642 
643   /* Change the CRYP peripheral state */
644   hcryp->State = HAL_CRYP_STATE_READY;
645   __HAL_UNLOCK(hcryp);
646   return HAL_OK;
647 }
648 
649 /**
650   * @brief  Key Encryption
651   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
652   * @param  Timeout specify Timeout value
653   * @retval HAL status
654   */
CRYPEx_KeyEncrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)655 static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
656 {
657   uint32_t incount; /* Temporary CrypInCount Value */
658   uint32_t i;
659   uint32_t tickstart;
660   uint32_t temp; /* Temporary CrypOutBuff */
661 
662   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
663 
664   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
665   {
666     /* Set the Initialization Vector */
667     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
668     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
669     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
670     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
671   }
672   /* It is strongly recommended to select hardware secret keys */
673   if (hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL)
674   {
675     /* Set the Key */
676     CRYPEx_SetKey(hcryp, hcryp->Init.KeySize);
677   }
678   /* Get tick */
679   tickstart = HAL_GetTick();
680 
681   /* Wait for Valid KEY flag to set */
682   while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_KEYVALID))
683   {
684     /* Check for the Timeout */
685     if (Timeout != HAL_MAX_DELAY)
686     {
687       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
688       {
689         /* Change state */
690         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
691         hcryp->State = HAL_CRYP_STATE_READY;
692         __HAL_UNLOCK(hcryp);
693         return HAL_ERROR;
694       }
695     }
696   }
697 
698   /* Enable CRYP */
699   __HAL_CRYP_ENABLE(hcryp);
700 
701   /* Set the phase */
702   hcryp->Phase = CRYPEx_PHASE_PROCESS;
703 
704   if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
705   {
706     incount = 4U;
707   }
708   else
709   {
710     incount = 8U;
711   }
712   while (hcryp->CrypInCount < incount)
713   {
714     for (i = 0U; i < 4U; i++)
715     {
716       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
717       hcryp->CrypInCount++;
718     }
719     /* Wait for CCF flag to be raised */
720     tickstart = HAL_GetTick();
721     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
722     {
723       /* Check for the Timeout */
724       if (Timeout != HAL_MAX_DELAY)
725       {
726         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
727         {
728           /* Disable the CRYP peripheral clock */
729           __HAL_CRYP_DISABLE(hcryp);
730 
731           /* Change state */
732           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
733           hcryp->State = HAL_CRYP_STATE_READY;
734           __HAL_UNLOCK(hcryp);
735           return HAL_ERROR;
736         }
737       }
738     }
739 
740     /* Clear CCF Flag */
741     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
742 
743     /* Read the output block from the output FIFO and put them in temporary buffer then
744        get CrypOutBuff from temporary buffer */
745     for (i = 0U; i < 4U; i++)
746     {
747       temp  = hcryp->Instance->DOUTR;
748       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
749       hcryp->CrypOutCount++;
750     }
751   }
752 
753   /* Disable the CRYP peripheral clock */
754   __HAL_CRYP_DISABLE(hcryp);
755 
756   /* Change the CRYP peripheral state */
757   hcryp->State = HAL_CRYP_STATE_READY;
758   __HAL_UNLOCK(hcryp);
759   return HAL_OK;
760 }
761 
762 /**
763   * @brief  Write Key in Key registers.
764   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
765   *         the configuration information for CRYP module
766   * @param  KeySize Size of Key
767   * @note   If pKey is NULL, the Key registers are not written.
768   * @retval None
769   */
CRYPEx_SetKey(const CRYP_HandleTypeDef * hcryp,uint32_t KeySize)770 static void CRYPEx_SetKey(const CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
771 {
772   if (hcryp->Init.pKey != NULL)
773   {
774     switch (KeySize)
775     {
776       case CRYP_KEYSIZE_256B:
777         hcryp->Instance->KEYR7 = *(uint32_t *)(hcryp->Init.pKey);
778         hcryp->Instance->KEYR6 = *(uint32_t *)(hcryp->Init.pKey + 1U);
779         hcryp->Instance->KEYR5 = *(uint32_t *)(hcryp->Init.pKey + 2U);
780         hcryp->Instance->KEYR4 = *(uint32_t *)(hcryp->Init.pKey + 3U);
781         hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey + 4U);
782         hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 5U);
783         hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 6U);
784         hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 7U);
785         break;
786       case CRYP_KEYSIZE_128B:
787         hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey);
788         hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 1U);
789         hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 2U);
790         hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 3U);
791         break;
792       default:
793         break;
794     }
795   }
796 }
797 /**
798   * @}
799   */
800 
801 /**
802   * @}
803   */
804 
805 /**
806   * @}
807   */
808 
809 #endif /* HAL_CRYP_MODULE_ENABLED */
810 
811 #endif /* AES */
812 /**
813   * @}
814   */
815 
816 /**
817   * @}
818   */
819