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