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