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