1 /**
2   ******************************************************************************
3   * @file    stm32h7rsxx_hal_mce.c
4   * @author  MCD Application Team
5   * @brief   MCE HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          features of the Memory Cipher Engine (MCE) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Region setting/enable functions
10   *           + Peripheral State functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2022 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                      ##### How to use this driver #####
26   ==============================================================================
27  [..]
28     The MCE HAL driver can be used as follows:
29 
30     (#) ToBC (refer to MCE comments)
31 
32 
33     [..]
34 
35     *** Callback registration ***
36     =============================================
37     [..]
38 
39      The compilation flag USE_HAL_MCE_REGISTER_CALLBACKS, when set to 1,
40      allows the user to configure dynamically the driver callbacks.
41      Use Functions @ref HAL_MCE_RegisterCallback()
42      to register an interrupt callback.
43     [..]
44 
45      ToBC (refer to MCE comments)
46 
47      When the compilation flag USE_HAL_MCE_REGISTER_CALLBACKS is set to 0 or
48      not defined, the callback registration feature is not available and all callbacks
49      are set to the corresponding weak functions.
50 
51   @endverbatim
52   */
53 
54 /* Includes ------------------------------------------------------------------*/
55 #include "stm32h7rsxx_hal.h"
56 
57 /** @addtogroup STM32H7RSxx_HAL_Driver
58   * @{
59   */
60 
61 /** @defgroup MCE MCE
62   * @brief MCE HAL module driver.
63   * @{
64   */
65 
66 
67 #ifdef HAL_MCE_MODULE_ENABLED
68 
69 #if defined(MCE1)
70 
71 /* Private typedef -----------------------------------------------------------*/
72 /* Private defines -----------------------------------------------------------*/
73 #define MCE_TIMEOUT_VALUE  255U   /* Internal timeout for keys valid flag */
74 #define MCE1_CONTEXT_NB    2U
75 /* Private macros ------------------------------------------------------------*/
76 
77 #define IS_MCE_AES_INSTANCE(INSTANCE) ((INSTANCE) == MCE1)
78 
79 
80 #define IS_MCE_NOEKEON_INSTANCE(INSTANCE) ((INSTANCE) == MCE2) || ((INSTANCE) == MCE3)
81 
82 /* Private variables ---------------------------------------------------------*/
83 /* Private function prototypes -----------------------------------------------*/
84 /* Private functions ---------------------------------------------------------*/
85 
86 /* Exported functions --------------------------------------------------------*/
87 /** @addtogroup MCE_Exported_Functions
88   * @{
89   */
90 
91 /** @defgroup MCE_Exported_Functions_Group1 Initialization and de-initialization functions
92   *  @brief    Initialization and Configuration functions.
93   *
94 @verbatim
95   ==============================================================================
96               ##### Initialization and de-initialization functions #####
97   ==============================================================================
98 
99 @endverbatim
100   * @{
101   */
102 
103 /**
104   * @brief  Initialize the MCE peripheral and create the associated handle.
105   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
106   *         the configuration information for MCE module
107   * @retval HAL status
108   */
HAL_MCE_Init(MCE_HandleTypeDef * hmce)109 HAL_StatusTypeDef HAL_MCE_Init(MCE_HandleTypeDef *hmce)
110 {
111   /* Check the MCE handle allocation */
112   if (hmce == NULL)
113   {
114     return HAL_ERROR;
115   }
116 
117   /* Check the parameters */
118   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
119 
120   if (hmce->State == HAL_MCE_STATE_RESET)
121   {
122     /* Allocate lock resource and initialize it */
123     __HAL_UNLOCK(hmce);
124 
125 #if (USE_HAL_MCE_REGISTER_CALLBACKS == 1)
126     /* Init the MCE Callback settings */
127     hmce->ErrorCallback = HAL_MCE_ErrorCallback; /* Legacy weak callback */
128 
129     if (hmce->MspInitCallback == NULL)
130     {
131       hmce->MspInitCallback = HAL_MCE_MspInit; /* Legacy weak MspInit */
132     }
133 
134     /* Init the low level hardware */
135     hmce->MspInitCallback(hmce);
136 #else
137     /* Init the low level hardware */
138     HAL_MCE_MspInit(hmce);
139 #endif /* USE_HAL_MCE_REGISTER_CALLBACKS */
140   }
141 
142   /* Change the MCE state */
143   hmce->State = HAL_MCE_STATE_READY;
144 
145   /* Return function status */
146   return HAL_OK;
147 }
148 
149 /**
150   * @brief  DeInitialize the MCE peripheral.
151   * @note   Any lock set at peripheral, key or cipher context level requires a MCE peripheral reset
152   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
153   *         the configuration information for MCE module
154   * @retval HAL status
155   */
HAL_MCE_DeInit(MCE_HandleTypeDef * hmce)156 HAL_StatusTypeDef HAL_MCE_DeInit(MCE_HandleTypeDef *hmce)
157 {
158   MCE_Region_TypeDef *p_region;
159   MCE_Context_TypeDef *p_context;
160 
161   /* Check the MCE handle allocation */
162   if (hmce == NULL)
163   {
164     return HAL_ERROR;
165   }
166 
167   /* Check the parameters */
168   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
169 
170   /* Change the MCE state */
171   hmce->State = HAL_MCE_STATE_BUSY;
172 
173   /* Disable interrupts */
174   CLEAR_BIT(hmce->Instance->IAIER, MCE_IAIER_IAEIE | MCE_IAIER_CAEIE);
175 
176   /* Disable all regions */
177   for (uint32_t i = MCE_REGION1; i <= MCE_REGION4; i++)
178   {
179     p_region = (MCE_Region_TypeDef *)((uint32_t)(hmce->Instance) + 0x40U + (0x10U * i));
180     CLEAR_BIT(p_region->REGCR, MCE_REGCR_BREN);
181     CLEAR_BIT(p_region->ATTR, MCE_ATTR_WREN);
182   }
183 
184   /* Disable all cipher contexts if any for the MCE instance */
185   if (hmce->Instance == MCE1)
186   {
187     for (uint32_t i = 0; i < MCE1_CONTEXT_NB; i++)
188     {
189       p_context = (MCE_Context_TypeDef *)((uint32_t)(hmce->Instance) + 0x240U + (0x30U * i));
190       CLEAR_BIT(p_context->CCCFGR, MCE_CCCFGR_CCEN);
191     }
192   }
193 
194   /* Clear privileged-only configuration access */
195   CLEAR_BIT(hmce->Instance->PRIVCFGR, MCE_PRIVCFGR_PRIV);
196 
197   /* Clear flags */
198   WRITE_REG(hmce->Instance->IACR, MCE_IACR_IAEF | MCE_IACR_CAEF);
199 
200 #if (USE_HAL_MCE_REGISTER_CALLBACKS == 1)
201   if (hmce->MspDeInitCallback == NULL)
202   {
203     hmce->MspDeInitCallback = HAL_MCE_MspDeInit; /* Legacy weak MspDeInit */
204   }
205 
206   /* DeInit the low level hardware: CLOCK, NVIC */
207   hmce->MspDeInitCallback(hmce);
208 #else
209   /* DeInit the low level hardware: CLOCK, NVIC */
210   HAL_MCE_MspDeInit(hmce);
211 #endif /* USE_HAL_MCE_REGISTER_CALLBACKS */
212 
213   /* Change the MCE state */
214   hmce->State = HAL_MCE_STATE_RESET;
215 
216   /* Reset MCE error status */
217   hmce->ErrorCode = HAL_MCE_ERROR_NONE;
218 
219   /* Release Lock */
220   __HAL_UNLOCK(hmce);
221 
222   /* Return function status */
223   return HAL_OK;
224 }
225 
226 
227 /** *********  main sequence functions : set the configuration of regions, AES context and Noekeon config *********/
228 
229 /**
230   * @brief  Write instance master or fast master keys
231   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
232   *         the configuration information for MCE module
233   * @param  pConfig pointer at an MCE_NoekeonConfig structure that contains
234             the configuration on the Noekeon encryption engine
235   * @note   Writes are ignored if MKLOCK or GLOCK bit is set in MCE_CR register and HAL error
236   *         is reported in that case
237   * @retval HAL status
238   */
HAL_MCE_ConfigNoekeon(MCE_HandleTypeDef * hmce,const MCE_NoekeonConfigTypeDef * pConfig)239 HAL_StatusTypeDef HAL_MCE_ConfigNoekeon(MCE_HandleTypeDef *hmce, const MCE_NoekeonConfigTypeDef *pConfig)
240 {
241   HAL_StatusTypeDef ret = HAL_OK;
242   uint32_t tickstart;
243 
244   /* Check the parameters */
245   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
246 
247   assert_param(IS_MCE_NOEKEON_INSTANCE(hmce->Instance));
248   /* If Key is null, or
249      if the global lock is set or
250      if the master keys lock is set,
251      return an error */
252   tickstart = HAL_GetTick();
253   if (((hmce->Instance->CR & (MCE_CR_GLOCK | MCE_CR_MKLOCK)) == 0U) && (pConfig->pKey != NULL))
254   {
255     /* Take Lock */
256     __HAL_LOCK(hmce);
257 
258     /* master keys are used for encryption */
259     if (pConfig->KeyType == MCE_USE_MASTERKEYS)
260     {
261       /* If Master Key valid flag is set, need to write dummy value in MKEYRx to reset it */
262       if ((hmce->Instance->SR & MCE_SR_MKVALID) != 0U)
263       {
264         WRITE_REG(hmce->Instance->MKEYR0, 0U);
265       }
266 
267       /* Set Key */
268       WRITE_REG(hmce->Instance->MKEYR0, pConfig->pKey[0]);
269       WRITE_REG(hmce->Instance->MKEYR1, pConfig->pKey[1]);
270       WRITE_REG(hmce->Instance->MKEYR2, pConfig->pKey[2]);
271       WRITE_REG(hmce->Instance->MKEYR3, pConfig->pKey[3]);
272       while (HAL_IS_BIT_CLR(hmce->Instance->SR, MCE_SR_MKVALID))
273       {
274         /* Check for the Timeout */
275         if ((HAL_GetTick() - tickstart) > MCE_TIMEOUT_VALUE)
276         {
277 
278           hmce->ErrorCode |= HAL_MCE_MASTER_KEY_ERROR;
279           ret = HAL_ERROR;
280           break;
281         }
282       }
283 
284     }
285     else if (pConfig->KeyType == MCE_USE_FASTMASTERKEYS)
286     {
287       /* If Fast Master Key valid flag is set, need to write dummy value in FMKEYRx to reset it */
288       if ((hmce->Instance->SR & MCE_SR_FMKVALID) != 0U)
289       {
290         WRITE_REG(hmce->Instance->FMKEYR0, 0U);
291       }
292       /* Set Key */
293       WRITE_REG(hmce->Instance->FMKEYR0, pConfig->pKey[0]);
294       WRITE_REG(hmce->Instance->FMKEYR1, pConfig->pKey[1]);
295       WRITE_REG(hmce->Instance->FMKEYR2, pConfig->pKey[2]);
296       WRITE_REG(hmce->Instance->FMKEYR3, pConfig->pKey[3]);
297       while (HAL_IS_BIT_CLR(hmce->Instance->SR, MCE_SR_FMKVALID))
298       {
299         /* Check for the Timeout */
300         if ((HAL_GetTick() - tickstart) > MCE_TIMEOUT_VALUE)
301         {
302           hmce->ErrorCode |= HAL_MCE_FASTMASTER_KEY_ERROR;
303           ret = HAL_ERROR;
304           break;
305         }
306       }
307     }
308     else
309     {
310       /* nothing to do, the keytype is not valid */
311     }
312     __HAL_UNLOCK(hmce);
313   }
314   return ret;
315 }
316 
317 
318 /**
319   * @brief  Set context configuration.
320   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
321   *         the configuration information for MCE module
322   * @param  AESConfig context configuration
323   * @param  ContextIndex index of context that is configured
324   * @retval HAL status
325   */
HAL_MCE_ConfigAESContext(MCE_HandleTypeDef * hmce,const MCE_AESConfigTypeDef * AESConfig,uint32_t ContextIndex)326 HAL_StatusTypeDef HAL_MCE_ConfigAESContext(MCE_HandleTypeDef *hmce, const MCE_AESConfigTypeDef  *AESConfig,
327                                            uint32_t ContextIndex)
328 {
329   HAL_StatusTypeDef ret = HAL_ERROR;
330   MCE_Context_TypeDef *p_context;
331   uint32_t *p_key;
332   __IO uint32_t address;
333 
334   /* Check the parameters */
335   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
336   assert_param(IS_MCE_AES_INSTANCE(hmce->Instance));
337   assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
338 
339 
340   /* If global lock is set or no configuration provided, context cannot be configured */
341   if (((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK) && (AESConfig != NULL) && \
342       ((ContextIndex == MCE_CONTEXT1) || (ContextIndex == MCE_CONTEXT2)))
343   {
344     address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
345                               (0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
346     p_context = (MCE_Context_TypeDef *)address;
347     /* Check cipher context is not locked */
348     if (((p_context->CCCFGR & MCE_CCCFGR_CCLOCK) != MCE_CCCFGR_CCLOCK))
349     {
350       if ((p_context->CCCFGR & MCE_CCCFGR_KEYLOCK) != MCE_CCCFGR_KEYLOCK)
351       {
352         /* Take Lock */
353         __HAL_LOCK(hmce);
354 
355         /* Write nonce */
356         WRITE_REG(p_context->CCNR0, AESConfig->Nonce[0]);
357         WRITE_REG(p_context->CCNR1, AESConfig->Nonce[1]);
358 
359         if (AESConfig->pKey != NULL)
360         {
361           p_key = AESConfig->pKey;
362           WRITE_REG(p_context->CCKEYR0, *p_key);
363           p_key++;
364           WRITE_REG(p_context->CCKEYR1, *p_key);
365           p_key++;
366           WRITE_REG(p_context->CCKEYR2, *p_key);
367           p_key++;
368           WRITE_REG(p_context->CCKEYR3, *p_key);
369         }
370         /* Compute theoretically expected CRC and compare it with that reported by the peripheral */
371 
372         /* Write version */
373         MODIFY_REG(p_context->CCCFGR, MCE_CCCFGR_VERSION, ((uint32_t) AESConfig->Version) << MCE_CCCFGR_VERSION_Pos);
374 
375         ret = HAL_OK;
376 
377         /* Release Lock */
378         __HAL_UNLOCK(hmce);
379       }
380     }
381   }
382   return ret;
383 }
384 
385 
386 /**
387   * @brief  Set region configuration.
388   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
389   *         the configuration information for MCE module
390   * @param  RegionIndex index of region that is configured
391   * @param  pConfig region configuration
392   * @note   The region is enabled by default once the configuration is complete
393   * @note   An enabled region is temporary disabled to apply the new configuration
394   * @retval HAL status
395   */
HAL_MCE_ConfigRegion(MCE_HandleTypeDef * hmce,uint32_t RegionIndex,const MCE_RegionConfigTypeDef * pConfig)396 HAL_StatusTypeDef HAL_MCE_ConfigRegion(MCE_HandleTypeDef *hmce, uint32_t RegionIndex,
397                                        const MCE_RegionConfigTypeDef *pConfig)
398 {
399   HAL_StatusTypeDef ret = HAL_ERROR;
400   MCE_Region_TypeDef *p_region;
401   __IO uint32_t address;
402 
403   /* Check the parameters */
404   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
405   assert_param(IS_MCE_REGIONINDEX(RegionIndex));
406   assert_param(IS_MCE_ALGORITHM(hmce->Instance, pConfig->Mode));
407 
408   assert_param(IS_MCE_WRITE(pConfig->AccessMode));
409   assert_param(IS_MCE_REGIONPRIVILEGED(pConfig->PrivilegedAccess));
410 
411   /* If global lock is set or no configuration provided, region cannot be configured */
412   if (((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK) && (pConfig != NULL))
413   {
414     /* Take Lock */
415     __HAL_LOCK(hmce);
416 
417     address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x40U + (0x10U * RegionIndex));
418     p_region = (MCE_Region_TypeDef *)address;
419 
420     /* If region is enabled, disable it during the configuration process */
421     if ((p_region->REGCR & MCE_REGCR_BREN) == MCE_REGCR_BREN)
422     {
423       CLEAR_BIT(p_region->REGCR, MCE_REGCR_BREN);
424     }
425 
426     /* Set privileged access, ciphering algorithm and context ID */
427     MODIFY_REG(p_region->REGCR,  MCE_REGCR_ENC | MCE_REGCR_PRIV, \
428                pConfig->PrivilegedAccess | pConfig->Mode);
429 
430     /* Set start and end addresses */
431     WRITE_REG(p_region->SADDR, pConfig->StartAddress);
432     WRITE_REG(p_region->EADDR, pConfig->EndAddress);
433 
434     /* Set write attribute for the region */
435     MODIFY_REG(p_region->ATTR, MCE_ATTR_WREN, pConfig->AccessMode);
436 
437     /* Enable the region by default */
438     SET_BIT(p_region->REGCR, MCE_REGCR_BREN);
439 
440     ret = HAL_OK;
441 
442     /* Release Lock */
443     __HAL_UNLOCK(hmce);
444   }
445 
446   return ret;
447 
448 }
449 
450 /**
451   * @brief  Set region AES Context.
452   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
453   *         the configuration information for MCE module
454   * @param  ContextIndex index of context that is configured
455   * @param  RegionIndex index of region that is configured
456   * @note   The Region is enabled by default once the configuration is complete
457   * @note   An enabled region is temporary disabled to apply the new configuration
458   * @retval HAL status
459   */
460 
HAL_MCE_SetRegionAESContext(MCE_HandleTypeDef * hmce,uint32_t ContextIndex,uint32_t RegionIndex)461 HAL_StatusTypeDef HAL_MCE_SetRegionAESContext(MCE_HandleTypeDef *hmce, uint32_t ContextIndex, uint32_t RegionIndex)
462 {
463   HAL_StatusTypeDef ret = HAL_ERROR;
464   MCE_Region_TypeDef *p_region;
465   __IO uint32_t address;
466 
467   assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
468   assert_param(IS_MCE_REGIONINDEX(RegionIndex));
469 
470   /* If global lock is set, region cannot be configured */
471   if ((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK)
472   {
473 
474     /* Take Lock */
475     __HAL_LOCK(hmce);
476 
477     address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x40U + (0x10U * RegionIndex));
478     p_region = (MCE_Region_TypeDef *)address;
479 
480     /* If region is enabled, disable it during the configuration process */
481     if ((p_region->REGCR & MCE_REGCR_BREN) == MCE_REGCR_BREN)
482     {
483       CLEAR_BIT(p_region->REGCR, MCE_REGCR_BREN);
484     }
485 
486     /* Set context ID */
487     MODIFY_REG(p_region->REGCR, MCE_REGCR_CTXID, ContextIndex);
488 
489     /* Enable the region by default */
490     SET_BIT(p_region->REGCR, MCE_REGCR_BREN);
491 
492     ret = HAL_OK;
493 
494     /* Release Lock */
495     __HAL_UNLOCK(hmce);
496 
497   }
498 
499   return ret;
500 }
501 
502 
503 /** *********  Enabling and disabling functions : enable/disable AES and Noekeon configurations and regions *********/
504 
505 
506 /**
507   * @brief  Cipher context enable
508   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
509   *         the configuration information for MCE module
510   * @param  ContextIndex index of context that is enabled
511   * @retval HAL status
512   */
HAL_MCE_EnableAESContext(MCE_HandleTypeDef * hmce,uint32_t ContextIndex)513 HAL_StatusTypeDef HAL_MCE_EnableAESContext(MCE_HandleTypeDef *hmce, uint32_t ContextIndex)
514 {
515   MCE_Context_TypeDef *p_context;
516   __IO uint32_t address;
517 
518   /* Check the parameters */
519   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
520   assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
521 
522   if ((ContextIndex != MCE_CONTEXT1) && (ContextIndex != MCE_CONTEXT2))
523   {
524     return HAL_ERROR;
525   }
526 
527   address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
528                             (0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
529   p_context = (MCE_Context_TypeDef *)address;
530 
531   /* If cipher context is locked or if global lock is set,
532      and if cipher context is not enabled already, return an error */
533 
534   if ((p_context->CCCFGR & MCE_CCCFGR_CCEN) != MCE_CCCFGR_CCEN)
535   {
536     if ((p_context->CCCFGR & MCE_CCCFGR_CCLOCK) == MCE_CCCFGR_CCLOCK)
537     {
538       return HAL_ERROR;
539     }
540     if ((hmce->Instance->CR & MCE_CR_GLOCK) == MCE_CR_GLOCK)
541     {
542       return HAL_ERROR;
543     }
544   }
545 
546   __HAL_LOCK(hmce);
547 
548   /* Enable context */
549   SET_BIT(p_context->CCCFGR, MCE_CCCFGR_CCEN);
550 
551   __HAL_UNLOCK(hmce);
552 
553   return HAL_OK;
554 
555 }
556 
557 /**
558   * @brief  Cipher context disable
559   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
560   *         the configuration information for MCE module
561   * @param  ContextIndex index of context that is disabled
562   * @retval HAL status
563   */
HAL_MCE_DisableAESContext(MCE_HandleTypeDef * hmce,uint32_t ContextIndex)564 HAL_StatusTypeDef HAL_MCE_DisableAESContext(MCE_HandleTypeDef *hmce, uint32_t ContextIndex)
565 {
566   MCE_Context_TypeDef *p_context;
567   __IO uint32_t address;
568 
569   /* Check the parameters */
570   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
571   assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
572 
573   if ((ContextIndex != MCE_CONTEXT1) && (ContextIndex != MCE_CONTEXT2))
574   {
575     return HAL_ERROR;
576   }
577 
578   address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
579                             (0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
580   p_context = (MCE_Context_TypeDef *)address;
581 
582   /* If cipher context is locked or if global lock is set,
583      and if cipher context is not disabled already, return an error */
584 
585   if ((p_context->CCCFGR & MCE_CCCFGR_CCEN) == MCE_CCCFGR_CCEN)
586   {
587     if ((p_context->CCCFGR & MCE_CCCFGR_CCLOCK) == MCE_CCCFGR_CCLOCK)
588     {
589       return HAL_ERROR;
590     }
591     if ((hmce->Instance->CR & MCE_CR_GLOCK) == MCE_CR_GLOCK)
592     {
593       return HAL_ERROR;
594     }
595   }
596 
597   __HAL_LOCK(hmce);
598 
599   /* Disable context */
600   CLEAR_BIT(p_context->CCCFGR, MCE_CCCFGR_CCEN);
601 
602   __HAL_UNLOCK(hmce);
603 
604   return HAL_OK;
605 
606 }
607 
608 
609 /**
610   * @brief  Enable region.
611   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
612   *         the configuration information for MCE module
613   * @param  RegionIndex index of region that is enabled
614   * @retval HAL status
615   */
HAL_MCE_EnableRegion(MCE_HandleTypeDef * hmce,uint32_t RegionIndex)616 HAL_StatusTypeDef HAL_MCE_EnableRegion(MCE_HandleTypeDef *hmce, uint32_t RegionIndex)
617 {
618   HAL_StatusTypeDef ret = HAL_ERROR;
619   MCE_Region_TypeDef *p_region;
620   __IO uint32_t address;
621 
622   /* Check the parameters */
623   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
624   assert_param(IS_MCE_REGIONINDEX(RegionIndex));
625 
626   /* If global lock is set, region cannot be configured */
627   if ((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK)
628   {
629     address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x40U + (0x10U * RegionIndex));
630     p_region = (MCE_Region_TypeDef *)address;
631 
632     /* Take Lock */
633     __HAL_LOCK(hmce);
634 
635     /* Check region is not enabled, else error */
636     if ((p_region->REGCR & MCE_REGCR_BREN) != MCE_REGCR_BREN)
637     {
638       /* Enable the region */
639       SET_BIT(p_region->REGCR, MCE_REGCR_BREN);
640 
641       ret = HAL_OK;
642     }
643 
644     /* Release Lock */
645     __HAL_UNLOCK(hmce);
646   }
647 
648   return ret;
649 
650 }
651 
652 
653 /**
654   * @brief  Disable region.
655   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
656   *         the configuration information for MCE module
657   * @param  RegionIndex index of region that is disabled
658   * @retval HAL status
659   */
HAL_MCE_DisableRegion(MCE_HandleTypeDef * hmce,uint32_t RegionIndex)660 HAL_StatusTypeDef HAL_MCE_DisableRegion(MCE_HandleTypeDef *hmce, uint32_t RegionIndex)
661 {
662   HAL_StatusTypeDef ret = HAL_ERROR;
663   MCE_Region_TypeDef *p_region;
664   __IO uint32_t address;
665 
666   /* Check the parameters */
667   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
668   assert_param(IS_MCE_REGIONINDEX(RegionIndex));
669 
670   address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x40U + (0x10U * RegionIndex));
671   p_region = (MCE_Region_TypeDef *)address;
672 
673   /* If global lock is set, region cannot be configured */
674   if ((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK)
675   {
676     /* Take Lock */
677     __HAL_LOCK(hmce);
678 
679     /* Check region is enabled, else error */
680     if ((p_region->REGCR & MCE_REGCR_BREN) == MCE_REGCR_BREN)
681     {
682       /* Disable the region */
683       CLEAR_BIT(p_region->REGCR, MCE_REGCR_BREN);
684 
685       ret = HAL_OK;
686     }
687 
688     /* Release Lock */
689     __HAL_UNLOCK(hmce);
690   }
691 
692   return ret;
693 
694 }
695 
696 
697 /** *************  Lock functions : Lock AES and Noekeon configurations and keys *********/
698 
699 /**
700   * @brief  Lock MCE instance registers configuration
701   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
702   *         the configuration information for MCE module
703   * @note   Once MCE_CR_GLOCK is set, all writes to MCE registers are ignored,
704   *         with the exception of MCE_IACR and MCE_IAIER registers.
705   * @retval HAL status
706   */
HAL_MCE_LockGlobalConfig(MCE_HandleTypeDef * hmce)707 HAL_StatusTypeDef HAL_MCE_LockGlobalConfig(MCE_HandleTypeDef *hmce)
708 {
709   /* Check the parameters */
710   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
711 
712   /* Take Lock */
713   __HAL_LOCK(hmce);
714 
715   SET_BIT(hmce->Instance->CR, MCE_CR_GLOCK);
716 
717   /* Release Lock */
718   __HAL_UNLOCK(hmce);
719 
720   return HAL_OK;
721 
722 }
723 
724 /**
725   * @brief  Lock cipher context
726   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
727   *         the configuration information for MCE module
728   * @param  ContextIndex index of context that is locked
729   * @note   Once MCE_CCCFGR_CCLOCK is set, writes to MCE_CCxCFGR and MCE_CCxNR registers
730   *         are ignored until next MCE reset.
731   * @retval HAL status
732   */
HAL_MCE_LockAESContextConfig(MCE_HandleTypeDef * hmce,uint32_t ContextIndex)733 HAL_StatusTypeDef HAL_MCE_LockAESContextConfig(MCE_HandleTypeDef *hmce, uint32_t ContextIndex)
734 {
735   HAL_StatusTypeDef ret = HAL_ERROR;
736   MCE_Context_TypeDef *p_context;
737   __IO uint32_t address;
738 
739   /* Check the parameters */
740   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
741   assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
742 
743   /* If global lock is set or no configuration provided, context cannot be configured */
744   if (((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK) && \
745       ((ContextIndex == MCE_CONTEXT1) || (ContextIndex == MCE_CONTEXT2)))
746   {
747     address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
748                               (0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
749     p_context = (MCE_Context_TypeDef *)address;
750 
751     /* Take Lock */
752     __HAL_LOCK(hmce);
753 
754     SET_BIT(p_context->CCCFGR, MCE_CCCFGR_CCLOCK);
755 
756     ret = HAL_OK;
757 
758     /* Release Lock */
759     __HAL_UNLOCK(hmce);
760   }
761 
762   return ret;
763 
764 }
765 
766 /**
767   * @brief  Lock context cipher key
768   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
769   *         the configuration information for MCE module
770   * @param  ContextIndex index of context the cipher key of which is locked
771   * @note   Once MCE_CCCFGR_KEYLOCK is set, writes to MCE_CCxKEYR registers are ignored
772   *         until next MCE reset. KEYCRC bitfield value does not change.
773   * @retval HAL status
774   */
HAL_MCE_LockAESContextKey(MCE_HandleTypeDef * hmce,uint32_t ContextIndex)775 HAL_StatusTypeDef HAL_MCE_LockAESContextKey(MCE_HandleTypeDef *hmce, uint32_t ContextIndex)
776 {
777   HAL_StatusTypeDef ret = HAL_ERROR;
778   MCE_Context_TypeDef *p_context;
779   __IO uint32_t address;
780 
781   /* Check the parameters */
782   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
783   assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
784 
785   /* If global lock is set or no configuration provided, context cannot be configured */
786   if (((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK) && \
787       ((ContextIndex == MCE_CONTEXT1) || (ContextIndex == MCE_CONTEXT2)))
788   {
789     address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
790                               (0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
791     p_context = (MCE_Context_TypeDef *)address;
792 
793     /* Take Lock */
794     __HAL_LOCK(hmce);
795 
796     SET_BIT(p_context->CCCFGR, MCE_CCCFGR_KEYLOCK);
797 
798     ret = HAL_OK;
799 
800     /* Release Lock */
801     __HAL_UNLOCK(hmce);
802   }
803 
804   return ret;
805 
806 }
807 
808 /**
809   * @brief  Lock Noekeon master keys
810   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
811   *         the configuration information for MCE module
812   * @note   Once MCE_CR_MKLOCK is set, writes to MCE_MKEYRx and MCE_FMKEYRx registers are ignored until next MCE reset.
813   * @retval HAL status
814   */
HAL_MCE_LockNoekeonMasterKeys(MCE_HandleTypeDef * hmce)815 HAL_StatusTypeDef HAL_MCE_LockNoekeonMasterKeys(MCE_HandleTypeDef *hmce)
816 {
817   HAL_StatusTypeDef ret = HAL_ERROR;
818 
819   /* Check the parameters */
820   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
821 
822   /* If global lock is set, master keys lock cannot be set */
823   if ((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK)
824   {
825     /* Take Lock */
826     __HAL_LOCK(hmce);
827 
828     SET_BIT(hmce->Instance->CR, MCE_CR_MKLOCK);
829 
830     ret = HAL_OK;
831 
832     /* Release Lock */
833     __HAL_UNLOCK(hmce);
834   }
835 
836   return ret;
837 
838 }
839 
840 
841 /**
842   * @brief  Initialize the MCE MSP.
843   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
844   *         the configuration information for MCE module
845   * @retval None
846   */
HAL_MCE_MspInit(MCE_HandleTypeDef * hmce)847 __weak void HAL_MCE_MspInit(MCE_HandleTypeDef *hmce)
848 {
849   /* Prevent unused argument(s) compilation warning */
850   UNUSED(hmce);
851 
852   /* NOTE : This function should not be modified; when the callback is needed,
853             the HAL_MCE_MspInit can be implemented in the user file.
854    */
855 }
856 
857 /**
858   * @brief  DeInitialize MCE MSP.
859   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
860   *         the configuration information for MCE module
861   * @retval None
862   */
HAL_MCE_MspDeInit(MCE_HandleTypeDef * hmce)863 __weak void HAL_MCE_MspDeInit(MCE_HandleTypeDef *hmce)
864 {
865   /* Prevent unused argument(s) compilation warning */
866   UNUSED(hmce);
867 
868   /* NOTE : This function should not be modified; when the callback is needed,
869             the HAL_MCE_MspDeInit can be implemented in the user file.
870    */
871 }
872 
873 /**
874   * @brief  get the CRC key of the specified context.
875   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
876   *         the configuration information for MCE module
877   * @param  pCRCKey pointer to the CRC key
878   * @param  ContextIndex index of CONTEXT the CRC key
879   * @retval HAL status
880   */
881 
HAL_MCE_GetAESContextCRCKey(const MCE_HandleTypeDef * hmce,uint32_t * pCRCKey,uint32_t ContextIndex)882 HAL_StatusTypeDef HAL_MCE_GetAESContextCRCKey(const MCE_HandleTypeDef *hmce, uint32_t *pCRCKey, uint32_t ContextIndex)
883 {
884   HAL_StatusTypeDef ret = HAL_OK;
885   MCE_Context_TypeDef *p_context;
886   __IO uint32_t address;
887 
888   /* Check the parameters */
889   assert_param(IS_MCE_AES_INSTANCE(hmce->Instance));
890   assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
891 
892   if (*pCRCKey == 0x00U)
893   {
894     ret = HAL_ERROR;
895   }
896 
897   address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
898                             (0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
899   p_context = (MCE_Context_TypeDef *)address;
900 
901   *pCRCKey = READ_REG((p_context->CCCFGR)) & MCE_CCCFGR_KEYCRC;
902 
903   *pCRCKey >>= MCE_CCCFGR_KEYCRC_Pos;
904   return ret;
905 }
906 
907 /**
908   * @brief  Compute Key CRC
909   * @param  pKey pointer at set of keys
910   * @retval CRC value
911   */
HAL_MCE_KeyCRCComputation(const uint32_t * pKey)912 uint32_t HAL_MCE_KeyCRCComputation(const uint32_t *pKey)
913 {
914   uint8_t crc7_poly = 0x7;
915   const uint32_t key_strobe[4] = {0xAA55AA55U, 0x3U, 0x18U, 0xC0U};
916   uint8_t  i;
917   uint8_t crc = 0;
918   uint32_t  j;
919   uint32_t  keyval;
920   uint32_t k;
921   const uint32_t *temp = pKey;
922 
923   for (j = 0U; j < 4U; j++)
924   {
925     keyval = *temp;
926     temp++;
927     if (j == 0U)
928     {
929       keyval ^= key_strobe[0];
930     }
931     else
932     {
933       keyval ^= (key_strobe[j] << 24) | ((uint32_t)crc << 16) | (key_strobe[j] << 8) | crc;
934     }
935 
936     crc = 0;
937     for (i = 0; i < (uint8_t)32; i++)
938     {
939       k = ((((uint32_t)crc >> 7) ^ ((keyval >> ((uint8_t)31 - i)) & ((uint8_t)0xF)))) & 1U;
940       crc <<= 1;
941       if (k != 0U)
942       {
943         crc ^= crc7_poly;
944       }
945     }
946 
947     crc ^= (uint8_t)0x55;
948   }
949 
950   return (uint32_t) crc;
951 }
952 
953 /**
954   * @brief  Handle MCE interrupt request.
955   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
956   *         the configuration information for MCE module
957   * @retval None
958   */
HAL_MCE_IRQHandler(MCE_HandleTypeDef * hmce)959 void HAL_MCE_IRQHandler(MCE_HandleTypeDef *hmce)
960 {
961   uint32_t isr_reg;
962   uint32_t iaesr_reg;
963 
964   isr_reg = READ_REG(hmce->Instance->IASR);
965   if ((isr_reg & MCE_IASR_CAEF) == MCE_IASR_CAEF)
966   {
967     /* Set configuration access error */
968     hmce->ErrorCode |= HAL_MCE_CONFIGURATION_ACCESS_ERROR;
969 
970     /* Clear configuration access error flag */
971     WRITE_REG(hmce->Instance->IACR, MCE_IACR_CAEF);
972   }
973   if ((isr_reg & MCE_IASR_IAEF) == MCE_IASR_IAEF)
974   {
975     iaesr_reg = (READ_REG(hmce->Instance->IAESR) & (MCE_IAESR_IAPRIV | MCE_IAESR_IANRW));
976 
977     /* Clear illegal access error flag */
978     WRITE_REG(hmce->Instance->IACR, MCE_IACR_IAEF);
979 
980     /* Set precise illegal access error */
981     if (iaesr_reg == MCE_IAESR_IAPRIV)
982     {
983       /* Illegal privileged data read or instruction fetch access error */
984       hmce->ErrorCode |= HAL_MCE_ILLEGAL_ACCESS_READ_PRIV_ERROR;
985     }
986     else if (iaesr_reg == (MCE_IAESR_IAPRIV | MCE_IAESR_IANRW))
987     {
988       /* Illegal privileged data write access error */
989       hmce->ErrorCode |= HAL_MCE_ILLEGAL_ACCESS_WRITE_PRIV_ERROR;
990     }
991     else if (iaesr_reg == MCE_IAESR_IANRW)
992     {
993       /* Illegal un privileged data write access error */
994       hmce->ErrorCode |= HAL_MCE_ILLEGAL_ACCESS_WRITE_NPRIV_ERROR;
995     }
996     else
997     {
998       /* Illegal unprivileged data read or instruction fetch access error */
999       hmce->ErrorCode |= HAL_MCE_ILLEGAL_ACCESS_READ_NPRIV_ERROR;
1000     }
1001   }
1002 
1003 #if (USE_HAL_MCE_REGISTER_CALLBACKS == 1)
1004   hmce->ErrorCallback(hmce);
1005 #else
1006   HAL_MCE_ErrorCallback(hmce);
1007 #endif /* USE_HAL_MCE_REGISTER_CALLBACKS */
1008 }
1009 
1010 /**
1011   * @brief MCE error callback.
1012   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
1013   *         the configuration information for MCE module
1014   * @retval None
1015   */
HAL_MCE_ErrorCallback(MCE_HandleTypeDef * hmce)1016 __weak void HAL_MCE_ErrorCallback(MCE_HandleTypeDef *hmce)
1017 {
1018   /* Prevent unused argument(s) compilation warning */
1019   UNUSED(hmce);
1020 
1021   /* NOTE : This function should not be modified; when the callback is needed,
1022             the HAL_MCE_ErrorCallback can be implemented in the user file.
1023    */
1024 }
1025 
1026 /**
1027   * @brief  Return the MCE state.
1028   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
1029   *         the configuration information for MCE module
1030   * @retval HAL status
1031   */
HAL_MCE_GetState(MCE_HandleTypeDef const * hmce)1032 HAL_MCE_StateTypeDef HAL_MCE_GetState(MCE_HandleTypeDef const *hmce)
1033 {
1034   /* Check the parameters */
1035   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
1036 
1037   return hmce->State;
1038 }
1039 
1040 /**
1041   * @brief  Return the MCE error code.
1042   * @param  hmce pointer to an MCE_HandleTypeDef structure that contains
1043   *         the configuration information for MCE module
1044   * @retval MCE error code (bitfield on 32 bits)
1045   */
HAL_MCE_GetError(MCE_HandleTypeDef const * hmce)1046 uint32_t HAL_MCE_GetError(MCE_HandleTypeDef const *hmce)
1047 {
1048   /* Check the parameters */
1049   assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
1050 
1051   return hmce->ErrorCode;
1052 }
1053 
1054 
1055 /**
1056   * @}
1057   */
1058 
1059 /**
1060   * @}
1061   */
1062 
1063 #endif /* MCE1 */
1064 
1065 #endif /* HAL_MCE_MODULE_ENABLED */
1066 
1067 
1068 /**
1069   * @}
1070   */
1071 
1072 /**
1073   * @}
1074   */
1075