1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_otfdec.c
4   * @author  MCD Application Team
5   * @brief   OTFDEC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the On-The-Fly Decryption (OTFDEC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Region setting/enable functions
10   *           + Peripheral State functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2018 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 OTFDEC HAL driver can be used as follows:
29 
30     (#) Declare an OTFDEC_HandleTypeDef handle structure (eg. OTFDEC_HandleTypeDef hotfdec).
31 
32     (#) Initialize the OTFDEC low level resources by implementing the HAL_OTFDEC_MspInit() API:
33         (++) Enable the OTFDEC interface clock.
34         (++) NVIC configuration if interrupts are used
35             (+++) Configure the OTFDEC interrupt priority.
36             (+++) Enable the NVIC OTFDEC IRQ handle.
37 
38     (#) Initialize the OTFDEC peripheral by calling the HAL_OTFDEC_Init() API.
39 
40     (#) For each region,
41 
42         (++) Configure the region deciphering mode by calling the HAL_OTFDEC_RegionSetMode() API.
43 
44         (++) Write the region Key by calling the HAL_OTFDEC_RegionSetKey() API. If desired,
45         read the key CRC by calling HAL_OTFDEC_RegionGetKeyCRC() API and compare the
46         result with the theoretically expected CRC.
47 
48         (++) Initialize the OTFDEC region config structure with the Nonce, protected
49         region start and end addresses and firmware version, and wrap-up the region
50         configuration by calling HAL_OTFDEC_RegionConfig() API.
51 
52     (#) At this point, the OTFDEC region configuration is done and the deciphering
53         is enabled. The region can be deciphered on the fly after having made sure
54         the OctoSPI is configured in memory-mapped mode.
55 
56     [..]
57     (@) Warning: the OTFDEC deciphering is based on a different endianness compared
58         to the AES-CTR as implemented in the AES peripheral. E.g., if the OTFEC
59         resorts to the Key (B0, B1, B2, B3) where Bi are 32-bit longwords and B0
60         is the Least Significant Word, the AES has to be configured with the Key
61         (B3, B2, B1, B0) to report the same result (with the same swapping applied
62         to the Initialization Vector).
63 
64     [..]
65 
66     *** Callback registration ***
67     =============================================
68     [..]
69 
70      The compilation flag USE_HAL_OTFDEC_REGISTER_CALLBACKS, when set to 1,
71      allows the user to configure dynamically the driver callbacks.
72      Use Functions @ref HAL_OTFDEC_RegisterCallback()
73      to register an interrupt callback.
74     [..]
75 
76      Function @ref HAL_OTFDEC_RegisterCallback() allows to register following callbacks:
77        (+) ErrorCallback                  : OTFDEC error callback
78        (+) MspInitCallback                : OTFDEC Msp Init callback
79        (+) MspDeInitCallback              : OTFDEC Msp DeInit callback
80      This function takes as parameters the HAL peripheral handle, the Callback ID
81      and a pointer to the user callback function.
82     [..]
83 
84      Use function @ref HAL_OTFDEC_UnRegisterCallback to reset a callback to the default
85      weak function.
86     [..]
87 
88      @ref HAL_OTFDEC_UnRegisterCallback takes as parameters the HAL peripheral handle,
89      and the Callback ID.
90      This function allows to reset following callbacks:
91        (+) ErrorCallback                  : OTFDEC error callback
92        (+) MspInitCallback                : OTFDEC Msp Init callback
93        (+) MspDeInitCallback              : OTFDEC Msp DeInit callback
94      [..]
95 
96      By default, after the @ref HAL_OTFDEC_Init() and when the state is @ref HAL_OTFDEC_STATE_RESET
97      all callbacks are set to the corresponding weak functions:
98      example @ref HAL_OTFDEC_ErrorCallback().
99      Exception done for MspInit and MspDeInit functions that are
100      reset to the legacy weak functions in the @ref HAL_OTFDEC_Init()/ @ref HAL_OTFDEC_DeInit() only when
101      these callbacks are null (not registered beforehand).
102     [..]
103 
104      If MspInit or MspDeInit are not null, the @ref HAL_OTFDEC_Init()/ @ref HAL_OTFDEC_DeInit()
105      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
106      [..]
107 
108      Callbacks can be registered/unregistered in @ref HAL_OTFDEC_STATE_READY state only.
109      Exception done MspInit/MspDeInit functions that can be registered/unregistered
110      in @ref HAL_OTFDEC_STATE_READY or @ref HAL_OTFDEC_STATE_RESET state,
111      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
112     [..]
113 
114      Then, the user first registers the MspInit/MspDeInit user callbacks
115      using @ref HAL_OTFDEC_RegisterCallback() before calling @ref HAL_OTFDEC_DeInit()
116      or @ref HAL_OTFDEC_Init() function.
117      [..]
118 
119      When the compilation flag USE_HAL_OTFDEC_REGISTER_CALLBACKS is set to 0 or
120      not defined, the callback registration feature is not available and all callbacks
121      are set to the corresponding weak functions.
122 
123   @endverbatim
124   ******************************************************************************
125   */
126 
127 /* Includes ------------------------------------------------------------------*/
128 #include "stm32h7xx_hal.h"
129 
130 /** @addtogroup STM32H7xx_HAL_Driver
131   * @{
132   */
133 
134 /** @defgroup OTFDEC OTFDEC
135   * @brief OTFDEC HAL module driver.
136   * @{
137   */
138 
139 
140 #ifdef HAL_OTFDEC_MODULE_ENABLED
141 
142 #if defined(OTFDEC1)
143 
144 /* Private typedef -----------------------------------------------------------*/
145 /* Private define ------------------------------------------------------------*/
146 /* Private macro -------------------------------------------------------------*/
147 /* Private variables ---------------------------------------------------------*/
148 /* Private function prototypes -----------------------------------------------*/
149 /* Private functions ---------------------------------------------------------*/
150 
151 /* Exported functions --------------------------------------------------------*/
152 /** @addtogroup OTFDEC_Exported_Functions
153   * @{
154   */
155 
156 /** @defgroup OTFDEC_Exported_Functions_Group1 Initialization and de-initialization functions
157   *  @brief    Initialization and Configuration functions.
158   *
159 @verbatim
160   ==============================================================================
161               ##### Initialization and de-initialization functions #####
162   ==============================================================================
163 
164 @endverbatim
165   * @{
166   */
167 
168 /**
169   * @brief  Initialize the OTFDEC peripheral and create the associated handle.
170   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
171   *         the configuration information for OTFDEC module
172   * @retval HAL status
173   */
HAL_OTFDEC_Init(OTFDEC_HandleTypeDef * hotfdec)174 HAL_StatusTypeDef HAL_OTFDEC_Init(OTFDEC_HandleTypeDef *hotfdec)
175 {
176   /* Check the OTFDEC handle allocation */
177   if (hotfdec == NULL)
178   {
179     return HAL_ERROR;
180   }
181 
182   /* Check the parameters */
183   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
184 
185   if (hotfdec->State == HAL_OTFDEC_STATE_RESET)
186   {
187     /* Allocate lock resource and initialize it */
188     __HAL_UNLOCK(hotfdec);
189 
190 #if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
191     /* Init the OTFDEC Callback settings */
192     hotfdec->ErrorCallback = HAL_OTFDEC_ErrorCallback; /* Legacy weak callback */
193 
194     if (hotfdec->MspInitCallback == NULL)
195     {
196       hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
197     }
198 
199     /* Init the low level hardware */
200     hotfdec->MspInitCallback(hotfdec);
201 #else
202     /* Init the low level hardware */
203     HAL_OTFDEC_MspInit(hotfdec);
204 #endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
205   }
206 
207   /* Change the OTFDEC state */
208   hotfdec->State = HAL_OTFDEC_STATE_READY;
209 
210   /* Return function status */
211   return HAL_OK;
212 }
213 
214 /**
215   * @brief  DeInitialize the OTFDEC peripheral.
216   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
217   *         the configuration information for OTFDEC module
218   * @retval HAL status
219   */
HAL_OTFDEC_DeInit(OTFDEC_HandleTypeDef * hotfdec)220 HAL_StatusTypeDef HAL_OTFDEC_DeInit(OTFDEC_HandleTypeDef *hotfdec)
221 {
222   /* Check the OTFDEC handle allocation */
223   if (hotfdec == NULL)
224   {
225     return HAL_ERROR;
226   }
227 
228   /* Check the parameters */
229   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
230 
231   /* Change the OTFDEC state */
232   hotfdec->State = HAL_OTFDEC_STATE_BUSY;
233 
234 #if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
235   if (hotfdec->MspDeInitCallback == NULL)
236   {
237     hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
238   }
239 
240   /* DeInit the low level hardware: CLOCK, NVIC */
241   hotfdec->MspDeInitCallback(hotfdec);
242 #else
243   /* DeInit the low level hardware: CLOCK, NVIC */
244   HAL_OTFDEC_MspDeInit(hotfdec);
245 #endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
246 
247   /* Change the OTFDEC state */
248   hotfdec->State = HAL_OTFDEC_STATE_RESET;
249 
250   /* Reset OTFDEC error status */
251   hotfdec->ErrorCode = HAL_OTFDEC_ERROR_NONE;
252 
253   /* Release Lock */
254   __HAL_UNLOCK(hotfdec);
255 
256   /* Return function status */
257   return HAL_OK;
258 }
259 
260 /**
261   * @brief  Initialize the OTFDEC MSP.
262   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
263   *         the configuration information for OTFDEC module
264   * @retval None
265   */
HAL_OTFDEC_MspInit(OTFDEC_HandleTypeDef * hotfdec)266 __weak void HAL_OTFDEC_MspInit(OTFDEC_HandleTypeDef *hotfdec)
267 {
268   /* Prevent unused argument(s) compilation warning */
269   UNUSED(hotfdec);
270 
271   /* NOTE : This function should not be modified; when the callback is needed,
272             the HAL_OTFDEC_MspInit can be implemented in the user file.
273    */
274 }
275 
276 /**
277   * @brief  DeInitialize OTFDEC MSP.
278   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
279   *         the configuration information for OTFDEC module
280   * @retval None
281   */
HAL_OTFDEC_MspDeInit(OTFDEC_HandleTypeDef * hotfdec)282 __weak void HAL_OTFDEC_MspDeInit(OTFDEC_HandleTypeDef *hotfdec)
283 {
284   /* Prevent unused argument(s) compilation warning */
285   UNUSED(hotfdec);
286 
287   /* NOTE : This function should not be modified; when the callback is needed,
288             the HAL_OTFDEC_MspDeInit can be implemented in the user file.
289    */
290 }
291 
292 #if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
293 /**
294   * @brief  Register a User OTFDEC Callback
295   *         To be used instead of the weak predefined callback
296   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
297   *         the configuration information for OTFDEC module
298   * @param  CallbackID ID of the callback to be registered
299   *         This parameter can be one of the following values:
300   *          @arg @ref HAL_OTFDEC_ERROR_CB_ID           OTFDEC error callback ID
301   *          @arg @ref HAL_OTFDEC_MSPINIT_CB_ID         MspInit callback ID
302   *          @arg @ref HAL_OTFDEC_MSPDEINIT_CB_ID       MspDeInit callback ID
303   * @param  pCallback pointer to the Callback function
304   * @retval HAL status
305   */
HAL_OTFDEC_RegisterCallback(OTFDEC_HandleTypeDef * hotfdec,HAL_OTFDEC_CallbackIDTypeDef CallbackID,pOTFDEC_CallbackTypeDef pCallback)306 HAL_StatusTypeDef HAL_OTFDEC_RegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID,
307                                               pOTFDEC_CallbackTypeDef pCallback)
308 {
309   HAL_StatusTypeDef status = HAL_OK;
310 
311   if (pCallback == NULL)
312   {
313     /* Update the error code */
314     hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
315 
316     return HAL_ERROR;
317   }
318 
319   if (hotfdec->State == HAL_OTFDEC_STATE_READY)
320   {
321     switch (CallbackID)
322     {
323       case HAL_OTFDEC_ERROR_CB_ID :
324         hotfdec->ErrorCallback = pCallback;
325         break;
326 
327       case HAL_OTFDEC_MSPINIT_CB_ID :
328         hotfdec->MspInitCallback = pCallback;
329         break;
330 
331       case HAL_OTFDEC_MSPDEINIT_CB_ID :
332         hotfdec->MspDeInitCallback = pCallback;
333         break;
334 
335       default :
336         /* Update the error code */
337         hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
338 
339         /* Return error status */
340         status = HAL_ERROR;
341         break;
342     }
343   }
344   else if (HAL_OTFDEC_STATE_RESET == hotfdec->State)
345   {
346     switch (CallbackID)
347     {
348       case HAL_OTFDEC_MSPINIT_CB_ID :
349         hotfdec->MspInitCallback = pCallback;
350         break;
351 
352       case HAL_OTFDEC_MSPDEINIT_CB_ID :
353         hotfdec->MspDeInitCallback = pCallback;
354         break;
355 
356       default :
357         /* Update the error code */
358         hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
359 
360         /* Return error status */
361         status = HAL_ERROR;
362         break;
363     }
364   }
365   else
366   {
367     /* Update the error code */
368     hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
369 
370     /* Return error status */
371     status =  HAL_ERROR;
372   }
373 
374   return status;
375 }
376 
377 /**
378   * @brief  Unregister a OTFDEC Callback
379   *         OTFDEC callback is redirected to the weak predefined callback
380   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
381   *         the configuration information for OTFDEC module
382   * @param  CallbackID ID of the callback to be registered
383   *         This parameter can be one of the following values:
384   *          @arg @ref HAL_OTFDEC_ERROR_CB_ID           OTFDEC error callback ID
385   *          @arg @ref HAL_OTFDEC_MSPINIT_CB_ID         MspInit callback ID
386   *          @arg @ref HAL_OTFDEC_MSPDEINIT_CB_ID       MspDeInit callback ID
387   * @retval HAL status
388   */
HAL_OTFDEC_UnRegisterCallback(OTFDEC_HandleTypeDef * hotfdec,HAL_OTFDEC_CallbackIDTypeDef CallbackID)389 HAL_StatusTypeDef HAL_OTFDEC_UnRegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID)
390 {
391   HAL_StatusTypeDef status = HAL_OK;
392 
393   if (hotfdec->State == HAL_OTFDEC_STATE_READY)
394   {
395     switch (CallbackID)
396     {
397       case HAL_OTFDEC_ERROR_CB_ID :
398         hotfdec->ErrorCallback = HAL_OTFDEC_ErrorCallback;
399         break;
400 
401       case HAL_OTFDEC_MSPINIT_CB_ID :
402         hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
403         break;
404 
405       case HAL_OTFDEC_MSPDEINIT_CB_ID :
406         hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
407         break;
408 
409       default :
410         /* Update the error code */
411         hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
412 
413         /* Return error status */
414         status =  HAL_ERROR;
415         break;
416     }
417   }
418   else if (HAL_OTFDEC_STATE_RESET == hotfdec->State)
419   {
420     switch (CallbackID)
421     {
422       case HAL_OTFDEC_MSPINIT_CB_ID :
423         hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
424         break;
425 
426       case HAL_OTFDEC_MSPDEINIT_CB_ID :
427         hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
428         break;
429 
430       default :
431         /* Update the error code */
432         hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
433 
434         /* Return error status */
435         status =  HAL_ERROR;
436         break;
437     }
438   }
439   else
440   {
441     /* Update the error code */
442     hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
443 
444     /* Return error status */
445     status =  HAL_ERROR;
446   }
447 
448   return status;
449 }
450 
451 #endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
452 
453 /**
454   * @}
455   */
456 
457 /** @defgroup OTFDEC_Exported_Functions_Group2  OTFDEC IRQ handler management
458   *  @brief   OTFDEC IRQ handler.
459   *
460 @verbatim
461   ==============================================================================
462                 ##### OTFDEC IRQ handler management #####
463   ==============================================================================
464 [..]  This section provides OTFDEC IRQ handler function.
465 
466 @endverbatim
467   * @{
468   */
469 
470 /**
471   * @brief  Handle OTFDEC interrupt request.
472   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
473   *         the configuration information for OTFDEC module
474   * @retval None
475   */
HAL_OTFDEC_IRQHandler(OTFDEC_HandleTypeDef * hotfdec)476 void HAL_OTFDEC_IRQHandler(OTFDEC_HandleTypeDef *hotfdec)
477 {
478   uint32_t isr_reg;
479 
480   isr_reg = READ_REG(hotfdec->Instance->ISR);
481   if ((isr_reg & OTFDEC_ISR_SEIF) == OTFDEC_ISR_SEIF)
482   {
483     SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_SEIF);
484     hotfdec->ErrorCode |= HAL_OTFDEC_SECURITY_ERROR;
485   }
486   if ((isr_reg & OTFDEC_ISR_XONEIF) == OTFDEC_ISR_XONEIF)
487   {
488     SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_XONEIF);
489     hotfdec->ErrorCode |= HAL_OTFDEC_EXECUTE_ERROR;
490   }
491   if ((isr_reg & OTFDEC_ISR_KEIF) == OTFDEC_ISR_KEIF)
492   {
493     SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_KEIF);
494     hotfdec->ErrorCode |= HAL_OTFDEC_KEY_ERROR;
495   }
496 
497 #if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
498   hotfdec->ErrorCallback(hotfdec);
499 #else
500   HAL_OTFDEC_ErrorCallback(hotfdec);
501 #endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
502 }
503 
504 /**
505   * @brief OTFDEC error callback.
506   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
507   *         the configuration information for OTFDEC module
508   * @retval None
509   */
HAL_OTFDEC_ErrorCallback(OTFDEC_HandleTypeDef * hotfdec)510 __weak void HAL_OTFDEC_ErrorCallback(OTFDEC_HandleTypeDef *hotfdec)
511 {
512   /* Prevent unused argument(s) compilation warning */
513   UNUSED(hotfdec);
514 
515   /* NOTE : This function should not be modified; when the callback is needed,
516             the HAL_OTFDEC_ErrorCallback can be implemented in the user file.
517    */
518 }
519 
520 /**
521   * @}
522   */
523 
524 
525 
526 
527 /** @defgroup OTFDEC_Exported_Functions_Group3 Peripheral Control functions
528   *  @brief   Peripheral control functions.
529   *
530 @verbatim
531   ==============================================================================
532                       ##### Peripheral Control functions #####
533   ==============================================================================
534     [..]
535     This subsection permits to configure the OTFDEC peripheral
536 
537 @endverbatim
538   * @{
539   */
540 
541 /**
542   * @brief  Lock region keys.
543   * @note   Writes to this region KEYRx registers are ignored until next OTFDEC reset.
544   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
545   *         the configuration information for OTFDEC module
546   * @param  RegionIndex index of region the keys of which are locked
547   * @retval HAL state
548   */
HAL_OTFDEC_RegionKeyLock(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex)549 HAL_StatusTypeDef HAL_OTFDEC_RegionKeyLock(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
550 {
551   OTFDEC_Region_TypeDef *region;
552   uint32_t address;
553 
554   /* Check the parameters */
555   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
556   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
557 
558   /* Take Lock */
559   __HAL_LOCK(hotfdec);
560 
561   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
562   region = (OTFDEC_Region_TypeDef *)address;
563 
564   SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_KEYLOCK);
565 
566   /* Release Lock */
567   __HAL_UNLOCK(hotfdec);
568 
569   /* Status is okay */
570   return HAL_OK;
571 }
572 
573 /**
574   * @brief  Set region keys.
575   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
576   *         the configuration information for OTFDEC module
577   * @param  RegionIndex index of region the keys of which are set
578   * @param  pKey pointer at set of keys
579   * @note   The API reads the key CRC computed by the peripheral and compares it with that
580   *         theoretically expected. An error is reported if they are different.
581   * @retval HAL state
582   */
HAL_OTFDEC_RegionSetKey(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex,uint32_t * pKey)583 HAL_StatusTypeDef HAL_OTFDEC_RegionSetKey(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t *pKey)
584 {
585   OTFDEC_Region_TypeDef *region;
586   uint32_t address;
587 
588   /* Check the parameters */
589   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
590   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
591 
592   if (pKey == NULL)
593   {
594     return HAL_ERROR;
595   }
596   else
597   {
598     /* Take Lock */
599     __HAL_LOCK(hotfdec);
600 
601     address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
602     region = (OTFDEC_Region_TypeDef *)address;
603 
604     /* Set Key */
605     WRITE_REG(region->REG_KEYR0, pKey[0]);
606 
607     __DSB();
608     __ISB();
609 
610     WRITE_REG(region->REG_KEYR1, pKey[1]);
611 
612     __DSB();
613     __ISB();
614 
615     WRITE_REG(region->REG_KEYR2, pKey[2]);
616 
617     __DSB();
618     __ISB();
619 
620     WRITE_REG(region->REG_KEYR3, pKey[3]);
621 
622     /* Compute theoretically expected CRC and compare it with that reported by the peripheral */
623     if (HAL_OTFDEC_KeyCRCComputation(pKey) != HAL_OTFDEC_RegionGetKeyCRC(hotfdec, RegionIndex))
624     {
625       /* Release Lock */
626       __HAL_UNLOCK(hotfdec);
627 
628       /* Status is okay */
629       return HAL_ERROR;
630     }
631 
632     /* Release Lock */
633     __HAL_UNLOCK(hotfdec);
634 
635     /* Status is okay */
636     return HAL_OK;
637   }
638 }
639 
640 /**
641   * @brief  Set region mode.
642   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
643   *         the configuration information for OTFDEC module
644   * @param  RegionIndex index of region the mode of which is set
645   * @param  mode This parameter can be only:
646   *           @arg @ref OTFDEC_REG_MODE_INSTRUCTION_ACCESSES_ONLY
647                         Only instruction accesses are decrypted
648   *           @arg @ref OTFDEC_REG_MODE_DATA_ACCESSES_ONLY
649                         Only data accesses are decrypted
650   *           @arg @ref OTFDEC_REG_MODE_INSTRUCTION_OR_DATA_ACCESSES
651                         All read accesses are decrypted (instruction or data)
652   *           @arg @ref OTFDEC_REG_MODE_INSTRUCTION_ACCESSES_ONLY_WITH_CIPHER
653                         Only instruction accesses are decrypted with proprietary cipher activated
654   * @retval HAL state
655   */
HAL_OTFDEC_RegionSetMode(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex,uint32_t mode)656 HAL_StatusTypeDef HAL_OTFDEC_RegionSetMode(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t mode)
657 {
658   OTFDEC_Region_TypeDef *region;
659   uint32_t address;
660 
661   /* Check the parameters */
662   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
663   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
664   assert_param(IS_OTFDEC_REGION_OPERATING_MODE(mode));
665 
666   /* Take Lock */
667   __HAL_LOCK(hotfdec);
668 
669   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
670   region = (OTFDEC_Region_TypeDef *)address;
671 
672   /* Set mode */
673   MODIFY_REG(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_MODE, mode);
674 
675   /* Release Lock */
676   __HAL_UNLOCK(hotfdec);
677 
678   /* Status is okay */
679   return HAL_OK;
680 }
681 
682 /**
683   * @brief  Set region configuration.
684   * @note  Region deciphering is enabled at the end of this function
685   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
686   *         the configuration information for OTFDEC module
687   * @param  RegionIndex index of region that is configured
688   * @param  Config pointer on structure containing the region configuration parameters
689   * @param  lock configuration lock enable or disable parameter
690   *         This parameter can be one of the following values:
691   *          @arg @ref OTFDEC_REG_CONFIGR_LOCK_DISABLE      OTFDEC region configuration is not locked
692   *          @arg @ref OTFDEC_REG_CONFIGR_LOCK_ENABLE       OTFDEC region configuration is locked
693   * @retval HAL state
694   */
HAL_OTFDEC_RegionConfig(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex,const OTFDEC_RegionConfigTypeDef * Config,uint32_t lock)695 HAL_StatusTypeDef HAL_OTFDEC_RegionConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex,
696                                           const OTFDEC_RegionConfigTypeDef *Config, uint32_t lock)
697 {
698   OTFDEC_Region_TypeDef *region;
699   uint32_t address;
700 
701   /* Check the parameters */
702   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
703   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
704   assert_param(IS_OTFDEC_REGION_CONFIG_LOCK(lock));
705 
706   if (Config == NULL)
707   {
708     return HAL_ERROR;
709   }
710   else
711   {
712 
713     /* Take Lock */
714     __HAL_LOCK(hotfdec);
715 
716     address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
717     region = (OTFDEC_Region_TypeDef *)address;
718 
719     /* Set Nonce */
720     WRITE_REG(region->REG_NONCER0, Config->Nonce[0]);
721 
722     WRITE_REG(region->REG_NONCER1, Config->Nonce[1]);
723 
724     /* Write region protected area start and end addresses */
725     WRITE_REG(region->REG_START_ADDR, Config->StartAddress);
726 
727     WRITE_REG(region->REG_END_ADDR, Config->EndAddress);
728 
729     /* Write Version */
730     MODIFY_REG(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_VERSION,
731                (uint32_t)(Config->Version) << OTFDEC_REG_CONFIGR_VERSION_Pos);
732 
733     /* Enable region deciphering or enciphering (depending of OTFDEC_CR ENC bit setting) */
734     SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE);
735 
736     /* Lock the region configuration according to lock parameter value */
737     if (lock == OTFDEC_REG_CONFIGR_LOCK_ENABLE)
738     {
739       SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE);
740     }
741 
742     /* Release Lock */
743     __HAL_UNLOCK(hotfdec);
744 
745     /* Status is okay */
746     return HAL_OK;
747   }
748 }
749 
750 
751 /**
752   * @brief  Compute Key CRC
753   * @param  pKey pointer at set of keys
754   * @retval CRC value
755   */
HAL_OTFDEC_KeyCRCComputation(const uint32_t * pKey)756 uint32_t HAL_OTFDEC_KeyCRCComputation(const uint32_t *pKey)
757 {
758   uint8_t crc7_poly = 0x7;
759   const uint32_t key_strobe[4] = {0xAA55AA55U, 0x3U, 0x18U, 0xC0U};
760   uint8_t  i;
761   uint8_t crc = 0;
762   uint32_t  j;
763   uint32_t  keyval;
764   uint32_t  k;
765   const uint32_t *temp = pKey;
766 
767   for (j = 0U; j < 4U; j++)
768   {
769     keyval = *temp;
770     temp++;
771     if (j == 0U)
772     {
773       keyval ^= key_strobe[0];
774     }
775     else
776     {
777       keyval ^= (key_strobe[j] << 24) | ((uint32_t)crc << 16) | (key_strobe[j] << 8) | crc;
778     }
779 
780     crc = 0;
781     for (i = 0; i < (uint8_t)32; i++)
782     {
783       k = ((((uint32_t)crc >> 7) ^ ((keyval >> ((uint8_t)31 - i)) & ((uint8_t)0xF)))) & 1U;
784       crc <<= 1;
785       if (k != 0U)
786       {
787         crc ^= crc7_poly;
788       }
789     }
790 
791     crc ^= (uint8_t)0x55;
792   }
793 
794   return (uint32_t) crc;
795 }
796 
797 
798 /**
799   * @brief  Enable region deciphering.
800   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
801   *         the configuration information for OTFDEC module
802   * @param  RegionIndex index of region the deciphering is enabled
803   * @note   An error is reported when the configuration is locked.
804   * @retval HAL state
805   */
HAL_OTFDEC_RegionEnable(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex)806 HAL_StatusTypeDef HAL_OTFDEC_RegionEnable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
807 {
808   OTFDEC_Region_TypeDef *region;
809   uint32_t address;
810 
811   /* Check the parameters */
812   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
813   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
814 
815   /* Take Lock */
816   __HAL_LOCK(hotfdec);
817 
818   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
819   region = (OTFDEC_Region_TypeDef *)address;
820 
821   if (READ_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE) == OTFDEC_REG_CONFIGR_LOCK_ENABLE)
822   {
823     /* Configuration is locked, REG_EN bit can't be modified */
824     __HAL_UNLOCK(hotfdec);
825 
826     return HAL_ERROR;
827   }
828 
829   /* Enable region processing */
830   SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE);
831 
832   /* Release Lock */
833   __HAL_UNLOCK(hotfdec);
834 
835   /* Status is okay */
836   return HAL_OK;
837 }
838 
839 /**
840   * @brief  Disable region deciphering.
841   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
842   *         the configuration information for OTFDEC module
843   * @param  RegionIndex index of region the deciphering is disabled
844   * @note   An error is reported when the configuration is locked.
845   * @retval HAL state
846   */
HAL_OTFDEC_RegionDisable(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex)847 HAL_StatusTypeDef HAL_OTFDEC_RegionDisable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
848 {
849   OTFDEC_Region_TypeDef *region;
850   uint32_t address;
851 
852   /* Check the parameters */
853   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
854   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
855 
856   /* Take Lock */
857   __HAL_LOCK(hotfdec);
858 
859   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
860   region = (OTFDEC_Region_TypeDef *)address;
861 
862   if (READ_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE) == OTFDEC_REG_CONFIGR_LOCK_ENABLE)
863   {
864     /* Configuration is locked, REG_EN bit can't be modified */
865     __HAL_UNLOCK(hotfdec);
866 
867     return HAL_ERROR;
868   }
869 
870   /* Disable region processing */
871   CLEAR_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE);
872 
873   /* Release Lock */
874   __HAL_UNLOCK(hotfdec);
875 
876   /* Status is okay */
877   return HAL_OK;
878 }
879 
880 /**
881   * @}
882   */
883 
884 /** @defgroup OTFDEC_Exported_Functions_Group4 Peripheral State and Status functions
885   *  @brief   Peripheral State functions.
886   *
887 @verbatim
888   ==============================================================================
889                       ##### Peripheral State functions #####
890   ==============================================================================
891     [..]
892     This subsection permits to get in run-time the status of the peripheral.
893 
894 @endverbatim
895   * @{
896   */
897 
898 /**
899   * @brief  Return the OTFDEC state.
900   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
901   *         the configuration information for OTFDEC module
902   * @retval HAL state
903   */
HAL_OTFDEC_GetState(const OTFDEC_HandleTypeDef * hotfdec)904 HAL_OTFDEC_StateTypeDef HAL_OTFDEC_GetState(const OTFDEC_HandleTypeDef *hotfdec)
905 {
906   return hotfdec->State;
907 }
908 
909 
910 /**
911   * @brief  Return region keys CRC.
912   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
913   *         the configuration information for OTFDEC module
914   * @param  RegionIndex index of region the keys CRC of which is read
915   * @retval Key CRC
916   */
HAL_OTFDEC_RegionGetKeyCRC(const OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex)917 uint32_t HAL_OTFDEC_RegionGetKeyCRC(const OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
918 {
919   const OTFDEC_Region_TypeDef *region;
920   uint32_t address;
921   uint32_t keycrc;
922 
923   /* Check the parameters */
924   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
925   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
926 
927   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
928   region = (OTFDEC_Region_TypeDef *)address;
929 
930   keycrc = (READ_REG(region->REG_CONFIGR)) & OTFDEC_REG_CONFIGR_KEYCRC;
931 
932   keycrc >>= OTFDEC_REG_CONFIGR_KEYCRC_Pos;
933 
934   return keycrc;
935 }
936 
937 /**
938   * @brief  Return region configuration parameters.
939   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
940   *         the configuration information for OTFDEC module
941   * @param  RegionIndex index of region the configuration of which is read
942   * @param  Config pointer on structure that will be filled up with the region configuration parameters
943   * @retval HAL state
944   */
HAL_OTFDEC_RegionGetConfig(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex,OTFDEC_RegionConfigTypeDef * Config)945 HAL_StatusTypeDef HAL_OTFDEC_RegionGetConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex,
946                                              OTFDEC_RegionConfigTypeDef *Config)
947 {
948   OTFDEC_Region_TypeDef *region;
949   uint32_t address;
950 
951   /* Check the parameters */
952   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
953   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
954 
955   if (Config == NULL)
956   {
957     return HAL_ERROR;
958   }
959   else
960   {
961     /* Take Lock */
962     __HAL_LOCK(hotfdec);
963 
964     address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
965     region = (OTFDEC_Region_TypeDef *)address;
966 
967     /* Read Nonce */
968     Config->Nonce[0] = READ_REG(region->REG_NONCER0);
969     Config->Nonce[1] = READ_REG(region->REG_NONCER1);
970 
971     /* Read Addresses */
972     Config->StartAddress = READ_REG(region->REG_START_ADDR);
973     Config->EndAddress = READ_REG(region->REG_END_ADDR);
974 
975     /* Read Version */
976     Config->Version = (uint16_t)(READ_REG(region->REG_CONFIGR) &
977                                  OTFDEC_REG_CONFIGR_VERSION) >> OTFDEC_REG_CONFIGR_VERSION_Pos;
978 
979     /* Release Lock */
980     __HAL_UNLOCK(hotfdec);
981 
982     /* Status is okay */
983     return HAL_OK;
984   }
985 }
986 
987 
988 /**
989   * @}
990   */
991 
992 /**
993   * @}
994   */
995 
996 #endif /* OTFDEC1 */
997 
998 #endif /* HAL_OTFDEC_MODULE_ENABLED */
999 
1000 
1001 /**
1002   * @}
1003   */
1004 
1005 /**
1006   * @}
1007   */
1008