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