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