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