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 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 "stm32u5xx_hal.h"
24 
25 /** @addtogroup STM32U5xx_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 /* Exported functions---------------------------------------------------------*/
71 /** @addtogroup CRYPEx_Exported_Functions
72   * @{
73   */
74 
75 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
76   *  @brief   Extended processing functions.
77   *
78 @verbatim
79   ==============================================================================
80               ##### Extended AES processing functions #####
81   ==============================================================================
82     [..]  This section provides functions allowing to generate the authentication
83           TAG in Polling mode
84       (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG
85       (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG
86          they should be used after Encrypt/Decrypt operation.
87 
88 @endverbatim
89   * @{
90   */
91 
92 /**
93   * @brief  generate the GCM authentication TAG.
94   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
95   *         the configuration information for CRYP module
96   * @param  pAuthTag Pointer to the authentication buffer
97   *         the pAuthTag generated here is 128bits length, if the TAG length is
98   *         less than 128bits, user should consider only the valid part of pAuthTag
99   *         buffer which correspond exactly to TAG length.
100   * @param  Timeout Timeout duration
101   * @retval HAL status
102   */
HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,const uint32_t * pAuthTag,uint32_t Timeout)103 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *pAuthTag,
104                                                     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       /* Check the busy flag before writing CR register */
130       if (CRYPEx_WaitFLAG(hcryp, AES_SR_BUSY, SET, CRYPEx_GENERAL_TIMEOUT) != HAL_OK)
131       {
132         hcryp->State = HAL_CRYP_STATE_READY;
133         __HAL_UNLOCK(hcryp);
134         return HAL_ERROR;
135       }
136       /* Change the CRYP phase */
137       hcryp->Phase = CRYPEx_PHASE_FINAL;
138 
139       /* Select final phase */
140       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
141 
142       /* Write into the AES_DINR register the number of bits in header (64 bits)
143       followed by the number of bits in the payload */
144       hcryp->Instance->DINR = 0U;
145       hcryp->Instance->DINR = (uint32_t)(headerlength);
146       hcryp->Instance->DINR = 0U;
147       hcryp->Instance->DINR = (uint32_t)(inputlength);
148 
149       /* Wait for CCF flag to be raised */
150       tickstart = HAL_GetTick();
151       while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
152       {
153         /* Check for the Timeout */
154         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
155         {
156           /* Disable the CRYP peripheral clock */
157           __HAL_CRYP_DISABLE(hcryp);
158 
159           /* Change state */
160           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
161           hcryp->State = HAL_CRYP_STATE_READY;
162           __HAL_UNLOCK(hcryp);
163           return HAL_ERROR;
164         }
165       }
166 
167       /* Read the authentication TAG in the output FIFO */
168       for (i = 0U; i < 4U; i++)
169       {
170         *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
171         tagaddr += 4U;
172       }
173 
174       /* Clear CCF flag */
175       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
176 
177       /* Disable the peripheral */
178       __HAL_CRYP_DISABLE(hcryp);
179 
180       /* Change the CRYP peripheral state */
181       hcryp->State = HAL_CRYP_STATE_READY;
182       __HAL_UNLOCK(hcryp);
183     }
184     else /* Initialization phase has not been performed */
185     {
186       /* Disable the Peripheral */
187       __HAL_CRYP_DISABLE(hcryp);
188 
189       /* Sequence error code field */
190       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
191 
192       /* Change the CRYP peripheral state */
193       hcryp->State = HAL_CRYP_STATE_READY;
194       __HAL_UNLOCK(hcryp);
195       return HAL_ERROR;
196     }
197   }
198   else
199   {
200     /* Busy error code field */
201     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
202     return HAL_ERROR;
203   }
204   /* Return function status */
205   return HAL_OK;
206 }
207 
208 /**
209   * @brief  AES CCM Authentication TAG generation.
210   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
211   *         the configuration information for CRYP module
212   * @param  pAuthTag Pointer to the authentication buffer
213   *         the pAuthTag generated here is 128bits length, if the TAG length is
214   *         less than 128bits, user should consider only the valid part of pAuthTag
215   *         buffer which correspond exactly to TAG length.
216   * @param  Timeout Timeout duration
217   * @retval HAL status
218   */
HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef * hcryp,const uint32_t * pAuthTag,uint32_t Timeout)219 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *pAuthTag,
220                                                     uint32_t Timeout)
221 {
222   uint32_t tagaddr = (uint32_t)pAuthTag;
223   uint32_t i;
224   uint32_t tickstart;
225 
226   if (hcryp->State == HAL_CRYP_STATE_READY)
227   {
228     __HAL_LOCK(hcryp);
229 
230     /* Disable interrupts in case they were kept enabled to proceed
231        a single message in several iterations */
232     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
233 
234     /* Change the CRYP peripheral state */
235     hcryp->State = HAL_CRYP_STATE_BUSY;
236 
237     /* Check if initialization phase has already been performed */
238     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
239     {
240       /* Change the CRYP phase */
241       hcryp->Phase = CRYPEx_PHASE_FINAL;
242       /* Select final phase */
243       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
244 
245       /* Wait for CCF flag to be raised */
246       tickstart = HAL_GetTick();
247       while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
248       {
249         /* Check for the Timeout */
250         if (Timeout != HAL_MAX_DELAY)
251         {
252           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
253           {
254             /* Disable the CRYP peripheral Clock */
255             __HAL_CRYP_DISABLE(hcryp);
256 
257             /* Change state */
258             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
259             hcryp->State = HAL_CRYP_STATE_READY;
260             __HAL_UNLOCK(hcryp);
261             return HAL_ERROR;
262           }
263         }
264       }
265 
266       /* Read the authentication TAG in the output FIFO */
267       for (i = 0U; i < 4U; i++)
268       {
269         *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
270         tagaddr += 4U;
271       }
272 
273       /* Clear CCF Flag */
274       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
275 
276       /* Change the CRYP peripheral state */
277       hcryp->State = HAL_CRYP_STATE_READY;
278       __HAL_UNLOCK(hcryp);
279 
280       /* Disable CRYP */
281       __HAL_CRYP_DISABLE(hcryp);
282     }
283     else /* Initialization phase has not been performed */
284     {
285       /* Disable the peripheral */
286       __HAL_CRYP_DISABLE(hcryp);
287 
288       /* Sequence error code field */
289       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
290 
291       /* Change the CRYP peripheral state */
292       hcryp->State = HAL_CRYP_STATE_READY;
293       __HAL_UNLOCK(hcryp);
294       return HAL_ERROR;
295     }
296   }
297   else
298   {
299     /* Busy error code field */
300     hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
301     return HAL_ERROR;
302   }
303   /* Return function status */
304   return HAL_OK;
305 }
306 
307 /**
308   * @}
309   */
310 
311 
312 /** @defgroup CRYPEx_Exported_Functions_Group2 Wrap and Unwrap key functions
313   * @brief    Wrap and Unwrap key functions.
314   *
315 @verbatim
316   ==============================================================================
317                       ##### Wrap and Unwrap key #####
318   ==============================================================================
319     [..]  This section provides API allowing to wrap (encrypt) and unwrap (decrypt)
320           key using one of the following keys, and AES Algorithm.
321           Key selection :
322            - Derived hardware unique key (DHUK)
323            - XOR of DHUK and BHK
324            - Boot hardware key (BHK)
325 
326 @endverbatim
327   * @{
328   */
329 
330 /**
331   * @brief  Wrap (encrypt) application keys.
332   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
333   *         the configuration information for CRYP module
334   * @param  pInput Pointer to the Key buffer to encrypt in case of ECB or CBC
335   * @param  pOutput Pointer to the Key buffer encrypted in case of ECB or CBC
336   * @param  Timeout Specify Timeout value
337   * @retval HAL status
338   */
HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t * pOutput,uint32_t Timeout)339 HAL_StatusTypeDef HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t *pOutput, uint32_t Timeout)
340 {
341   HAL_StatusTypeDef status;
342 
343   if (hcryp->State == HAL_CRYP_STATE_READY)
344   {
345     /* Change state Busy */
346     hcryp->State = HAL_CRYP_STATE_BUSY;
347     __HAL_LOCK(hcryp);
348 
349     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/
350     hcryp->CrypInCount = 0U;
351     hcryp->CrypOutCount = 0U;
352     hcryp->pCrypInBuffPtr = pInput;
353     hcryp->pCrypOutBuffPtr = pOutput;
354 
355     /* Disable the CRYP peripheral clock */
356     __HAL_CRYP_DISABLE(hcryp);
357 
358     /* Set the operating mode*/
359     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED);
360 
361     /* Encryption operating mode(Mode 0)*/
362     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
363 
364     status = CRYPEx_KeyEncrypt(hcryp, Timeout);
365   }
366   else
367   {
368     /* Busy error code field */
369     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
370     status = HAL_ERROR;
371   }
372   /* Return function status */
373   return status;
374 }
375 
376 /**
377   * @brief  Unwrap (Decrypt) application keys.
378   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
379   *         the configuration information for CRYP module
380   * @param  pInput Pointer to the Key buffer to decrypt.
381   * @param  Timeout Specify Timeout value
382   * @retval HAL status
383   */
HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t Timeout)384 HAL_StatusTypeDef HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t Timeout)
385 {
386   HAL_StatusTypeDef status;
387 
388   if (hcryp->State == HAL_CRYP_STATE_READY)
389   {
390     /* Change state Busy */
391     hcryp->State = HAL_CRYP_STATE_BUSY;
392 
393     __HAL_LOCK(hcryp);
394 
395     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
396     hcryp->CrypInCount = 0U;
397     hcryp->CrypOutCount = 0U;
398     hcryp->pCrypInBuffPtr = pInput;
399 
400     /* Disable the CRYP peripheral clock */
401     __HAL_CRYP_DISABLE(hcryp);
402 
403     /* Set the operating mode*/
404     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED);
405 
406     status = CRYPEx_KeyDecrypt(hcryp, Timeout);
407   }
408   else
409   {
410     /* Busy error code field */
411     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
412     status = HAL_ERROR;
413   }
414   /* Return function status */
415   return status;
416 }
417 
418 /**
419   * @}
420   */
421 
422 /** @defgroup CRYPEx_Exported_Functions_Group3 Encrypt and Decrypt Shared key functions
423   * @brief    Encrypt and Decrypt Shared key functions.
424   *
425 @verbatim
426   ==============================================================================
427                       ##### Encrypt and Decrypt Shared key functions #####
428   ==============================================================================
429     [..]  This section provides API allowing to Encrypt and Decrypt Shared key
430 
431 @endverbatim
432   * @{
433   */
434 
435 /**
436   * @brief  Encrypt Shared key.
437   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
438   *         the configuration information for CRYP module
439   * @param  pKey Pointer to the Key buffer to share
440   * @param  pOutput Pointer to the Key buffer encrypted
441   * @param  ID Key share identification
442   * @param  Timeout Specify Timeout value
443   * @retval HAL status
444   */
HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t * pOutput,uint32_t ID,uint32_t Timeout)445 HAL_StatusTypeDef HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t *pOutput, uint32_t ID,
446                                               uint32_t Timeout)
447 {
448   HAL_StatusTypeDef status;
449 
450   if (hcryp->State == HAL_CRYP_STATE_READY)
451   {
452     /* Change state Busy */
453     hcryp->State = HAL_CRYP_STATE_BUSY;
454     __HAL_LOCK(hcryp);
455 
456     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
457     hcryp->CrypInCount = 0U;
458     hcryp->CrypOutCount = 0U;
459     hcryp->pCrypInBuffPtr = pKey;
460     hcryp->pCrypOutBuffPtr = pOutput;
461 
462     /* Disable the CRYP peripheral clock */
463     __HAL_CRYP_DISABLE(hcryp);
464 
465     /* Set the operating mode */
466     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
467     /* Check the busy flag before writing CR register */
468     if (CRYPEx_WaitFLAG(hcryp, AES_SR_BUSY, SET, CRYPEx_GENERAL_TIMEOUT) != HAL_OK)
469     {
470       hcryp->State = HAL_CRYP_STATE_READY;
471       __HAL_UNLOCK(hcryp);
472       return HAL_ERROR;
473     }
474     /* Encryption operating mode(Mode 0)*/
475     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
476 
477     status = CRYPEx_KeyEncrypt(hcryp, Timeout);
478   }
479   else
480   {
481     /* Busy error code field */
482     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
483     status = HAL_ERROR;
484   }
485   /* Return function status */
486   return status;
487 }
488 
489 /**
490   * @brief  Decrypt Shared key.
491   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
492   *         the configuration information for CRYP module
493   * @param  pKey Pointer to the Key buffer to share
494   * @param  ID Key share identification
495   * @param  Timeout Specify Timeout value
496   * @retval HAL status
497   */
HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t ID,uint32_t Timeout)498 HAL_StatusTypeDef HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t ID, uint32_t Timeout)
499 {
500   HAL_StatusTypeDef status;
501 
502   if (hcryp->State == HAL_CRYP_STATE_READY)
503   {
504     /* Change state Busy */
505     hcryp->State = HAL_CRYP_STATE_BUSY;
506     __HAL_LOCK(hcryp);
507 
508     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
509     hcryp->CrypInCount = 0U;
510     hcryp->CrypOutCount = 0U;
511     hcryp->pCrypInBuffPtr = pKey;
512 
513     /* Disable the CRYP peripheral clock */
514     __HAL_CRYP_DISABLE(hcryp);
515 
516     /* Set the operating mode */
517     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
518     /* Check the busy flag before writing CR register */
519     if (CRYPEx_WaitFLAG(hcryp, AES_SR_BUSY, SET, CRYPEx_GENERAL_TIMEOUT) != HAL_OK)
520     {
521       hcryp->State = HAL_CRYP_STATE_READY;
522       __HAL_UNLOCK(hcryp);
523       return HAL_ERROR;
524     }
525     status = CRYPEx_KeyDecrypt(hcryp, Timeout);
526   }
527   else
528   {
529     /* Busy error code field */
530     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
531     status = HAL_ERROR;
532   }
533   /* Return function status */
534   return status;
535 }
536 
537 /**
538   * @}
539   */
540 
541 /**
542   * @}
543   */
544 
545 /* Private functions ---------------------------------------------------------*/
546 /** @addtogroup CRYP_Private_Functions
547   * @{
548   */
549 /**
550   * @brief  Key Decryption
551   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
552   * @param  Timeout specify Timeout value
553   * @note   It is strongly recommended to select hardware secret keys
554   * @retval HAL status
555   */
CRYPEx_KeyDecrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)556 static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
557 {
558   uint32_t incount; /* Temporary CrypInCount Value */
559   uint32_t i;
560   uint32_t tickstart;
561 
562   /* key preparation for decryption, operating mode 2*/
563   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
564 
565   /* Enable CRYP */
566   __HAL_CRYP_ENABLE(hcryp);
567 
568   /* Wait for CCF flag to be raised */
569   tickstart = HAL_GetTick();
570   while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
571   {
572     /* Check for the Timeout */
573     if (Timeout != HAL_MAX_DELAY)
574     {
575       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
576       {
577         /* Disable the CRYP peripheral clock */
578         __HAL_CRYP_DISABLE(hcryp);
579 
580         /* Change state */
581         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
582         hcryp->State = HAL_CRYP_STATE_READY;
583         __HAL_UNLOCK(hcryp);
584         return HAL_ERROR;
585       }
586     }
587   }
588   /* Clear CCF Flag */
589   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
590 
591   /*  End of Key preparation for ECB/CBC */
592   /* Return to decryption operating mode(Mode 3)*/
593   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
594 
595   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
596   {
597     /* Set the Initialization Vector */
598     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
599     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
600     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
601     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
602   }
603   /* Enable CRYP */
604   __HAL_CRYP_ENABLE(hcryp);
605 
606   /* Set the phase */
607   hcryp->Phase = CRYPEx_PHASE_PROCESS;
608 
609   if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
610   {
611     incount = 4U;
612   }
613   else
614   {
615     incount = 8U;
616   }
617   while (hcryp->CrypInCount < incount)
618   {
619     /* Write four times to input the key to encrypt */
620     for (i = 0U; i < 4U; i++)
621     {
622       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
623       hcryp->CrypInCount++;
624     }
625     /* Wait for CCF flag to be raised */
626     tickstart = HAL_GetTick();
627     while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
628     {
629       /* Check for the Timeout */
630       if (Timeout != HAL_MAX_DELAY)
631       {
632         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
633         {
634           /* Disable the CRYP peripheral clock */
635           __HAL_CRYP_DISABLE(hcryp);
636 
637           /* Change state */
638           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
639           hcryp->State = HAL_CRYP_STATE_READY;
640           __HAL_UNLOCK(hcryp);
641           return HAL_ERROR;
642         }
643       }
644     }
645 
646     /* Clear CCF Flag */
647     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
648   }
649 
650   /* Disable the CRYP peripheral clock */
651   __HAL_CRYP_DISABLE(hcryp);
652 
653   /* Change the CRYP peripheral state */
654   hcryp->State = HAL_CRYP_STATE_READY;
655   __HAL_UNLOCK(hcryp);
656   return HAL_OK;
657 }
658 
659 /**
660   * @brief  Key Encryption
661   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
662   * @param  Timeout specify Timeout value
663   * @retval HAL status
664   */
CRYPEx_KeyEncrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)665 static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
666 {
667   uint32_t incount; /* Temporary CrypInCount Value */
668   uint32_t i;
669   uint32_t tickstart;
670   uint32_t temp; /* Temporary CrypOutBuff */
671 
672   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
673   {
674     /* Set the Initialization Vector */
675     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
676     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
677     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
678     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
679   }
680 
681   /* Enable CRYP */
682   __HAL_CRYP_ENABLE(hcryp);
683 
684   /* Set the phase */
685   hcryp->Phase = CRYPEx_PHASE_PROCESS;
686 
687   if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
688   {
689     incount = 4U;
690   }
691   else
692   {
693     incount = 8U;
694   }
695   while (hcryp->CrypInCount < incount)
696   {
697     for (i = 0U; i < 4U; i++)
698     {
699       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
700       hcryp->CrypInCount++;
701     }
702     /* Wait for CCF flag to be raised */
703     tickstart = HAL_GetTick();
704     while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
705     {
706       /* Check for the Timeout */
707       if (Timeout != HAL_MAX_DELAY)
708       {
709         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
710         {
711           /* Disable the CRYP peripheral clock */
712           __HAL_CRYP_DISABLE(hcryp);
713 
714           /* Change state */
715           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
716           hcryp->State = HAL_CRYP_STATE_READY;
717           __HAL_UNLOCK(hcryp);
718           return HAL_ERROR;
719         }
720       }
721     }
722 
723     /* Clear CCF Flag */
724     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
725 
726     /* Read the output block from the output FIFO and put them in temporary buffer then
727        get CrypOutBuff from temporary buffer */
728     for (i = 0U; i < 4U; i++)
729     {
730       temp  = hcryp->Instance->DOUTR;
731       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
732       hcryp->CrypOutCount++;
733     }
734   }
735 
736   /* Disable the CRYP peripheral clock */
737   __HAL_CRYP_DISABLE(hcryp);
738 
739   /* Change the CRYP peripheral state */
740   hcryp->State = HAL_CRYP_STATE_READY;
741   __HAL_UNLOCK(hcryp);
742   return HAL_OK;
743 }
744 /**
745   * @brief  Wait Instance Flag
746   * @param  hcryp cryp handle
747   * @param  flag Specifies the flag to check
748   * @param  Status Flag status (SET or RESET)
749   * @param  Timeout Timeout duration
750   * @retval HAL status.
751   */
752 
CRYPEx_WaitFLAG(CRYP_HandleTypeDef * hcryp,uint32_t flag,FlagStatus Status,uint32_t Timeout)753 static HAL_StatusTypeDef CRYPEx_WaitFLAG(CRYP_HandleTypeDef *hcryp, uint32_t flag, FlagStatus Status, uint32_t Timeout)
754 {
755   uint32_t tickstart = HAL_GetTick();
756   while (__HAL_CRYP_GET_FLAG(hcryp, flag) == Status)
757   {
758     if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
759     {
760       CLEAR_BIT(hcryp->Instance->CR, AES_CR_EN);
761       /* Change state */
762       hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
763       /* return error */
764       return HAL_ERROR;
765     }
766   }
767   return HAL_OK;
768 }
769 
770 /**
771   * @}
772   */
773 
774 /**
775   * @}
776   */
777 
778 /**
779   * @}
780   */
781 
782 #endif /* HAL_CRYP_MODULE_ENABLED */
783 
784 #endif /* AES */
785 /**
786   * @}
787   */
788 
789 /**
790   * @}
791   */
792