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