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       default:
371         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
372         status = HAL_ERROR;
373         break;
374     }
375   }
376   else
377   {
378     /* Busy error code field */
379     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
380     status = HAL_ERROR;
381   }
382   /* Return function status */
383   return status;
384 }
385 
386 /**
387   * @brief  Unwrap (Decrypt) application keys.
388   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
389   *         the configuration information for CRYP module
390   * @param  pInput Pointer to the Key buffer to decrypt in case of ECB or CBC.
391   * @param  Timeout Specify Timeout value
392   * @retval HAL status
393   */
HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef * hcryp,uint32_t * pInput,uint32_t Timeout)394 HAL_StatusTypeDef HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t Timeout)
395 {
396   HAL_StatusTypeDef status;
397   uint32_t algo;
398 
399   if (hcryp->State == HAL_CRYP_STATE_READY)
400   {
401     /* Change state Busy */
402     hcryp->State = HAL_CRYP_STATE_BUSY;
403 
404     __HAL_LOCK(hcryp);
405 
406     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
407     hcryp->CrypInCount = 0U;
408     hcryp->CrypOutCount = 0U;
409     hcryp->pCrypInBuffPtr = pInput;
410 
411     /* Disable the CRYP peripheral clock */
412     __HAL_CRYP_DISABLE(hcryp);
413 
414     /* Set the operating mode*/
415     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED);
416 
417     /* Decryption operating mode(Mode 3)*/
418     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
419 
420     /* algo get algorithm selected */
421     algo = hcryp->Instance->CR & AES_CR_CHMOD;
422 
423     switch (algo)
424     {
425       case CRYP_AES_ECB:
426       case CRYP_AES_CBC:
427         /* AES decryption */
428         status = CRYPEx_KeyDecrypt(hcryp, Timeout);
429         break;
430 
431       case CRYP_AES_CTR:
432         /* AES Key generation */
433         status = CRYPEx_KeyGeneration(hcryp, Timeout);
434         break;
435       default:
436         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
437         status = HAL_ERROR;
438         break;
439     }
440   }
441   else
442   {
443     /* Busy error code field */
444     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
445     status = HAL_ERROR;
446   }
447   /* Return function status */
448   return status;
449 }
450 
451 /**
452   * @}
453   */
454 
455 /** @defgroup CRYPEx_Exported_Functions_Group3 Encrypt and Decrypt Shared key functions
456   * @brief    Encrypt and Decrypt Shared key functions.
457   *
458 @verbatim
459   ==============================================================================
460                       ##### Encrypt and Decrypt Shared key functions #####
461   ==============================================================================
462     [..]  This section provides API allowing to Encrypt/Decrypt Shared key
463 
464 @endverbatim
465   * @{
466   */
467 
468 /**
469   * @brief  Encrypt Shared key.
470   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
471   *         the configuration information for CRYP module
472   * @param  pKey Pointer to the Key buffer to share
473   * @param  pOutput Pointer to the Key buffer encrypted
474   * @param  ID Key share identification
475   * @param  Timeout Specify Timeout value
476   * @retval HAL status
477   */
HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t * pOutput,uint32_t ID,uint32_t Timeout)478 HAL_StatusTypeDef HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t *pOutput, uint32_t ID,
479                                               uint32_t Timeout)
480 {
481   HAL_StatusTypeDef status;
482   uint32_t algo;
483 
484   if (hcryp->State == HAL_CRYP_STATE_READY)
485   {
486     /* Change state Busy */
487     hcryp->State = HAL_CRYP_STATE_BUSY;
488     __HAL_LOCK(hcryp);
489 
490     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
491     hcryp->CrypInCount = 0U;
492     hcryp->CrypOutCount = 0U;
493     hcryp->pCrypInBuffPtr = pKey;
494     hcryp->pCrypOutBuffPtr = pOutput;
495 
496     /* Disable the CRYP peripheral clock */
497     __HAL_CRYP_DISABLE(hcryp);
498 
499     /* Set the operating mode */
500     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
501 
502     /* Encryption operating mode(Mode 0)*/
503     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
504 
505     /* algo get algorithm selected */
506     algo = hcryp->Instance->CR & AES_CR_CHMOD;
507 
508     switch (algo)
509     {
510       case CRYP_AES_ECB:
511       case CRYP_AES_CBC:
512         /* AES decryption */
513         status = CRYPEx_KeyEncrypt(hcryp, Timeout);
514         break;
515       default:
516         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
517         status = HAL_ERROR;
518         break;
519     }
520   }
521   else
522   {
523     /* Busy error code field */
524     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
525     status = HAL_ERROR;
526   }
527   /* Return function status */
528   return status;
529 }
530 
531 /**
532   * @brief  Decrypt Shared key.
533   * @param  hcryp pointer to a CRYP_HandleTypeDef structure that contains
534   *         the configuration information for CRYP module
535   * @param  pKey Pointer to the Key buffer to share
536   * @param  ID Key share identification
537   * @param  Timeout Specify Timeout value
538   * @retval HAL status
539   */
HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef * hcryp,uint32_t * pKey,uint32_t ID,uint32_t Timeout)540 HAL_StatusTypeDef HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t ID, uint32_t Timeout)
541 {
542   HAL_StatusTypeDef status;
543   uint32_t algo;
544 
545   if (hcryp->State == HAL_CRYP_STATE_READY)
546   {
547     /* Change state Busy */
548     hcryp->State = HAL_CRYP_STATE_BUSY;
549     __HAL_LOCK(hcryp);
550 
551     /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */
552     hcryp->CrypInCount = 0U;
553     hcryp->CrypOutCount = 0U;
554     hcryp->pCrypInBuffPtr = pKey;
555 
556     /* Disable the CRYP peripheral clock */
557     __HAL_CRYP_DISABLE(hcryp);
558 
559     /* Set the operating mode */
560     MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID);
561 
562     /* Decryption operating mode(Mode 3)*/
563     MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
564 
565     /* algo get algorithm selected */
566     algo = hcryp->Instance->CR & AES_CR_CHMOD;
567 
568     switch (algo)
569     {
570       case CRYP_AES_ECB:
571       case CRYP_AES_CBC:
572         /* AES decryption */
573         status = CRYPEx_KeyDecrypt(hcryp, Timeout);
574         break;
575       default:
576         hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
577         status = HAL_ERROR;
578         break;
579     }
580   }
581   else
582   {
583     /* Busy error code field */
584     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
585     status = HAL_ERROR;
586   }
587   /* Return function status */
588   return status;
589 }
590 
591 /**
592   * @}
593   */
594 
595 /**
596   * @}
597   */
598 
599 /* Private functions ---------------------------------------------------------*/
600 /** @addtogroup CRYP_Private_Functions
601   * @{
602   */
603 /**
604   * @brief  Key Decryption
605   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
606   * @param  Timeout specify Timeout value
607   * @note   It is strongly recommended to select hardware secret keys
608   * @retval HAL status
609   */
CRYPEx_KeyDecrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)610 static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
611 {
612   uint32_t incount; /* Temporary CrypInCount Value */
613   uint32_t i;
614   uint32_t tickstart;
615 
616   /* key preparation for decryption, operating mode 2*/
617   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION);
618 
619   /* Enable CRYP */
620   __HAL_CRYP_ENABLE(hcryp);
621 
622   /* Wait for CCF flag to be raised */
623   tickstart = HAL_GetTick();
624   while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
625   {
626     /* Check for the Timeout */
627     if (Timeout != HAL_MAX_DELAY)
628     {
629       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
630       {
631         /* Disable the CRYP peripheral clock */
632         __HAL_CRYP_DISABLE(hcryp);
633 
634         /* Change state */
635         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
636         hcryp->State = HAL_CRYP_STATE_READY;
637         __HAL_UNLOCK(hcryp);
638         return HAL_ERROR;
639       }
640     }
641   }
642   /* Clear CCF Flag */
643   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
644 
645   /*  End of Key preparation for ECB/CBC */
646   /* Return to decryption operating mode(Mode 3)*/
647   MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT);
648 
649   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
650   {
651     /* Set the Initialization Vector */
652     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
653     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
654     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
655     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
656   }
657   /* Enable CRYP */
658   __HAL_CRYP_ENABLE(hcryp);
659 
660   /* Set the phase */
661   hcryp->Phase = CRYPEx_PHASE_PROCESS;
662 
663   if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
664   {
665     incount = 4U;
666   }
667   else
668   {
669     incount = 8U;
670   }
671   while (hcryp->CrypInCount < incount)
672   {
673     /* Write four times to input the key to encrypt */
674     for (i = 0U; i < 4U; i++)
675     {
676       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
677       hcryp->CrypInCount++;
678     }
679     /* Wait for CCF flag to be raised */
680     tickstart = HAL_GetTick();
681     while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
682     {
683       /* Check for the Timeout */
684       if (Timeout != HAL_MAX_DELAY)
685       {
686         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
687         {
688           /* Disable the CRYP peripheral clock */
689           __HAL_CRYP_DISABLE(hcryp);
690 
691           /* Change state */
692           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
693           hcryp->State = HAL_CRYP_STATE_READY;
694           __HAL_UNLOCK(hcryp);
695           return HAL_ERROR;
696         }
697       }
698     }
699 
700     /* Clear CCF Flag */
701     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
702   }
703 
704   /* Disable the CRYP peripheral clock */
705   __HAL_CRYP_DISABLE(hcryp);
706 
707   /* Change the CRYP peripheral state */
708   hcryp->State = HAL_CRYP_STATE_READY;
709   __HAL_UNLOCK(hcryp);
710   return HAL_OK;
711 }
712 
713 /**
714   * @brief  Key Encryption
715   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
716   * @param  Timeout specify Timeout value
717   * @retval HAL status
718   */
CRYPEx_KeyEncrypt(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)719 static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
720 {
721   uint32_t incount; /* Temporary CrypInCount Value */
722   uint32_t i;
723   uint32_t tickstart;
724   uint32_t temp; /* Temporary CrypOutBuff */
725 
726   if (hcryp->Init.Algorithm != CRYP_AES_ECB)
727   {
728     /* Set the Initialization Vector */
729     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
730     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
731     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
732     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
733   }
734 
735   /* Enable CRYP */
736   __HAL_CRYP_ENABLE(hcryp);
737 
738   /* Set the phase */
739   hcryp->Phase = CRYPEx_PHASE_PROCESS;
740 
741   if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B)
742   {
743     incount = 4U;
744   }
745   else
746   {
747     incount = 8U;
748   }
749   while (hcryp->CrypInCount < incount)
750   {
751     for (i = 0U; i < 4U; i++)
752     {
753       hcryp->Instance->DINR  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
754       hcryp->CrypInCount++;
755     }
756     /* Wait for CCF flag to be raised */
757     tickstart = HAL_GetTick();
758     while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
759     {
760       /* Check for the Timeout */
761       if (Timeout != HAL_MAX_DELAY)
762       {
763         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
764         {
765           /* Disable the CRYP peripheral clock */
766           __HAL_CRYP_DISABLE(hcryp);
767 
768           /* Change state */
769           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
770           hcryp->State = HAL_CRYP_STATE_READY;
771           __HAL_UNLOCK(hcryp);
772           return HAL_ERROR;
773         }
774       }
775     }
776 
777     /* Clear CCF Flag */
778     __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
779 
780     /* Read the output block from the output FIFO and put them in temporary buffer then
781        get CrypOutBuff from temporary buffer */
782     for (i = 0U; i < 4U; i++)
783     {
784       temp  = hcryp->Instance->DOUTR;
785       *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp;
786       hcryp->CrypOutCount++;
787     }
788   }
789 
790   /* Disable the CRYP peripheral clock */
791   __HAL_CRYP_DISABLE(hcryp);
792 
793   /* Change the CRYP peripheral state */
794   hcryp->State = HAL_CRYP_STATE_READY;
795   __HAL_UNLOCK(hcryp);
796   return HAL_OK;
797 }
798 /**
799   * @brief  Key Generation
800   * @param  hcryp pointer to a CRYP_HandleTypeDef structure
801   * @param  Timeout specify Timeout value
802   * @retval HAL status
803   */
CRYPEx_KeyGeneration(CRYP_HandleTypeDef * hcryp,uint32_t Timeout)804 static HAL_StatusTypeDef CRYPEx_KeyGeneration(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
805 {
806   uint32_t tickstart;
807 
808   /* No swap, DATATYPE must be kept to 0x0.*/
809   MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE, CRYP_NO_SWAP);
810 
811   /*Writes initialization vector in IV registers*/
812   if (hcryp->Init.pInitVect != NULL)
813   {
814     /* Set the Initialization Vector*/
815     hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect);
816     hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
817     hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
818     /* Keeping the two least significant bit of SAES_IVR0 to 00 */
819     hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
820     hcryp->Instance->IVR0 &= 0xFFFFFFFCU ;
821   }
822   else
823   {
824     return HAL_ERROR;
825   }
826 
827   /* Enable CRYP */
828   __HAL_CRYP_ENABLE(hcryp);
829 
830   /* Wait for CCF flag to be raised */
831   tickstart = HAL_GetTick();
832   while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF))
833   {
834     /* Check for the Timeout */
835     if (Timeout != HAL_MAX_DELAY)
836     {
837       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
838       {
839         /* Disable the CRYP peripheral clock */
840         __HAL_CRYP_DISABLE(hcryp);
841 
842         /* Change state */
843         hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
844         hcryp->State = HAL_CRYP_STATE_READY;
845         __HAL_UNLOCK(hcryp);
846         return HAL_ERROR;
847       }
848     }
849   }
850   /* Clear CCF Flag */
851   __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF);
852 
853   /* Disable the CRYP peripheral clock */
854   __HAL_CRYP_DISABLE(hcryp);
855 
856   /* Change the CRYP peripheral state */
857   hcryp->State = HAL_CRYP_STATE_READY;
858   __HAL_UNLOCK(hcryp);
859 
860   return HAL_OK;
861 }
862 
863 /**
864   * @}
865   */
866 
867 /**
868   * @}
869   */
870 
871 /**
872   * @}
873   */
874 
875 #endif /* HAL_CRYP_MODULE_ENABLED */
876 
877 #endif /* AES */
878 /**
879   * @}
880   */
881 
882 /**
883   * @}
884   */
885