1 /**
2   ******************************************************************************
3   * @file    stm32f7xx_hal_hash.c
4   * @author  MCD Application Team
5   * @version V1.0.1
6   * @date    25-June-2015
7   * @brief   HASH HAL module driver.
8   *          This file provides firmware functions to manage the following
9   *          functionalities of the HASH peripheral:
10   *           + Initialization and de-initialization functions
11   *           + HASH/HMAC Processing functions by algorithm using polling mode
12   *           + HASH/HMAC functions by algorithm using interrupt mode
13   *           + HASH/HMAC functions by algorithm using DMA mode
14   *           + Peripheral State functions
15   *
16   @verbatim
17   ==============================================================================
18                      ##### How to use this driver #####
19   ==============================================================================
20     [..]
21     The HASH HAL driver can be used as follows:
22     (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
23         (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
24         (##) In case of using processing APIs based on interrupts (e.g. HAL_HMAC_SHA1_Start_IT())
25             (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
26             (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
27             (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
28         (##) In case of using DMA to control data transfer (e.g. HAL_HMAC_SHA1_Start_DMA())
29             (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
30             (+++) Configure and enable one DMA stream one for managing data transfer from
31                 memory to peripheral (input stream). Managing data transfer from
32                 peripheral to memory can be performed only using CPU
33             (+++) Associate the initialized DMA handle to the HASH DMA handle
34                 using  __HAL_LINKDMA()
35             (+++) Configure the priority and enable the NVIC for the transfer complete
36                 interrupt on the DMA Stream using HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
37     (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
38         (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
39         (##) For HMAC, the encryption key.
40         (##) For HMAC, the key size used for encryption.
41     (#)Three processing functions are available:
42         (##) Polling mode: processing APIs are blocking functions
43              i.e. they process the data and wait till the digest computation is finished
44              e.g. HAL_HASH_SHA1_Start()
45         (##) Interrupt mode: encryption and decryption APIs are not blocking functions
46                 i.e. they process the data under interrupt
47                 e.g. HAL_HASH_SHA1_Start_IT()
48         (##) DMA mode: processing APIs are not blocking functions and the CPU is
49              not used for data transfer i.e. the data transfer is ensured by DMA
50                 e.g. HAL_HASH_SHA1_Start_DMA()
51     (#)When the processing function is called at first time after HAL_HASH_Init()
52        the HASH peripheral is initialized and processes the buffer in input.
53        After that, the digest computation is started.
54        When processing multi-buffer use the accumulate function to write the
55        data in the peripheral without starting the digest computation. In last
56        buffer use the start function to input the last buffer ans start the digest
57        computation.
58        (##) e.g. HAL_HASH_SHA1_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
59        (##) write (n-1)th data buffer in the peripheral without starting the digest computation
60        (##) HAL_HASH_SHA1_Start() : write (n)th data buffer in the peripheral and start the digest computation
61     (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
62     (#)In case of using DMA, call the DMA start processing e.g. HAL_HASH_SHA1_Start_DMA().
63        After that, call the finish function in order to get the digest value
64        e.g. HAL_HASH_SHA1_Finish()
65     (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
66 
67   @endverbatim
68   ******************************************************************************
69   * @attention
70   *
71   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
72   *
73   * Redistribution and use in source and binary forms, with or without modification,
74   * are permitted provided that the following conditions are met:
75   *   1. Redistributions of source code must retain the above copyright notice,
76   *      this list of conditions and the following disclaimer.
77   *   2. Redistributions in binary form must reproduce the above copyright notice,
78   *      this list of conditions and the following disclaimer in the documentation
79   *      and/or other materials provided with the distribution.
80   *   3. Neither the name of STMicroelectronics nor the names of its contributors
81   *      may be used to endorse or promote products derived from this software
82   *      without specific prior written permission.
83   *
84   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
85   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
86   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
88   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
89   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
90   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
91   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
92   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
93   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94   *
95   ******************************************************************************
96   */
97 
98 /* Includes ------------------------------------------------------------------*/
99 #include "stm32f7xx_hal.h"
100 
101 /** @addtogroup STM32F7xx_HAL_Driver
102   * @{
103   */
104 
105 #if defined(STM32F756xx)
106 
107 /** @defgroup HASH HASH
108   * @brief HASH HAL module driver.
109   * @{
110   */
111 #ifdef HAL_HASH_MODULE_ENABLED
112 
113 /* Private typedef -----------------------------------------------------------*/
114 /* Private define ------------------------------------------------------------*/
115 /* Private macro -------------------------------------------------------------*/
116 /* Private variables ---------------------------------------------------------*/
117 /* Private function prototypes -----------------------------------------------*/
118 /** @defgroup HASH_Private_Functions HASH Private Functions
119   * @{
120   */
121 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
122 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
123 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
124 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size);
125 /**
126   * @}
127   */
128 
129 /* Private functions ---------------------------------------------------------*/
130 /** @addtogroup HASH_Private_Functions
131   * @{
132   */
133 
134 /**
135   * @brief  DMA HASH Input Data complete callback.
136   * @param  hdma: DMA handle
137   * @retval None
138   */
HASH_DMAXferCplt(DMA_HandleTypeDef * hdma)139 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
140 {
141     HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
142     uint32_t inputaddr = 0;
143     uint32_t buffersize = 0;
144 
145     if ((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE) {
146         /* Disable the DMA transfer */
147         HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
148 
149         /* Change HASH peripheral state */
150         hhash->State = HAL_HASH_STATE_READY;
151 
152         /* Call Input data transfer complete callback */
153         HAL_HASH_InCpltCallback(hhash);
154     } else {
155         /* Increment Interrupt counter */
156         hhash->HashInCount++;
157         /* Disable the DMA transfer before starting the next transfer */
158         HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
159 
160         if (hhash->HashInCount <= 2) {
161             /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
162             if (hhash->HashInCount == 1) {
163                 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
164                 buffersize = hhash->HashBuffSize;
165             }
166             /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
167             else if (hhash->HashInCount == 2) {
168                 inputaddr = (uint32_t)hhash->Init.pKey;
169                 buffersize = hhash->Init.KeySize;
170             }
171             /* Configure the number of valid bits in last word of the message */
172             MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8 * (buffersize % 4));
173 
174             /* Set the HASH DMA transfer complete */
175             hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
176 
177             /* Enable the DMA In DMA Stream */
178             HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
179 
180             /* Enable DMA requests */
181             HASH->CR |= (HASH_CR_DMAE);
182         } else {
183             /* Disable the DMA transfer */
184             HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
185 
186             /* Reset the InCount */
187             hhash->HashInCount = 0;
188 
189             /* Change HASH peripheral state */
190             hhash->State = HAL_HASH_STATE_READY;
191 
192             /* Call Input data transfer complete callback */
193             HAL_HASH_InCpltCallback(hhash);
194         }
195     }
196 }
197 
198 /**
199   * @brief  DMA HASH communication error callback.
200   * @param  hdma: DMA handle
201   * @retval None
202   */
HASH_DMAError(DMA_HandleTypeDef * hdma)203 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
204 {
205     HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
206     hhash->State= HAL_HASH_STATE_READY;
207     HAL_HASH_ErrorCallback(hhash);
208 }
209 
210 /**
211   * @brief  Writes the input buffer in data register.
212   * @param  pInBuffer: Pointer to input buffer
213   * @param  Size: The size of input buffer
214   * @retval None
215   */
HASH_WriteData(uint8_t * pInBuffer,uint32_t Size)216 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
217 {
218     uint32_t buffercounter;
219     uint32_t inputaddr = (uint32_t) pInBuffer;
220 
221     for (buffercounter = 0; buffercounter < Size; buffercounter+=4) {
222         HASH->DIN = *(uint32_t*)inputaddr;
223         inputaddr+=4;
224     }
225 }
226 
227 /**
228   * @brief  Provides the message digest result.
229   * @param  pMsgDigest: Pointer to the message digest
230   * @param  Size: The size of the message digest in bytes
231   * @retval None
232   */
HASH_GetDigest(uint8_t * pMsgDigest,uint8_t Size)233 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
234 {
235     uint32_t msgdigest = (uint32_t)pMsgDigest;
236 
237     switch (Size) {
238         case 16:
239             /* Read the message digest */
240             *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
241             msgdigest+=4;
242             *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
243             msgdigest+=4;
244             *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
245             msgdigest+=4;
246             *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
247             break;
248         case 20:
249             /* Read the message digest */
250             *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
251             msgdigest+=4;
252             *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
253             msgdigest+=4;
254             *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
255             msgdigest+=4;
256             *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
257             msgdigest+=4;
258             *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
259             break;
260         case 28:
261             /* Read the message digest */
262             *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
263             msgdigest+=4;
264             *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
265             msgdigest+=4;
266             *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
267             msgdigest+=4;
268             *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
269             msgdigest+=4;
270             *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
271             msgdigest+=4;
272             *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
273             msgdigest+=4;
274             *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
275             break;
276         case 32:
277             /* Read the message digest */
278             *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
279             msgdigest+=4;
280             *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
281             msgdigest+=4;
282             *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
283             msgdigest+=4;
284             *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
285             msgdigest+=4;
286             *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
287             msgdigest+=4;
288             *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
289             msgdigest+=4;
290             *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
291             msgdigest+=4;
292             *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
293             break;
294         default:
295             break;
296     }
297 }
298 
299 /**
300   * @}
301   */
302 
303 /* Exported functions --------------------------------------------------------*/
304 /** @addtogroup HASH_Exported_Functions
305   * @{
306   */
307 
308 
309 /** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions
310  *  @brief    Initialization and Configuration functions.
311  *
312 @verbatim
313  ===============================================================================
314               ##### Initialization and de-initialization functions #####
315  ===============================================================================
316     [..]  This section provides functions allowing to:
317       (+) Initialize the HASH according to the specified parameters
318           in the HASH_InitTypeDef and creates the associated handle.
319       (+) DeInitialize the HASH peripheral.
320       (+) Initialize the HASH MSP.
321       (+) DeInitialize HASH MSP.
322 
323 @endverbatim
324   * @{
325   */
326 
327 /**
328   * @brief  Initializes the HASH according to the specified parameters in the
329             HASH_HandleTypeDef and creates the associated handle.
330   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
331   *         the configuration information for HASH module
332   * @retval HAL status
333   */
HAL_HASH_Init(HASH_HandleTypeDef * hhash)334 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
335 {
336     /* Check the hash handle allocation */
337     if (hhash == NULL) {
338         return HAL_ERROR;
339     }
340 
341     /* Check the parameters */
342     assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
343 
344     if (hhash->State == HAL_HASH_STATE_RESET) {
345         /* Allocate lock resource and initialize it */
346         hhash->Lock = HAL_UNLOCKED;
347         /* Init the low level hardware */
348         HAL_HASH_MspInit(hhash);
349     }
350 
351     /* Change the HASH state */
352     hhash->State = HAL_HASH_STATE_BUSY;
353 
354     /* Reset HashInCount, HashBuffSize and HashITCounter */
355     hhash->HashInCount = 0;
356     hhash->HashBuffSize = 0;
357     hhash->HashITCounter = 0;
358 
359     /* Set the data type */
360     HASH->CR |= (uint32_t) (hhash->Init.DataType);
361 
362     /* Change the HASH state */
363     hhash->State = HAL_HASH_STATE_READY;
364 
365     /* Set the default HASH phase */
366     hhash->Phase = HAL_HASH_PHASE_READY;
367 
368     /* Return function status */
369     return HAL_OK;
370 }
371 
372 /**
373   * @brief  DeInitializes the HASH peripheral.
374   * @note   This API must be called before starting a new processing.
375   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
376   *         the configuration information for HASH module
377   * @retval HAL status
378   */
HAL_HASH_DeInit(HASH_HandleTypeDef * hhash)379 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
380 {
381     /* Check the HASH handle allocation */
382     if (hhash == NULL) {
383         return HAL_ERROR;
384     }
385 
386     /* Change the HASH state */
387     hhash->State = HAL_HASH_STATE_BUSY;
388 
389     /* Set the default HASH phase */
390     hhash->Phase = HAL_HASH_PHASE_READY;
391 
392     /* Reset HashInCount, HashBuffSize and HashITCounter */
393     hhash->HashInCount = 0;
394     hhash->HashBuffSize = 0;
395     hhash->HashITCounter = 0;
396 
397     /* DeInit the low level hardware */
398     HAL_HASH_MspDeInit(hhash);
399 
400     /* Change the HASH state */
401     hhash->State = HAL_HASH_STATE_RESET;
402 
403     /* Release Lock */
404     __HAL_UNLOCK(hhash);
405 
406     /* Return function status */
407     return HAL_OK;
408 }
409 
410 /**
411   * @brief  Initializes the HASH MSP.
412   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
413   *         the configuration information for HASH module
414   * @retval None
415   */
HAL_HASH_MspInit(HASH_HandleTypeDef * hhash)416 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
417 {
418     /* NOTE: This function Should not be modified, when the callback is needed,
419              the HAL_HASH_MspInit could be implemented in the user file
420      */
421 }
422 
423 /**
424   * @brief  DeInitializes HASH MSP.
425   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
426   *         the configuration information for HASH module
427   * @retval None
428   */
HAL_HASH_MspDeInit(HASH_HandleTypeDef * hhash)429 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
430 {
431     /* NOTE: This function Should not be modified, when the callback is needed,
432              the HAL_HASH_MspDeInit could be implemented in the user file
433      */
434 }
435 
436 /**
437   * @brief  Input data transfer complete callback.
438   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
439   *         the configuration information for HASH module
440   * @retval None
441   */
HAL_HASH_InCpltCallback(HASH_HandleTypeDef * hhash)442 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
443 {
444     /* NOTE: This function Should not be modified, when the callback is needed,
445              the HAL_HASH_InCpltCallback could be implemented in the user file
446      */
447 }
448 
449 /**
450   * @brief  Data transfer Error callback.
451   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
452   *         the configuration information for HASH module
453   * @retval None
454   */
HAL_HASH_ErrorCallback(HASH_HandleTypeDef * hhash)455 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
456 {
457     /* NOTE: This function Should not be modified, when the callback is needed,
458              the HAL_HASH_ErrorCallback could be implemented in the user file
459      */
460 }
461 
462 /**
463   * @brief  Digest computation complete callback. It is used only with interrupt.
464   * @note   This callback is not relevant with DMA.
465   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
466   *         the configuration information for HASH module
467   * @retval None
468   */
HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef * hhash)469 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
470 {
471     /* NOTE: This function Should not be modified, when the callback is needed,
472              the HAL_HASH_DgstCpltCallback could be implemented in the user file
473      */
474 }
475 
476 /**
477   * @}
478   */
479 
480 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions using polling mode
481  *  @brief   processing functions using polling mode
482  *
483 @verbatim
484  ===============================================================================
485               ##### HASH processing using polling mode functions#####
486  ===============================================================================
487     [..]  This section provides functions allowing to calculate in polling mode
488           the hash value using one of the following algorithms:
489       (+) MD5
490       (+) SHA1
491 
492 @endverbatim
493   * @{
494   */
495 
496 /**
497   * @brief  Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
498             The digest is available in pOutBuffer.
499   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
500   *         the configuration information for HASH module
501   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
502   * @param  Size: Length of the input buffer in bytes.
503   *          If the Size is multiple of 64 bytes, appending the input buffer is possible.
504   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware
505   *          and appending the input buffer is no more possible.
506   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
507   * @param  Timeout: Timeout value
508   * @retval HAL status
509   */
HAL_HASH_MD5_Start(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size,uint8_t * pOutBuffer,uint32_t Timeout)510 HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
511 {
512     uint32_t tickstart = 0;
513 
514     /* Process Locked */
515     __HAL_LOCK(hhash);
516 
517     /* Change the HASH state */
518     hhash->State = HAL_HASH_STATE_BUSY;
519 
520     /* Check if initialization phase has already been performed */
521     if (hhash->Phase == HAL_HASH_PHASE_READY) {
522         /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
523            the message digest of a new message */
524         HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
525     }
526 
527     /* Set the phase */
528     hhash->Phase = HAL_HASH_PHASE_PROCESS;
529 
530     /* Configure the number of valid bits in last word of the message */
531     __HAL_HASH_SET_NBVALIDBITS(Size);
532 
533     /* Write input buffer in data register */
534     HASH_WriteData(pInBuffer, Size);
535 
536     /* Start the digest calculation */
537     __HAL_HASH_START_DIGEST();
538 
539     /* Get tick */
540     tickstart = HAL_GetTick();
541 
542     while (HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY)) {
543         /* Check for the Timeout */
544         if (Timeout != HAL_MAX_DELAY) {
545             if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
546                 /* Change state */
547                 hhash->State = HAL_HASH_STATE_TIMEOUT;
548 
549                 /* Process Unlocked */
550                 __HAL_UNLOCK(hhash);
551 
552                 return HAL_TIMEOUT;
553             }
554         }
555     }
556 
557     /* Read the message digest */
558     HASH_GetDigest(pOutBuffer, 16);
559 
560     /* Change the HASH state */
561     hhash->State = HAL_HASH_STATE_READY;
562 
563     /* Process Unlocked */
564     __HAL_UNLOCK(hhash);
565 
566     /* Return function status */
567     return HAL_OK;
568 }
569 
570 /**
571   * @brief  Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
572   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
573   *         the configuration information for HASH module
574   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
575   * @param  Size: Length of the input buffer in bytes.
576   *          If the Size is multiple of 64 bytes, appending the input buffer is possible.
577   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware
578   *          and appending the input buffer is no more possible.
579   * @retval HAL status
580   */
HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size)581 HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
582 {
583     /* Process Locked */
584     __HAL_LOCK(hhash);
585 
586     /* Change the HASH state */
587     hhash->State = HAL_HASH_STATE_BUSY;
588 
589     /* Check if initialization phase has already been performed */
590     if (hhash->Phase == HAL_HASH_PHASE_READY) {
591         /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
592            the message digest of a new message */
593         HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
594     }
595 
596     /* Set the phase */
597     hhash->Phase = HAL_HASH_PHASE_PROCESS;
598 
599     /* Configure the number of valid bits in last word of the message */
600     __HAL_HASH_SET_NBVALIDBITS(Size);
601 
602     /* Write input buffer in data register */
603     HASH_WriteData(pInBuffer, Size);
604 
605     /* Change the HASH state */
606     hhash->State = HAL_HASH_STATE_READY;
607 
608     /* Process Unlocked */
609     __HAL_UNLOCK(hhash);
610 
611     /* Return function status */
612     return HAL_OK;
613 }
614 
615 /**
616   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
617             The digest is available in pOutBuffer.
618   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
619   *         the configuration information for HASH module
620   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
621   * @param  Size: Length of the input buffer in bytes.
622   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
623   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
624   * @param  Timeout: Timeout value
625   * @retval HAL status
626   */
HAL_HASH_SHA1_Start(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size,uint8_t * pOutBuffer,uint32_t Timeout)627 HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
628 {
629     uint32_t tickstart = 0;
630 
631     /* Process Locked */
632     __HAL_LOCK(hhash);
633 
634     /* Change the HASH state */
635     hhash->State = HAL_HASH_STATE_BUSY;
636 
637     /* Check if initialization phase has already been performed */
638     if (hhash->Phase == HAL_HASH_PHASE_READY) {
639         /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
640            the message digest of a new message */
641         HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
642     }
643 
644     /* Set the phase */
645     hhash->Phase = HAL_HASH_PHASE_PROCESS;
646 
647     /* Configure the number of valid bits in last word of the message */
648     __HAL_HASH_SET_NBVALIDBITS(Size);
649 
650     /* Write input buffer in data register */
651     HASH_WriteData(pInBuffer, Size);
652 
653     /* Start the digest calculation */
654     __HAL_HASH_START_DIGEST();
655 
656     /* Get tick */
657     tickstart = HAL_GetTick();
658 
659     while (HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY)) {
660         /* Check for the Timeout */
661         if (Timeout != HAL_MAX_DELAY) {
662             if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
663                 /* Change state */
664                 hhash->State = HAL_HASH_STATE_TIMEOUT;
665 
666                 /* Process Unlocked */
667                 __HAL_UNLOCK(hhash);
668 
669                 return HAL_TIMEOUT;
670             }
671         }
672     }
673 
674     /* Read the message digest */
675     HASH_GetDigest(pOutBuffer, 20);
676 
677     /* Change the HASH state */
678     hhash->State = HAL_HASH_STATE_READY;
679 
680     /* Process Unlocked */
681     __HAL_UNLOCK(hhash);
682 
683     /* Return function status */
684     return HAL_OK;
685 }
686 
687 /**
688   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
689   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
690   *         the configuration information for HASH module
691   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
692   * @param  Size: Length of the input buffer in bytes.
693   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
694   * @note  Input buffer size in bytes must be a multiple of 4 otherwise the digest computation is corrupted.
695   * @retval HAL status
696   */
HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size)697 HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
698 {
699     /* Check the parameters */
700     assert_param(IS_HASH_SHA1_BUFFER_SIZE(Size));
701 
702     /* Process Locked */
703     __HAL_LOCK(hhash);
704 
705     /* Change the HASH state */
706     hhash->State = HAL_HASH_STATE_BUSY;
707 
708     /* Check if initialization phase has already been performed */
709     if (hhash->Phase == HAL_HASH_PHASE_READY) {
710         /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
711            the message digest of a new message */
712         HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
713     }
714 
715     /* Set the phase */
716     hhash->Phase = HAL_HASH_PHASE_PROCESS;
717 
718     /* Configure the number of valid bits in last word of the message */
719     __HAL_HASH_SET_NBVALIDBITS(Size);
720 
721     /* Write input buffer in data register */
722     HASH_WriteData(pInBuffer, Size);
723 
724     /* Change the HASH state */
725     hhash->State = HAL_HASH_STATE_READY;
726 
727     /* Process Unlocked */
728     __HAL_UNLOCK(hhash);
729 
730     /* Return function status */
731     return HAL_OK;
732 }
733 
734 /**
735   * @}
736   */
737 
738 /** @defgroup HASH_Exported_Functions_Group3 HASH processing functions using interrupt mode
739  *  @brief   processing functions using interrupt mode.
740  *
741 @verbatim
742  ===============================================================================
743               ##### HASH processing using interrupt mode functions #####
744  ===============================================================================
745     [..]  This section provides functions allowing to calculate in interrupt mode
746           the hash value using one of the following algorithms:
747       (+) MD5
748       (+) SHA1
749 
750 @endverbatim
751   * @{
752   */
753 
754 /**
755   * @brief  Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
756   *         The digest is available in pOutBuffer.
757   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
758   *         the configuration information for HASH module
759   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
760   * @param  Size: Length of the input buffer in bytes.
761   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
762   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
763   * @retval HAL status
764   */
HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size,uint8_t * pOutBuffer)765 HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
766 {
767     uint32_t inputaddr;
768     uint32_t outputaddr;
769     uint32_t buffercounter;
770     uint32_t inputcounter;
771 
772     /* Process Locked */
773     __HAL_LOCK(hhash);
774 
775     if (hhash->State == HAL_HASH_STATE_READY) {
776         /* Change the HASH state */
777         hhash->State = HAL_HASH_STATE_BUSY;
778 
779         hhash->HashInCount = Size;
780         hhash->pHashInBuffPtr = pInBuffer;
781         hhash->pHashOutBuffPtr = pOutBuffer;
782 
783         /* Check if initialization phase has already been performed */
784         if (hhash->Phase == HAL_HASH_PHASE_READY) {
785             /* Select the SHA1 mode */
786             HASH->CR |= HASH_ALGOSELECTION_MD5;
787             /* Reset the HASH processor core, so that the HASH will be ready to compute
788                the message digest of a new message */
789             HASH->CR |= HASH_CR_INIT;
790         }
791 
792         /* Reset interrupt counter */
793         hhash->HashITCounter = 0;
794 
795         /* Set the phase */
796         hhash->Phase = HAL_HASH_PHASE_PROCESS;
797 
798         /* Process Unlocked */
799         __HAL_UNLOCK(hhash);
800 
801         /* Enable Interrupts */
802         HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
803 
804         /* Return function status */
805         return HAL_OK;
806     }
807     if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS)) {
808         outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
809         /* Read the Output block from the Output FIFO */
810         *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
811         outputaddr+=4;
812         *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
813         outputaddr+=4;
814         *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
815         outputaddr+=4;
816         *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
817 
818         if (hhash->HashInCount == 0) {
819             /* Disable Interrupts */
820             HASH->IMR = 0;
821             /* Change the HASH state */
822             hhash->State = HAL_HASH_STATE_READY;
823             /* Call digest computation complete callback */
824             HAL_HASH_DgstCpltCallback(hhash);
825 
826             /* Process Unlocked */
827             __HAL_UNLOCK(hhash);
828 
829             /* Return function status */
830             return HAL_OK;
831         }
832     }
833 
834     if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) {
835         if (hhash->HashInCount >= 68) {
836             inputaddr = (uint32_t)hhash->pHashInBuffPtr;
837             /* Write the Input block in the Data IN register */
838             for (buffercounter = 0; buffercounter < 64; buffercounter+=4) {
839                 HASH->DIN = *(uint32_t*)inputaddr;
840                 inputaddr+=4;
841             }
842             if (hhash->HashITCounter == 0) {
843                 HASH->DIN = *(uint32_t*)inputaddr;
844 
845                 if (hhash->HashInCount >= 68) {
846                     /* Decrement buffer counter */
847                     hhash->HashInCount -= 68;
848                     hhash->pHashInBuffPtr+= 68;
849                 } else {
850                     hhash->HashInCount = 0;
851                     hhash->pHashInBuffPtr+= hhash->HashInCount;
852                 }
853                 /* Set Interrupt counter */
854                 hhash->HashITCounter = 1;
855             } else {
856                 /* Decrement buffer counter */
857                 hhash->HashInCount -= 64;
858                 hhash->pHashInBuffPtr+= 64;
859             }
860         } else {
861             /* Get the buffer address */
862             inputaddr = (uint32_t)hhash->pHashInBuffPtr;
863             /* Get the buffer counter */
864             inputcounter = hhash->HashInCount;
865             /* Disable Interrupts */
866             HASH->IMR &= ~(HASH_IT_DINI);
867             /* Configure the number of valid bits in last word of the message */
868             __HAL_HASH_SET_NBVALIDBITS(inputcounter);
869 
870             if ((inputcounter > 4) && (inputcounter%4)) {
871                 inputcounter = (inputcounter+4-inputcounter%4);
872             } else if ((inputcounter < 4) && (inputcounter != 0)) {
873                 inputcounter = 4;
874             }
875 
876             /* Write the Input block in the Data IN register */
877             for (buffercounter = 0; buffercounter < inputcounter/4; buffercounter++) {
878                 HASH->DIN = *(uint32_t*)inputaddr;
879                 inputaddr+=4;
880             }
881             /* Start the digest calculation */
882             __HAL_HASH_START_DIGEST();
883             /* Reset buffer counter */
884             hhash->HashInCount = 0;
885             /* Call Input data transfer complete callback */
886             HAL_HASH_InCpltCallback(hhash);
887         }
888     }
889 
890     /* Process Unlocked */
891     __HAL_UNLOCK(hhash);
892 
893     /* Return function status */
894     return HAL_OK;
895 }
896 
897 /**
898   * @brief  Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
899   *         The digest is available in pOutBuffer.
900   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
901   *         the configuration information for HASH module
902   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
903   * @param  Size: Length of the input buffer in bytes.
904   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
905   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
906   * @retval HAL status
907   */
HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size,uint8_t * pOutBuffer)908 HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
909 {
910     uint32_t inputaddr;
911     uint32_t outputaddr;
912     uint32_t buffercounter;
913     uint32_t inputcounter;
914 
915     /* Process Locked */
916     __HAL_LOCK(hhash);
917 
918     if (hhash->State == HAL_HASH_STATE_READY) {
919         /* Change the HASH state */
920         hhash->State = HAL_HASH_STATE_BUSY;
921 
922         hhash->HashInCount = Size;
923         hhash->pHashInBuffPtr = pInBuffer;
924         hhash->pHashOutBuffPtr = pOutBuffer;
925 
926         /* Check if initialization phase has already been performed */
927         if (hhash->Phase == HAL_HASH_PHASE_READY) {
928             /* Select the SHA1 mode */
929             HASH->CR |= HASH_ALGOSELECTION_SHA1;
930             /* Reset the HASH processor core, so that the HASH will be ready to compute
931                the message digest of a new message */
932             HASH->CR |= HASH_CR_INIT;
933         }
934 
935         /* Reset interrupt counter */
936         hhash->HashITCounter = 0;
937 
938         /* Set the phase */
939         hhash->Phase = HAL_HASH_PHASE_PROCESS;
940 
941         /* Process Unlocked */
942         __HAL_UNLOCK(hhash);
943 
944         /* Enable Interrupts */
945         HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
946 
947         /* Return function status */
948         return HAL_OK;
949     }
950     if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS)) {
951         outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
952         /* Read the Output block from the Output FIFO */
953         *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
954         outputaddr+=4;
955         *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
956         outputaddr+=4;
957         *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
958         outputaddr+=4;
959         *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
960         outputaddr+=4;
961         *(uint32_t*)(outputaddr) = __REV(HASH->HR[4]);
962         if (hhash->HashInCount == 0) {
963             /* Disable Interrupts */
964             HASH->IMR = 0;
965             /* Change the HASH state */
966             hhash->State = HAL_HASH_STATE_READY;
967             /* Call digest computation complete callback */
968             HAL_HASH_DgstCpltCallback(hhash);
969 
970             /* Process Unlocked */
971             __HAL_UNLOCK(hhash);
972 
973             /* Return function status */
974             return HAL_OK;
975         }
976     }
977     if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) {
978         if (hhash->HashInCount >= 68) {
979             inputaddr = (uint32_t)hhash->pHashInBuffPtr;
980             /* Write the Input block in the Data IN register */
981             for (buffercounter = 0; buffercounter < 64; buffercounter+=4) {
982                 HASH->DIN = *(uint32_t*)inputaddr;
983                 inputaddr+=4;
984             }
985             if (hhash->HashITCounter == 0) {
986                 HASH->DIN = *(uint32_t*)inputaddr;
987 
988                 if (hhash->HashInCount >= 68) {
989                     /* Decrement buffer counter */
990                     hhash->HashInCount -= 68;
991                     hhash->pHashInBuffPtr+= 68;
992                 } else {
993                     hhash->HashInCount = 0;
994                     hhash->pHashInBuffPtr+= hhash->HashInCount;
995                 }
996                 /* Set Interrupt counter */
997                 hhash->HashITCounter = 1;
998             } else {
999                 /* Decrement buffer counter */
1000                 hhash->HashInCount -= 64;
1001                 hhash->pHashInBuffPtr+= 64;
1002             }
1003         } else {
1004             /* Get the buffer address */
1005             inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1006             /* Get the buffer counter */
1007             inputcounter = hhash->HashInCount;
1008             /* Disable Interrupts */
1009             HASH->IMR &= ~(HASH_IT_DINI);
1010             /* Configure the number of valid bits in last word of the message */
1011             __HAL_HASH_SET_NBVALIDBITS(inputcounter);
1012 
1013             if ((inputcounter > 4) && (inputcounter%4)) {
1014                 inputcounter = (inputcounter+4-inputcounter%4);
1015             } else if ((inputcounter < 4) && (inputcounter != 0)) {
1016                 inputcounter = 4;
1017             }
1018             /* Write the Input block in the Data IN register */
1019             for (buffercounter = 0; buffercounter < inputcounter/4; buffercounter++) {
1020                 HASH->DIN = *(uint32_t*)inputaddr;
1021                 inputaddr+=4;
1022             }
1023             /* Start the digest calculation */
1024             __HAL_HASH_START_DIGEST();
1025             /* Reset buffer counter */
1026             hhash->HashInCount = 0;
1027             /* Call Input data transfer complete callback */
1028             HAL_HASH_InCpltCallback(hhash);
1029         }
1030     }
1031 
1032     /* Process Unlocked */
1033     __HAL_UNLOCK(hhash);
1034 
1035     /* Return function status */
1036     return HAL_OK;
1037 }
1038 
1039 /**
1040   * @brief This function handles HASH interrupt request.
1041   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1042   *         the configuration information for HASH module
1043   * @retval None
1044   */
HAL_HASH_IRQHandler(HASH_HandleTypeDef * hhash)1045 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
1046 {
1047     switch (HASH->CR & HASH_CR_ALGO) {
1048         case HASH_ALGOSELECTION_MD5:
1049             HAL_HASH_MD5_Start_IT(hhash, NULL, 0, NULL);
1050             break;
1051 
1052         case HASH_ALGOSELECTION_SHA1:
1053             HAL_HASH_SHA1_Start_IT(hhash, NULL, 0, NULL);
1054             break;
1055 
1056         default:
1057             break;
1058     }
1059 }
1060 
1061 /**
1062   * @}
1063   */
1064 
1065 /** @defgroup HASH_Exported_Functions_Group4 HASH processing functions using DMA mode
1066  *  @brief   processing functions using DMA mode.
1067  *
1068 @verbatim
1069  ===============================================================================
1070               ##### HASH processing using DMA mode functions #####
1071  ===============================================================================
1072     [..]  This section provides functions allowing to calculate in DMA mode
1073           the hash value using one of the following algorithms:
1074       (+) MD5
1075       (+) SHA1
1076 
1077 @endverbatim
1078   * @{
1079   */
1080 
1081 /**
1082   * @brief  Initializes the HASH peripheral in MD5 mode then enables DMA to
1083             control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
1084   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1085   *         the configuration information for HASH module
1086   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1087   * @param  Size: Length of the input buffer in bytes.
1088   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1089   * @retval HAL status
1090   */
HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size)1091 HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1092 {
1093     uint32_t inputaddr  = (uint32_t)pInBuffer;
1094 
1095     /* Process Locked */
1096     __HAL_LOCK(hhash);
1097 
1098     /* Change the HASH state */
1099     hhash->State = HAL_HASH_STATE_BUSY;
1100 
1101     /* Check if initialization phase has already been performed */
1102     if (hhash->Phase == HAL_HASH_PHASE_READY) {
1103         /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
1104            the message digest of a new message */
1105         HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
1106     }
1107 
1108     /* Configure the number of valid bits in last word of the message */
1109     __HAL_HASH_SET_NBVALIDBITS(Size);
1110 
1111     /* Set the phase */
1112     hhash->Phase = HAL_HASH_PHASE_PROCESS;
1113 
1114     /* Set the HASH DMA transfer complete callback */
1115     hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1116     /* Set the DMA error callback */
1117     hhash->hdmain->XferErrorCallback = HASH_DMAError;
1118 
1119     /* Enable the DMA In DMA Stream */
1120     HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
1121 
1122     /* Enable DMA requests */
1123     HASH->CR |= (HASH_CR_DMAE);
1124 
1125     /* Process Unlocked */
1126     __HAL_UNLOCK(hhash);
1127 
1128     /* Return function status */
1129     return HAL_OK;
1130 }
1131 
1132 /**
1133   * @brief  Returns the computed digest in MD5 mode
1134   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1135   *         the configuration information for HASH module
1136   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
1137   * @param  Timeout: Timeout value
1138   * @retval HAL status
1139   */
HAL_HASH_MD5_Finish(HASH_HandleTypeDef * hhash,uint8_t * pOutBuffer,uint32_t Timeout)1140 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1141 {
1142     uint32_t tickstart = 0;
1143 
1144     /* Process Locked */
1145     __HAL_LOCK(hhash);
1146 
1147     /* Change HASH peripheral state */
1148     hhash->State = HAL_HASH_STATE_BUSY;
1149 
1150     /* Get tick */
1151     tickstart = HAL_GetTick();
1152 
1153     while (HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS)) {
1154         /* Check for the Timeout */
1155         if (Timeout != HAL_MAX_DELAY) {
1156             if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1157                 /* Change state */
1158                 hhash->State = HAL_HASH_STATE_TIMEOUT;
1159 
1160                 /* Process Unlocked */
1161                 __HAL_UNLOCK(hhash);
1162 
1163                 return HAL_TIMEOUT;
1164             }
1165         }
1166     }
1167 
1168     /* Read the message digest */
1169     HASH_GetDigest(pOutBuffer, 16);
1170 
1171     /* Change HASH peripheral state */
1172     hhash->State = HAL_HASH_STATE_READY;
1173 
1174     /* Process Unlocked */
1175     __HAL_UNLOCK(hhash);
1176 
1177     /* Return function status */
1178     return HAL_OK;
1179 }
1180 
1181 /**
1182   * @brief  Initializes the HASH peripheral in SHA1 mode then enables DMA to
1183             control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
1184   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1185   *         the configuration information for HASH module
1186   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1187   * @param  Size: Length of the input buffer in bytes.
1188   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1189   * @retval HAL status
1190   */
HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size)1191 HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1192 {
1193     uint32_t inputaddr  = (uint32_t)pInBuffer;
1194 
1195     /* Process Locked */
1196     __HAL_LOCK(hhash);
1197 
1198     /* Change the HASH state */
1199     hhash->State = HAL_HASH_STATE_BUSY;
1200 
1201     /* Check if initialization phase has already been performed */
1202     if (hhash->Phase == HAL_HASH_PHASE_READY) {
1203         /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
1204            the message digest of a new message */
1205         HASH->CR |= HASH_ALGOSELECTION_SHA1;
1206         HASH->CR |= HASH_CR_INIT;
1207     }
1208 
1209     /* Configure the number of valid bits in last word of the message */
1210     __HAL_HASH_SET_NBVALIDBITS(Size);
1211 
1212     /* Set the phase */
1213     hhash->Phase = HAL_HASH_PHASE_PROCESS;
1214 
1215     /* Set the HASH DMA transfer complete callback */
1216     hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1217     /* Set the DMA error callback */
1218     hhash->hdmain->XferErrorCallback = HASH_DMAError;
1219 
1220     /* Enable the DMA In DMA Stream */
1221     HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
1222 
1223     /* Enable DMA requests */
1224     HASH->CR |= (HASH_CR_DMAE);
1225 
1226     /* Process Unlocked */
1227     __HAL_UNLOCK(hhash);
1228 
1229     /* Return function status */
1230     return HAL_OK;
1231 }
1232 
1233 /**
1234   * @brief  Returns the computed digest in SHA1 mode.
1235   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1236   *         the configuration information for HASH module
1237   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1238   * @param  Timeout: Timeout value
1239   * @retval HAL status
1240   */
HAL_HASH_SHA1_Finish(HASH_HandleTypeDef * hhash,uint8_t * pOutBuffer,uint32_t Timeout)1241 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1242 {
1243     uint32_t tickstart = 0;
1244 
1245     /* Process Locked */
1246     __HAL_LOCK(hhash);
1247 
1248     /* Change HASH peripheral state */
1249     hhash->State = HAL_HASH_STATE_BUSY;
1250 
1251     /* Get tick */
1252     tickstart = HAL_GetTick();
1253     while (HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS)) {
1254         /* Check for the Timeout */
1255         if (Timeout != HAL_MAX_DELAY) {
1256             if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1257                 /* Change state */
1258                 hhash->State = HAL_HASH_STATE_TIMEOUT;
1259 
1260                 /* Process Unlocked */
1261                 __HAL_UNLOCK(hhash);
1262 
1263                 return HAL_TIMEOUT;
1264             }
1265         }
1266     }
1267 
1268     /* Read the message digest */
1269     HASH_GetDigest(pOutBuffer, 20);
1270 
1271     /* Change HASH peripheral state */
1272     hhash->State = HAL_HASH_STATE_READY;
1273 
1274     /* Process UnLock */
1275     __HAL_UNLOCK(hhash);
1276 
1277     /* Return function status */
1278     return HAL_OK;
1279 }
1280 
1281 
1282 /**
1283   * @}
1284   */
1285 
1286 /** @defgroup HASH_Exported_Functions_Group5 HASH-MAC (HMAC) processing functions using polling mode
1287  *  @brief   HMAC processing functions using polling mode .
1288  *
1289 @verbatim
1290  ===============================================================================
1291               ##### HMAC processing using polling mode functions #####
1292  ===============================================================================
1293     [..]  This section provides functions allowing to calculate in polling mode
1294           the HMAC value using one of the following algorithms:
1295       (+) MD5
1296       (+) SHA1
1297 
1298 @endverbatim
1299   * @{
1300   */
1301 
1302 /**
1303   * @brief  Initializes the HASH peripheral in HMAC MD5 mode
1304   *         then processes pInBuffer. The digest is available in pOutBuffer
1305   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1306   *         the configuration information for HASH module
1307   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1308   * @param  Size: Length of the input buffer in bytes.
1309   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1310   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1311   * @param  Timeout: Timeout value
1312   * @retval HAL status
1313   */
HAL_HMAC_MD5_Start(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size,uint8_t * pOutBuffer,uint32_t Timeout)1314 HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1315 {
1316     uint32_t tickstart = 0;
1317 
1318     /* Process Locked */
1319     __HAL_LOCK(hhash);
1320 
1321     /* Change the HASH state */
1322     hhash->State = HAL_HASH_STATE_BUSY;
1323 
1324     /* Check if initialization phase has already been performed */
1325     if (hhash->Phase == HAL_HASH_PHASE_READY) {
1326         /* Check if key size is greater than 64 bytes */
1327         if (hhash->Init.KeySize > 64) {
1328             /* Select the HMAC MD5 mode */
1329             HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1330         } else {
1331             /* Select the HMAC MD5 mode */
1332             HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1333         }
1334     }
1335 
1336     /* Set the phase */
1337     hhash->Phase = HAL_HASH_PHASE_PROCESS;
1338 
1339     /************************** STEP 1 ******************************************/
1340     /* Configure the number of valid bits in last word of the message */
1341     __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1342 
1343     /* Write input buffer in data register */
1344     HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1345 
1346     /* Start the digest calculation */
1347     __HAL_HASH_START_DIGEST();
1348 
1349     /* Get tick */
1350     tickstart = HAL_GetTick();
1351 
1352     while (HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY)) {
1353         /* Check for the Timeout */
1354         if (Timeout != HAL_MAX_DELAY) {
1355             if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1356                 /* Change state */
1357                 hhash->State = HAL_HASH_STATE_TIMEOUT;
1358 
1359                 /* Process Unlocked */
1360                 __HAL_UNLOCK(hhash);
1361 
1362                 return HAL_TIMEOUT;
1363             }
1364         }
1365     }
1366     /************************** STEP 2 ******************************************/
1367     /* Configure the number of valid bits in last word of the message */
1368     __HAL_HASH_SET_NBVALIDBITS(Size);
1369 
1370     /* Write input buffer in data register */
1371     HASH_WriteData(pInBuffer, Size);
1372 
1373     /* Start the digest calculation */
1374     __HAL_HASH_START_DIGEST();
1375 
1376     /* Get tick */
1377     tickstart = HAL_GetTick();
1378 
1379     while (HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY)) {
1380         /* Check for the Timeout */
1381         if (Timeout != HAL_MAX_DELAY) {
1382             if ((HAL_GetTick() - tickstart ) > Timeout) {
1383                 /* Change state */
1384                 hhash->State = HAL_HASH_STATE_TIMEOUT;
1385 
1386                 /* Process Unlocked */
1387                 __HAL_UNLOCK(hhash);
1388 
1389                 return HAL_TIMEOUT;
1390             }
1391         }
1392     }
1393     /************************** STEP 3 ******************************************/
1394     /* Configure the number of valid bits in last word of the message */
1395     __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1396 
1397     /* Write input buffer in data register */
1398     HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1399 
1400     /* Start the digest calculation */
1401     __HAL_HASH_START_DIGEST();
1402 
1403     /* Get tick */
1404     tickstart = HAL_GetTick();
1405 
1406     while (HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY)) {
1407         /* Check for the Timeout */
1408         if (Timeout != HAL_MAX_DELAY) {
1409             if ((HAL_GetTick() - tickstart ) > Timeout) {
1410                 /* Change state */
1411                 hhash->State = HAL_HASH_STATE_TIMEOUT;
1412 
1413                 /* Process Unlocked */
1414                 __HAL_UNLOCK(hhash);
1415 
1416                 return HAL_TIMEOUT;
1417             }
1418         }
1419     }
1420 
1421     /* Read the message digest */
1422     HASH_GetDigest(pOutBuffer, 16);
1423 
1424     /* Change the HASH state */
1425     hhash->State = HAL_HASH_STATE_READY;
1426 
1427     /* Process Unlocked */
1428     __HAL_UNLOCK(hhash);
1429 
1430     /* Return function status */
1431     return HAL_OK;
1432 }
1433 
1434 /**
1435   * @brief  Initializes the HASH peripheral in HMAC SHA1 mode
1436   *         then processes pInBuffer. The digest is available in pOutBuffer.
1437   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1438   *         the configuration information for HASH module
1439   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1440   * @param   Size: Length of the input buffer in bytes.
1441   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1442   * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1443   * @param  Timeout: Timeout value
1444   * @retval HAL status
1445   */
HAL_HMAC_SHA1_Start(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size,uint8_t * pOutBuffer,uint32_t Timeout)1446 HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1447 {
1448     uint32_t tickstart = 0;
1449 
1450     /* Process Locked */
1451     __HAL_LOCK(hhash);
1452 
1453     /* Change the HASH state */
1454     hhash->State = HAL_HASH_STATE_BUSY;
1455 
1456     /* Check if initialization phase has already been performed */
1457     if (hhash->Phase == HAL_HASH_PHASE_READY) {
1458         /* Check if key size is greater than 64 bytes */
1459         if (hhash->Init.KeySize > 64) {
1460             /* Select the HMAC SHA1 mode */
1461             HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1462         } else {
1463             /* Select the HMAC SHA1 mode */
1464             HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1465         }
1466     }
1467 
1468     /* Set the phase */
1469     hhash->Phase = HAL_HASH_PHASE_PROCESS;
1470 
1471     /************************** STEP 1 ******************************************/
1472     /* Configure the number of valid bits in last word of the message */
1473     __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1474 
1475     /* Write input buffer in data register */
1476     HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1477 
1478     /* Start the digest calculation */
1479     __HAL_HASH_START_DIGEST();
1480 
1481     /* Get tick */
1482     tickstart = HAL_GetTick();
1483 
1484     while (HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY)) {
1485         /* Check for the Timeout */
1486         if (Timeout != HAL_MAX_DELAY) {
1487             if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1488                 /* Change state */
1489                 hhash->State = HAL_HASH_STATE_TIMEOUT;
1490 
1491                 /* Process Unlocked */
1492                 __HAL_UNLOCK(hhash);
1493 
1494                 return HAL_TIMEOUT;
1495             }
1496         }
1497     }
1498     /************************** STEP 2 ******************************************/
1499     /* Configure the number of valid bits in last word of the message */
1500     __HAL_HASH_SET_NBVALIDBITS(Size);
1501 
1502     /* Write input buffer in data register */
1503     HASH_WriteData(pInBuffer, Size);
1504 
1505     /* Start the digest calculation */
1506     __HAL_HASH_START_DIGEST();
1507 
1508     /* Get tick */
1509     tickstart = HAL_GetTick();
1510 
1511     while (HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY)) {
1512         /* Check for the Timeout */
1513         if (Timeout != HAL_MAX_DELAY) {
1514             if ((HAL_GetTick() - tickstart ) > Timeout) {
1515                 /* Change state */
1516                 hhash->State = HAL_HASH_STATE_TIMEOUT;
1517 
1518                 /* Process Unlocked */
1519                 __HAL_UNLOCK(hhash);
1520 
1521                 return HAL_TIMEOUT;
1522             }
1523         }
1524     }
1525     /************************** STEP 3 ******************************************/
1526     /* Configure the number of valid bits in last word of the message */
1527     __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1528 
1529     /* Write input buffer in data register */
1530     HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1531 
1532     /* Start the digest calculation */
1533     __HAL_HASH_START_DIGEST();
1534 
1535     /* Get tick */
1536     tickstart = HAL_GetTick();
1537 
1538     while (HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY)) {
1539         /* Check for the Timeout */
1540         if (Timeout != HAL_MAX_DELAY) {
1541             if ((HAL_GetTick() - tickstart ) > Timeout) {
1542                 /* Change state */
1543                 hhash->State = HAL_HASH_STATE_TIMEOUT;
1544 
1545                 /* Process Unlocked */
1546                 __HAL_UNLOCK(hhash);
1547 
1548                 return HAL_TIMEOUT;
1549             }
1550         }
1551     }
1552     /* Read the message digest */
1553     HASH_GetDigest(pOutBuffer, 20);
1554 
1555     /* Change the HASH state */
1556     hhash->State = HAL_HASH_STATE_READY;
1557 
1558     /* Process Unlocked */
1559     __HAL_UNLOCK(hhash);
1560 
1561     /* Return function status */
1562     return HAL_OK;
1563 }
1564 
1565 /**
1566   * @}
1567   */
1568 
1569 /** @defgroup HASH_Exported_Functions_Group6 HASH-MAC (HMAC) processing functions using DMA mode
1570  *  @brief   HMAC processing functions using DMA mode .
1571  *
1572 @verbatim
1573  ===============================================================================
1574                 ##### HMAC processing using DMA mode functions #####
1575  ===============================================================================
1576     [..]  This section provides functions allowing to calculate in DMA mode
1577           the HMAC value using one of the following algorithms:
1578       (+) MD5
1579       (+) SHA1
1580 
1581 @endverbatim
1582   * @{
1583   */
1584 
1585 /**
1586   * @brief  Initializes the HASH peripheral in HMAC MD5 mode
1587   *         then enables DMA to control data transfer.
1588   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1589   *         the configuration information for HASH module
1590   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1591   * @param  Size: Length of the input buffer in bytes.
1592   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1593   * @retval HAL status
1594   */
HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size)1595 HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1596 {
1597     uint32_t inputaddr  = 0;
1598 
1599     /* Process Locked */
1600     __HAL_LOCK(hhash);
1601 
1602     /* Change the HASH state */
1603     hhash->State = HAL_HASH_STATE_BUSY;
1604 
1605     /* Save buffer pointer and size in handle */
1606     hhash->pHashInBuffPtr = pInBuffer;
1607     hhash->HashBuffSize = Size;
1608     hhash->HashInCount = 0;
1609 
1610     /* Check if initialization phase has already been performed */
1611     if (hhash->Phase == HAL_HASH_PHASE_READY) {
1612         /* Check if key size is greater than 64 bytes */
1613         if (hhash->Init.KeySize > 64) {
1614             /* Select the HMAC MD5 mode */
1615             HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1616         } else {
1617             /* Select the HMAC MD5 mode */
1618             HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1619         }
1620     }
1621 
1622     /* Set the phase */
1623     hhash->Phase = HAL_HASH_PHASE_PROCESS;
1624 
1625     /* Configure the number of valid bits in last word of the message */
1626     __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1627 
1628     /* Get the key address */
1629     inputaddr = (uint32_t)(hhash->Init.pKey);
1630 
1631     /* Set the HASH DMA transfer complete callback */
1632     hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1633     /* Set the DMA error callback */
1634     hhash->hdmain->XferErrorCallback = HASH_DMAError;
1635 
1636     /* Enable the DMA In DMA Stream */
1637     HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1638     /* Enable DMA requests */
1639     HASH->CR |= (HASH_CR_DMAE);
1640 
1641     /* Process Unlocked */
1642     __HAL_UNLOCK(hhash);
1643 
1644     /* Return function status */
1645     return HAL_OK;
1646 }
1647 
1648 /**
1649   * @brief  Initializes the HASH peripheral in HMAC SHA1 mode
1650   *         then enables DMA to control data transfer.
1651   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1652   *         the configuration information for HASH module
1653   * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
1654   * @param  Size: Length of the input buffer in bytes.
1655   *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1656   * @retval HAL status
1657   */
HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef * hhash,uint8_t * pInBuffer,uint32_t Size)1658 HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1659 {
1660     uint32_t inputaddr  = 0;
1661 
1662     /* Process Locked */
1663     __HAL_LOCK(hhash);
1664 
1665     /* Change the HASH state */
1666     hhash->State = HAL_HASH_STATE_BUSY;
1667 
1668     /* Save buffer pointer and size in handle */
1669     hhash->pHashInBuffPtr = pInBuffer;
1670     hhash->HashBuffSize = Size;
1671     hhash->HashInCount = 0;
1672 
1673     /* Check if initialization phase has already been performed */
1674     if (hhash->Phase == HAL_HASH_PHASE_READY) {
1675         /* Check if key size is greater than 64 bytes */
1676         if (hhash->Init.KeySize > 64) {
1677             /* Select the HMAC SHA1 mode */
1678             HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1679         } else {
1680             /* Select the HMAC SHA1 mode */
1681             HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1682         }
1683     }
1684 
1685     /* Set the phase */
1686     hhash->Phase = HAL_HASH_PHASE_PROCESS;
1687 
1688     /* Configure the number of valid bits in last word of the message */
1689     __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1690 
1691     /* Get the key address */
1692     inputaddr = (uint32_t)(hhash->Init.pKey);
1693 
1694     /* Set the HASH DMA transfer complete callback */
1695     hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1696     /* Set the DMA error callback */
1697     hhash->hdmain->XferErrorCallback = HASH_DMAError;
1698 
1699     /* Enable the DMA In DMA Stream */
1700     HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1701     /* Enable DMA requests */
1702     HASH->CR |= (HASH_CR_DMAE);
1703 
1704     /* Process Unlocked */
1705     __HAL_UNLOCK(hhash);
1706 
1707     /* Return function status */
1708     return HAL_OK;
1709 }
1710 
1711 /**
1712   * @}
1713   */
1714 
1715 /** @defgroup HASH_Exported_Functions_Group7 Peripheral State functions
1716  *  @brief   Peripheral State functions.
1717  *
1718 @verbatim
1719  ===============================================================================
1720                       ##### Peripheral State functions #####
1721  ===============================================================================
1722     [..]
1723     This subsection permits to get in run-time the status of the peripheral.
1724 
1725 @endverbatim
1726   * @{
1727   */
1728 
1729 /**
1730   * @brief return the HASH state
1731   * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
1732   *         the configuration information for HASH module
1733   * @retval HAL state
1734   */
HAL_HASH_GetState(HASH_HandleTypeDef * hhash)1735 HAL_HASH_STATETypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
1736 {
1737     return hhash->State;
1738 }
1739 
1740 /**
1741   * @}
1742   */
1743 
1744 /**
1745   * @}
1746   */
1747 
1748 #endif /* HAL_HASH_MODULE_ENABLED */
1749 
1750 /**
1751   * @}
1752   */
1753 #endif /* STM32F756xx */
1754 
1755 /**
1756   * @}
1757   */
1758 
1759 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1760