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