1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_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/Encryption (OTFDEC)
8   *          peripheral:
9   *           + Initialization and de-initialization functions
10   *           + Region setting/enable functions
11   *           + Peripheral State functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2019 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                      ##### How to use this driver #####
27   ==============================================================================
28  [..]
29     The OTFDEC HAL driver can be used as follows:
30 
31     (#) Declare an OTFDEC_HandleTypeDef handle structure (eg. OTFDEC_HandleTypeDef hotfdec).
32 
33     (#) Initialize the OTFDEC low level resources by implementing the HAL_OTFDEC_MspInit() API:
34         (++) Enable the OTFDEC interface clock.
35         (++) NVIC configuration if interrupts are used
36             (+++) Configure the OTFDEC interrupt priority.
37             (+++) Enable the NVIC OTFDEC IRQ handle.
38 
39     (#) Initialize the OTFDEC peripheral by calling the HAL_OTFDEC_Init() API.
40 
41     (#) In the case of encryption, enable ciphering mode for the peripheral
42 
43     (#) For each region,
44 
45         (++) Configure the region deciphering mode by calling the HAL_OTFDEC_RegionSetMode() API.
46 
47         (++) Write the region Key by calling the HAL_OTFDEC_RegionSetKey() API. If desired,
48         read the key CRC by calling HAL_OTFDEC_RegionGetKeyCRC() API and compare the
49         result with the theoretically expected CRC.
50 
51         (++) Initialize the OTFDEC region config structure with the Nonce, protected
52         region start and end addresses and firmware version, and wrap-up the region
53         configuration by calling HAL_OTFDEC_RegionConfig() API.
54 
55     (#) At this point, the OTFDEC region configuration is done and the deciphering
56         or enciphering enabled. The region can be deciphered on the fly after
57         having made sure the OctoSPI is configured in memory-mapped mode or data can
58         be enciphered by calling HAL_OTFDEC_Cipher() API.
59 
60     [..]
61     (@) Warning: the OTFDEC en/deciphering is based on a different endianness compared
62         to the AES-CTR as implemented in the AES peripheral. E.g., if the OTFEC
63         resorts to the Key (B0, B1, B2, B3) where Bi are 32-bit longwords and B0
64         is the Least Significant Word, the AES has to be configured with the Key
65         (B3, B2, B1, B0) to report the same result (with the same swapping applied
66         to the Initialization Vector).
67 
68     [..]
69 
70     *** Callback registration ***
71     =============================================
72     [..]
73 
74      The compilation flag USE_HAL_OTFDEC_REGISTER_CALLBACKS, when set to 1,
75      allows the user to configure dynamically the driver callbacks.
76      Use Functions HAL_OTFDEC_RegisterCallback()
77      to register an interrupt callback.
78     [..]
79 
80      Function HAL_OTFDEC_RegisterCallback() allows to register following callbacks:
81        (+) ErrorCallback                  : OTFDEC error callback
82        (+) MspInitCallback                : OTFDEC Msp Init callback
83        (+) MspDeInitCallback              : OTFDEC Msp DeInit callback
84      This function takes as parameters the HAL peripheral handle, the Callback ID
85      and a pointer to the user callback function.
86     [..]
87 
88      Use function HAL_OTFDEC_UnRegisterCallback to reset a callback to the default
89      weak function.
90     [..]
91 
92     HAL_OTFDEC_UnRegisterCallback takes as parameters the HAL peripheral handle,
93      and the Callback ID.
94      This function allows to reset following callbacks:
95        (+) ErrorCallback                  : OTFDEC error callback
96        (+) MspInitCallback                : OTFDEC Msp Init callback
97        (+) MspDeInitCallback              : OTFDEC Msp DeInit callback
98      [..]
99 
100      By default, after the HAL_OTFDEC_Init() and when the state is HAL_OTFDEC_STATE_RESET
101      all callbacks are set to the corresponding weak functions:
102      example HAL_OTFDEC_ErrorCallback().
103      Exception done for MspInit and MspDeInit functions that are
104      reset to the legacy weak functions in the HAL_OTFDEC_Init()HAL_OTFDEC_DeInit() only when
105      these callbacks are null (not registered beforehand).
106     [..]
107 
108      If MspInit or MspDeInit are not null, the HAL_OTFDEC_Init()/HAL_OTFDEC_DeInit()
109      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
110      [..]
111 
112      Callbacks can be registered/unregistered in HAL_OTFDEC_STATE_READY state only.
113      Exception done MspInit/MspDeInit functions that can be registered/unregistered
114      in HAL_OTFDEC_STATE_READY or HAL_OTFDEC_STATE_RESET state,
115      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
116     [..]
117 
118      Then, the user first registers the MspInit/MspDeInit user callbacks
119      using HAL_OTFDEC_RegisterCallback() before calling HAL_OTFDEC_DeInit()
120      or HAL_OTFDEC_Init() function.
121      [..]
122 
123      When the compilation flag USE_HAL_OTFDEC_REGISTER_CALLBACKS is set to 0 or
124      not defined, the callback registration feature is not available and all callbacks
125      are set to the corresponding weak functions.
126 
127   @endverbatim
128   ******************************************************************************
129   */
130 
131 /* Includes ------------------------------------------------------------------*/
132 #include "stm32l5xx_hal.h"
133 
134 /** @addtogroup STM32L5xx_HAL_Driver
135   * @{
136   */
137 
138 /** @defgroup OTFDEC OTFDEC
139   * @brief OTFDEC HAL module driver.
140   * @{
141   */
142 
143 
144 #ifdef HAL_OTFDEC_MODULE_ENABLED
145 
146 #if defined(OTFDEC1)
147 
148 /* Private typedef -----------------------------------------------------------*/
149 /* Private define ------------------------------------------------------------*/
150 /* Private macro -------------------------------------------------------------*/
151 /* Private variables ---------------------------------------------------------*/
152 /* Private function prototypes -----------------------------------------------*/
153 /* Private functions ---------------------------------------------------------*/
154 
155 /* Exported functions --------------------------------------------------------*/
156 /** @addtogroup OTFDEC_Exported_Functions
157   * @{
158   */
159 
160 /** @defgroup OTFDEC_Exported_Functions_Group1 Initialization and de-initialization functions
161   *  @brief    Initialization and Configuration functions.
162   *
163 @verbatim
164   ==============================================================================
165               ##### Initialization and de-initialization functions #####
166   ==============================================================================
167 
168 @endverbatim
169   * @{
170   */
171 
172 /**
173   * @brief  Initialize the OTFDEC peripheral and create the associated handle.
174   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
175   *         the configuration information for OTFDEC module
176   * @retval HAL status
177   */
HAL_OTFDEC_Init(OTFDEC_HandleTypeDef * hotfdec)178 HAL_StatusTypeDef HAL_OTFDEC_Init(OTFDEC_HandleTypeDef *hotfdec)
179 {
180   /* Check the OTFDEC handle allocation */
181   if (hotfdec == NULL)
182   {
183     return HAL_ERROR;
184   }
185 
186   /* Check the parameters */
187   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
188 
189   if (hotfdec->State == HAL_OTFDEC_STATE_RESET)
190   {
191     /* Allocate lock resource and initialize it */
192     __HAL_UNLOCK(hotfdec);
193 
194 #if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
195     /* Init the OTFDEC Callback settings */
196     hotfdec->ErrorCallback = HAL_OTFDEC_ErrorCallback; /* Legacy weak callback */
197 
198     if (hotfdec->MspInitCallback == NULL)
199     {
200       hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
201     }
202 
203     /* Init the low level hardware */
204     hotfdec->MspInitCallback(hotfdec);
205 #else
206     /* Init the low level hardware */
207     HAL_OTFDEC_MspInit(hotfdec);
208 #endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
209   }
210 
211   /* Change the OTFDEC state */
212   hotfdec->State = HAL_OTFDEC_STATE_READY;
213 
214   /* Return function status */
215   return HAL_OK;
216 }
217 
218 /**
219   * @brief  DeInitialize the OTFDEC peripheral.
220   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
221   *         the configuration information for OTFDEC module
222   * @retval HAL status
223   */
HAL_OTFDEC_DeInit(OTFDEC_HandleTypeDef * hotfdec)224 HAL_StatusTypeDef HAL_OTFDEC_DeInit(OTFDEC_HandleTypeDef *hotfdec)
225 {
226   /* Check the OTFDEC handle allocation */
227   if (hotfdec == NULL)
228   {
229     return HAL_ERROR;
230   }
231 
232   /* Check the parameters */
233   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
234 
235   /* Change the OTFDEC state */
236   hotfdec->State = HAL_OTFDEC_STATE_BUSY;
237 
238 #if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
239   if (hotfdec->MspDeInitCallback == NULL)
240   {
241     hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
242   }
243 
244   /* DeInit the low level hardware: CLOCK, NVIC */
245   hotfdec->MspDeInitCallback(hotfdec);
246 #else
247   /* DeInit the low level hardware: CLOCK, NVIC */
248   HAL_OTFDEC_MspDeInit(hotfdec);
249 #endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
250 
251   /* Change the OTFDEC state */
252   hotfdec->State = HAL_OTFDEC_STATE_RESET;
253 
254   /* Reset OTFDEC error status */
255   hotfdec->ErrorCode = HAL_OTFDEC_ERROR_NONE;
256 
257   /* Release Lock */
258   __HAL_UNLOCK(hotfdec);
259 
260   /* Return function status */
261   return HAL_OK;
262 }
263 
264 /**
265   * @brief  Initialize the OTFDEC MSP.
266   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
267   *         the configuration information for OTFDEC module
268   * @retval None
269   */
HAL_OTFDEC_MspInit(OTFDEC_HandleTypeDef * hotfdec)270 __weak void HAL_OTFDEC_MspInit(OTFDEC_HandleTypeDef *hotfdec)
271 {
272   /* Prevent unused argument(s) compilation warning */
273   UNUSED(hotfdec);
274 
275   /* NOTE : This function should not be modified; when the callback is needed,
276             the HAL_OTFDEC_MspInit can be implemented in the user file.
277    */
278 }
279 
280 /**
281   * @brief  DeInitialize OTFDEC MSP.
282   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
283   *         the configuration information for OTFDEC module
284   * @retval None
285   */
HAL_OTFDEC_MspDeInit(OTFDEC_HandleTypeDef * hotfdec)286 __weak void HAL_OTFDEC_MspDeInit(OTFDEC_HandleTypeDef *hotfdec)
287 {
288   /* Prevent unused argument(s) compilation warning */
289   UNUSED(hotfdec);
290 
291   /* NOTE : This function should not be modified; when the callback is needed,
292             the HAL_OTFDEC_MspDeInit can be implemented in the user file.
293    */
294 }
295 
296 #if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
297 /**
298   * @brief  Register a User OTFDEC Callback
299   *         To be used instead of the weak predefined callback
300   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
301   *         the configuration information for OTFDEC module
302   * @param  CallbackID ID of the callback to be registered
303   *         This parameter can be one of the following values:
304   *          @arg @ref HAL_OTFDEC_ERROR_CB_ID           OTFDEC error callback ID
305   *          @arg @ref HAL_OTFDEC_MSPINIT_CB_ID         MspInit callback ID
306   *          @arg @ref HAL_OTFDEC_MSPDEINIT_CB_ID       MspDeInit callback ID
307   * @param  pCallback pointer to the Callback function
308   * @retval HAL status
309   */
HAL_OTFDEC_RegisterCallback(OTFDEC_HandleTypeDef * hotfdec,HAL_OTFDEC_CallbackIDTypeDef CallbackID,pOTFDEC_CallbackTypeDef pCallback)310 HAL_StatusTypeDef HAL_OTFDEC_RegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID,
311                                               pOTFDEC_CallbackTypeDef pCallback)
312 {
313   HAL_StatusTypeDef status = HAL_OK;
314 
315   if (pCallback == NULL)
316   {
317     /* Update the error code */
318     hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
319 
320     return HAL_ERROR;
321   }
322 
323   if (hotfdec->State == HAL_OTFDEC_STATE_READY)
324   {
325     switch (CallbackID)
326     {
327       case HAL_OTFDEC_ERROR_CB_ID :
328         hotfdec->ErrorCallback = pCallback;
329         break;
330 
331       case HAL_OTFDEC_MSPINIT_CB_ID :
332         hotfdec->MspInitCallback = pCallback;
333         break;
334 
335       case HAL_OTFDEC_MSPDEINIT_CB_ID :
336         hotfdec->MspDeInitCallback = pCallback;
337         break;
338 
339       default :
340         /* Update the error code */
341         hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
342 
343         /* Return error status */
344         status = HAL_ERROR;
345         break;
346     }
347   }
348   else if (HAL_OTFDEC_STATE_RESET == hotfdec->State)
349   {
350     switch (CallbackID)
351     {
352       case HAL_OTFDEC_MSPINIT_CB_ID :
353         hotfdec->MspInitCallback = pCallback;
354         break;
355 
356       case HAL_OTFDEC_MSPDEINIT_CB_ID :
357         hotfdec->MspDeInitCallback = pCallback;
358         break;
359 
360       default :
361         /* Update the error code */
362         hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
363 
364         /* Return error status */
365         status = HAL_ERROR;
366         break;
367     }
368   }
369   else
370   {
371     /* Update the error code */
372     hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
373 
374     /* Return error status */
375     status =  HAL_ERROR;
376   }
377 
378   return status;
379 }
380 
381 /**
382   * @brief  Unregister a OTFDEC Callback
383   *         OTFDEC callback is redirected to the weak predefined callback
384   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
385   *         the configuration information for OTFDEC module
386   * @param  CallbackID ID of the callback to be registered
387   *         This parameter can be one of the following values:
388   *          @arg @ref HAL_OTFDEC_ERROR_CB_ID           OTFDEC error callback ID
389   *          @arg @ref HAL_OTFDEC_MSPINIT_CB_ID         MspInit callback ID
390   *          @arg @ref HAL_OTFDEC_MSPDEINIT_CB_ID       MspDeInit callback ID
391   * @retval HAL status
392   */
HAL_OTFDEC_UnRegisterCallback(OTFDEC_HandleTypeDef * hotfdec,HAL_OTFDEC_CallbackIDTypeDef CallbackID)393 HAL_StatusTypeDef HAL_OTFDEC_UnRegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID)
394 {
395   HAL_StatusTypeDef status = HAL_OK;
396 
397   if (hotfdec->State == HAL_OTFDEC_STATE_READY)
398   {
399     switch (CallbackID)
400     {
401       case HAL_OTFDEC_ERROR_CB_ID :
402         hotfdec->ErrorCallback = HAL_OTFDEC_ErrorCallback;
403         break;
404 
405       case HAL_OTFDEC_MSPINIT_CB_ID :
406         hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
407         break;
408 
409       case HAL_OTFDEC_MSPDEINIT_CB_ID :
410         hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
411         break;
412 
413       default :
414         /* Update the error code */
415         hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
416 
417         /* Return error status */
418         status =  HAL_ERROR;
419         break;
420     }
421   }
422   else if (HAL_OTFDEC_STATE_RESET == hotfdec->State)
423   {
424     switch (CallbackID)
425     {
426       case HAL_OTFDEC_MSPINIT_CB_ID :
427         hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
428         break;
429 
430       case HAL_OTFDEC_MSPDEINIT_CB_ID :
431         hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
432         break;
433 
434       default :
435         /* Update the error code */
436         hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
437 
438         /* Return error status */
439         status =  HAL_ERROR;
440         break;
441     }
442   }
443   else
444   {
445     /* Update the error code */
446     hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
447 
448     /* Return error status */
449     status =  HAL_ERROR;
450   }
451 
452   return status;
453 }
454 
455 #endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
456 
457 /**
458   * @}
459   */
460 
461 /** @defgroup OTFDEC_Exported_Functions_Group2  OTFDEC IRQ handler management
462   *  @brief   OTFDEC IRQ handler.
463   *
464 @verbatim
465   ==============================================================================
466                 ##### OTFDEC IRQ handler management #####
467   ==============================================================================
468 [..]  This section provides OTFDEC IRQ handler function.
469 
470 @endverbatim
471   * @{
472   */
473 
474 /**
475   * @brief  Handle OTFDEC interrupt request.
476   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
477   *         the configuration information for OTFDEC module
478   * @retval None
479   */
HAL_OTFDEC_IRQHandler(OTFDEC_HandleTypeDef * hotfdec)480 void HAL_OTFDEC_IRQHandler(OTFDEC_HandleTypeDef *hotfdec)
481 {
482   uint32_t isr_reg;
483 
484   isr_reg = READ_REG(hotfdec->Instance->ISR);
485   if ((isr_reg & OTFDEC_ISR_SEIF) == OTFDEC_ISR_SEIF)
486   {
487     SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_SEIF);
488     hotfdec->ErrorCode |= HAL_OTFDEC_SECURITY_ERROR;
489   }
490   if ((isr_reg & OTFDEC_ISR_XONEIF) == OTFDEC_ISR_XONEIF)
491   {
492     SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_XONEIF);
493     hotfdec->ErrorCode |= HAL_OTFDEC_EXECUTE_ERROR;
494   }
495   if ((isr_reg & OTFDEC_ISR_KEIF) == OTFDEC_ISR_KEIF)
496   {
497     SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_KEIF);
498     hotfdec->ErrorCode |= HAL_OTFDEC_KEY_ERROR;
499   }
500 
501 #if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
502   hotfdec->ErrorCallback(hotfdec);
503 #else
504   HAL_OTFDEC_ErrorCallback(hotfdec);
505 #endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
506 }
507 
508 /**
509   * @brief OTFDEC error callback.
510   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
511   *         the configuration information for OTFDEC module
512   * @retval None
513   */
HAL_OTFDEC_ErrorCallback(OTFDEC_HandleTypeDef * hotfdec)514 __weak void HAL_OTFDEC_ErrorCallback(OTFDEC_HandleTypeDef *hotfdec)
515 {
516   /* Prevent unused argument(s) compilation warning */
517   UNUSED(hotfdec);
518 
519   /* NOTE : This function should not be modified; when the callback is needed,
520             the HAL_OTFDEC_ErrorCallback can be implemented in the user file.
521    */
522 }
523 
524 /**
525   * @}
526   */
527 
528 
529 
530 
531 /** @defgroup OTFDEC_Exported_Functions_Group3 Peripheral Control functions
532   *  @brief   Peripheral control functions.
533   *
534 @verbatim
535   ==============================================================================
536                       ##### Peripheral Control functions #####
537   ==============================================================================
538     [..]
539     This subsection permits to configure the OTFDEC peripheral
540 
541 @endverbatim
542   * @{
543   */
544 
545 /**
546   * @brief  Lock region keys.
547   * @note   Writes to this region KEYRx registers are ignored until next OTFDEC reset.
548   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
549   *         the configuration information for OTFDEC module
550   * @param  RegionIndex index of region the keys of which are locked
551   * @retval HAL state
552   */
HAL_OTFDEC_RegionKeyLock(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex)553 HAL_StatusTypeDef HAL_OTFDEC_RegionKeyLock(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
554 {
555   OTFDEC_Region_TypeDef *region;
556   uint32_t address;
557 
558   /* Check the parameters */
559   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
560   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
561 
562   /* Take Lock */
563   __HAL_LOCK(hotfdec);
564 
565   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
566   region = (OTFDEC_Region_TypeDef *)address;
567 
568   SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_KEYLOCK);
569 
570   /* Release Lock */
571   __HAL_UNLOCK(hotfdec);
572 
573   /* Status is okay */
574   return HAL_OK;
575 }
576 
577 /**
578   * @brief  Set region keys.
579   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
580   *         the configuration information for OTFDEC module
581   * @param  RegionIndex index of region the keys of which are set
582   * @param  pKey pointer at set of keys
583   * @note   The API reads the key CRC computed by the peripheral and compares it with that
584   *         theoretically expected. An error is reported if they are different.
585   * @retval HAL state
586   */
HAL_OTFDEC_RegionSetKey(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex,uint32_t * pKey)587 HAL_StatusTypeDef HAL_OTFDEC_RegionSetKey(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t *pKey)
588 {
589   OTFDEC_Region_TypeDef *region;
590   uint32_t address;
591 
592   /* Check the parameters */
593   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
594   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
595 
596   if (pKey == NULL)
597   {
598     return HAL_ERROR;
599   }
600   else
601   {
602     /* Take Lock */
603     __HAL_LOCK(hotfdec);
604 
605     address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
606     region = (OTFDEC_Region_TypeDef *)address;
607 
608     /* Set Key */
609     WRITE_REG(region->REG_KEYR0, pKey[0]);
610 
611     __DSB();
612     __ISB();
613 
614     WRITE_REG(region->REG_KEYR1, pKey[1]);
615 
616     __DSB();
617     __ISB();
618 
619     WRITE_REG(region->REG_KEYR2, pKey[2]);
620 
621     __DSB();
622     __ISB();
623 
624     WRITE_REG(region->REG_KEYR3, pKey[3]);
625 
626     /* Compute theoretically expected CRC and compare it with that reported by the peripheral */
627     if (HAL_OTFDEC_KeyCRCComputation(pKey) != HAL_OTFDEC_RegionGetKeyCRC(hotfdec, RegionIndex))
628     {
629       /* Release Lock */
630       __HAL_UNLOCK(hotfdec);
631 
632       /* Status is okay */
633       return HAL_ERROR;
634     }
635 
636     /* Release Lock */
637     __HAL_UNLOCK(hotfdec);
638 
639     /* Status is okay */
640     return HAL_OK;
641   }
642 }
643 
644 /**
645   * @brief  Set region mode.
646   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
647   *         the configuration information for OTFDEC module
648   * @param  RegionIndex index of region the mode of which is set
649   * @param  mode This parameter can be only:
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 enciphering/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,OTFDEC_RegionConfigTypeDef * Config,uint32_t lock)695 HAL_StatusTypeDef HAL_OTFDEC_RegionConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex,
696                                           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   * @brief  Configure OTFDEC attributes.
752   * @note   This function sets or resets regions privileged access protection.
753   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
754   *         the configuration information for OTFDEC module
755   * @param  Attributes This parameter can be only:
756   *           @arg @ref OTFDEC_ATTRIBUTE_PRIV   Set privileged access protection
757   *           @arg @ref OTFDEC_ATTRIBUTE_NPRIV  Reset privileged access protection
758   * @retval HAL state
759   */
HAL_OTFDEC_ConfigAttributes(OTFDEC_HandleTypeDef * hotfdec,uint32_t Attributes)760 HAL_StatusTypeDef HAL_OTFDEC_ConfigAttributes(OTFDEC_HandleTypeDef *hotfdec, uint32_t Attributes)
761 {
762   /* Check the parameters */
763   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
764   assert_param(IS_OTFDEC_ATTRIBUTE(Attributes));
765 
766   /* Take Lock */
767   __HAL_LOCK(hotfdec);
768 
769   MODIFY_REG(hotfdec->Instance->PRIVCFGR, OTFDEC_PRIVCFGR_PRIV, Attributes);
770 
771   /* Release Lock */
772   __HAL_UNLOCK(hotfdec);
773 
774   /* Status is okay */
775   return HAL_OK;
776 }
777 
778 /**
779   * @brief  Compute Key CRC
780   * @param  pKey pointer at set of keys
781   * @retval CRC value
782   */
HAL_OTFDEC_KeyCRCComputation(uint32_t * pKey)783 uint32_t HAL_OTFDEC_KeyCRCComputation(uint32_t *pKey)
784 {
785   uint8_t crc7_poly = 0x7;
786   uint32_t key_strobe[4] = {0xAA55AA55U, 0x3U, 0x18U, 0xC0U};
787   uint8_t  i;
788   uint8_t crc = 0;
789   uint32_t  j;
790   uint32_t  keyval;
791   uint32_t  k;
792   uint32_t *temp = pKey;
793 
794   for (j = 0U; j < 4U; j++)
795   {
796     keyval = *temp;
797     temp++;
798     if (j == 0U)
799     {
800       keyval ^= key_strobe[0];
801     }
802     else
803     {
804       keyval ^= (key_strobe[j] << 24) | ((uint32_t)crc << 16) | (key_strobe[j] << 8) | crc;
805     }
806 
807     crc = 0;
808     for (i = 0; i < (uint8_t)32; i++)
809     {
810       k = ((((uint32_t)crc >> 7) ^ ((keyval >> ((uint8_t)31 - i)) & ((uint8_t)0xF)))) & 1U;
811       crc <<= 1;
812       if (k != 0U)
813       {
814         crc ^= crc7_poly;
815       }
816     }
817 
818     crc ^= (uint8_t)0x55;
819   }
820 
821   return (uint32_t) crc;
822 }
823 
824 /**
825   * @brief  Enable peripheral enciphering.
826   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
827   *         the configuration information for OTFDEC module
828   * @note By default, deciphering mode is enabled at reset
829   * @retval HAL state
830   */
HAL_OTFDEC_EnableEnciphering(OTFDEC_HandleTypeDef * hotfdec)831 HAL_StatusTypeDef HAL_OTFDEC_EnableEnciphering(OTFDEC_HandleTypeDef *hotfdec)
832 {
833   /* Take Lock */
834   __HAL_LOCK(hotfdec);
835 
836   SET_BIT(hotfdec->Instance->CR, OTFDEC_CR_ENC);
837 
838   /* Release Lock */
839   __HAL_UNLOCK(hotfdec);
840 
841   /* Status is okay */
842   return HAL_OK;
843 }
844 
845 /**
846   * @brief  Disable peripheral enciphering.
847   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
848   *         the configuration information for OTFDEC module
849   * @retval HAL state
850   */
HAL_OTFDEC_DisableEnciphering(OTFDEC_HandleTypeDef * hotfdec)851 HAL_StatusTypeDef HAL_OTFDEC_DisableEnciphering(OTFDEC_HandleTypeDef *hotfdec)
852 {
853   /* Take Lock */
854   __HAL_LOCK(hotfdec);
855 
856   CLEAR_BIT(hotfdec->Instance->CR, OTFDEC_CR_ENC);
857 
858   /* Release Lock */
859   __HAL_UNLOCK(hotfdec);
860 
861   /* Status is okay */
862   return HAL_OK;
863 }
864 
865 
866 /**
867   * @brief  Cipher data.
868   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
869   *         the configuration information for OTFDEC module
870   * @param  RegionIndex index of region the configuration of which is used to encipher
871   * @param  input plain data
872   * @param  output ciphered data
873   * @param  size plain data size in words
874   * @param  start_address starting address in the external memory area
875             where the enciphered data will be eventually stored
876   * @note   Region configuration parameters and OTFDEC_CR ENC bit must be set.
877   * @note   output pointer points at a temporary area in RAM to store the ciphered data. It is up to the user code
878   *         to copy the ciphered data in external RAM once the enciphering process is over.
879   * @retval HAL state
880   */
HAL_OTFDEC_Cipher(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex,uint32_t * input,uint32_t * output,uint32_t size,uint32_t start_address)881 HAL_StatusTypeDef HAL_OTFDEC_Cipher(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex,
882                                     uint32_t *input, uint32_t *output, uint32_t size, uint32_t start_address)
883 {
884   uint32_t j;
885   __IO uint32_t *extMem_ptr = (uint32_t *)start_address;
886   uint32_t *in_ptr = input;
887   uint32_t *out_ptr = output;
888 
889   /* Check the parameters */
890   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
891   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
892 
893   /* Prevent unused argument(s) compilation warning */
894   UNUSED(RegionIndex);
895 
896   if ((input == NULL) || (output == NULL) || (size == 0U))
897   {
898     return HAL_ERROR;
899   }
900   else
901   {
902     /* Take Lock */
903     __HAL_LOCK(hotfdec);
904 
905     for (j = 0; j < size; j++)
906     {
907       *extMem_ptr = *in_ptr;
908       in_ptr++;
909       *out_ptr = *extMem_ptr;
910       out_ptr++;
911       extMem_ptr++;
912     }
913 
914     /* Release Lock */
915     __HAL_UNLOCK(hotfdec);
916 
917     /* Status is okay */
918     return HAL_OK;
919   }
920 }
921 
922 /**
923   * @brief  Enable region processing (enciphering or deciphering).
924   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
925   *         the configuration information for OTFDEC module
926   * @param  RegionIndex index of region the enciphering or deciphering is enabled
927   * @note   An error is reported when the configuration is locked.
928   * @retval HAL state
929   */
HAL_OTFDEC_RegionEnable(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex)930 HAL_StatusTypeDef HAL_OTFDEC_RegionEnable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
931 {
932   OTFDEC_Region_TypeDef *region;
933   uint32_t address;
934 
935   /* Check the parameters */
936   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
937   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
938 
939   /* Take Lock */
940   __HAL_LOCK(hotfdec);
941 
942   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
943   region = (OTFDEC_Region_TypeDef *)address;
944 
945   if (READ_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE) == OTFDEC_REG_CONFIGR_LOCK_ENABLE)
946   {
947     /* Configuration is locked, REG_EN bit can't be modified */
948     __HAL_UNLOCK(hotfdec);
949 
950     return HAL_ERROR;
951   }
952 
953   /* Enable region processing */
954   SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE);
955 
956   /* Release Lock */
957   __HAL_UNLOCK(hotfdec);
958 
959   /* Status is okay */
960   return HAL_OK;
961 }
962 
963 /**
964   * @brief  Disable region processing (enciphering or deciphering).
965   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
966   *         the configuration information for OTFDEC module
967   * @param  RegionIndex index of region the enciphering or deciphering is disabled
968   * @note   An error is reported when the configuration is locked.
969   * @retval HAL state
970   */
HAL_OTFDEC_RegionDisable(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex)971 HAL_StatusTypeDef HAL_OTFDEC_RegionDisable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
972 {
973   OTFDEC_Region_TypeDef *region;
974   uint32_t address;
975 
976   /* Check the parameters */
977   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
978   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
979 
980   /* Take Lock */
981   __HAL_LOCK(hotfdec);
982 
983   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
984   region = (OTFDEC_Region_TypeDef *)address;
985 
986   if (READ_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE) == OTFDEC_REG_CONFIGR_LOCK_ENABLE)
987   {
988     /* Configuration is locked, REG_EN bit can't be modified */
989     __HAL_UNLOCK(hotfdec);
990 
991     return HAL_ERROR;
992   }
993 
994   /* Disable region processing */
995   CLEAR_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE);
996 
997   /* Release Lock */
998   __HAL_UNLOCK(hotfdec);
999 
1000   /* Status is okay */
1001   return HAL_OK;
1002 }
1003 
1004 /**
1005   * @}
1006   */
1007 
1008 /** @defgroup OTFDEC_Exported_Functions_Group4 Peripheral State and Status functions
1009   *  @brief   Peripheral State functions.
1010   *
1011 @verbatim
1012   ==============================================================================
1013                       ##### Peripheral State functions #####
1014   ==============================================================================
1015     [..]
1016     This subsection permits to get in run-time the status of the peripheral.
1017 
1018 @endverbatim
1019   * @{
1020   */
1021 
1022 /**
1023   * @brief  Return the OTFDEC state.
1024   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
1025   *         the configuration information for OTFDEC module
1026   * @retval HAL state
1027   */
HAL_OTFDEC_GetState(OTFDEC_HandleTypeDef * hotfdec)1028 HAL_OTFDEC_StateTypeDef HAL_OTFDEC_GetState(OTFDEC_HandleTypeDef *hotfdec)
1029 {
1030   return hotfdec->State;
1031 }
1032 
1033 /**
1034   * @brief  Get OTFDEC configuration attributes.
1035   * @note   This function returns whether or not the regions access protection is in privileged mode.
1036   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
1037   *         the configuration information for OTFDEC module
1038   * @param  Attributes pointer to attributes variable. This parameter can be only:
1039   *           @arg @ref OTFDEC_ATTRIBUTE_PRIV   Set privileged access protection
1040   *           @arg @ref OTFDEC_ATTRIBUTE_NPRIV  Reset privileged access protection
1041   * @retval HAL state
1042   */
HAL_OTFDEC_GetConfigAttributes(OTFDEC_HandleTypeDef * hotfdec,uint32_t * Attributes)1043 HAL_StatusTypeDef HAL_OTFDEC_GetConfigAttributes(OTFDEC_HandleTypeDef *hotfdec, uint32_t *Attributes)
1044 {
1045   /* Check the parameters */
1046   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
1047 
1048   /* Take Lock */
1049   __HAL_LOCK(hotfdec);
1050 
1051   *Attributes = READ_BIT(hotfdec->Instance->PRIVCFGR, OTFDEC_PRIVCFGR_PRIV);
1052 
1053   /* Release Lock */
1054   __HAL_UNLOCK(hotfdec);
1055 
1056   /* Status is okay */
1057   return HAL_OK;
1058 }
1059 
1060 /**
1061   * @brief  Return region keys CRC.
1062   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
1063   *         the configuration information for OTFDEC module
1064   * @param  RegionIndex index of region the keys CRC of which is read
1065   * @retval Key CRC
1066   */
HAL_OTFDEC_RegionGetKeyCRC(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex)1067 uint32_t HAL_OTFDEC_RegionGetKeyCRC(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
1068 {
1069   OTFDEC_Region_TypeDef *region;
1070   uint32_t address;
1071   uint32_t keycrc;
1072 
1073   /* Check the parameters */
1074   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
1075   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
1076 
1077   address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
1078   region = (OTFDEC_Region_TypeDef *)address;
1079 
1080   keycrc = (READ_REG(region->REG_CONFIGR)) & OTFDEC_REG_CONFIGR_KEYCRC;
1081 
1082   keycrc >>= OTFDEC_REG_CONFIGR_KEYCRC_Pos;
1083 
1084   return keycrc;
1085 }
1086 
1087 /**
1088   * @brief  Return region configuration parameters.
1089   * @param  hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
1090   *         the configuration information for OTFDEC module
1091   * @param  RegionIndex index of region the configuration of which is read
1092   * @param  Config pointer on structure that will be filled up with the region configuration parameters
1093   * @retval HAL state
1094   */
HAL_OTFDEC_RegionGetConfig(OTFDEC_HandleTypeDef * hotfdec,uint32_t RegionIndex,OTFDEC_RegionConfigTypeDef * Config)1095 HAL_StatusTypeDef HAL_OTFDEC_RegionGetConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex,
1096                                              OTFDEC_RegionConfigTypeDef *Config)
1097 {
1098   OTFDEC_Region_TypeDef *region;
1099   uint32_t address;
1100 
1101   /* Check the parameters */
1102   assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
1103   assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
1104 
1105   if (Config == NULL)
1106   {
1107     return HAL_ERROR;
1108   }
1109   else
1110   {
1111     /* Take Lock */
1112     __HAL_LOCK(hotfdec);
1113 
1114     address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
1115     region = (OTFDEC_Region_TypeDef *)address;
1116 
1117     /* Read Nonce */
1118     Config->Nonce[0] = READ_REG(region->REG_NONCER0);
1119     Config->Nonce[1] = READ_REG(region->REG_NONCER1);
1120 
1121     /* Read Addresses */
1122     Config->StartAddress = READ_REG(region->REG_START_ADDR);
1123     Config->EndAddress = READ_REG(region->REG_END_ADDR);
1124 
1125     /* Read Version */
1126     Config->Version = (uint16_t)(READ_REG(region->REG_CONFIGR) &
1127                                  OTFDEC_REG_CONFIGR_VERSION) >> OTFDEC_REG_CONFIGR_VERSION_Pos;
1128 
1129     /* Release Lock */
1130     __HAL_UNLOCK(hotfdec);
1131 
1132     /* Status is okay */
1133     return HAL_OK;
1134   }
1135 }
1136 
1137 
1138 /**
1139   * @}
1140   */
1141 
1142 /**
1143   * @}
1144   */
1145 
1146 #endif /* OTFDEC1 */
1147 
1148 #endif /* HAL_OTFDEC_MODULE_ENABLED */
1149 
1150 
1151 /**
1152   * @}
1153   */
1154 
1155 /**
1156   * @}
1157   */
1158