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) 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 "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 
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_KeyGeneration(CRYP_HandleTypeDef *hcryp, 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,uint32_t * pAuthTag,uint32_t Timeout)103 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *pAuthTag, 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,uint32_t * pAuthTag,uint32_t Timeout)214 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *pAuthTag, uint32_t Timeout)
215 {
216   uint32_t tagaddr = (uint32_t)pAuthTag;
217   uint32_t i;
218   uint32_t tickstart;
219 
220   if (hcryp->State == HAL_CRYP_STATE_READY)
221   {
222     __HAL_LOCK(hcryp);
223 
224     /* Disable interrupts in case they were kept enabled to proceed
225        a single message in several iterations */
226     __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE);
227 
228     /* Change the CRYP peripheral state */
229     hcryp->State = HAL_CRYP_STATE_BUSY;
230 
231     /* Check if initialization phase has already been performed */
232     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
233     {
234       /* Change the CRYP phase */
235       hcryp->Phase = CRYPEx_PHASE_FINAL;
236       /* Select final phase */
237       MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
238 
239       /* Wait for CCF flag to be raised */
240       tickstart = HAL_GetTick();
241       while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
242       {
243         /* Check for the Timeout */
244         if (Timeout != HAL_MAX_DELAY)
245         {
246           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
247           {
248             /* Disable the CRYP peripheral Clock */
249             __HAL_CRYP_DISABLE(hcryp);
250 
251             /* Change state */
252             hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
253             hcryp->State = HAL_CRYP_STATE_READY;
254             __HAL_UNLOCK(hcryp);
255             return HAL_ERROR;
256           }
257         }
258       }
259 
260       /* Read the authentication TAG in the output FIFO */
261       for (i = 0U; i < 4U; i++)
262       {
263         *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
264         tagaddr += 4U;
265       }
266 
267       /* Clear CCF Flag */
268       __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
269 
270       /* Change the CRYP peripheral state */
271       hcryp->State = HAL_CRYP_STATE_READY;
272       __HAL_UNLOCK(hcryp);
273 
274       /* Disable CRYP */
275       __HAL_CRYP_DISABLE(hcryp);
276     }
277     else /* Initialization phase has not been performed */
278     {
279       /* Disable the peripheral */
280       __HAL_CRYP_DISABLE(hcryp);
281 
282       /* Sequence error code field */
283       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
284 
285       /* Change the CRYP peripheral state */
286       hcryp->State = HAL_CRYP_STATE_READY;
287       __HAL_UNLOCK(hcryp);
288       return HAL_ERROR;
289     }
290   }
291   else
292   {
293     /* Busy error code field */
294     hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
295     return HAL_ERROR;
296   }
297   /* Return function status */
298   return HAL_OK;
299 }
300 
301 /**
302   * @}
303   */
304 
305 
306 /** @defgroup CRYPEx_Exported_Functions_Group2 Wrap and Unwrap key functions
307   * @brief    Wrap and Unwrap key functions.
308   *
309 @verbatim
310   ==============================================================================
311                       ##### Wrap and Unwrap key #####
312   ==============================================================================
313     [..]  This section provides API allowing to wrap (encrypt) and unwrap (decrypt)
314           key using one of the following keys, and AES Algorithm.
315           Key selection :
316            - Derived hardware unique key (DHUK)
317            - XOR of DHUK and BHK
318            - Boot hardware key (BHK)
319 
320 @endverbatim
321   * @{
322   */
323 
324 /**
325   * @brief  Wrap (encrypt) application keys.
326   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
327   *         the configuration information for CRYP module
328   * @param  pInput Pointer to the Key buffer to encrypt in case of ECB or CBC
329   * @param  pOutput Pointer to the Key buffer encrypted in case of ECB or CBC
330   * @param  Timeout Specify Timeout value
331   * @retval HAL status
332   */
HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t * pOutput,uint32_t Timeout)333 HAL_StatusTypeDef HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t *pOutput, uint32_t Timeout)
334 {
335   HAL_StatusTypeDef status;
336   uint32_t algo;
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 
360     /* algo get algorithm selected */
361     algo = hcryp->Instance->CR & AES_CR_CHMOD;
362 
363     switch (algo)
364     {
365       case CRYP_AES_ECB:
366       case CRYP_AES_CBC:
367         /* AES decryption */
368         status = CRYPEx_KeyEncrypt(hcryp, Timeout);
369         break;
370       case CRYP_AES_CTR:
371         /* AES Key generation */
372         status = CRYPEx_KeyGeneration(hcryp, Timeout);
373         break;
374       default:
375         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
376         status = HAL_ERROR;
377         break;
378     }
379   }
380   else
381   {
382     /* Busy error code field */
383     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
384     status = HAL_ERROR;
385   }
386   /* Return function status */
387   return status;
388 }
389 
390 /**
391   * @brief  Unwrap (Decrypt) application keys.
392   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
393   *         the configuration information for CRYP module
394   * @param  pInput Pointer to the Key buffer to decrypt or generated key in case of CTR.
395   * @param  Timeout Specify Timeout value
396   * @retval HAL status
397   */
HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t Timeout)398 HAL_StatusTypeDef HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t Timeout)
399 {
400   HAL_StatusTypeDef status;
401   uint32_t algo;
402 
403   if (hcryp->State == HAL_CRYP_STATE_READY)
404   {
405     /* Change state Busy */
406     hcryp->State = HAL_CRYP_STATE_BUSY;
407 
408     __HAL_LOCK(hcryp);
409 
410     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
411     hcryp->CrypInCount = 0U;
412     hcryp->CrypOutCount = 0U;
413     hcryp->pCrypInBuffPtr = pInput;
414 
415     /* Disable the CRYP peripheral clock */
416     __HAL_CRYP_DISABLE(hcryp);
417 
418     /* Set the operating mode*/
419     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED);
420 
421     /* Decryption operating mode(Mode 3)*/
422     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
423 
424     /* algo get algorithm selected */
425     algo = hcryp->Instance->CR & AES_CR_CHMOD;
426 
427     switch (algo)
428     {
429       case CRYP_AES_ECB:
430       case CRYP_AES_CBC:
431         /* AES decryption */
432         status = CRYPEx_KeyDecrypt(hcryp, Timeout);
433         break;
434 
435       case CRYP_AES_CTR:
436         /* AES Key generation */
437         status = CRYPEx_KeyGeneration(hcryp, Timeout);
438         break;
439       default:
440         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
441         status = HAL_ERROR;
442         break;
443     }
444   }
445   else
446   {
447     /* Busy error code field */
448     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
449     status = HAL_ERROR;
450   }
451   /* Return function status */
452   return status;
453 }
454 
455 /**
456   * @}
457   */
458 
459 /** @defgroup CRYPEx_Exported_Functions_Group3 Encrypt and Decrypt Shared key functions
460   * @brief    Encrypt and Decrypt Shared key functions.
461   *
462 @verbatim
463   ==============================================================================
464                       ##### Encrypt and Decrypt Shared key functions #####
465   ==============================================================================
466     [..]  This section provides API allowing to Encrypt and Decrypt Shared key
467 
468 @endverbatim
469   * @{
470   */
471 
472 /**
473   * @brief  Encrypt Shared key.
474   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
475   *         the configuration information for CRYP module
476   * @param  pKey Pointer to the Key buffer to share
477   * @param  pOutput Pointer to the Key buffer encrypted
478   * @param  ID Key share identification
479   * @param  Timeout Specify Timeout value
480   * @retval HAL status
481   */
HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t * pOutput,uint32_t ID,uint32_t Timeout)482 HAL_StatusTypeDef HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t *pOutput, uint32_t ID,
483                                               uint32_t Timeout)
484 {
485   HAL_StatusTypeDef status;
486   uint32_t algo;
487 
488   if (hcryp->State == HAL_CRYP_STATE_READY)
489   {
490     /* Change state Busy */
491     hcryp->State = HAL_CRYP_STATE_BUSY;
492     __HAL_LOCK(hcryp);
493 
494     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
495     hcryp->CrypInCount = 0U;
496     hcryp->CrypOutCount = 0U;
497     hcryp->pCrypInBuffPtr = pKey;
498     hcryp->pCrypOutBuffPtr = pOutput;
499 
500     /* Disable the CRYP peripheral clock */
501     __HAL_CRYP_DISABLE(hcryp);
502 
503     /* Set the operating mode */
504     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
505 
506     /* Encryption operating mode(Mode 0)*/
507     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
508 
509     /* algo get algorithm selected */
510     algo = hcryp->Instance->CR & AES_CR_CHMOD;
511 
512     switch (algo)
513     {
514       case CRYP_AES_ECB:
515       case CRYP_AES_CBC:
516         /* AES decryption */
517         status = CRYPEx_KeyEncrypt(hcryp, Timeout);
518         break;
519       case CRYP_AES_CTR:
520         /* AES CTR key generation */
521         status = CRYPEx_KeyGeneration(hcryp, Timeout);
522         break;
523       default:
524         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
525         status = HAL_ERROR;
526         break;
527     }
528   }
529   else
530   {
531     /* Busy error code field */
532     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
533     status = HAL_ERROR;
534   }
535   /* Return function status */
536   return status;
537 }
538 
539 /**
540   * @brief  Decrypt Shared key.
541   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
542   *         the configuration information for CRYP module
543   * @param  pKey Pointer to the Key buffer to share
544   * @param  ID Key share identification
545   * @param  Timeout Specify Timeout value
546   * @retval HAL status
547   */
HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t ID,uint32_t Timeout)548 HAL_StatusTypeDef HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t ID, uint32_t Timeout)
549 {
550   HAL_StatusTypeDef status;
551   uint32_t algo;
552 
553   if (hcryp->State == HAL_CRYP_STATE_READY)
554   {
555     /* Change state Busy */
556     hcryp->State = HAL_CRYP_STATE_BUSY;
557     __HAL_LOCK(hcryp);
558 
559     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
560     hcryp->CrypInCount = 0U;
561     hcryp->CrypOutCount = 0U;
562     hcryp->pCrypInBuffPtr = pKey;
563 
564     /* Disable the CRYP peripheral clock */
565     __HAL_CRYP_DISABLE(hcryp);
566 
567     /* Set the operating mode */
568     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
569 
570     /* Decryption operating mode(Mode 3)*/
571     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
572 
573     /* algo get algorithm selected */
574     algo = hcryp->Instance->CR & AES_CR_CHMOD;
575 
576     switch (algo)
577     {
578       case CRYP_AES_ECB:
579       case CRYP_AES_CBC:
580         /* AES decryption */
581         status = CRYPEx_KeyDecrypt(hcryp, Timeout);
582         break;
583       case CRYP_AES_CTR:
584         /* AES CTR key generation */
585         status = CRYPEx_KeyGeneration(hcryp, Timeout);
586         break;
587       default:
588         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
589         status = HAL_ERROR;
590         break;
591     }
592   }
593   else
594   {
595     /* Busy error code field */
596     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
597     status = HAL_ERROR;
598   }
599   /* Return function status */
600   return status;
601 }
602 
603 /**
604   * @}
605   */
606 
607 /**
608   * @}
609   */
610 
611 /* Private functions ---------------------------------------------------------*/
612 /** @addtogroup CRYP_Private_Functions
613   * @{
614   */
615 /**
616   * @brief  Key Decryption
617   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
618   * @param  Timeout specify Timeout value
619   * @note   It is strongly recommended to select hardware secret keys
620   * @retval HAL status
621   */
CRYPEx_KeyDecrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)622 static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
623 {
624   uint32_t incount; /* Temporary CrypInCount Value */
625   uint32_t i;
626   uint32_t tickstart;
627 
628   /* key preparation for decryption, operating mode 2*/
629   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
630 
631   /* Enable CRYP */
632   __HAL_CRYP_ENABLE(hcryp);
633 
634   /* Wait for CCF flag to be raised */
635   tickstart = HAL_GetTick();
636   while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
637   {
638     /* Check for the Timeout */
639     if (Timeout != HAL_MAX_DELAY)
640     {
641       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
642       {
643         /* Disable the CRYP peripheral clock */
644         __HAL_CRYP_DISABLE(hcryp);
645 
646         /* Change state */
647         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
648         hcryp->State = HAL_CRYP_STATE_READY;
649         __HAL_UNLOCK(hcryp);
650         return HAL_ERROR;
651       }
652     }
653   }
654   /* Clear CCF Flag */
655   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
656 
657   /*  End of Key preparation for ECB/CBC */
658   /* Return to decryption operating mode(Mode 3)*/
659   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
660 
661   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
662   {
663     /* Set the Initialization Vector */
664     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
665     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
666     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
667     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
668   }
669   /* Enable CRYP */
670   __HAL_CRYP_ENABLE(hcryp);
671 
672   /* Set the phase */
673   hcryp->Phase = CRYPEx_PHASE_PROCESS;
674 
675   if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
676   {
677     incount = 4U;
678   }
679   else
680   {
681     incount = 8U;
682   }
683   while (hcryp->CrypInCount < incount)
684   {
685     /* Write four times to input the key to encrypt */
686     for (i = 0U; i < 4U; i++)
687     {
688       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
689       hcryp->CrypInCount++;
690     }
691     /* Wait for CCF flag to be raised */
692     tickstart = HAL_GetTick();
693     while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
694     {
695       /* Check for the Timeout */
696       if (Timeout != HAL_MAX_DELAY)
697       {
698         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
699         {
700           /* Disable the CRYP peripheral clock */
701           __HAL_CRYP_DISABLE(hcryp);
702 
703           /* Change state */
704           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
705           hcryp->State = HAL_CRYP_STATE_READY;
706           __HAL_UNLOCK(hcryp);
707           return HAL_ERROR;
708         }
709       }
710     }
711 
712     /* Clear CCF Flag */
713     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
714   }
715 
716   /* Disable the CRYP peripheral clock */
717   __HAL_CRYP_DISABLE(hcryp);
718 
719   /* Change the CRYP peripheral state */
720   hcryp->State = HAL_CRYP_STATE_READY;
721   __HAL_UNLOCK(hcryp);
722   return HAL_OK;
723 }
724 
725 /**
726   * @brief  Key Encryption
727   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
728   * @param  Timeout specify Timeout value
729   * @retval HAL status
730   */
CRYPEx_KeyEncrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)731 static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
732 {
733   uint32_t incount; /* Temporary CrypInCount Value */
734   uint32_t i;
735   uint32_t tickstart;
736   uint32_t temp; /* Temporary CrypOutBuff */
737 
738   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
739   {
740     /* Set the Initialization Vector */
741     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
742     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
743     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
744     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
745   }
746 
747   /* Enable CRYP */
748   __HAL_CRYP_ENABLE(hcryp);
749 
750   /* Set the phase */
751   hcryp->Phase = CRYPEx_PHASE_PROCESS;
752 
753   if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
754   {
755     incount = 4U;
756   }
757   else
758   {
759     incount = 8U;
760   }
761   while (hcryp->CrypInCount < incount)
762   {
763     for (i = 0U; i < 4U; i++)
764     {
765       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
766       hcryp->CrypInCount++;
767     }
768     /* Wait for CCF flag to be raised */
769     tickstart = HAL_GetTick();
770     while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
771     {
772       /* Check for the Timeout */
773       if (Timeout != HAL_MAX_DELAY)
774       {
775         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
776         {
777           /* Disable the CRYP peripheral clock */
778           __HAL_CRYP_DISABLE(hcryp);
779 
780           /* Change state */
781           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
782           hcryp->State = HAL_CRYP_STATE_READY;
783           __HAL_UNLOCK(hcryp);
784           return HAL_ERROR;
785         }
786       }
787     }
788 
789     /* Clear CCF Flag */
790     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
791 
792     /* Read the output block from the output FIFO and put them in temporary buffer then
793        get CrypOutBuff from temporary buffer */
794     for (i = 0U; i < 4U; i++)
795     {
796       temp  = hcryp->Instance->DOUTR;
797       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
798       hcryp->CrypOutCount++;
799     }
800   }
801 
802   /* Disable the CRYP peripheral clock */
803   __HAL_CRYP_DISABLE(hcryp);
804 
805   /* Change the CRYP peripheral state */
806   hcryp->State = HAL_CRYP_STATE_READY;
807   __HAL_UNLOCK(hcryp);
808   return HAL_OK;
809 }
810 /**
811   * @brief  Key Generation
812   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
813   * @param  Timeout specify Timeout value
814   * @retval HAL status
815   */
CRYPEx_KeyGeneration(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)816 static HAL_StatusTypeDef CRYPEx_KeyGeneration(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
817 {
818   uint32_t tickstart;
819 
820   /* No swap, DATATYPE must be kept to 0x0.*/
821   MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE, CRYP_NO_SWAP);
822 
823   /*Writes initialization vector in IV registers*/
824   if (hcryp->Init.pInitVect != NULL)
825   {
826     /* Set the Initialization Vector*/
827     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
828     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
829     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
830     /* Keeping the two least significant bit of SAES_IVR0 to 00 */
831     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
832     hcryp->Instance->IVR0 &= 0xFFFFFFFCU ;
833   }
834   else
835   {
836     return HAL_ERROR;
837   }
838 
839   /* Enable CRYP */
840   __HAL_CRYP_ENABLE(hcryp);
841 
842   /* Wait for CCF flag to be raised */
843   tickstart = HAL_GetTick();
844   while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
845   {
846     /* Check for the Timeout */
847     if (Timeout != HAL_MAX_DELAY)
848     {
849       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
850       {
851         /* Disable the CRYP peripheral clock */
852         __HAL_CRYP_DISABLE(hcryp);
853 
854         /* Change state */
855         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
856         hcryp->State = HAL_CRYP_STATE_READY;
857         __HAL_UNLOCK(hcryp);
858         return HAL_ERROR;
859       }
860     }
861   }
862   /* Clear CCF Flag */
863   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
864 
865   /* Disable the CRYP peripheral clock */
866   __HAL_CRYP_DISABLE(hcryp);
867 
868   /* Change the CRYP peripheral state */
869   hcryp->State = HAL_CRYP_STATE_READY;
870   __HAL_UNLOCK(hcryp);
871 
872   return HAL_OK;
873 }
874 
875 /**
876   * @}
877   */
878 
879 /**
880   * @}
881   */
882 
883 /**
884   * @}
885   */
886 
887 #endif /* HAL_CRYP_MODULE_ENABLED */
888 
889 #endif /* AES */
890 /**
891   * @}
892   */
893 
894 /**
895   * @}
896   */
897