1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_hal_hash.c
4   * @author  MCD Application Team
5   * @brief   HASH HAL module driver.
6   *          This file provides firmware functions to manage HASH peripheral
7   *
8   ******************************************************************************
9   * @attention
10   *
11   * Copyright (c) 2022 STMicroelectronics.
12   * All rights reserved.
13   *
14   * This software is licensed under terms that can be found in the LICENSE file
15   * in the root directory of this software component.
16   * If no LICENSE file comes with this software, it is provided AS-IS.
17   *
18   ******************************************************************************
19   @verbatim
20  ===============================================================================
21                      ##### How to use this driver #####
22  ===============================================================================
23    [..]
24     The HASH HAL driver can be used as follows:
25 
26     (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
27         (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
28         (##) When resorting to interrupt-based APIs (e.g. HAL_HASH_Start_IT())
29             (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
30             (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
31             (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler() API
32         (##) When resorting to DMA-based APIs  (e.g. HAL_HASH_Start_DMA())
33             (+++) Enable the DMA interface clock
34             (+++) Configure and enable one DMA to manage data transfer from
35                 memory to peripheral (input DMA). Managing data transfer from
36                 peripheral to memory can be performed only using CPU.
37             (+++) Associate the initialized DMA handle to the HASH DMA handle
38                 using  __HAL_LINKDMA()
39             (+++) Configure the priority and enable the NVIC for the transfer complete
40                 interrupt on the DMA: use
41                  HAL_NVIC_SetPriority() and
42                  HAL_NVIC_EnableIRQ()
43 
44     (#)Initialize the HASH HAL using HAL_HASH_Init(). This function:
45         (##) resorts to HAL_HASH_MspInit() for low-level initialization,
46         (##) configures the data type: no swap, half word swap, bit swap or byte swap,
47         (##) configures the Algorithm : MD5, SHA1 or SHA2
48 
49     (#)Three processing schemes are available:
50         (##) Polling mode: processing APIs are blocking functions
51              i.e. they process the data and wait till the digest computation is finished,
52              e.g. HAL_HASH_Start() for HASH or HAL_HMAC_Start() for HMAC
53         (##) Interrupt mode: processing APIs are not blocking functions
54                 i.e. they process the data under interrupt,
55                 e.g. HAL_HASH_Start_IT() for HASH or HAL_HMAC_Start_IT() for HMAC
56         (##) DMA mode: processing APIs are not blocking functions and the CPU is
57              not used for data transfer i.e. the data transfer is ensured by DMA,
58                 e.g. HAL_HASH_Start_DMA() for HASH or HAL_HMAC_Start_DMA() for HMAC.
59 
60     (#)When the processing function is called after HAL_HASH_Init(), the HASH peripheral is
61        initialized and processes the buffer fed in input. When the input data have all been
62        fed to the Peripheral, the digest computation can start.
63 
64     (#)Multi-buffer processing HASH and HMAC are possible in polling, interrupt and DMA modes.
65         (##) In polling mode, API HAL_HASH_Accumulate()/HAL_HASH_HMAC_Accumulate() must be called
66              for each input buffer, except for the last one.
67              User must resort to HAL_HASH_AccumulateLast()/HAL_HASH_HMAC_AccumulateLast()
68              to enter the last one and retrieve as well the computed digest.
69 
70         (##) In interrupt mode, API HAL_HASH_Accumulate_IT()/HAL_HASH_HMAC_Accumulate_IT() must
71              be called for each input buffer, except for the last one.
72              User must resort to HAL_HASH_AccumulateLast_IT()/HAL_HASH_HMAC_AccumulateLast_IT()
73              to enter the last one and retrieve as well the computed digest.
74 
75         (##) In DMA mode, once initialization is done, MDMAT bit must be set through
76              __HAL_HASH_SET_MDMAT() macro.
77              From that point, each buffer can be fed to the Peripheral through HAL_HASH_Start_DMA() API
78              for HASH and HAL_HASH_HMAC_Start_DMA() API for HMAC .
79              Before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT()
80              macro then wrap-up the HASH processing in feeding the last input buffer through the
81              same API HAL_HASH_Start_DMA()for HASH and HAL_HASH_HMAC_Start_DMA() API for HMAC and
82              retrieve as well the computed digest.
83 
84     (#)To use this driver (version 2.0.0) with application developed with old driver (version 1.0.0) user have to:
85         (##) Add Algorithm as parameter like DataType or KeySize.
86         (##) Use new API HAL_HASH_Start() for HASH and HAL_HASH_HMAC_Start() for HMAC processing instead of old API
87              like HAL_HASH_SHA1_Start and HAL_HMAC_SHA1_Start.
88 
89 
90   @endverbatim
91   ******************************************************************************
92   */
93 
94 /* Includes ------------------------------------------------------------------*/
95 #include "stm32h5xx_hal.h"
96 
97 
98 /** @addtogroup STM32H5xx_HAL_Driver
99   * @{
100   */
101 
102 #if defined (HASH)
103 
104 /** @defgroup HASH  HASH
105   * @brief HASH HAL module driver.
106   * @{
107   */
108 
109 #ifdef HAL_HASH_MODULE_ENABLED
110 
111 /* Private typedef -----------------------------------------------------------*/
112 /* Private define ------------------------------------------------------------*/
113 /** @defgroup HASH_Private_Defines HASH Private Defines
114   * @{
115   */
116 #define HASH_TIMEOUTVALUE                         1000U  /*!< Time-out value  */
117 /**
118   * @}
119   */
120 
121 /** @defgroup HASH_Number_Of_CSR_Registers HASH Number of Context Swap Registers
122   * @{
123   */
124 #if defined(HASH_ALGOSELECTION_SHA512)
125 #define HASH_NUMBER_OF_CSR_REGISTERS              103U /*!< Number of Context Swap Registers */
126 #else
127 #define HASH_NUMBER_OF_CSR_REGISTERS              54U                          /*!< Number of Context Swap Registers */
128 #endif /* HASH_ALGOSELECTION_SHA512 */
129 /**
130   * @}
131   */
132 
133 /* Private Constants ---------------------------------------------------------*/
134 /* Private macro -------------------------------------------------------------*/
135 /* Private variables ---------------------------------------------------------*/
136 /* Private function prototypes -----------------------------------------------*/
137 /** @defgroup HASH_Private_Functions HASH Private Functions
138   * @{
139   */
140 static void HASH_GetDigest(HASH_HandleTypeDef *hhash, uint8_t *pMsgDigest, uint8_t Size);
141 static void HASH_WriteData(HASH_HandleTypeDef *hhash, const uint8_t *pInBuffer, uint32_t Size);
142 static HAL_StatusTypeDef HASH_WriteData_IT(HASH_HandleTypeDef *hhash);
143 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
144 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
145 static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status,
146                                                      uint32_t Timeout);
147 /**
148   * @}
149   */
150 
151 /* Exported functions ---------------------------------------------------------*/
152 
153 /** @defgroup HASH_Exported_Functions HASH Exported Functions
154   * @{
155   */
156 
157 /** @defgroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions
158   *  @brief    Initialization and configuration functions.
159   *
160 @verbatim
161  ===============================================================================
162               ##### Initialization and de-initialization functions #####
163  ===============================================================================
164     [..]  This section provides functions allowing to:
165       (+) Initialize the HASH according to the specified parameters
166           in the HASH_InitTypeDef and create the associated handle
167       (+) DeInitialize the HASH peripheral
168       (+) Initialize the HASH MCU Specific Package (MSP)
169       (+) DeInitialize the HASH MSP
170       (+) Configure HASH (HAL_HASH_SetConfig) with the specified parameters in the HASH_ConfigTypeDef
171           Parameters which are configured in This section are :
172           (+) Data Type : no swap, half word swap, bit swap or byte swap
173           (+) Algorithm : MD5,SHA1 or SHA2
174       (+) Get HASH configuration (HAL_HASH_GetConfig) from the specified parameters in the HASH_HandleTypeDef
175 
176 @endverbatim
177   * @{
178   */
179 
180 /**
181   * @brief  Initializes the HASH according to the specified parameters in the
182             HASH_HandleTypeDef and create the associated handle.
183   * @note   Only Algorithm and DATATYPE bits of HASH Peripheral are set by HAL_HASH_Init(),
184   *         other configuration bits are set by HASH or HMAC processing APIs.
185   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
186   *         the configuration information for HASH module.
187   * @retval HAL status
188   */
HAL_HASH_Init(HASH_HandleTypeDef * hhash)189 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
190 {
191   uint32_t cr_value;
192 
193   /* Check the hash handle allocation */
194   if (hhash == NULL)
195   {
196     return HAL_ERROR;
197   }
198 
199   /* Check the parameters */
200   assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
201   assert_param(IS_HASH_ALGORITHM(hhash->Init.Algorithm));
202 
203 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
204   if (hhash->State == HAL_HASH_STATE_RESET)
205   {
206     /* Allocate lock resource and initialize it */
207     hhash->Lock = HAL_UNLOCKED;
208 
209     /* Reset Callback pointers in HAL_HASH_STATE_RESET only */
210     hhash->InCpltCallback =  HAL_HASH_InCpltCallback;     /* Legacy weak InCpltCallback */
211     hhash->DgstCpltCallback =  HAL_HASH_DgstCpltCallback; /* Legacy weak DgstCpltCallback */
212     hhash->ErrorCallback =  HAL_HASH_ErrorCallback;       /* Legacy weak ErrorCallback */
213     if (hhash->MspInitCallback == NULL)
214     {
215       hhash->MspInitCallback = HAL_HASH_MspInit;
216     }
217 
218     /* Init the low level hardware */
219     hhash->MspInitCallback(hhash);
220   }
221 #else
222   if (hhash->State == HAL_HASH_STATE_RESET)
223   {
224     /* Allocate lock resource and initialize it */
225     hhash->Lock = HAL_UNLOCKED;
226 
227     /* Init the low level hardware */
228     HAL_HASH_MspInit(hhash);
229   }
230 #endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */
231 
232   /* Set the key size, data type and Algorithm */
233   cr_value = (uint32_t)(hhash->Init.DataType | hhash->Init.Algorithm);
234   /* Set the key size, data type, algorithm and mode */
235   MODIFY_REG(hhash->Instance->CR, HASH_CR_DATATYPE | HASH_CR_ALGO | HASH_CR_INIT, cr_value);
236 
237   /* Change HASH phase to Ready */
238   hhash->Phase = HAL_HASH_PHASE_READY;
239 
240   /* Change HASH state to Ready */
241   hhash->State = HAL_HASH_STATE_READY;
242 
243   /* Reset error code field */
244   hhash->ErrorCode = HAL_HASH_ERROR_NONE;
245 
246 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
247   /* Reset suspension request flag */
248   hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
249 #endif /* (USE_HAL_HASH_SUSPEND_RESUME) */
250   /* Return function status */
251   return HAL_OK;
252 }
253 
254 /**
255   * @brief  DeInitialize the HASH peripheral.
256   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
257   *         the configuration information for HASH module.
258   * @retval HAL status
259   */
HAL_HASH_DeInit(HASH_HandleTypeDef * hhash)260 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
261 {
262   /* Check the HASH handle allocation */
263   if (hhash == NULL)
264   {
265     return HAL_ERROR;
266   }
267 
268   /* Change the default HASH phase */
269   hhash->Phase = HAL_HASH_PHASE_READY;
270 
271   /* Reset HashInCount */
272   hhash->HashInCount = 0U;
273 
274   /* Reset multi buffers accumulation flag */
275   hhash->Accumulation = 0U;
276 
277 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
278   if (hhash->MspDeInitCallback == NULL)
279   {
280     hhash->MspDeInitCallback = HAL_HASH_MspDeInit;
281   }
282 
283   /* DeInit the low level hardware */
284   hhash->MspDeInitCallback(hhash);
285 #else
286   /* DeInit the low level hardware: CLOCK, NVIC */
287   HAL_HASH_MspDeInit(hhash);
288 #endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */
289 
290   /* Set the HASH state to Ready */
291   hhash->State = HAL_HASH_STATE_RESET;
292 
293   __HAL_UNLOCK(hhash);
294 
295   return HAL_OK;
296 }
297 
298 /**
299   * @brief  Configure the HASH according to the specified
300   *         parameters in the HASH_ConfigTypeDef
301   * @param  hcryp pointer to a HASH_HandleTypeDef structure
302   * @param  pConf pointer to a HASH_ConfigTypeDef structure that contains
303   *         the configuration information for HASH module
304   * @retval HAL status
305   */
HAL_HASH_SetConfig(HASH_HandleTypeDef * hhash,HASH_ConfigTypeDef * pConf)306 HAL_StatusTypeDef HAL_HASH_SetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf)
307 {
308   uint32_t cr_value;
309 
310   /* Check the HASH handle allocation */
311   if ((hhash == NULL) || (pConf == NULL))
312   {
313     return HAL_ERROR;
314   }
315 
316   /* Check parameters */
317   assert_param(IS_HASH_DATATYPE(pConf->DataType));
318   assert_param(IS_HASH_ALGORITHM(pConf->Algorithm));
319 
320   if (hhash->State == HAL_HASH_STATE_READY)
321   {
322     /* Change the HASH state */
323     hhash->State = HAL_HASH_STATE_BUSY;
324     __HAL_LOCK(hhash);
325 
326     /* Set HASH parameters */
327     hhash->Init.DataType   = pConf->DataType;
328     hhash->Init.pKey       = pConf->pKey;
329     hhash->Init.Algorithm  = pConf->Algorithm;
330     hhash->Init.KeySize    = pConf->KeySize;
331 
332     /* Set the key size, data type and Algorithm */
333     cr_value = (uint32_t)(hhash->Init.DataType | hhash->Init.Algorithm);
334     /* Set the key size, data type, algorithm and mode */
335     MODIFY_REG(hhash->Instance->CR, HASH_CR_DATATYPE | HASH_CR_ALGO | HASH_CR_INIT, cr_value);
336 
337     /* Change HASH phase to Ready */
338     hhash->Phase = HAL_HASH_PHASE_READY;
339 
340     /* Change HASH state to Ready */
341     hhash->State = HAL_HASH_STATE_READY;
342 
343     /* Reset error code field */
344     hhash->ErrorCode = HAL_HASH_ERROR_NONE;
345 
346     __HAL_UNLOCK(hhash);
347 
348     return HAL_OK;
349 
350   }
351   else
352   {
353     /* Busy error code field */
354     hhash->ErrorCode |= HAL_HASH_ERROR_BUSY;
355     return HAL_ERROR;
356   }
357 }
358 
359 /**
360   * @brief  Get HASH Configuration parameters in associated handle
361   * @param  pConf pointer to a HASH_HandleTypeDef structure
362   * @param  hhash pointer to a HASH_ConfigTypeDef structure that contains
363   *         the configuration information for HASH module
364   * @retval HAL status
365   */
HAL_HASH_GetConfig(HASH_HandleTypeDef * hhash,HASH_ConfigTypeDef * pConf)366 HAL_StatusTypeDef HAL_HASH_GetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf)
367 {
368 
369   /* Check the HASH handle allocation */
370   if ((hhash == NULL) || (pConf == NULL))
371   {
372     return HAL_ERROR;
373   }
374 
375   if (hhash->State == HAL_HASH_STATE_READY)
376   {
377     /* Change the HASH state */
378     hhash->State = HAL_HASH_STATE_BUSY;
379     __HAL_LOCK(hhash);
380 
381     /* Set HASH parameters */
382     pConf->DataType   = hhash->Init.DataType;
383     pConf->pKey       = hhash->Init.pKey;
384     pConf->Algorithm  = hhash->Init.Algorithm;
385     pConf->KeySize    = hhash->Init.KeySize;
386 
387     /* Change HASH state to Ready */
388     hhash->State = HAL_HASH_STATE_READY;
389     __HAL_UNLOCK(hhash);
390 
391     return HAL_OK;
392 
393   }
394   else
395   {
396     /* Busy error code field */
397     hhash->ErrorCode |= HAL_HASH_ERROR_BUSY;
398     return HAL_ERROR;
399   }
400 }
401 
402 /**
403   * @brief  Initialize the HASH MSP.
404   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
405   *         the configuration information for HASH module.
406   * @retval None
407   */
HAL_HASH_MspInit(HASH_HandleTypeDef * hhash)408 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
409 {
410   /* Prevent unused argument(s) compilation warning */
411   UNUSED(hhash);
412 
413   /* NOTE : This function should not be modified; when the callback is needed,
414             HAL_HASH_MspInit() can be implemented in the user file.
415    */
416 }
417 
418 /**
419   * @brief  DeInitialize the HASH MSP.
420   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
421   *         the configuration information for HASH module.
422   * @retval None
423   */
HAL_HASH_MspDeInit(HASH_HandleTypeDef * hhash)424 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
425 {
426   /* Prevent unused argument(s) compilation warning */
427   UNUSED(hhash);
428 
429   /* NOTE : This function should not be modified; when the callback is needed,
430             HAL_HASH_MspDeInit() can be implemented in the user file.
431    */
432 }
433 
434 
435 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
436 /**
437   * @brief  Register a User HASH Callback
438   *         To be used instead of the weak (surcharged) predefined callback
439   * @param hhash HASH handle
440   * @param CallbackID ID of the callback to be registered
441   *        This parameter can be one of the following values:
442   *          @arg HAL_HASH_INPUTCPLT_CB_ID input completion callback ID
443   *          @arg HAL_HASH_DGSTCPLT_CB_ID digest computation completion callback ID
444   *          @arg HAL_HASH_ERROR_CB_ID error callback ID
445   *          @arg HAL_HASH_MSPINIT_CB_ID MspInit callback ID
446   *          @arg HAL_HASH_MSPDEINIT_CB_ID MspDeInit callback ID
447   * @param pCallback pointer to the Callback function
448   * @retval status
449   */
HAL_HASH_RegisterCallback(HASH_HandleTypeDef * hhash,HAL_HASH_CallbackIDTypeDef CallbackID,pHASH_CallbackTypeDef pCallback)450 HAL_StatusTypeDef HAL_HASH_RegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID,
451                                             pHASH_CallbackTypeDef pCallback)
452 {
453   HAL_StatusTypeDef status = HAL_OK;
454 
455   if (pCallback == NULL)
456   {
457     /* Update the error code */
458     hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
459     return HAL_ERROR;
460   }
461 
462   if (hhash->State == HAL_HASH_STATE_READY)
463   {
464     switch (CallbackID)
465     {
466       case HAL_HASH_INPUTCPLT_CB_ID :
467         hhash->InCpltCallback = pCallback;
468         break;
469 
470       case HAL_HASH_DGSTCPLT_CB_ID :
471         hhash->DgstCpltCallback = pCallback;
472         break;
473 
474       case HAL_HASH_ERROR_CB_ID :
475         hhash->ErrorCallback = pCallback;
476         break;
477 
478       case HAL_HASH_MSPINIT_CB_ID :
479         hhash->MspInitCallback = pCallback;
480         break;
481 
482       case HAL_HASH_MSPDEINIT_CB_ID :
483         hhash->MspDeInitCallback = pCallback;
484         break;
485 
486       default :
487         /* Update the error code */
488         hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
489         /* update return status */
490         status =  HAL_ERROR;
491         break;
492     }
493   }
494   else if (hhash->State == HAL_HASH_STATE_RESET)
495   {
496     switch (CallbackID)
497     {
498       case HAL_HASH_MSPINIT_CB_ID :
499         hhash->MspInitCallback = pCallback;
500         break;
501 
502       case HAL_HASH_MSPDEINIT_CB_ID :
503         hhash->MspDeInitCallback = pCallback;
504         break;
505 
506       default :
507         /* Update the error code */
508         hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
509         /* update return status */
510         status =  HAL_ERROR;
511         break;
512     }
513   }
514   else
515   {
516     /* Update the error code */
517     hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
518     /* update return status */
519     status =  HAL_ERROR;
520   }
521 
522   return status;
523 }
524 
525 /**
526   * @brief  Unregister a HASH Callback
527   *         HASH Callback is redirected to the weak (surcharged) predefined callback
528   * @param hhash HASH handle
529   * @param CallbackID ID of the callback to be unregistered
530   *        This parameter can be one of the following values:
531   *          @arg HAL_HASH_INPUTCPLT_CB_ID HASH input completion Callback ID
532   *          @arg HAL_HASH_DGSTCPLT_CB_ID HASH digest computation completion Callback ID
533   *          @arg HAL_HASH_ERROR_CB_ID HASH error Callback ID
534   *          @arg HAL_HASH_MSPINIT_CB_ID HASH MspInit callback ID
535   *          @arg HAL_HASH_MSPDEINIT_CB_ID HASH MspDeInit callback ID
536   * @retval status
537   */
HAL_HASH_UnRegisterCallback(HASH_HandleTypeDef * hhash,HAL_HASH_CallbackIDTypeDef CallbackID)538 HAL_StatusTypeDef HAL_HASH_UnRegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID)
539 {
540   HAL_StatusTypeDef status = HAL_OK;
541 
542 
543   if (hhash->State == HAL_HASH_STATE_READY)
544   {
545     switch (CallbackID)
546     {
547       case HAL_HASH_INPUTCPLT_CB_ID :
548         hhash->InCpltCallback = HAL_HASH_InCpltCallback;     /* Legacy weak input completion callback */
549         break;
550 
551       case HAL_HASH_DGSTCPLT_CB_ID :
552         hhash->DgstCpltCallback = HAL_HASH_DgstCpltCallback; /* Legacy weak digest computation
553       completion callback */
554         break;
555 
556       case HAL_HASH_ERROR_CB_ID :
557         hhash->ErrorCallback = HAL_HASH_ErrorCallback;       /* Legacy weak error callback */
558         break;
559 
560       case HAL_HASH_MSPINIT_CB_ID :
561         hhash->MspInitCallback = HAL_HASH_MspInit;           /* Legacy weak MspInit Callback */
562         break;
563 
564       case HAL_HASH_MSPDEINIT_CB_ID :
565         hhash->MspDeInitCallback = HAL_HASH_MspDeInit;       /* Legacy weak MspDeInit Callback */
566         break;
567 
568       default :
569         /* Update the error code */
570         hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
571         /* update return status */
572         status =  HAL_ERROR;
573         break;
574     }
575   }
576   else if (hhash->State == HAL_HASH_STATE_RESET)
577   {
578     switch (CallbackID)
579     {
580       case HAL_HASH_MSPINIT_CB_ID :
581         hhash->MspInitCallback = HAL_HASH_MspInit;           /* Legacy weak MspInit Callback */
582         break;
583 
584       case HAL_HASH_MSPDEINIT_CB_ID :
585         hhash->MspDeInitCallback = HAL_HASH_MspDeInit;       /* Legacy weak MspDeInit Callback */
586         break;
587 
588       default :
589         /* Update the error code */
590         hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
591         /* update return status */
592         status =  HAL_ERROR;
593         break;
594     }
595   }
596   else
597   {
598     /* Update the error code */
599     hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
600     /* update return status */
601     status =  HAL_ERROR;
602   }
603 
604   return status;
605 }
606 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
607 
608 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
609 /**
610   * @brief  Save the HASH context in case of processing suspension.
611   * @param  hhash HASH handle.
612   * @param  pMemBuffer pointer to the memory buffer where the HASH context
613   *         is saved.
614   * @note   The IMR, STR, CR then all the CSR registers are saved
615   *         in that order. Only the r/w bits are read to be restored later on.
616   * @note   By default, all the context swap registers (there are
617   *         HASH_NUMBER_OF_CSR_REGISTERS of those) are saved.
618   * @note   pMemBuffer points to a buffer allocated by the user. The buffer size
619   *         must be at least (HASH_NUMBER_OF_CSR_REGISTERS + 3) * 4 uint8 long.
620   * @retval None
621   */
HAL_HASH_Suspend(HASH_HandleTypeDef * hhash,uint8_t * pMemBuffer)622 void HAL_HASH_Suspend(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer)
623 {
624   uint32_t mem_ptr = (uint32_t)pMemBuffer;
625   uint32_t csr_ptr = (uint32_t)(hhash->Instance->CSR);
626   uint32_t i;
627 
628   /* Prevent unused argument(s) compilation warning */
629   UNUSED(hhash);
630 
631   /* Save IMR register content */
632   *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->IMR, HASH_IT_DINI | HASH_IT_DCI);
633   mem_ptr += 4U;
634   /* Save STR register content */
635   *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->STR, HASH_STR_NBLW);
636   mem_ptr += 4U;
637   /* Save CR register content */
638   *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->CR, HASH_CR_DMAE | HASH_CR_DATATYPE | HASH_CR_MODE | HASH_CR_ALGO |
639                                     HASH_CR_LKEY | HASH_CR_MDMAT);
640 
641   mem_ptr += 4U;
642   /* By default, save all CSRs registers */
643   for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--)
644   {
645     *(uint32_t *)(mem_ptr) = *(uint32_t *)(csr_ptr);
646     mem_ptr += 4U;
647     csr_ptr += 4U;
648   }
649   /* Save low-priority block HASH handle parameters */
650   hhash->Init_saved              = hhash->Init;
651   hhash->pHashOutBuffPtr_saved   = hhash->pHashOutBuffPtr;
652   hhash->HashInCount_saved       = hhash->HashInCount;
653   hhash->Size_saved              = hhash->Size;
654   hhash->pHashInBuffPtr_saved    = hhash->pHashInBuffPtr;
655   hhash->Phase_saved             = hhash->Phase;
656   hhash->pHashKeyBuffPtr_saved   = hhash->pHashKeyBuffPtr;
657 }
658 
659 
660 /**
661   * @brief  Restore the HASH context in case of processing resumption.
662   * @param  hhash HASH handle.
663   * @param  pMemBuffer pointer to the memory buffer where the HASH context
664   *         is stored.
665   * @note   The IMR, STR, CR then all the CSR registers are restored
666   *         in that order. Only the r/w bits are restored.
667   * @note   By default, all the context swap registers (HASH_NUMBER_OF_CSR_REGISTERS
668   *         of those) are restored (all of them have been saved by default
669   *         beforehand).
670   * @retval None
671   */
HAL_HASH_Resume(HASH_HandleTypeDef * hhash,uint8_t * pMemBuffer)672 void HAL_HASH_Resume(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer)
673 {
674   uint32_t mem_ptr = (uint32_t)pMemBuffer;
675   uint32_t csr_ptr = (uint32_t)(hhash->Instance->CSR);
676   uint32_t i;
677 
678   /* Prevent unused argument(s) compilation warning */
679   UNUSED(hhash);
680 
681   /* Restore IMR register content */
682   WRITE_REG(hhash->Instance->IMR, (*(uint32_t *)(mem_ptr)));
683   mem_ptr += 4U;
684   /* Restore STR register content */
685   WRITE_REG(hhash->Instance->STR, (*(uint32_t *)(mem_ptr)));
686   mem_ptr += 4U;
687   /* Restore CR register content */
688   WRITE_REG(hhash->Instance->CR, (*(uint32_t *)(mem_ptr)));
689   mem_ptr += 4U;
690 
691   /* Reset the HASH processor before restoring the Context
692   Swap Registers (CSR) */
693   SET_BIT(hhash->Instance->CR, HASH_CR_INIT);
694 
695 
696   /* By default, restore all CSR registers */
697   for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--)
698   {
699     WRITE_REG((*(uint32_t *)(csr_ptr)), (*(uint32_t *)(mem_ptr)));
700     mem_ptr += 4U;
701     csr_ptr += 4U;
702   }
703 
704   /* Restore low-priority block HASH handle parameters */
705   hhash->Init              = hhash->Init_saved;
706   hhash->pHashOutBuffPtr   = hhash->pHashOutBuffPtr_saved;
707   hhash->HashInCount       = hhash->HashInCount_saved;
708   hhash->Size              = hhash->Size_saved;
709   hhash->pHashInBuffPtr    = hhash->pHashInBuffPtr_saved;
710   hhash->Phase             = hhash->Phase_saved;
711   hhash->State             = HAL_HASH_STATE_SUSPENDED;
712   hhash->pHashKeyBuffPtr   = hhash->pHashKeyBuffPtr_saved;
713 }
714 
715 /**
716   * @brief  Initiate HASH processing suspension when in interruption mode.
717   * @param  hhash HASH handle.
718   * @note   Set the handle field SuspendRequest to the appropriate value so that
719   *         the on-going HASH processing is suspended as soon as the required
720   *         conditions are met. Note that the actual suspension is carried out
721   *         by the functions HASH_WriteData() in polling mode and HASH_IT() in
722   *         interruption mode.
723   * @retval None
724   */
HAL_HASH_ProcessSuspend(HASH_HandleTypeDef * hhash)725 HAL_StatusTypeDef HAL_HASH_ProcessSuspend(HASH_HandleTypeDef *hhash)
726 {
727   uint32_t remainingwords; /*remaining number in of source block to be transferred.*/
728   uint32_t nbbytePartialHash  = (((hhash->Instance->SR) >> 16U) * 4U); /* Nb byte  to enter in HASH fifo
729                                                                       to trig a partial HASH computation*/
730   uint32_t sizeinwords;/* number in word of source block to be transferred.*/
731 
732   /* suspension in DMA mode*/
733   if (__HAL_HASH_GET_FLAG(hhash, HASH_FLAG_DMAS) != RESET)
734   {
735     if (hhash->State == HAL_HASH_STATE_READY)
736     {
737       return HAL_ERROR;
738     }
739     else
740     {
741 
742       /* Clear the DMAE bit to disable the DMA interface */
743       CLEAR_BIT(HASH->CR, HASH_CR_DMAE);
744 
745       /* Wait until the last DMA transfer is complete (DMAS = 0 in the HASH_SR register) */
746       if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DMAS, SET, HASH_TIMEOUTVALUE) != HAL_OK)
747       {
748         return HAL_TIMEOUT;
749       }
750 
751       /* At this point, DMA interface is disabled and no transfer is on-going */
752       /* Retrieve from the DMA handle how many words remain to be written */
753       /* DMA3 used, DMA_CBR1_BNDT in bytes, DMA_CSR_FIFOL in words */
754       remainingwords = ((((DMA_Channel_TypeDef *)hhash->hdmain->Instance)->CBR1) \
755                         & DMA_CBR1_BNDT) / 4U;
756       remainingwords += ((((DMA_Channel_TypeDef *)hhash->hdmain->Instance)->CSR) \
757                          & DMA_CSR_FIFOL) >> DMA_CSR_FIFOL_Pos;
758 
759       if (remainingwords <= nbbytePartialHash)
760       {
761         /* No suspension attempted since almost to the end of the transferred data. */
762         /* Best option for user code is to wrap up low priority message hashing     */
763         return HAL_ERROR;
764       }
765 
766       /* Disable DMA channel */
767       /* Note that the Abort function will
768         - Clear the transfer error flags
769         - Unlock
770         - Set the State
771       */
772       if (HAL_DMA_Abort(hhash->hdmain) != HAL_OK)
773       {
774         return HAL_ERROR;
775       }
776 
777       if (__HAL_HASH_GET_FLAG(hhash, HASH_FLAG_DCIS) != RESET)
778       {
779         return HAL_ERROR;
780       }
781 
782       /* Wait until the hash processor is ready (no block is being processed), that is wait for DINIS=1 in HASH_SR */
783       if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DINIS, RESET, HASH_TIMEOUTVALUE) != HAL_OK)
784       {
785         return HAL_TIMEOUT;
786       }
787 
788       /* Compute how many words were supposed to be transferred by DMA */
789       sizeinwords = (((hhash->Size % 4U) != 0U) ? \
790                      ((hhash->Size + 3U) / 4U) : (hhash->Size / 4U));
791       /* Accordingly, update the input pointer that points at the next word to be
792          transferred to the Peripheral by DMA */
793       hhash->pHashInBuffPtr +=  4U * (sizeinwords - remainingwords) ;
794 
795       /* And store in HashInCount the remaining size to transfer (in bytes) */
796       hhash->HashInCount = 4U * remainingwords;
797 
798 
799       hhash->State = HAL_HASH_STATE_SUSPENDED;
800       __HAL_UNLOCK(hhash);
801       return HAL_OK;
802     }
803 
804   }
805   else /* suspension when in interruption mode*/
806   {
807     /* Set Handle Suspend Request field */
808     hhash->SuspendRequest = HAL_HASH_SUSPEND;
809     return HAL_OK;
810   }
811 }
812 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
813 /**
814   * @}
815   */
816 
817 
818 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions
819   *  @brief   HASH processing functions using different mode.
820   *
821 @verbatim
822  ===============================================================================
823                  ##### HASH processing functions #####
824  ===============================================================================
825     [..]  This section provides API allowing to calculate the hash value using
826           one of the HASH algorithms supported by the peripheral.
827 
828     [..] For a single buffer to be hashed, user can resort to one of three processing
829          functions available .
830       (+) Polling mode : HAL_HASH_Start()
831       (+) Interrupt mode : HAL_HASH_Start_IT()
832       (+) DMA mode : HAL_HASH_Start_DMA()
833 
834     [..]  In case of multi-buffer HASH processing (a single digest is computed while
835           several buffers are fed to the Peripheral), the user can resort to successive calls
836           to :
837       (+) Polling mode : HAL_HASH_Accumulate() and wrap-up the digest computation by a call
838           to HAL_HASH_AccumulateLast()
839       (+) Interrupt mode : HAL_HASH_Accumulate_IT() and wrap-up the digest computation by a call
840           to HAL_HASH_AccumulateLast_IT()
841       (+) DMA mode : HAL_HASH_Start_DMA(), MDMAT bit must be set through __HAL_HASH_SET_MDMAT() macro,
842           before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT()
843           macro then wrap-up the HASH processing in feeding the last input buffer through the
844           same API HAL_HASH_Start_DMA()
845 
846 @endverbatim
847   * @{
848   */
849 
850 /**
851   * @brief  HASH peripheral processes in polling mode pInBuffer then reads the computed digest.
852   * @param  hhash HASH handle.
853   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
854   * @param  Size length of the input buffer in bytes.
855   * @param  pOutBuffer pointer to the computed digest.
856   * @param  Timeout specify timeout value
857   * @retval HAL status
858   */
HAL_HASH_Start(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer,uint32_t Timeout)859 HAL_StatusTypeDef HAL_HASH_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
860                                  uint8_t *const pOutBuffer, uint32_t Timeout)
861 {
862   /* Check the hash handle allocation */
863   if (hhash == NULL)
864   {
865     return HAL_ERROR;
866   }
867 
868   /* Check if peripheral is ready to start process */
869   if (hhash->State == HAL_HASH_STATE_READY)
870   {
871     /* Process Locked */
872     __HAL_LOCK(hhash);
873 
874     /* Change the HASH state */
875     hhash->State = HAL_HASH_STATE_BUSY;
876 
877     /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
878     hhash->pHashInBuffPtr = pInBuffer;
879     hhash->pHashOutBuffPtr = pOutBuffer;
880     hhash->HashInCount =  0U;
881     hhash->Size = Size;
882 
883     /* Set HASH mode */
884     CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
885     /* Reset the HASH processor core */
886     MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
887 
888     /* Configure the number of valid bits in last word of the message */
889     MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
890 
891     /* Set the phase */
892     hhash->Phase = HAL_HASH_PHASE_PROCESS;
893 
894     HASH_WriteData(hhash, pInBuffer, Size);
895 
896     /* Start the message padding then the Digest calculation */
897     SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
898 
899     /* Wait for digest calculation completion status(DCIS) flag to be set */
900     if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
901     {
902       return HAL_ERROR;
903     }
904 
905     /* Read the message digest */
906     HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash));
907 
908     /* Change the HASH state */
909     hhash->State = HAL_HASH_STATE_READY;
910 
911     /* Reset HASH state machine */
912     hhash->Phase = HAL_HASH_PHASE_READY;
913 
914     /* Process Unlocked */
915     __HAL_UNLOCK(hhash);
916 
917     /* Return function status */
918     return HAL_OK;
919   }
920   else
921   {
922     return HAL_BUSY;
923   }
924 }
925 
926 
927 /**
928   * @brief  HASH peripheral processes in interrupt mode pInBuffer then reads the computed digest.
929   * @param  hhash HASH handle.
930   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
931   * @param  Size length of the input buffer in bytes.
932   * @param  pOutBuffer pointer to the computed digest.
933   * @retval HAL status
934   */
HAL_HASH_Start_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)935 HAL_StatusTypeDef HAL_HASH_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
936                                     uint8_t *const pOutBuffer)
937 {
938   HAL_StatusTypeDef status;
939   HAL_HASH_StateTypeDef temp_state;
940 
941   /* Check the hash handle allocation */
942   if (hhash == NULL)
943   {
944     return HAL_ERROR;
945   }
946 
947   /* Check if peripheral is ready to start process or suspended */
948   temp_state = hhash->State;
949   if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED))
950   {
951     /* Process Locked */
952     __HAL_LOCK(hhash);
953 
954     if (hhash->State == HAL_HASH_STATE_READY)
955     {
956       /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
957       hhash->HashInCount =  0U;
958       hhash->pHashInBuffPtr = pInBuffer;
959       hhash->pHashOutBuffPtr = pOutBuffer;
960       hhash->Size = Size;
961 
962       /* Set HASH mode */
963       CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
964       /* Reset the HASH processor core */
965       MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
966 
967       /* Configure the number of valid bits in last word of the message */
968       MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
969     }
970     /* Change the HASH state */
971     hhash->State = HAL_HASH_STATE_BUSY;
972     /* Set the phase */
973     hhash->Phase = HAL_HASH_PHASE_PROCESS;
974 
975     /* Enable the specified HASH interrupt*/
976     __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
977 
978     status = HASH_WriteData_IT(hhash);
979   }
980   else
981   {
982     status =  HAL_BUSY;
983   }
984   /* Return function status */
985   return status;
986 }
987 
988 /**
989   * @brief  HASH peripheral processes in DMA mode pInBuffer then reads the computed digest.
990   * @note   Multi-buffer HASH processing is possible, consecutive calls to HAL_HASH_Start_DMA
991   *         (MDMAT bit must be set) can be used to feed several input buffers
992   *         back-to-back to the Peripheral that will yield a single
993   *         HASH signature once all buffers have been entered. Wrap-up of input
994   *         buffers feeding and retrieval of digest is done by a call to
995   *         HAL_HASH_Start_DMA (MDMAT bit must be reset).
996   * @param  hhash HASH handle.
997   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
998   * @param  Size length of the input buffer in bytes (must be a multiple of 4 in
999   *         case of Multi-buffer and not last buffer).
1000   * @param  pOutBuffer pointer to the computed digest.
1001   * @retval HAL status
1002   */
HAL_HASH_Start_DMA(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)1003 HAL_StatusTypeDef HAL_HASH_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1004                                      uint8_t *const pOutBuffer)
1005 {
1006   HAL_StatusTypeDef status;
1007   HAL_HASH_StateTypeDef temp_state;
1008 
1009   /* Check the hash handle allocation */
1010   if (hhash == NULL)
1011   {
1012     return HAL_ERROR;
1013   }
1014 
1015   /* Check if peripheral is ready to start process or suspended  */
1016   temp_state = hhash->State;
1017   if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED))
1018   {
1019 
1020     /* Process Locked */
1021     __HAL_LOCK(hhash);
1022 
1023     /* Check if initialization phase has not been already performed */
1024     if (hhash->State == HAL_HASH_STATE_READY)
1025     {
1026       /* Change the HASH state */
1027       hhash->State = HAL_HASH_STATE_BUSY;
1028 
1029       /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1030       hhash->HashInCount =  0U;
1031       hhash->pHashInBuffPtr = pInBuffer;
1032       hhash->pHashOutBuffPtr = pOutBuffer;
1033       hhash->HashInCount =  0U;
1034       hhash->Size = Size;
1035 
1036       /* Check if initialization phase has already been performed.
1037       If Phase is already set to HAL_HASH_PHASE_PROCESS, this means the
1038       API is processing a new input data message in case of multi-buffer HASH
1039       computation. */
1040       if (hhash->Phase == HAL_HASH_PHASE_READY)
1041       {
1042         /* Set HASH mode */
1043         CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1044         /* Reset the HASH processor core */
1045         MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1046 
1047         /* Set the phase */
1048         hhash->Phase = HAL_HASH_PHASE_PROCESS;
1049       }
1050       /* Configure the number of valid bits in last word of the message */
1051       if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U)
1052       {
1053         /* Configure the number of valid bits in last word of the message */
1054         MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Size) % 4U));
1055       }
1056       else
1057       {
1058         /* Configure the number of valid bits in last word of the message */
1059         MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U);
1060       }
1061 
1062     }
1063     else /* HAL_HASH_STATE_SUSPENDED */
1064     {
1065       /* Change the HASH state */
1066       hhash->State = HAL_HASH_STATE_BUSY;
1067       /*only part not yet hashed to compute  */
1068       hhash->Size = hhash->HashInCount;
1069     }
1070     /* Set the HASH DMA transfer complete callback */
1071     hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1072     /* Set the DMA error callback */
1073     hhash->hdmain->XferErrorCallback = HASH_DMAError;
1074 
1075     if ((hhash->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1076     {
1077       if ((hhash->hdmain->LinkedListQueue != NULL) && (hhash->hdmain->LinkedListQueue->Head != NULL))
1078       {
1079         /* Enable the DMA channel */
1080         hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET]\
1081           = ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : (hhash->Size));
1082         hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET]\
1083           = (uint32_t)(hhash->pHashInBuffPtr);  /* Set DMA source address */
1084         hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET]\
1085           = (uint32_t)&hhash->Instance->DIN; /* Set DMA destination address */
1086 
1087         status = HAL_DMAEx_List_Start_IT(hhash->hdmain);
1088       }
1089       else
1090       {
1091         /* Return error status */
1092         status = HAL_ERROR;
1093       }
1094     }
1095     else
1096     {
1097       status = HAL_DMA_Start_IT(hhash->hdmain, (uint32_t)pInBuffer, (uint32_t)&hhash->Instance->DIN, \
1098                                 ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : \
1099                                  (hhash->Size)));
1100     }
1101     if (status != HAL_OK)
1102     {
1103       /* DMA error code field */
1104       hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
1105 
1106       /* Return error */
1107 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
1108       /*Call registered error callback*/
1109       hhash->ErrorCallback(hhash);
1110 #else
1111       /*Call legacy weak error callback*/
1112       HAL_HASH_ErrorCallback(hhash);
1113 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1114     }
1115     else
1116     {
1117       /* Enable DMA requests */
1118       SET_BIT(hhash->Instance->CR, HASH_CR_DMAE);
1119     }
1120   }
1121   else
1122   {
1123     status =  HAL_BUSY;
1124 
1125   }
1126 
1127   /* Return function status */
1128   return status;
1129 }
1130 
1131 
1132 /**
1133   * @brief  HASH peripheral processes in polling mode several input buffers.
1134   * @note   Consecutive calls to HAL_HASH_Accumulate() can be used to feed
1135   *         several input buffers back-to-back to the Peripheral that will yield a single
1136   *         HASH signature once all buffers have been entered. Wrap-up of input
1137   *         buffers feeding and retrieval of digest is done by a call to
1138   *         HAL_HASH_AccumulateLast()
1139   * @param  hhash HASH handle.
1140   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1141   * @param  Size length of the input buffer in bytes and a multiple of 4.
1142   * @param  Timeout specify timeout value
1143   * @retval HAL status
1144   */
HAL_HASH_Accumulate(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint32_t Timeout)1145 HAL_StatusTypeDef HAL_HASH_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1146                                       uint32_t Timeout)
1147 {
1148   HAL_HASH_StateTypeDef temp_state;
1149 
1150   /* Check the hash handle allocation and buffer length multiple of 4 */
1151   if ((hhash == NULL) || ((Size % 4U) != 0U))
1152   {
1153     return HAL_ERROR;
1154   }
1155 
1156   /* Check if peripheral is ready to start process or suspended  */
1157   temp_state = hhash->State;
1158   if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED))
1159   {
1160     /* Process Locked */
1161     __HAL_LOCK(hhash);
1162 
1163     /* Change the HASH state */
1164     hhash->State = HAL_HASH_STATE_BUSY;
1165 
1166     /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1167     hhash->pHashInBuffPtr = pInBuffer;
1168     hhash->HashInCount =  0U;
1169     hhash->Size = Size;
1170 
1171     if (hhash->Phase == HAL_HASH_PHASE_READY)
1172     {
1173       /* Set HASH mode */
1174       CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1175       /* Reset the HASH processor core */
1176       MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1177 
1178       /* Set the phase */
1179       hhash->Phase = HAL_HASH_PHASE_PROCESS;
1180     }
1181     HASH_WriteData(hhash, pInBuffer, Size);
1182 
1183     /* Wait for BUSY flag to be cleared */
1184     if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1185     {
1186       return HAL_ERROR;
1187     }
1188     /* Change the HASH state */
1189     hhash->State = HAL_HASH_STATE_READY;
1190 
1191     /* Process Unlocked */
1192     __HAL_UNLOCK(hhash);
1193 
1194     return HAL_OK;
1195   }
1196   else
1197   {
1198     return HAL_BUSY;
1199   }
1200 }
1201 
1202 
1203 /**
1204   * @brief  End computation of a single HASH signature after several calls to HAL_HASH_Accumulate() API.
1205   * @note   Digest is available in pOutBuffer
1206   * @param  hhash HASH handle.
1207   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1208   * @param  Size length of the input buffer in bytes.
1209   * @param  pOutBuffer pointer to the computed digest.
1210   * @param  Timeout specify timeout value
1211   * @retval HAL status
1212   */
HAL_HASH_AccumulateLast(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer,uint32_t Timeout)1213 HAL_StatusTypeDef HAL_HASH_AccumulateLast(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1214                                           uint8_t *const pOutBuffer, uint32_t Timeout)
1215 {
1216   HAL_HASH_StateTypeDef temp_state;
1217 
1218   /* Check the hash handle allocation */
1219   if (hhash == NULL)
1220   {
1221     return HAL_ERROR;
1222   }
1223 
1224   /* Check if peripheral is ready to start process or suspended */
1225   temp_state = hhash->State;
1226   if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED))
1227   {
1228     /* Process Locked */
1229     __HAL_LOCK(hhash);
1230 
1231     /* Change the HASH state */
1232     hhash->State = HAL_HASH_STATE_BUSY;
1233 
1234     /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1235     hhash->pHashInBuffPtr = pInBuffer;
1236     hhash->pHashOutBuffPtr = pOutBuffer;
1237     hhash->HashInCount =  0U;
1238     hhash->Size = Size;
1239 
1240     if (hhash->Phase == HAL_HASH_PHASE_READY)
1241     {
1242       /* Set HASH mode */
1243       CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1244       /* Reset the HASH processor core */
1245       MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1246 
1247       /* Set the phase */
1248       hhash->Phase = HAL_HASH_PHASE_PROCESS;
1249     }
1250     /* Configure the number of valid bits in last word of the message */
1251     MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
1252 
1253 
1254     HASH_WriteData(hhash, pInBuffer, Size);
1255 
1256     /* Start the message padding then the Digest calculation */
1257     SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1258 
1259     /* Wait for digest calculation completion status(DCIS) flag to be set */
1260     if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
1261     {
1262       return HAL_ERROR;
1263     }
1264     /* Read the message digest */
1265     HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash));
1266 
1267     /* Change the HASH state */
1268     hhash->State = HAL_HASH_STATE_READY;
1269 
1270     /* Reset HASH state machine */
1271     hhash->Phase = HAL_HASH_PHASE_READY;
1272     hhash->Accumulation = 0;
1273     /* Process Unlocked */
1274     __HAL_UNLOCK(hhash);
1275 
1276     return HAL_OK;
1277   }
1278   else
1279   {
1280     return HAL_BUSY;
1281   }
1282 }
1283 
1284 /**
1285   * @brief  HASH peripheral processes in interrupt mode several input buffers.
1286   * @note   Consecutive calls to HAL_HASH_Accumulate_IT() can be used to feed
1287   *         several input buffers back-to-back to the Peripheral that will yield a single
1288   *         HASH signature once all buffers have been entered. Wrap-up of input
1289   *         buffers feeding and retrieval of digest is done by a call to
1290   *         HAL_HASH_AccumulateLast_IT()
1291   * @param  hhash HASH handle.
1292   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1293   * @param  Size length of the input buffer in bytes and a multiple of 4.
1294   * @retval HAL status
1295   */
HAL_HASH_Accumulate_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size)1296 HAL_StatusTypeDef HAL_HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1297 {
1298   HAL_StatusTypeDef status;
1299 
1300   /* Check the hash handle allocation */
1301   if ((hhash == NULL) || ((Size % 4U) != 0U))
1302   {
1303     return HAL_ERROR;
1304   }
1305 
1306   /* Check if peripheral is ready to start process */
1307   if (hhash->State == HAL_HASH_STATE_READY)
1308   {
1309     /* Process Locked */
1310     __HAL_LOCK(hhash);
1311 
1312     /* Change the HASH state */
1313     hhash->State = HAL_HASH_STATE_BUSY;
1314 
1315     /* Reset HashInCount and Initialize Size and pHashInBuffPtr parameters  */
1316     hhash->pHashInBuffPtr = pInBuffer;
1317     hhash->HashInCount =  0U;
1318     hhash->Size = Size;
1319     /* Set multi buffers accumulation flag */
1320     hhash->Accumulation = 1U;
1321 
1322     if (hhash->Phase == HAL_HASH_PHASE_READY)
1323     {
1324       /* Set HASH mode */
1325       CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1326       /* Reset the HASH processor core */
1327       MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1328       /* Set the phase */
1329       hhash->Phase = HAL_HASH_PHASE_PROCESS;
1330     }
1331     /* Enable the specified HASH interrupt*/
1332     __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI);
1333 
1334     status = HASH_WriteData_IT(hhash);
1335 
1336     /* Change the HASH state */
1337     hhash->State = HAL_HASH_STATE_READY;
1338 
1339     /* Process Unlocked */
1340     __HAL_UNLOCK(hhash);
1341   }
1342   else
1343   {
1344     status = HAL_BUSY;
1345   }
1346   /* Return function status */
1347   return status;
1348 }
1349 
1350 
1351 /**
1352   * @brief  End computation of a single HASH signature after several calls to HAL_HASH_Accumulate_IT() API.
1353   * @note   Digest is available in pOutBuffer
1354   * @param  hhash HASH handle.
1355   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1356   * @param  Size length of the input buffer in bytes.
1357   * @param  pOutBuffer pointer to the computed digest.
1358   * @retval HAL status
1359   */
HAL_HASH_AccumulateLast_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)1360 HAL_StatusTypeDef HAL_HASH_AccumulateLast_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1361                                              uint8_t *const pOutBuffer)
1362 {
1363   HAL_StatusTypeDef status;
1364 
1365   /* Check the hash handle allocation */
1366   if (hhash == NULL)
1367   {
1368     return HAL_ERROR;
1369   }
1370 
1371   /* Check if peripheral is ready to start process */
1372   if (hhash->State == HAL_HASH_STATE_READY)
1373   {
1374     /* Process Locked */
1375     __HAL_LOCK(hhash);
1376 
1377     /* Change the HASH state */
1378     hhash->State = HAL_HASH_STATE_BUSY;
1379 
1380     /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1381     hhash->pHashInBuffPtr = pInBuffer;
1382     hhash->pHashOutBuffPtr = pOutBuffer;
1383     hhash->HashInCount =  0U;
1384     hhash->Size = Size;
1385     if (hhash->Phase == HAL_HASH_PHASE_READY)
1386     {
1387       /* Set HASH mode */
1388       CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1389       /* Reset the HASH processor core */
1390       MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1391 
1392       /* Set the phase */
1393       hhash->Phase = HAL_HASH_PHASE_PROCESS;
1394     }
1395     /* Configure the number of valid bits in last word of the message */
1396     MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
1397 
1398     /* Enable the specified HASH interrupt*/
1399     __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
1400 
1401     status = HASH_WriteData_IT(hhash);
1402 
1403     /* Change the HASH state */
1404     hhash->State = HAL_HASH_STATE_READY;
1405 
1406     /* Reset HASH state machine */
1407     hhash->Phase = HAL_HASH_PHASE_READY;
1408 
1409     /* Process Unlocked */
1410     __HAL_UNLOCK(hhash);
1411   }
1412   else
1413   {
1414     status =  HAL_BUSY;
1415   }
1416   /* Return function status */
1417   return status;
1418 }
1419 
1420 /**
1421   * @}
1422   */
1423 
1424 
1425 /** @defgroup HASH_Exported_Functions_Group3 HMAC processing functions
1426   *  @brief   HMAC processing functions using different mode.
1427   *
1428 @verbatim
1429  ===============================================================================
1430                  ##### HMAC processing functions #####
1431  ===============================================================================
1432     [..]  This section provides API allowing to calculate the HMAC (keyed-hash
1433           message authentication code) value using:
1434       (+) one of the algorithms supported by the peripheral
1435       (+) Key selection
1436          (++) Long key : HMAC key is longer than the block size
1437          (++) Short key : HMAC key is shorter or equal to the block size
1438 
1439     [..] To calculate the HMAC for a single buffer, user can resort to one of three processing
1440          functions available .
1441       (+) Polling mode : HAL_HASH_HMAC_Start()
1442       (+) Interrupt mode : HAL_HASH_HMAC_Start_IT()
1443       (+) DMA mode : HAL_HASH_HMAC_Start_DMA()
1444 
1445     [..]  In case of multi-buffer HMAC processing (a single digest is computed while
1446           several buffers are fed to the Peripheral), the user can resort to successive calls
1447           to :
1448       (+) Polling mode : HAL_HASH_HMAC_Accumulate() and wrap-up the digest computation by a call
1449           to HAL_HASH_HMAC_AccumulateLast()
1450       (+) Interrupt mode : HAL_HASH_HMAC_Accumulate_IT() and wrap-up the digest computation by a call
1451           to HAL_HASH_HMAC_AccumulateLast_IT()
1452       (+) DMA mode : HAL_HASH_HMAC_Start_DMA(),MDMAT bit must be set through __HAL_HASH_SET_MDMAT() macro,
1453           before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT()
1454           macro then wrap-up the HMAC processing in feeding the last input buffer through the
1455           same API HAL_HASH_HMAC_Start_DMA()
1456 
1457 @endverbatim
1458   * @{
1459   */
1460 
1461 /**
1462   * @brief  HMAC in polling mode, HASH peripheral processes Key then pInBuffer then reads the computed digest.
1463   * @param  hhash HASH handle.
1464   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1465   * @param  Size length of the input buffer in bytes.
1466   * @param  pOutBuffer pointer to the computed digest.
1467   * @param  Timeout specify timeout value
1468   * @retval HAL status
1469   */
HAL_HASH_HMAC_Start(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer,uint32_t Timeout)1470 HAL_StatusTypeDef HAL_HASH_HMAC_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1471                                       uint8_t *const pOutBuffer, uint32_t Timeout)
1472 {
1473   uint32_t blocksize; /* Block size in bytes */
1474 
1475   /* Check the hash handle allocation */
1476   if (hhash == NULL)
1477   {
1478     return HAL_ERROR;
1479   }
1480 
1481   /* Check if peripheral is ready to start process */
1482   if (hhash->State == HAL_HASH_STATE_READY)
1483   {
1484 
1485     /* Process Locked */
1486     __HAL_LOCK(hhash);
1487 
1488     /* Change the HASH state */
1489     hhash->State = HAL_HASH_STATE_BUSY;
1490 
1491     /* Reset HASH Phase */
1492     hhash->Phase = HAL_HASH_PHASE_READY;
1493 
1494     /* Reset HashInCount and Initialize Size, pHashKeyBuffPtr, pHashInBuffPtr and pHashOutBuffPtr parameters */
1495     hhash->pHashInBuffPtr = pInBuffer;
1496     hhash->pHashOutBuffPtr = pOutBuffer;
1497     hhash->pHashKeyBuffPtr =  hhash->Init.pKey;
1498     hhash->HashInCount =  0U;
1499     hhash->Size = Size;
1500 
1501     /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting bits */
1502     if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
1503         (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
1504         (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
1505     {
1506       blocksize = 64U;
1507     }
1508     else
1509     {
1510       blocksize = 128U;
1511     }
1512     if (hhash->Init.KeySize > blocksize)
1513     {
1514       MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1515                  HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
1516     }
1517     else
1518     {
1519 
1520       MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1521                  HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1522     }
1523 
1524     /* Configure the number of valid bits in last word of the Key */
1525     MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1526 
1527 
1528     /* Set the phase */
1529     hhash->Phase = HAL_HASH_PHASE_PROCESS;
1530     /* Write Key */
1531     HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
1532 
1533     /* Start the Key padding then the Digest calculation */
1534     SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1535 
1536     /* Wait for BUSY flag to be cleared */
1537     if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1538     {
1539       return HAL_ERROR;
1540     }
1541 
1542     /* Configure the number of valid bits in last word of the message */
1543     MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
1544 
1545     /* Write message */
1546     HASH_WriteData(hhash, pInBuffer, Size);
1547 
1548     /* Start the message padding then the Digest calculation */
1549     SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1550 
1551     /* Wait for BUSY flag to be cleared */
1552     if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1553     {
1554       return HAL_ERROR;
1555     }
1556     /* Configure the number of valid bits in last word of the Key */
1557     MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1558 
1559     /* Write Key */
1560     HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
1561 
1562     /* Start the Key padding then the Digest calculation */
1563     SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1564 
1565     /* Wait for digest calculation completion status(DCIS) flag to be set */
1566     if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
1567     {
1568       return HAL_ERROR;
1569     }
1570 
1571     /* Read the message digest */
1572     HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash));
1573 
1574     /* Change the HASH state */
1575     hhash->State = HAL_HASH_STATE_READY;
1576 
1577     /* Change the HASH phase  */
1578     hhash->Phase = HAL_HASH_PHASE_READY;
1579 
1580     /* Process Unlocked */
1581     __HAL_UNLOCK(hhash);
1582 
1583     /* Return function status */
1584     return HAL_OK;
1585 
1586   }
1587   else
1588   {
1589     return HAL_BUSY;
1590   }
1591 }
1592 
1593 /**
1594   * @brief  HMAC accumulate mode, HASH peripheral processes Key then  several input buffers.
1595   * @note   Consecutive calls to HAL_HASH_HMAC_Accumulate() can be used to feed
1596   *         several input buffers back-to-back to the Peripheral that will yield a single
1597   *         HASH signature once all buffers have been entered. Wrap-up of input
1598   *         buffers feeding and retrieval of digest is done by a call to
1599   *         HAL_HASH_HMAC_AccumulateLast()
1600   * @param  hhash HASH handle.
1601   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1602   * @param  Size length of the input buffer in bytes and a multiple of 4
1603   * @param  Timeout specify timeout value
1604   * @retval HAL status
1605   */
HAL_HASH_HMAC_Accumulate(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint32_t Timeout)1606 HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1607                                            uint32_t Timeout)
1608 {
1609   uint32_t blocksize; /* Block size in bytes */
1610 
1611   /* Check the hash handle allocation and buffer length multiple of 4 */
1612   if ((hhash == NULL) || ((Size % 4U) != 0U))
1613   {
1614     return HAL_ERROR;
1615   }
1616 
1617   /* Check if peripheral is ready to start process */
1618   if (hhash->State == HAL_HASH_STATE_READY)
1619   {
1620     /* Process Locked */
1621     __HAL_LOCK(hhash);
1622 
1623     /* Change the HASH state */
1624     hhash->State = HAL_HASH_STATE_BUSY;
1625 
1626     /* Initialize Size, pHashInBuffPtr and pHashKeyBuffPtr parameters */
1627     hhash->pHashInBuffPtr = pInBuffer;
1628     hhash->pHashKeyBuffPtr =  hhash->Init.pKey;
1629     hhash->Size = Size;
1630 
1631     if (hhash->Phase == HAL_HASH_PHASE_READY)
1632     {
1633       /* Reset HashInCount parameter */
1634       hhash->HashInCount =  0U;
1635       /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
1636       /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */
1637       if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
1638           (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
1639           (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
1640       {
1641         blocksize = 64U;
1642       }
1643       else
1644       {
1645         blocksize = 128U;
1646       }
1647       if (hhash->Init.KeySize > blocksize)
1648       {
1649         MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1650                    HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
1651       }
1652       else
1653       {
1654 
1655         MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1656                    HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1657       }
1658       /* Set phase process */
1659       hhash->Phase = HAL_HASH_PHASE_PROCESS;
1660 
1661       /* Configure the number of valid bits in last word of the Key */
1662       MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1663 
1664       /* Write Key */
1665       HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
1666 
1667       /* Start the Key padding then the Digest calculation */
1668       SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1669 
1670       /* Wait for BUSY flag to be cleared */
1671       if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1672       {
1673         return HAL_ERROR;
1674       }
1675     }
1676 
1677     /* Change the number of valid bits in last word of the message */
1678     MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U);
1679 
1680     /* Write message */
1681     HASH_WriteData(hhash, pInBuffer, Size);
1682 
1683     /* Change the HASH state */
1684     hhash->State = HAL_HASH_STATE_READY;
1685 
1686     /* Process Unlocked */
1687     __HAL_UNLOCK(hhash);
1688 
1689     /* Return function status */
1690     return HAL_OK;
1691 
1692   }
1693   else
1694   {
1695     return HAL_BUSY;
1696   }
1697 }
1698 /**
1699   * @brief  End computation of a single HMAC signature after several calls to HAL_HASH_HMAC_Accumulate() API.
1700   * @note   Digest is available in pOutBuffer
1701   * @param  hhash HASH handle.
1702   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1703   * @param  Size length of the input buffer in bytes.
1704   * @param  pOutBuffer pointer to the computed digest.
1705   * @param  Timeout specify timeout value
1706   * @retval HAL status
1707   */
HAL_HASH_HMAC_AccumulateLast(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer,uint32_t Timeout)1708 HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1709                                                uint8_t *const pOutBuffer, uint32_t Timeout)
1710 {
1711   /* Check the hash handle allocation */
1712   if (hhash == NULL)
1713   {
1714     return HAL_ERROR;
1715   }
1716 
1717   /* Check if peripheral is ready to start process */
1718   if (hhash->State == HAL_HASH_STATE_READY)
1719   {
1720 
1721     /* Process Locked */
1722     __HAL_LOCK(hhash);
1723 
1724     /* Change the HASH state */
1725     hhash->State = HAL_HASH_STATE_BUSY;
1726 
1727     /* Initialize Size, pHashInBuffPtr, pHashKeyBuffPtr and pHashOutBuffPtr parameters */
1728     hhash->pHashInBuffPtr = pInBuffer;
1729     hhash->pHashOutBuffPtr = pOutBuffer;
1730     hhash->pHashKeyBuffPtr =  hhash->Init.pKey;
1731     hhash->Size = Size;
1732 
1733     if (hhash->Phase != HAL_HASH_PHASE_PROCESS)
1734     {
1735       return HAL_ERROR;
1736     }
1737     else
1738     {
1739       /* Configure the number of valid bits in last word of the message */
1740       MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
1741 
1742       /* Write message */
1743       HASH_WriteData(hhash, pInBuffer, Size);
1744 
1745       /* Start the message padding then the Digest calculation */
1746       SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1747 
1748       /* Wait for BUSY flag to be cleared */
1749       if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1750       {
1751         return HAL_ERROR;
1752       }
1753       /* Configure the number of valid bits in last word of the Key */
1754       MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1755 
1756       /* Write Key */
1757       HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
1758 
1759       /* Start the Key padding then the Digest calculation */
1760       SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1761 
1762       /* Wait for digest calculation completion status(DCIS) flag to be set */
1763       if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
1764       {
1765         return HAL_ERROR;
1766       }
1767 
1768       /* Read the message digest */
1769       HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash));
1770     }
1771 
1772     /* Change the HASH state */
1773     hhash->State = HAL_HASH_STATE_READY;
1774 
1775     /* Reset HASH state machine */
1776     hhash->Phase = HAL_HASH_PHASE_READY;
1777 
1778     /* Process Unlocked */
1779     __HAL_UNLOCK(hhash);
1780 
1781     /* Return function status */
1782     return HAL_OK;
1783   }
1784   else
1785   {
1786     return HAL_BUSY;
1787   }
1788 }
1789 
1790 /**
1791   * @brief  HMAC in interrupt mode, HASH peripheral process Key then pInBuffer then read the computed digest.
1792   * @param  hhash HASH handle.
1793   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1794   * @param  Size length of the input buffer in bytes.
1795   * @param  pOutBuffer pointer to the computed digest.
1796   * @retval HAL status
1797   */
HAL_HASH_HMAC_Start_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)1798 HAL_StatusTypeDef HAL_HASH_HMAC_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1799                                          uint8_t *const pOutBuffer)
1800 {
1801   HAL_StatusTypeDef status;
1802   uint32_t blocksize; /* Block size in bytes */
1803 
1804   /* Check the hash handle allocation */
1805   if (hhash == NULL)
1806   {
1807     return HAL_ERROR;
1808   }
1809 
1810   /* Check if peripheral is ready to start process */
1811   if (hhash->State == HAL_HASH_STATE_READY)
1812   {
1813     /* Process Locked */
1814     __HAL_LOCK(hhash);
1815 
1816     /* Change the HASH state */
1817     hhash->State = HAL_HASH_STATE_BUSY;
1818 
1819     /* Reset HASH Phase */
1820     hhash->Phase = HAL_HASH_PHASE_READY;
1821 
1822     /* Reset HashInCount and Initialize Size, pHashKeyBuffPtr, pHashInBuffPtr and pHashOutBuffPtr parameters */
1823     hhash->pHashInBuffPtr = pInBuffer;
1824     hhash->pHashOutBuffPtr = pOutBuffer;
1825     hhash->pHashKeyBuffPtr =  hhash->Init.pKey;
1826     hhash->HashInCount =  0U;
1827     hhash->Size = Size;
1828 
1829     /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting bits */
1830     if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
1831         (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
1832         (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
1833     {
1834       blocksize = 64U;
1835     }
1836     else
1837     {
1838       blocksize = 128U;
1839     }
1840     if (hhash->Init.KeySize > blocksize)
1841     {
1842       MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1843                  HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
1844     }
1845     else
1846     {
1847 
1848       MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1849                  HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1850     }
1851 
1852     /* Configure the number of valid bits in last word of the Key */
1853     MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1854 
1855     /* Set the phase */
1856     hhash->Phase = HAL_HASH_PHASE_PROCESS;
1857   }
1858   else if (hhash->State ==  HAL_HASH_STATE_SUSPENDED)
1859   {
1860     /* Process Locked */
1861     __HAL_LOCK(hhash);
1862     /* Change the HASH state */
1863     hhash->State = HAL_HASH_STATE_BUSY;
1864   }
1865   else
1866   {
1867     return HAL_BUSY;
1868   }
1869 
1870   /* Enable the specified HASH interrupt*/
1871   __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
1872 
1873   status = HASH_WriteData_IT(hhash);
1874 
1875   /* Return function status */
1876   return status;
1877 }
1878 
1879 /**
1880   * @brief  HMAC accumulate in interrupt mode, HASH peripheral processes Key then several input buffers.
1881   * @note   Consecutive calls to HAL_HASH_HMAC_Accumulate_IT() can be used to feed
1882   *         several input buffers back-to-back to the Peripheral that will yield a single
1883   *         HASH signature once all buffers have been entered. Wrap-up of input
1884   *         buffers feeding and retrieval of digest is done by a call to
1885   *         HAL_HASH_HMAC_AccumulateLast_IT()
1886   * @param  hhash HASH handle.
1887   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1888   * @param  Size length of the input buffer in bytes and a multiple of 4.
1889   * @retval HAL status
1890   */
HAL_HASH_HMAC_Accumulate_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size)1891 HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1892 {
1893   HAL_StatusTypeDef status;
1894   uint32_t blocksize; /* Block size in bytes */
1895 
1896   /* Check the hash handle allocation and buffer length multiple of 4 */
1897   if ((hhash == NULL) || ((Size % 4U) != 0U))
1898   {
1899     return HAL_ERROR;
1900   }
1901 
1902   /* Check if peripheral is ready to start process */
1903   if (hhash->State == HAL_HASH_STATE_READY)
1904   {
1905     /* Process Locked */
1906     __HAL_LOCK(hhash);
1907 
1908     /* Change the HASH state */
1909     hhash->State = HAL_HASH_STATE_BUSY;
1910 
1911     /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1912     hhash->pHashInBuffPtr = pInBuffer;
1913     hhash->pHashKeyBuffPtr =  hhash->Init.pKey;
1914     hhash->HashInCount =  0U;
1915     hhash->Size = Size;
1916     /* Set multi buffers accumulation flag */
1917     hhash->Accumulation = 1U;
1918 
1919     if (hhash->Phase == HAL_HASH_PHASE_READY)
1920     {
1921       /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */
1922       if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
1923           (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
1924           (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
1925       {
1926         blocksize = 64U;
1927       }
1928       else
1929       {
1930         blocksize = 128U;
1931       }
1932       if (hhash->Init.KeySize > blocksize)
1933       {
1934         MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1935                    HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
1936       }
1937       else
1938       {
1939 
1940         MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1941                    HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1942       }
1943 
1944       /* Configure the number of valid bits in last word of the Key */
1945       MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1946 
1947       /* Set the phase */
1948       hhash->Phase = HAL_HASH_PHASE_PROCESS;
1949     }
1950     /* Enable the specified HASH interrupt*/
1951     __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
1952 
1953     status = HASH_WriteData_IT(hhash);
1954   }
1955   else
1956   {
1957     status =  HAL_BUSY;
1958   }
1959   /* Return function status */
1960   return status;
1961 }
1962 /**
1963   * @brief  End computation of a single HMAC signature in interrupt mode, after
1964   *         several calls to HAL_HASH_HMAC_Accumulate() API.
1965   * @note   Digest is available in pOutBuffer
1966   * @param  hhash HASH handle.
1967   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
1968   * @param  Size length of the input buffer in bytes.
1969   * @param  pOutBuffer pointer to the computed digest.
1970   * @retval HAL status
1971   */
HAL_HASH_HMAC_AccumulateLast_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)1972 HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer,
1973                                                   uint32_t Size, uint8_t *const pOutBuffer)
1974 {
1975   HAL_StatusTypeDef status;
1976 
1977   /* Check the hash handle allocation */
1978   if (hhash == NULL)
1979   {
1980     return HAL_ERROR;
1981   }
1982 
1983   /* Check if peripheral is ready to start process*/
1984   if (hhash->State == HAL_HASH_STATE_READY)
1985   {
1986     /* Process Locked */
1987     __HAL_LOCK(hhash);
1988 
1989     /* Change the HASH state */
1990     hhash->State = HAL_HASH_STATE_BUSY;
1991 
1992     /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1993     hhash->pHashInBuffPtr = pInBuffer;
1994     hhash->pHashOutBuffPtr = pOutBuffer;
1995     hhash->pHashKeyBuffPtr =  hhash->Init.pKey;
1996     hhash->HashInCount =  0U;
1997     hhash->Size = Size;
1998     /* Set multi buffers accumulation flag */
1999     hhash->Accumulation = 0U;
2000     /* Enable the specified HASH interrupt*/
2001     __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2002 
2003     status = HASH_WriteData_IT(hhash);
2004   }
2005   else
2006   {
2007     status =  HAL_BUSY;
2008   }
2009   /* Return function status */
2010   return status;
2011 }
2012 
2013 /**
2014   * @brief  HMAC in DMA mode,HASH peripheral processes Key then pInBuffer in DMA mode
2015   *         then read the computed digest.
2016   * @note   Multi-buffer HMAC processing is possible, consecutive calls to HAL_HASH_HMAC_Start_DMA
2017   *         (MDMAT bit must be set) can be used to feed several input buffers
2018   *         back-to-back to the Peripheral that will yield a single
2019   *         HASH signature once all buffers have been entered. Wrap-up of input
2020   *         buffers feeding and retrieval of digest is done by a call to
2021   *         HAL_HASH_HMAC_Start_DMA (MDMAT bit must be reset).
2022   * @param  hhash HASH handle.
2023   * @param  pInBuffer pointer to the input buffer (buffer to be hashed).
2024   * @param  Size length of the input buffer in bytes.
2025   * @param  pOutBuffer pointer to the computed digest.
2026   * @retval HAL status
2027   */
HAL_HASH_HMAC_Start_DMA(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)2028 HAL_StatusTypeDef HAL_HASH_HMAC_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
2029                                           uint8_t *const pOutBuffer)
2030 {
2031   HAL_StatusTypeDef status;
2032   uint32_t count;
2033   uint32_t blocksize; /* Block size in bytes */
2034 
2035   /* Check the hash handle allocation */
2036   if (hhash == NULL)
2037   {
2038     return HAL_ERROR;
2039   }
2040 
2041   /* Check if peripheral is ready to start process*/
2042   if (hhash->State == HAL_HASH_STATE_READY)
2043   {
2044     /* Process Locked */
2045     __HAL_LOCK(hhash);
2046 
2047     /* Change the HASH state */
2048     hhash->State = HAL_HASH_STATE_BUSY;
2049 
2050     /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
2051     hhash->pHashInBuffPtr = pInBuffer;
2052     hhash->pHashOutBuffPtr = pOutBuffer;
2053     hhash->pHashKeyBuffPtr =  hhash->Init.pKey;
2054     hhash->HashInCount =  0U;
2055     hhash->Size = Size;
2056 
2057     /* Set the phase */
2058     if (hhash->Phase == HAL_HASH_PHASE_READY)
2059     {
2060       /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */
2061       if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
2062           (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
2063           (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
2064       {
2065         blocksize = 64U;
2066       }
2067       else
2068       {
2069         blocksize = 128U;
2070       }
2071       if (hhash->Init.KeySize > blocksize)
2072       {
2073         MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
2074                    HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
2075       }
2076       else
2077       {
2078 
2079         MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
2080                    HASH_ALGOMODE_HMAC | HASH_CR_INIT);
2081       }
2082 
2083       /* Set the phase */
2084       hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
2085 
2086       /* Configure the number of valid bits in last word of the Key */
2087       MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
2088 
2089       /* Write Key */
2090       HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
2091 
2092       /* Start the Key padding then the Digest calculation */
2093       SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2094 
2095       /* Wait for DCIS flag to be set */
2096       count = HASH_TIMEOUTVALUE;
2097       do
2098       {
2099         count--;
2100         if (count == 0U)
2101         {
2102           /* Change state */
2103           hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2104           hhash->State = HAL_HASH_STATE_READY;
2105           __HAL_UNLOCK(hhash);
2106           return HAL_ERROR;
2107         }
2108       } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_BUSY));
2109     }
2110 
2111     hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2;
2112     if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U)
2113     {
2114       /* Configure the number of valid bits in last word of the message */
2115       MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Size) % 4U));
2116     }
2117     else
2118     {
2119       /* Configure the number of valid bits in last word of the message */
2120       MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U);
2121     }
2122   }
2123   else if (hhash->State ==  HAL_HASH_STATE_SUSPENDED)
2124   {
2125     /* Process Locked */
2126     __HAL_LOCK(hhash);
2127     /* Change the HASH state */
2128     hhash->State = HAL_HASH_STATE_BUSY;
2129 
2130     /*only part not yet hashed to compute  */
2131     hhash->Size = hhash->HashInCount;
2132   }
2133 
2134   else
2135   {
2136     /* Return busy status */
2137     return HAL_BUSY;
2138   }
2139 
2140   /* Set the HASH DMA transfer complete callback */
2141   hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
2142   /* Set the DMA error callback */
2143   hhash->hdmain->XferErrorCallback = HASH_DMAError;
2144 
2145   if ((hhash->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2146   {
2147     if ((hhash->hdmain->LinkedListQueue != NULL) && (hhash->hdmain->LinkedListQueue->Head != NULL))
2148     {
2149       /* Enable the DMA channel */
2150       hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET]\
2151         = ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : ((hhash->Size)));
2152       hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET]\
2153         = (uint32_t)(hhash->pHashInBuffPtr);  /* Set DMA source address */
2154       hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET]\
2155         = (uint32_t)&hhash->Instance->DIN; /* Set DMA destination address */
2156 
2157       status = HAL_DMAEx_List_Start_IT(hhash->hdmain);
2158     }
2159     else
2160     {
2161       /* Return error status */
2162       status = HAL_ERROR;
2163     }
2164   }
2165   else
2166   {
2167     status = HAL_DMA_Start_IT(hhash->hdmain, (uint32_t)(hhash->pHashInBuffPtr), (uint32_t)&hhash->Instance->DIN, \
2168                               ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : \
2169                                ((hhash->Size))));
2170   }
2171   if (status != HAL_OK)
2172   {
2173     /* DMA error code field */
2174     hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
2175 
2176     /* Return error */
2177 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
2178     /*Call registered error callback*/
2179     hhash->ErrorCallback(hhash);
2180 #else
2181     /*Call legacy weak error callback*/
2182     HAL_HASH_ErrorCallback(hhash);
2183 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2184   }
2185   else
2186   {
2187     /* Enable DMA requests */
2188     SET_BIT(hhash->Instance->CR, HASH_CR_DMAE);
2189   }
2190 
2191   /* Return function status */
2192   return status;
2193 }
2194 
2195 
2196 /**
2197   * @}
2198   */
2199 
2200 /** @defgroup HASH_Exported_Functions_Group4 HASH IRQ handler management
2201   * @brief    HASH IRQ handler.
2202   *
2203 @verbatim
2204   ==============================================================================
2205                 ##### HASH IRQ handler management #####
2206   ==============================================================================
2207 [..]  This section provides HASH IRQ handler and callback functions.
2208       (+) HAL_HASH_IRQHandler HASH interrupt request
2209       (+) HAL_HASH_InCpltCallback input data transfer complete callback
2210       (+) HAL_HASH_DgstCpltCallback digest computation complete callback
2211       (+) HAL_HASH_ErrorCallback  HASH error callback
2212       (+) HAL_HASH_GetState return the HASH state
2213       (+) HAL_HASH_GetError return the HASH error code
2214 @endverbatim
2215   * @{
2216   */
2217 
2218 /**
2219   * @brief Handle HASH interrupt request.
2220   * @param hhash HASH handle.
2221   * @note  HAL_HASH_IRQHandler() handles interrupts in HMAC processing as well.
2222   * @retval None
2223   */
HAL_HASH_IRQHandler(HASH_HandleTypeDef * hhash)2224 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
2225 {
2226   HAL_StatusTypeDef status;
2227   uint32_t itsource = hhash->Instance->IMR;
2228   uint32_t itflag   = hhash->Instance->SR;
2229 
2230   /* If digest is ready */
2231   if ((itflag & HASH_FLAG_DCIS) == HASH_FLAG_DCIS)
2232   {
2233     /* Read the digest */
2234     HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash));
2235 
2236     /* Disable Interrupts */
2237     __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2238     /* Change the HASH state */
2239     hhash->State = HAL_HASH_STATE_READY;
2240     /* Reset HASH state machine */
2241     hhash->Phase = HAL_HASH_PHASE_READY;
2242     /* Process Unlocked */
2243     __HAL_UNLOCK(hhash);
2244     /* Call digest computation complete call back */
2245 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2246     hhash->DgstCpltCallback(hhash);
2247 #else
2248     HAL_HASH_DgstCpltCallback(hhash);
2249 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2250 
2251   }
2252   /* If Peripheral ready to accept new data */
2253   if ((itflag & HASH_FLAG_DINIS) == HASH_FLAG_DINIS)
2254   {
2255     if ((itsource & HASH_IT_DINI) == HASH_IT_DINI)
2256     {
2257       status = HASH_WriteData_IT(hhash);
2258       if (status != HAL_OK)
2259       {
2260         /* Call error callback */
2261 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2262         hhash->ErrorCallback(hhash);
2263 #else
2264         HAL_HASH_ErrorCallback(hhash);
2265 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2266       }
2267     }
2268   }
2269 }
2270 
2271 /**
2272   * @brief  Input data transfer complete call back.
2273   * @note   HAL_HASH_InCpltCallback() is called when the complete input message
2274   *         has been fed to the Peripheral. This API is invoked only when input data are
2275   *         entered under interruption or through DMA.
2276   * @note   In case of HASH or HMAC multi-buffer DMA feeding case (MDMAT bit set),
2277   *         HAL_HASH_InCpltCallback() is called at the end of each buffer feeding
2278   *         to the Peripheral.
2279   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
2280   *         the configuration information for HASH module.
2281   * @retval None
2282   */
HAL_HASH_InCpltCallback(HASH_HandleTypeDef * hhash)2283 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
2284 {
2285   /* Prevent unused argument(s) compilation warning */
2286   UNUSED(hhash);
2287 
2288   /* NOTE : This function should not be modified; when the callback is needed,
2289             HAL_HASH_InCpltCallback() can be implemented in the user file.
2290    */
2291 }
2292 
2293 /**
2294   * @brief  Digest computation complete call back.
2295   * @note   HAL_HASH_DgstCpltCallback() is used under interruption, is not
2296   *         relevant with DMA.
2297   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
2298   *         the configuration information for HASH module.
2299   * @retval None
2300   */
HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef * hhash)2301 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
2302 {
2303   /* Prevent unused argument(s) compilation warning */
2304   UNUSED(hhash);
2305 
2306   /* NOTE : This function should not be modified; when the callback is needed,
2307             HAL_HASH_DgstCpltCallback() can be implemented in the user file.
2308    */
2309 }
2310 
2311 /**
2312   * @brief  HASH error callback.
2313   * @note   Code user can resort to hhash->Status (HAL_ERROR, HAL_TIMEOUT,...)
2314   *         to retrieve the error type.
2315   * @param  hhash pointer to a HASH_HandleTypeDef structure that contains
2316   *         the configuration information for HASH module.
2317   * @retval None
2318   */
HAL_HASH_ErrorCallback(HASH_HandleTypeDef * hhash)2319 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
2320 {
2321   /* Prevent unused argument(s) compilation warning */
2322   UNUSED(hhash);
2323 
2324   /* NOTE : This function should not be modified; when the callback is needed,
2325             HAL_HASH_ErrorCallback() can be implemented in the user file.
2326    */
2327 }
2328 
2329 /**
2330   * @brief  Return the HASH handle state.
2331   * @note   The API yields the current state of the handle (BUSY, READY,...).
2332   * @param  hhash HASH handle.
2333   * @retval HAL HASH state
2334   */
HAL_HASH_GetState(HASH_HandleTypeDef * hhash)2335 HAL_HASH_StateTypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
2336 {
2337   return hhash->State;
2338 }
2339 
2340 /**
2341   * @brief  Return the HASH handle error code.
2342   * @param  hhash pointer to a HASH_HandleTypeDef structure.
2343   * @retval HASH Error Code
2344   */
HAL_HASH_GetError(HASH_HandleTypeDef * hhash)2345 uint32_t HAL_HASH_GetError(HASH_HandleTypeDef *hhash)
2346 {
2347   /* Return HASH Error Code */
2348   return hhash->ErrorCode;
2349 }
2350 /**
2351   * @}
2352   */
2353 
2354 /**
2355   * @}
2356   */
2357 
2358 /* Private functions ---------------------------------------------------------*/
2359 /** @addtogroup HASH_Private_Functions
2360   * @{
2361   */
2362 
2363 /**
2364   * @brief DMA HASH Input Data transfer completion callback.
2365   * @param hdma DMA handle.
2366   * @retval None
2367   */
HASH_DMAXferCplt(DMA_HandleTypeDef * hdma)2368 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
2369 {
2370   HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2371   uint32_t count;
2372 
2373   if (READ_BIT(hhash->Instance->CR, HASH_CR_MODE) == 0U)
2374   {
2375     if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U)
2376     {
2377       /* Disable the DMA transfer */
2378       CLEAR_BIT(hhash->Instance->CR, HASH_CR_DMAE);
2379 
2380 
2381       /* Wait for DCIS flag to be set */
2382       count = HASH_TIMEOUTVALUE;
2383       do
2384       {
2385         count--;
2386         if (count == 0U)
2387         {
2388           /* Change state */
2389           hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2390           hhash->State = HAL_HASH_STATE_READY;
2391           __HAL_UNLOCK(hhash);
2392 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2393           hhash->ErrorCallback(hhash);
2394 #else
2395           HAL_HASH_ErrorCallback(hhash);
2396 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2397         }
2398       } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS));
2399       /* Call Input data transfer complete call back */
2400 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2401       hhash->InCpltCallback(hhash);
2402 #else
2403       HAL_HASH_InCpltCallback(hhash);
2404 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2405 
2406       /* Read the message digest */
2407       HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash));
2408 
2409       /* Change the HASH state to ready */
2410       hhash->State = HAL_HASH_STATE_READY;
2411 
2412       /* Reset HASH state machine */
2413       hhash->Phase = HAL_HASH_PHASE_READY;
2414 
2415       /* Process UnLock */
2416       __HAL_UNLOCK(hhash);
2417 
2418       /* Call digest complete call back */
2419 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2420       hhash->DgstCpltCallback(hhash);
2421 #else
2422       HAL_HASH_DgstCpltCallback(hhash);
2423 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2424     }
2425     else
2426     {
2427       hhash->State = HAL_HASH_STATE_READY;
2428       __HAL_UNLOCK(hhash);
2429     }
2430   }
2431   else /*HMAC DMA*/
2432   {
2433     if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
2434     {
2435       if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U)
2436       {
2437         /* Set the phase */
2438         hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3;
2439         /* Configure the number of valid bits in last word of the Key */
2440         MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
2441         /* Write Key */
2442         HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
2443 
2444         /* Start the Key padding then the Digest calculation */
2445         SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2446 
2447         /* Wait for DCIS flag to be set */
2448         count = HASH_TIMEOUTVALUE;
2449         do
2450         {
2451           count--;
2452           if (count == 0U)
2453           {
2454             /* Disable the DMA transfer */
2455             CLEAR_BIT(hhash->Instance->CR, HASH_CR_DMAE);
2456 
2457             /* Change state */
2458             hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
2459             hhash->State = HAL_HASH_STATE_READY;
2460             __HAL_UNLOCK(hhash);
2461 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2462             hhash->ErrorCallback(hhash);
2463 #else
2464             HAL_HASH_ErrorCallback(hhash);
2465 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2466           }
2467         } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS));
2468 
2469         /* Read the message digest */
2470         HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash));
2471 
2472         /* Change the HASH state to ready */
2473         hhash->State = HAL_HASH_STATE_READY;
2474 
2475         /* Reset HASH state machine */
2476         hhash->Phase = HAL_HASH_PHASE_READY;
2477 
2478         /* Process UnLock */
2479         __HAL_UNLOCK(hhash);
2480 
2481         /* Call digest complete call back */
2482 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2483         hhash->DgstCpltCallback(hhash);
2484 #else
2485         HAL_HASH_DgstCpltCallback(hhash);
2486 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2487 
2488       }
2489       else
2490       {
2491         hhash->State = HAL_HASH_STATE_READY;
2492         __HAL_UNLOCK(hhash);
2493         hhash->Accumulation = 1;
2494       }
2495     }
2496   }
2497 }
2498 
2499 /**
2500   * @brief DMA HASH communication error callback.
2501   * @param hdma DMA handle.
2502   * @retval None
2503   */
HASH_DMAError(DMA_HandleTypeDef * hdma)2504 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
2505 {
2506   HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2507 
2508   hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
2509   /* Set HASH state to ready to prevent any blocking issue in user code
2510   present in HAL_HASH_ErrorCallback() */
2511   hhash->State = HAL_HASH_STATE_READY;
2512 
2513 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2514   hhash->ErrorCallback(hhash);
2515 #else
2516   HAL_HASH_ErrorCallback(hhash);
2517 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2518 }
2519 
2520 /**
2521   * @brief  Feed the input buffer to the HASH peripheral in polling.
2522   * @param  hhash HASH handle.
2523   * @param  pInBuffer pointer to input buffer.
2524   * @param  Size the size of input buffer in bytes.
2525   * @retval HAL status
2526   */
HASH_WriteData(HASH_HandleTypeDef * hhash,const uint8_t * pInBuffer,uint32_t Size)2527 static void HASH_WriteData(HASH_HandleTypeDef *hhash, const uint8_t *pInBuffer, uint32_t Size)
2528 {
2529   uint32_t buffercounter;
2530   __IO uint32_t inputaddr = (uint32_t) pInBuffer;
2531 
2532 
2533   for (buffercounter = 0U; buffercounter < Size ; buffercounter += 4U)
2534   {
2535     /* Write input data 4 bytes at a time */
2536     hhash->Instance->DIN = *(uint32_t *)inputaddr;
2537     inputaddr += 4U;
2538     hhash->HashInCount += 4U;
2539   }
2540 }
2541 
2542 /**
2543   * @brief  Feed the input buffer to the HASH peripheral in interruption mode.
2544   * @param  hhash HASH handle.
2545   * @retval HAL status
2546   */
HASH_WriteData_IT(HASH_HandleTypeDef * hhash)2547 static HAL_StatusTypeDef HASH_WriteData_IT(HASH_HandleTypeDef *hhash)
2548 {
2549   uint32_t buffercounter;
2550   uint32_t count;
2551   __IO uint32_t keyaddr = (uint32_t)(hhash->pHashKeyBuffPtr);
2552   __IO uint32_t inputaddr = (uint32_t)(hhash->pHashInBuffPtr);
2553   uint32_t nbbytePartialHash  = (((hhash->Instance->SR) >> 16U) * 4U); /* Nb byte  to enter in HASH fifo to trig
2554                                                                       a partial HASH computation*/
2555 
2556   if (hhash->State == HAL_HASH_STATE_BUSY)
2557   {
2558     if ((hhash->Instance->CR & HASH_CR_MODE) == 0U)
2559     {
2560 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
2561       /* If suspension flag has been raised, suspend processing */
2562       if (hhash->SuspendRequest == HAL_HASH_SUSPEND)
2563       {
2564         /* reset SuspendRequest */
2565         hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
2566         /* Disable Computation Complete Flag and Errors Interrupts */
2567         __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2568         /* Change the HASH state */
2569         hhash->State = HAL_HASH_STATE_SUSPENDED;
2570         __HAL_UNLOCK(hhash);
2571       }
2572       else
2573       {
2574 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
2575 
2576         if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Size))
2577         {
2578           for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U)
2579           {
2580             /* Write input data 4 bytes at a time */
2581             hhash->Instance->DIN = *(uint32_t *)inputaddr;
2582             inputaddr += 4U;
2583             hhash->HashInCount += 4U;
2584             hhash->pHashInBuffPtr += 4U;
2585           }
2586           /* Wait for HASH_IT_DINI flag to be set */
2587           count = HASH_TIMEOUTVALUE;
2588           do
2589           {
2590             count--;
2591             if (count == 0U)
2592             {
2593               /* Disable Interrupts */
2594               __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2595 
2596               /* Change state */
2597               hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2598               hhash->State = HAL_HASH_STATE_READY;
2599               __HAL_UNLOCK(hhash);
2600               return HAL_ERROR;
2601             }
2602           } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS));
2603         }
2604         else
2605         {
2606           while ((hhash->HashInCount) < hhash->Size)
2607           {
2608             /* Write input data 4 bytes at a time */
2609             hhash->Instance->DIN = *(uint32_t *)inputaddr;
2610             inputaddr += 4U;
2611             hhash->HashInCount += 4U;
2612             hhash->pHashInBuffPtr += 4U;
2613           }
2614           /* Call Input transfer complete callback */
2615 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
2616           /*Call registered Input complete callback*/
2617           hhash->InCpltCallback(hhash);
2618 #else
2619           /*Call legacy weak Input complete callback*/
2620           HAL_HASH_InCpltCallback(hhash);
2621 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2622           if (hhash->Accumulation == 0U)
2623           {
2624             if (__HAL_HASH_GET_IT_SOURCE(hhash, HASH_IT_DINI))
2625             {
2626               /* Start the message padding then the Digest calculation */
2627               SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2628 
2629               /* Wait for HASH_FLAG_DCIS flag to be set */
2630               count = HASH_TIMEOUTVALUE;
2631               do
2632               {
2633                 count--;
2634                 if (count == 0U)
2635                 {
2636                   /* Disable Interrupts */
2637                   __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2638 
2639                   /* Change state */
2640                   hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2641                   hhash->State = HAL_HASH_STATE_READY;
2642                   __HAL_UNLOCK(hhash);
2643                   return HAL_ERROR;
2644                 }
2645               } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS));
2646             }
2647           }
2648           else
2649           {
2650             /* Reset multi buffers accumulation flag */
2651             hhash->Accumulation = 0U;
2652             /* Disable Interrupts */
2653             __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI);
2654           }
2655         }
2656 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
2657       }
2658 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
2659     }
2660     else /*HMAC */
2661     {
2662       if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2) /* loading input*/
2663       {
2664 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
2665         /* If suspension flag has been raised, suspend processing */
2666         if (hhash->SuspendRequest == HAL_HASH_SUSPEND)
2667         {
2668           /* reset SuspendRequest */
2669           hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
2670           /* Disable Computation Complete Flag and Errors Interrupts */
2671           __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2672           /* Change the HASH state */
2673           hhash->State = HAL_HASH_STATE_SUSPENDED;
2674           __HAL_UNLOCK(hhash);
2675         }
2676         else
2677         {
2678 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
2679           if (hhash->Accumulation == 1U)
2680           {
2681             /* Configure the number of valid bits in last word of the message */
2682             MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U);
2683           }
2684           else
2685           {
2686             /* Configure the number of valid bits in last word of the message */
2687             MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (hhash->Size % 4U));
2688           }
2689           if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Size))
2690           {
2691             for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U)
2692             {
2693               /* Write input data 4 bytes at a time */
2694               hhash->Instance->DIN = *(uint32_t *)inputaddr;
2695               inputaddr += 4U;
2696               hhash->HashInCount += 4U;
2697               hhash->pHashInBuffPtr += 4U;
2698             }
2699             /* Wait for HASH_IT_DINI flag to be set */
2700             count = HASH_TIMEOUTVALUE;
2701             do
2702             {
2703               count--;
2704               if (count == 0U)
2705               {
2706                 /* Disable Interrupts */
2707                 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2708 
2709                 /* Change state */
2710                 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2711                 hhash->State = HAL_HASH_STATE_READY;
2712                 __HAL_UNLOCK(hhash);
2713                 return HAL_ERROR;
2714               }
2715             } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS));
2716           }
2717           else
2718           {
2719             while ((hhash->HashInCount) < hhash->Size)
2720             {
2721               /* Write input data 4 bytes at a time */
2722               hhash->Instance->DIN = *(uint32_t *)inputaddr;
2723               inputaddr += 4U;
2724               hhash->HashInCount += 4U;
2725               hhash->pHashInBuffPtr += 4U;
2726             }
2727             /* Call Input transfer complete callback */
2728 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
2729             /*Call registered Input complete callback*/
2730             hhash->InCpltCallback(hhash);
2731 #else
2732             /*Call legacy weak Input complete callback*/
2733             HAL_HASH_InCpltCallback(hhash);
2734 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2735 
2736             if (hhash->Accumulation == 0U)
2737             {
2738               if (__HAL_HASH_GET_IT_SOURCE(hhash, HASH_IT_DINI))
2739               {
2740                 /* Start the message padding then the Digest calculation */
2741                 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2742 
2743                 /* Wait for HASH_FLAG_BUSY flag to be set */
2744                 count = HASH_TIMEOUTVALUE;
2745                 do
2746                 {
2747                   count--;
2748                   if (count == 0U)
2749                   {
2750                     /* Disable Interrupts */
2751                     __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2752 
2753                     /* Change state */
2754                     hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2755                     hhash->State = HAL_HASH_STATE_READY;
2756                     __HAL_UNLOCK(hhash);
2757                     return HAL_ERROR;
2758                   }
2759                 } while (HAL_IS_BIT_SET(hhash->Instance->SR, HASH_FLAG_BUSY));
2760 
2761                 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3;
2762                 hhash->HashInCount = 0U;
2763                 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
2764               }
2765             }
2766 
2767             else
2768             {
2769               /* Disable Interrupts */
2770               __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2771               hhash->State = HAL_HASH_STATE_READY;
2772               __HAL_UNLOCK(hhash);
2773               return HAL_OK;
2774             }
2775           }
2776 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
2777         }
2778 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
2779       }
2780 
2781       else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)/* loading Key*/
2782       {
2783 
2784         /* Configure the number of valid bits in last word of the Key */
2785         MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
2786 
2787         if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Init.KeySize))
2788         {
2789           for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U)
2790           {
2791             /* Write input data 4 bytes at a time */
2792             hhash->Instance->DIN = *(uint32_t *)keyaddr;
2793             keyaddr += 4U;
2794             hhash->HashInCount += 4U;
2795             hhash->pHashKeyBuffPtr += 4U;
2796           }
2797           /* Wait for HASH_IT_DINI flag to be set */
2798           count = HASH_TIMEOUTVALUE;
2799           do
2800           {
2801             count--;
2802             if (count == 0U)
2803             {
2804               /* Disable Interrupts */
2805               __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2806 
2807               /* Change state */
2808               hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2809               hhash->State = HAL_HASH_STATE_READY;
2810               __HAL_UNLOCK(hhash);
2811               return HAL_ERROR;
2812             }
2813           } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS));
2814         }
2815         else
2816         {
2817           while ((hhash->HashInCount) < (hhash->Init.KeySize))
2818           {
2819             /* Write input data 4 bytes at a time */
2820             hhash->Instance->DIN = *(uint32_t *)keyaddr;
2821             keyaddr += 4U;
2822             hhash->HashInCount += 4U;
2823           }
2824           /* Start the message padding then the Digest calculation */
2825           SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2826 
2827           /* Wait for HASH_FLAG_DCIS flag to be set */
2828           count = HASH_TIMEOUTVALUE;
2829           do
2830           {
2831             count--;
2832             if (count == 0U)
2833             {
2834               /* Disable Interrupts */
2835               __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2836 
2837               /* Change state */
2838               hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2839               hhash->State = HAL_HASH_STATE_READY;
2840               __HAL_UNLOCK(hhash);
2841               return HAL_ERROR;
2842             }
2843           } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS));
2844         }
2845       }
2846       else  /*first step , loading key*/
2847       {
2848 
2849         hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
2850 
2851         if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Init.KeySize))
2852         {
2853           for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U)
2854           {
2855             /* Write input data 4 bytes at a time */
2856             hhash->Instance->DIN = *(uint32_t *)keyaddr;
2857             keyaddr += 4U;
2858             hhash->HashInCount += 4U;
2859             hhash->pHashKeyBuffPtr += 4U;
2860           }
2861           /* Wait for HASH_IT_DINI flag to be set */
2862           count = HASH_TIMEOUTVALUE;
2863           do
2864           {
2865             count--;
2866             if (count == 0U)
2867             {
2868               /* Disable Interrupts */
2869               __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2870 
2871               /* Change state */
2872               hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2873               hhash->State = HAL_HASH_STATE_READY;
2874               __HAL_UNLOCK(hhash);
2875               return HAL_ERROR;
2876             }
2877           } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS));
2878         }
2879         else
2880         {
2881           while ((hhash->HashInCount) < (hhash->Init.KeySize))
2882           {
2883             /* Write input data 4 bytes at a time */
2884             hhash->Instance->DIN = *(uint32_t *)keyaddr;
2885             keyaddr += 4U;
2886             hhash->HashInCount += 4U;
2887             hhash->pHashKeyBuffPtr += 4U;
2888           }
2889           /* Start the message padding then the Digest calculation */
2890           SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2891 
2892           /* Wait for HASH_FLAG_BUSY flag to be set */
2893           count = HASH_TIMEOUTVALUE;
2894           do
2895           {
2896             count--;
2897             if (count == 0U)
2898             {
2899               /* Disable Interrupts */
2900               __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2901 
2902               /* Change state */
2903               hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2904               hhash->State = HAL_HASH_STATE_READY;
2905               __HAL_UNLOCK(hhash);
2906               return HAL_ERROR;
2907             }
2908           } while (HAL_IS_BIT_SET(hhash->Instance->SR, HASH_FLAG_BUSY));
2909           /*change Phase to step 2*/
2910           hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2;
2911           hhash->HashInCount = 0U;
2912         }
2913       }
2914     }
2915   }
2916   else if ((hhash->State == HAL_HASH_STATE_SUSPENDED))
2917   {
2918     return HAL_OK;
2919   }
2920   else
2921   {
2922     /* Busy error code field */
2923     hhash->ErrorCode |= HAL_HASH_ERROR_BUSY;
2924 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
2925     /*Call registered error callback*/
2926     hhash->ErrorCallback(hhash);
2927 #else
2928     /*Call legacy weak error callback*/
2929     HAL_HASH_ErrorCallback(hhash);
2930 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2931   }
2932 
2933   return HAL_OK;
2934 }
2935 
2936 /**
2937   * @brief  Retrieve the message digest.
2938   * @param hhash HASH handle
2939   * @param  pMsgDigest pointer to the computed digest.
2940   * @param  Size message digest size in bytes.
2941   * @retval None
2942   */
HASH_GetDigest(HASH_HandleTypeDef * hhash,uint8_t * pMsgDigest,uint8_t Size)2943 static void HASH_GetDigest(HASH_HandleTypeDef *hhash, uint8_t *pMsgDigest, uint8_t Size)
2944 {
2945   uint32_t msgdigest = (uint32_t)pMsgDigest;
2946 
2947   switch (Size)
2948   {
2949     case 20:  /* SHA1 */
2950       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
2951       msgdigest += 4U;
2952       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
2953       msgdigest += 4U;
2954       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
2955       msgdigest += 4U;
2956       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
2957       msgdigest += 4U;
2958       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
2959       break;
2960 
2961     case 28:  /* SHA224 */
2962       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
2963       msgdigest += 4U;
2964       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
2965       msgdigest += 4U;
2966       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
2967       msgdigest += 4U;
2968       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
2969       msgdigest += 4U;
2970       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
2971       msgdigest += 4U;
2972       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
2973       msgdigest += 4U;
2974       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
2975 
2976       break;
2977     case 32:   /* SHA256 */
2978       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
2979       msgdigest += 4U;
2980       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
2981       msgdigest += 4U;
2982       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
2983       msgdigest += 4U;
2984       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
2985       msgdigest += 4U;
2986       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
2987       msgdigest += 4U;
2988       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
2989       msgdigest += 4U;
2990       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
2991       msgdigest += 4U;
2992       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
2993       break;
2994 #if defined(HASH_ALGOSELECTION_SHA512)
2995     case 48:   /* SHA384 */
2996       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
2997       msgdigest += 4U;
2998       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
2999       msgdigest += 4U;
3000       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
3001       msgdigest += 4U;
3002       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
3003       msgdigest += 4U;
3004       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
3005       msgdigest += 4U;
3006       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
3007       msgdigest += 4U;
3008       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
3009       msgdigest += 4U;
3010       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
3011       msgdigest += 4U;
3012       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[8]);
3013       msgdigest += 4U;
3014       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[9]);
3015       msgdigest += 4U;
3016       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[10]);
3017       msgdigest += 4U;
3018       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[11]);
3019       break;
3020 
3021     case 64:   /* SHA 512 */
3022       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
3023       msgdigest += 4U;
3024       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
3025       msgdigest += 4U;
3026       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
3027       msgdigest += 4U;
3028       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
3029       msgdigest += 4U;
3030       *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
3031       msgdigest += 4U;
3032       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
3033       msgdigest += 4U;
3034       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
3035       msgdigest += 4U;
3036       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
3037       msgdigest += 4U;
3038       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[8]);
3039       msgdigest += 4U;
3040       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[9]);
3041       msgdigest += 4U;
3042       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[10]);
3043       msgdigest += 4U;
3044       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[11]);
3045       msgdigest += 4U;
3046       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[12]);
3047       msgdigest += 4U;
3048       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[13]);
3049       msgdigest += 4U;
3050       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[14]);
3051       msgdigest += 4U;
3052       *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[15]);
3053 
3054       break;
3055 #endif /* defined(HASH_ALGOSELECTION_SHA512)*/
3056     default:
3057       break;
3058   }
3059 }
3060 
3061 /**
3062   * @brief  Handle HASH processing Timeout.
3063   * @param  hhash HASH handle.
3064   * @param  Flag specifies the HASH flag to check.
3065   * @param  Status the Flag status (SET or RESET).
3066   * @param  Timeout Timeout duration.
3067   * @retval HAL status
3068   */
HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef * hhash,uint32_t Flag,FlagStatus Status,uint32_t Timeout)3069 static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status,
3070                                                      uint32_t Timeout)
3071 {
3072   uint32_t tickstart = HAL_GetTick();
3073 
3074   /* Wait until flag is set */
3075   if (Status == RESET)
3076   {
3077     while (__HAL_HASH_GET_FLAG(hhash, Flag) == RESET)
3078     {
3079       /* Check for the Timeout */
3080       if (Timeout != HAL_MAX_DELAY)
3081       {
3082         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3083         {
3084           /* Set State to Ready to be able to restart later on */
3085           hhash->State  = HAL_HASH_STATE_READY;
3086           hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
3087           /* Process Unlocked */
3088           __HAL_UNLOCK(hhash);
3089           return HAL_ERROR;
3090         }
3091       }
3092     }
3093   }
3094   else
3095   {
3096     while (__HAL_HASH_GET_FLAG(hhash, Flag) != RESET)
3097     {
3098       /* Check for the Timeout */
3099       if (Timeout != HAL_MAX_DELAY)
3100       {
3101         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3102         {
3103           /* Set State to Ready to be able to restart later on */
3104           hhash->State  = HAL_HASH_STATE_READY;
3105           hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
3106           /* Process Unlocked */
3107           __HAL_UNLOCK(hhash);
3108 
3109           return HAL_ERROR;
3110         }
3111       }
3112     }
3113   }
3114   return HAL_OK;
3115 }
3116 
3117 /**
3118   * @}
3119   */
3120 
3121 
3122 #endif /* HAL_HASH_MODULE_ENABLED */
3123 
3124 #endif /*  HASH*/
3125 /**
3126   * @}
3127   */
3128 
3129 /**
3130   * @}
3131   */
3132