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