2 ******************************************************************************
3 * @file stm32f4xx_hal_hash.c
4 * @author MCD Application Team
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
17 ==============================================================================
18 ##### How to use this driver #####
19 ==============================================================================
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 __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
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
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.
68 ******************************************************************************
71 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
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.
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.
95 ******************************************************************************
98 /* Includes ------------------------------------------------------------------*/
99 #include "stm32f4xx_hal.h"
101 /** @addtogroup STM32F4xx_HAL_Driver
106 * @brief HASH HAL module driver.
110 #ifdef HAL_HASH_MODULE_ENABLED
112 #if defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F437xx) || defined(STM32F439xx)
114 /* Private typedef -----------------------------------------------------------*/
115 /* Private define ------------------------------------------------------------*/
116 /* Private macro -------------------------------------------------------------*/
117 /* Private variables ---------------------------------------------------------*/
118 /* Private function prototypes -----------------------------------------------*/
119 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
120 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
121 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
122 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size);
124 /* Private functions ---------------------------------------------------------*/
126 /** @defgroup HASH_Private_Functions
130 /** @defgroup HASH_Group1 Initialization and de-initialization functions
131 * @brief Initialization and Configuration functions.
134 ===============================================================================
135 ##### Initialization and de-initialization functions #####
136 ===============================================================================
137 [..] This section provides functions allowing to:
138 (+) Initialize the HASH according to the specified parameters
139 in the HASH_InitTypeDef and creates the associated handle.
140 (+) DeInitialize the HASH peripheral.
141 (+) Initialize the HASH MSP.
142 (+) DeInitialize HASH MSP.
149 * @brief Initializes the HASH according to the specified parameters in the
150 HASH_HandleTypeDef and creates the associated handle.
151 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
152 * the configuration information for HASH module
155 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
157 /* Check the hash handle allocation */
158 if(hhash == HAL_NULL)
163 /* Check the parameters */
164 assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
166 if(hhash->State == HAL_HASH_STATE_RESET)
168 /* Init the low level hardware */
169 HAL_HASH_MspInit(hhash);
172 /* Change the HASH state */
173 hhash->State = HAL_HASH_STATE_BUSY;
175 /* Reset HashInCount, HashBuffSize and HashITCounter */
176 hhash->HashInCount = 0;
177 hhash->HashBuffSize = 0;
178 hhash->HashITCounter = 0;
180 /* Set the data type */
181 HASH->CR |= (uint32_t) (hhash->Init.DataType);
183 /* Change the HASH state */
184 hhash->State = HAL_HASH_STATE_READY;
186 /* Set the default HASH phase */
187 hhash->Phase = HAL_HASH_PHASE_READY;
189 /* Return function status */
194 * @brief DeInitializes the HASH peripheral.
195 * @note This API must be called before starting a new processing.
196 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
197 * the configuration information for HASH module
200 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
202 /* Check the HASH handle allocation */
203 if(hhash == HAL_NULL)
208 /* Change the HASH state */
209 hhash->State = HAL_HASH_STATE_BUSY;
211 /* Set the default HASH phase */
212 hhash->Phase = HAL_HASH_PHASE_READY;
214 /* Reset HashInCount, HashBuffSize and HashITCounter */
215 hhash->HashInCount = 0;
216 hhash->HashBuffSize = 0;
217 hhash->HashITCounter = 0;
219 /* DeInit the low level hardware */
220 HAL_HASH_MspDeInit(hhash);
222 /* Change the HASH state */
223 hhash->State = HAL_HASH_STATE_RESET;
228 /* Return function status */
233 * @brief Initializes the HASH MSP.
234 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
235 * the configuration information for HASH module
238 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
240 /* NOTE: This function Should not be modified, when the callback is needed,
241 the HAL_HASH_MspInit could be implemented in the user file
246 * @brief DeInitializes HASH MSP.
247 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
248 * the configuration information for HASH module
251 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
253 /* NOTE: This function Should not be modified, when the callback is needed,
254 the HAL_HASH_MspDeInit could be implemented in the user file
259 * @brief Input data transfer complete callback.
260 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
261 * the configuration information for HASH module
264 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
266 /* NOTE: This function Should not be modified, when the callback is needed,
267 the HAL_HASH_InCpltCallback could be implemented in the user file
272 * @brief Data transfer Error callback.
273 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
274 * the configuration information for HASH module
277 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
279 /* NOTE: This function Should not be modified, when the callback is needed,
280 the HAL_HASH_ErrorCallback could be implemented in the user file
285 * @brief Digest computation complete callback. It is used only with interrupt.
286 * @note This callback is not relevant with DMA.
287 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
288 * the configuration information for HASH module
291 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
293 /* NOTE: This function Should not be modified, when the callback is needed,
294 the HAL_HASH_DgstCpltCallback could be implemented in the user file
302 /** @defgroup HASH_Group2 HASH processing functions using polling mode
303 * @brief processing functions using polling mode
306 ===============================================================================
307 ##### HASH processing using polling mode functions#####
308 ===============================================================================
309 [..] This section provides functions allowing to calculate in polling mode
310 the hash value using one of the following algorithms:
319 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
320 The digest is available in pOutBuffer.
321 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
322 * the configuration information for HASH module
323 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
324 * @param Size: Length of the input buffer in bytes.
325 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
326 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
327 * and appending the input buffer is no more possible.
328 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
329 * @param Timeout: Timeout value
332 HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
334 uint32_t tickstart = 0;
339 /* Change the HASH state */
340 hhash->State = HAL_HASH_STATE_BUSY;
342 /* Check if initialization phase has already been performed */
343 if(hhash->Phase == HAL_HASH_PHASE_READY)
345 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
346 the message digest of a new message */
347 HASH->CR |= HASH_AlgoSelection_MD5 | HASH_CR_INIT;
351 hhash->Phase = HAL_HASH_PHASE_PROCESS;
353 /* Configure the number of valid bits in last word of the message */
354 __HAL_HASH_SET_NBVALIDBITS(Size);
356 /* Write input buffer in data register */
357 HASH_WriteData(pInBuffer, Size);
359 /* Start the digest calculation */
360 __HAL_HASH_START_DIGEST();
363 tickstart = HAL_GetTick();
365 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
367 /* Check for the Timeout */
368 if(Timeout != HAL_MAX_DELAY)
370 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
373 hhash->State = HAL_HASH_STATE_TIMEOUT;
375 /* Process Unlocked */
383 /* Read the message digest */
384 HASH_GetDigest(pOutBuffer, 16);
386 /* Change the HASH state */
387 hhash->State = HAL_HASH_STATE_READY;
389 /* Process Unlocked */
392 /* Return function status */
397 * @brief Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
398 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
399 * the configuration information for HASH module
400 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
401 * @param Size: Length of the input buffer in bytes.
402 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
403 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
404 * and appending the input buffer is no more possible.
407 HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
412 /* Change the HASH state */
413 hhash->State = HAL_HASH_STATE_BUSY;
415 /* Check if initialization phase has already been performed */
416 if(hhash->Phase == HAL_HASH_PHASE_READY)
418 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
419 the message digest of a new message */
420 HASH->CR |= HASH_AlgoSelection_MD5 | HASH_CR_INIT;
424 hhash->Phase = HAL_HASH_PHASE_PROCESS;
426 /* Configure the number of valid bits in last word of the message */
427 __HAL_HASH_SET_NBVALIDBITS(Size);
429 /* Write input buffer in data register */
430 HASH_WriteData(pInBuffer, Size);
432 /* Change the HASH state */
433 hhash->State = HAL_HASH_STATE_READY;
435 /* Process Unlocked */
438 /* Return function status */
443 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
444 The digest is available in pOutBuffer.
445 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
446 * the configuration information for HASH module
447 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
448 * @param Size: Length of the input buffer in bytes.
449 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
450 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
451 * @param Timeout: Timeout value
454 HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
456 uint32_t tickstart = 0;
461 /* Change the HASH state */
462 hhash->State = HAL_HASH_STATE_BUSY;
464 /* Check if initialization phase has already been performed */
465 if(hhash->Phase == HAL_HASH_PHASE_READY)
467 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
468 the message digest of a new message */
469 HASH->CR |= HASH_AlgoSelection_SHA1 | HASH_CR_INIT;
473 hhash->Phase = HAL_HASH_PHASE_PROCESS;
475 /* Configure the number of valid bits in last word of the message */
476 __HAL_HASH_SET_NBVALIDBITS(Size);
478 /* Write input buffer in data register */
479 HASH_WriteData(pInBuffer, Size);
481 /* Start the digest calculation */
482 __HAL_HASH_START_DIGEST();
485 tickstart = HAL_GetTick();
487 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
489 /* Check for the Timeout */
490 if(Timeout != HAL_MAX_DELAY)
492 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
495 hhash->State = HAL_HASH_STATE_TIMEOUT;
497 /* Process Unlocked */
505 /* Read the message digest */
506 HASH_GetDigest(pOutBuffer, 20);
508 /* Change the HASH state */
509 hhash->State = HAL_HASH_STATE_READY;
511 /* Process Unlocked */
514 /* Return function status */
519 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
520 The digest is available in pOutBuffer.
521 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
522 * the configuration information for HASH module
523 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
524 * @param Size: Length of the input buffer in bytes.
525 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
526 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
529 HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
534 /* Change the HASH state */
535 hhash->State = HAL_HASH_STATE_BUSY;
537 /* Check if initialization phase has already been performed */
538 if(hhash->Phase == HAL_HASH_PHASE_READY)
540 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
541 the message digest of a new message */
542 HASH->CR |= HASH_AlgoSelection_SHA1 | HASH_CR_INIT;
546 hhash->Phase = HAL_HASH_PHASE_PROCESS;
548 /* Configure the number of valid bits in last word of the message */
549 __HAL_HASH_SET_NBVALIDBITS(Size);
551 /* Write input buffer in data register */
552 HASH_WriteData(pInBuffer, Size);
554 /* Change the HASH state */
555 hhash->State = HAL_HASH_STATE_READY;
557 /* Process Unlocked */
560 /* Return function status */
568 /** @defgroup HASH_Group3 HASH processing functions using interrupt mode
569 * @brief processing functions using interrupt mode.
572 ===============================================================================
573 ##### HASH processing using interrupt mode functions #####
574 ===============================================================================
575 [..] This section provides functions allowing to calculate in interrupt mode
576 the hash value using one of the following algorithms:
585 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
586 * The digest is available in pOutBuffer.
587 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
588 * the configuration information for HASH module
589 * @param pOutBuffer: Pointer to the Output buffer (hashed buffer).
590 * @param Size: Length of the input buffer in bytes.
591 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
592 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
595 HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
599 uint32_t buffercounter;
600 uint32_t inputcounter;
605 if(hhash->HashITCounter == 0)
607 hhash->HashITCounter = 1;
611 hhash->HashITCounter = 0;
613 if(hhash->State == HAL_HASH_STATE_READY)
615 /* Change the HASH state */
616 hhash->State = HAL_HASH_STATE_BUSY;
618 hhash->HashInCount = Size;
619 hhash->pHashInBuffPtr = pInBuffer;
620 hhash->pHashOutBuffPtr = pOutBuffer;
622 /* Check if initialization phase has already been performed */
623 if(hhash->Phase == HAL_HASH_PHASE_READY)
625 /* Select the SHA1 mode */
626 HASH->CR |= HASH_AlgoSelection_MD5;
627 /* Reset the HASH processor core, so that the HASH will be ready to compute
628 the message digest of a new message */
629 HASH->CR |= HASH_CR_INIT;
633 hhash->Phase = HAL_HASH_PHASE_PROCESS;
635 /* Process Unlocked */
638 /* Enable Interrupts */
639 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
641 /* Return function status */
644 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
646 outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
647 /* Read the Output block from the Output FIFO */
648 *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
650 *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
652 *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
654 *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
656 if(hhash->HashInCount == 0)
658 /* Disable Interrupts */
660 /* Change the HASH state */
661 hhash->State = HAL_HASH_STATE_READY;
662 /* Call digest computation complete callback */
663 HAL_HASH_DgstCpltCallback(hhash);
666 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
668 if(hhash->HashInCount > 64)
670 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
671 /* Write the Input block in the Data IN register */
672 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
674 HASH->DIN = *(uint32_t*)inputaddr;
676 if(hhash->HashITCounter == 0)
678 HASH->DIN = *(uint32_t*)inputaddr;
680 if(hhash->HashInCount >= 68)
682 /* Decrement buffer counter */
683 hhash->HashInCount -= 68;
684 hhash->pHashInBuffPtr+= 68;
688 hhash->HashInCount -= 64;
693 /* Decrement buffer counter */
694 hhash->HashInCount -= 64;
695 hhash->pHashInBuffPtr+= 64;
700 /* Get the buffer address */
701 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
702 /* Get the buffer counter */
703 inputcounter = hhash->HashInCount;
704 /* Disable Interrupts */
705 HASH->IMR &= ~(HASH_IT_DINI);
706 /* Configure the number of valid bits in last word of the message */
707 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
709 if((inputcounter > 4) && (inputcounter%4))
711 inputcounter = (inputcounter+4-inputcounter%4);
714 /* Write the Input block in the Data IN register */
715 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
717 HASH->DIN = *(uint32_t*)inputaddr;
720 /* Start the digest calculation */
721 __HAL_HASH_START_DIGEST();
722 /* Reset buffer counter */
723 hhash->HashInCount = 0;
725 /* Call Input data transfer complete callback */
726 HAL_HASH_InCpltCallback(hhash);
729 /* Process Unlocked */
732 /* Return function status */
737 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
738 * The digest is available in pOutBuffer.
739 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
740 * the configuration information for HASH module
741 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
742 * @param Size: Length of the input buffer in bytes.
743 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
744 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
747 HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
751 uint32_t buffercounter;
752 uint32_t inputcounter;
757 if(hhash->HashITCounter == 0)
759 hhash->HashITCounter = 1;
763 hhash->HashITCounter = 0;
765 if(hhash->State == HAL_HASH_STATE_READY)
767 /* Change the HASH state */
768 hhash->State = HAL_HASH_STATE_BUSY;
770 hhash->HashInCount = Size;
771 hhash->pHashInBuffPtr = pInBuffer;
772 hhash->pHashOutBuffPtr = pOutBuffer;
774 /* Check if initialization phase has already been performed */
775 if(hhash->Phase == HAL_HASH_PHASE_READY)
777 /* Select the SHA1 mode */
778 HASH->CR |= HASH_AlgoSelection_SHA1;
779 /* Reset the HASH processor core, so that the HASH will be ready to compute
780 the message digest of a new message */
781 HASH->CR |= HASH_CR_INIT;
785 hhash->Phase = HAL_HASH_PHASE_PROCESS;
787 /* Process Unlocked */
790 /* Enable Interrupts */
791 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
793 /* Return function status */
796 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
798 outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
799 /* Read the Output block from the Output FIFO */
800 *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
802 *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
804 *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
806 *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
808 *(uint32_t*)(outputaddr) = __REV(HASH->HR[4]);
809 if(hhash->HashInCount == 0)
811 /* Disable Interrupts */
813 /* Change the HASH state */
814 hhash->State = HAL_HASH_STATE_READY;
815 /* Call digest computation complete callback */
816 HAL_HASH_DgstCpltCallback(hhash);
819 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
821 if(hhash->HashInCount > 64)
823 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
824 /* Write the Input block in the Data IN register */
825 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
827 HASH->DIN = *(uint32_t*)inputaddr;
830 if(hhash->HashITCounter == 0)
832 HASH->DIN = *(uint32_t*)inputaddr;
834 if(hhash->HashInCount >= 68)
836 /* Decrement buffer counter */
837 hhash->HashInCount -= 68;
838 hhash->pHashInBuffPtr+= 68;
842 hhash->HashInCount -= 64;
847 /* Decrement buffer counter */
848 hhash->HashInCount -= 64;
849 hhash->pHashInBuffPtr+= 64;
854 /* Get the buffer address */
855 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
856 /* Get the buffer counter */
857 inputcounter = hhash->HashInCount;
858 /* Disable Interrupts */
859 HASH->IMR &= ~(HASH_IT_DINI);
860 /* Configure the number of valid bits in last word of the message */
861 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
863 if((inputcounter > 4) && (inputcounter%4))
865 inputcounter = (inputcounter+4-inputcounter%4);
868 /* Write the Input block in the Data IN register */
869 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
871 HASH->DIN = *(uint32_t*)inputaddr;
874 /* Start the digest calculation */
875 __HAL_HASH_START_DIGEST();
876 /* Reset buffer counter */
877 hhash->HashInCount = 0;
879 /* Call Input data transfer complete callback */
880 HAL_HASH_InCpltCallback(hhash);
883 /* Process Unlocked */
886 /* Return function status */
891 * @brief This function handles HASH interrupt request.
892 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
893 * the configuration information for HASH module
896 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
898 switch(HASH->CR & HASH_CR_ALGO)
900 case HASH_AlgoSelection_MD5:
901 HAL_HASH_MD5_Start_IT(hhash, HAL_NULL, 0, HAL_NULL);
904 case HASH_AlgoSelection_SHA1:
905 HAL_HASH_SHA1_Start_IT(hhash, HAL_NULL, 0, HAL_NULL);
917 /** @defgroup HASH_Group4 HASH processing functions using DMA mode
918 * @brief processing functions using DMA mode.
921 ===============================================================================
922 ##### HASH processing using DMA mode functions #####
923 ===============================================================================
924 [..] This section provides functions allowing to calculate in DMA mode
925 the hash value using one of the following algorithms:
934 * @brief Initializes the HASH peripheral in MD5 mode then enables DMA to
935 control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
936 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
937 * the configuration information for HASH module
938 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
939 * @param Size: Length of the input buffer in bytes.
940 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
943 HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
945 uint32_t inputaddr = (uint32_t)pInBuffer;
950 /* Change the HASH state */
951 hhash->State = HAL_HASH_STATE_BUSY;
953 /* Check if initialization phase has already been performed */
954 if(hhash->Phase == HAL_HASH_PHASE_READY)
956 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
957 the message digest of a new message */
958 HASH->CR |= HASH_AlgoSelection_MD5 | HASH_CR_INIT;
961 /* Configure the number of valid bits in last word of the message */
962 __HAL_HASH_SET_NBVALIDBITS(Size);
965 hhash->Phase = HAL_HASH_PHASE_PROCESS;
967 /* Set the HASH DMA transfer complete callback */
968 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
969 /* Set the DMA error callback */
970 hhash->hdmain->XferErrorCallback = HASH_DMAError;
972 /* Enable the DMA In DMA Stream */
973 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
975 /* Enable DMA requests */
976 HASH->CR |= (HASH_CR_DMAE);
978 /* Process Unlocked */
981 /* Return function status */
986 * @brief Returns the computed digest in MD5 mode
987 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
988 * the configuration information for HASH module
989 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
990 * @param Timeout: Timeout value
993 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
995 uint32_t tickstart = 0;
1000 /* Change HASH peripheral state */
1001 hhash->State = HAL_HASH_STATE_BUSY;
1004 tickstart = HAL_GetTick();
1006 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1008 /* Check for the Timeout */
1009 if(Timeout != HAL_MAX_DELAY)
1011 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1014 hhash->State = HAL_HASH_STATE_TIMEOUT;
1016 /* Process Unlocked */
1017 __HAL_UNLOCK(hhash);
1024 /* Read the message digest */
1025 HASH_GetDigest(pOutBuffer, 16);
1027 /* Change HASH peripheral state */
1028 hhash->State = HAL_HASH_STATE_READY;
1030 /* Process Unlocked */
1031 __HAL_UNLOCK(hhash);
1033 /* Return function status */
1038 * @brief Initializes the HASH peripheral in SHA1 mode then enables DMA to
1039 control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
1040 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1041 * the configuration information for HASH module
1042 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1043 * @param Size: Length of the input buffer in bytes.
1044 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1045 * @retval HAL status
1047 HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1049 uint32_t inputaddr = (uint32_t)pInBuffer;
1051 /* Process Locked */
1054 /* Change the HASH state */
1055 hhash->State = HAL_HASH_STATE_BUSY;
1057 /* Check if initialization phase has already been performed */
1058 if(hhash->Phase == HAL_HASH_PHASE_READY)
1060 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
1061 the message digest of a new message */
1062 HASH->CR |= HASH_AlgoSelection_SHA1;
1063 HASH->CR |= HASH_CR_INIT;
1066 /* Configure the number of valid bits in last word of the message */
1067 __HAL_HASH_SET_NBVALIDBITS(Size);
1070 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1072 /* Set the HASH DMA transfer complete callback */
1073 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1074 /* Set the DMA error callback */
1075 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1077 /* Enable the DMA In DMA Stream */
1078 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
1080 /* Enable DMA requests */
1081 HASH->CR |= (HASH_CR_DMAE);
1083 /* Process Unlocked */
1084 __HAL_UNLOCK(hhash);
1086 /* Return function status */
1091 * @brief Returns the computed digest in SHA1 mode.
1092 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1093 * the configuration information for HASH module
1094 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1095 * @param Timeout: Timeout value
1096 * @retval HAL status
1098 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1100 uint32_t tickstart = 0;
1102 /* Process Locked */
1105 /* Change HASH peripheral state */
1106 hhash->State = HAL_HASH_STATE_BUSY;
1109 tickstart = HAL_GetTick();
1110 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1112 /* Check for the Timeout */
1113 if(Timeout != HAL_MAX_DELAY)
1115 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1118 hhash->State = HAL_HASH_STATE_TIMEOUT;
1120 /* Process Unlocked */
1121 __HAL_UNLOCK(hhash);
1128 /* Read the message digest */
1129 HASH_GetDigest(pOutBuffer, 20);
1131 /* Change HASH peripheral state */
1132 hhash->State = HAL_HASH_STATE_READY;
1134 /* Process UnLock */
1135 __HAL_UNLOCK(hhash);
1137 /* Return function status */
1146 /** @defgroup HASH_Group5 HASH-MAC (HMAC) processing functions using polling mode
1147 * @brief HMAC processing functions using polling mode .
1150 ===============================================================================
1151 ##### HMAC processing using polling mode functions #####
1152 ===============================================================================
1153 [..] This section provides functions allowing to calculate in polling mode
1154 the HMAC value using one of the following algorithms:
1163 * @brief Initializes the HASH peripheral in HMAC MD5 mode
1164 * then processes pInBuffer. The digest is available in pOutBuffer
1165 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1166 * the configuration information for HASH module
1167 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1168 * @param Size: Length of the input buffer in bytes.
1169 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1170 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1171 * @param Timeout: Timeout value
1172 * @retval HAL status
1174 HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1176 uint32_t tickstart = 0;
1178 /* Process Locked */
1181 /* Change the HASH state */
1182 hhash->State = HAL_HASH_STATE_BUSY;
1184 /* Check if initialization phase has already been performed */
1185 if(hhash->Phase == HAL_HASH_PHASE_READY)
1187 /* Check if key size is greater than 64 bytes */
1188 if(hhash->Init.KeySize > 64)
1190 /* Select the HMAC MD5 mode */
1191 HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1195 /* Select the HMAC MD5 mode */
1196 HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1201 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1203 /************************** STEP 1 ******************************************/
1204 /* Configure the number of valid bits in last word of the message */
1205 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1207 /* Write input buffer in data register */
1208 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1210 /* Start the digest calculation */
1211 __HAL_HASH_START_DIGEST();
1214 tickstart = HAL_GetTick();
1216 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1218 /* Check for the Timeout */
1219 if(Timeout != HAL_MAX_DELAY)
1221 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1224 hhash->State = HAL_HASH_STATE_TIMEOUT;
1226 /* Process Unlocked */
1227 __HAL_UNLOCK(hhash);
1233 /************************** STEP 2 ******************************************/
1234 /* Configure the number of valid bits in last word of the message */
1235 __HAL_HASH_SET_NBVALIDBITS(Size);
1237 /* Write input buffer in data register */
1238 HASH_WriteData(pInBuffer, Size);
1240 /* Start the digest calculation */
1241 __HAL_HASH_START_DIGEST();
1244 tickstart = HAL_GetTick();
1246 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1248 /* Check for the Timeout */
1249 if(Timeout != HAL_MAX_DELAY)
1251 if((HAL_GetTick() - tickstart ) > Timeout)
1254 hhash->State = HAL_HASH_STATE_TIMEOUT;
1256 /* Process Unlocked */
1257 __HAL_UNLOCK(hhash);
1263 /************************** STEP 3 ******************************************/
1264 /* Configure the number of valid bits in last word of the message */
1265 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1267 /* Write input buffer in data register */
1268 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1270 /* Start the digest calculation */
1271 __HAL_HASH_START_DIGEST();
1274 tickstart = HAL_GetTick();
1276 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1278 /* Check for the Timeout */
1279 if(Timeout != HAL_MAX_DELAY)
1281 if((HAL_GetTick() - tickstart ) > Timeout)
1284 hhash->State = HAL_HASH_STATE_TIMEOUT;
1286 /* Process Unlocked */
1287 __HAL_UNLOCK(hhash);
1294 /* Read the message digest */
1295 HASH_GetDigest(pOutBuffer, 16);
1297 /* Change the HASH state */
1298 hhash->State = HAL_HASH_STATE_READY;
1300 /* Process Unlocked */
1301 __HAL_UNLOCK(hhash);
1303 /* Return function status */
1308 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
1309 * then processes pInBuffer. The digest is available in pOutBuffer.
1310 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1311 * the configuration information for HASH module
1312 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1313 * @param Size: Length of the input buffer in bytes.
1314 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1315 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1316 * @param Timeout: Timeout value
1317 * @retval HAL status
1319 HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1321 uint32_t tickstart = 0;
1323 /* Process Locked */
1326 /* Change the HASH state */
1327 hhash->State = HAL_HASH_STATE_BUSY;
1329 /* Check if initialization phase has already been performed */
1330 if(hhash->Phase == HAL_HASH_PHASE_READY)
1332 /* Check if key size is greater than 64 bytes */
1333 if(hhash->Init.KeySize > 64)
1335 /* Select the HMAC SHA1 mode */
1336 HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1340 /* Select the HMAC SHA1 mode */
1341 HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1346 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1348 /************************** STEP 1 ******************************************/
1349 /* Configure the number of valid bits in last word of the message */
1350 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1352 /* Write input buffer in data register */
1353 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1355 /* Start the digest calculation */
1356 __HAL_HASH_START_DIGEST();
1359 tickstart = HAL_GetTick();
1361 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1363 /* Check for the Timeout */
1364 if(Timeout != HAL_MAX_DELAY)
1366 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1369 hhash->State = HAL_HASH_STATE_TIMEOUT;
1371 /* Process Unlocked */
1372 __HAL_UNLOCK(hhash);
1378 /************************** STEP 2 ******************************************/
1379 /* Configure the number of valid bits in last word of the message */
1380 __HAL_HASH_SET_NBVALIDBITS(Size);
1382 /* Write input buffer in data register */
1383 HASH_WriteData(pInBuffer, Size);
1385 /* Start the digest calculation */
1386 __HAL_HASH_START_DIGEST();
1389 tickstart = HAL_GetTick();
1391 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1393 /* Check for the Timeout */
1394 if(Timeout != HAL_MAX_DELAY)
1396 if((HAL_GetTick() - tickstart ) > Timeout)
1399 hhash->State = HAL_HASH_STATE_TIMEOUT;
1401 /* Process Unlocked */
1402 __HAL_UNLOCK(hhash);
1408 /************************** STEP 3 ******************************************/
1409 /* Configure the number of valid bits in last word of the message */
1410 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1412 /* Write input buffer in data register */
1413 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1415 /* Start the digest calculation */
1416 __HAL_HASH_START_DIGEST();
1419 tickstart = HAL_GetTick();
1421 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1423 /* Check for the Timeout */
1424 if(Timeout != HAL_MAX_DELAY)
1426 if((HAL_GetTick() - tickstart ) > Timeout)
1429 hhash->State = HAL_HASH_STATE_TIMEOUT;
1431 /* Process Unlocked */
1432 __HAL_UNLOCK(hhash);
1438 /* Read the message digest */
1439 HASH_GetDigest(pOutBuffer, 20);
1441 /* Change the HASH state */
1442 hhash->State = HAL_HASH_STATE_READY;
1444 /* Process Unlocked */
1445 __HAL_UNLOCK(hhash);
1447 /* Return function status */
1455 /** @defgroup HASH_Group6 HASH-MAC (HMAC) processing functions using DMA mode
1456 * @brief HMAC processing functions using DMA mode .
1459 ===============================================================================
1460 ##### HMAC processing using DMA mode functions #####
1461 ===============================================================================
1462 [..] This section provides functions allowing to calculate in DMA mode
1463 the HMAC value using one of the following algorithms:
1472 * @brief Initializes the HASH peripheral in HMAC MD5 mode
1473 * then enables DMA to control data transfer.
1474 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1475 * the configuration information for HASH module
1476 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1477 * @param Size: Length of the input buffer in bytes.
1478 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1479 * @retval HAL status
1481 HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1483 uint32_t inputaddr = 0;
1485 /* Process Locked */
1488 /* Change the HASH state */
1489 hhash->State = HAL_HASH_STATE_BUSY;
1491 /* Save buffer pointer and size in handle */
1492 hhash->pHashInBuffPtr = pInBuffer;
1493 hhash->HashBuffSize = Size;
1494 hhash->HashInCount = 0;
1496 /* Check if initialization phase has already been performed */
1497 if(hhash->Phase == HAL_HASH_PHASE_READY)
1499 /* Check if key size is greater than 64 bytes */
1500 if(hhash->Init.KeySize > 64)
1502 /* Select the HMAC MD5 mode */
1503 HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1507 /* Select the HMAC MD5 mode */
1508 HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1513 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1515 /* Configure the number of valid bits in last word of the message */
1516 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1518 /* Get the key address */
1519 inputaddr = (uint32_t)(hhash->Init.pKey);
1521 /* Set the HASH DMA transfer complete callback */
1522 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1523 /* Set the DMA error callback */
1524 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1526 /* Enable the DMA In DMA Stream */
1527 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1528 /* Enable DMA requests */
1529 HASH->CR |= (HASH_CR_DMAE);
1531 /* Process Unlocked */
1532 __HAL_UNLOCK(hhash);
1534 /* Return function status */
1539 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
1540 * then enables DMA to control data transfer.
1541 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1542 * the configuration information for HASH module
1543 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1544 * @param Size: Length of the input buffer in bytes.
1545 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1546 * @retval HAL status
1548 HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1550 uint32_t inputaddr = 0;
1552 /* Process Locked */
1555 /* Change the HASH state */
1556 hhash->State = HAL_HASH_STATE_BUSY;
1558 /* Save buffer pointer and size in handle */
1559 hhash->pHashInBuffPtr = pInBuffer;
1560 hhash->HashBuffSize = Size;
1561 hhash->HashInCount = 0;
1563 /* Check if initialization phase has already been performed */
1564 if(hhash->Phase == HAL_HASH_PHASE_READY)
1566 /* Check if key size is greater than 64 bytes */
1567 if(hhash->Init.KeySize > 64)
1569 /* Select the HMAC SHA1 mode */
1570 HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1574 /* Select the HMAC SHA1 mode */
1575 HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1580 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1582 /* Configure the number of valid bits in last word of the message */
1583 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1585 /* Get the key address */
1586 inputaddr = (uint32_t)(hhash->Init.pKey);
1588 /* Set the HASH DMA transfer complete callback */
1589 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1590 /* Set the DMA error callback */
1591 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1593 /* Enable the DMA In DMA Stream */
1594 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1595 /* Enable DMA requests */
1596 HASH->CR |= (HASH_CR_DMAE);
1598 /* Process Unlocked */
1599 __HAL_UNLOCK(hhash);
1601 /* Return function status */
1609 /** @defgroup HASH_Group7 Peripheral State functions
1610 * @brief Peripheral State functions.
1613 ===============================================================================
1614 ##### Peripheral State functions #####
1615 ===============================================================================
1617 This subsection permits to get in run-time the status of the peripheral.
1624 * @brief return the HASH state
1625 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1626 * the configuration information for HASH module
1629 HAL_HASH_STATETypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
1631 return hhash->State;
1639 * @brief DMA HASH Input Data complete callback.
1640 * @param hdma: DMA handle
1643 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
1645 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1646 uint32_t inputaddr = 0;
1647 uint32_t buffersize = 0;
1649 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
1651 /* Disable the DMA transfer */
1652 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1654 /* Change HASH peripheral state */
1655 hhash->State = HAL_HASH_STATE_READY;
1657 /* Call Input data transfer complete callback */
1658 HAL_HASH_InCpltCallback(hhash);
1662 /* Increment Interrupt counter */
1663 hhash->HashInCount++;
1664 /* Disable the DMA transfer before starting the next transfer */
1665 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1667 if(hhash->HashInCount <= 2)
1669 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
1670 if(hhash->HashInCount == 1)
1672 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1673 buffersize = hhash->HashBuffSize;
1675 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
1676 else if(hhash->HashInCount == 2)
1678 inputaddr = (uint32_t)hhash->Init.pKey;
1679 buffersize = hhash->Init.KeySize;
1681 /* Configure the number of valid bits in last word of the message */
1682 HASH->STR |= 8 * (buffersize % 4);
1684 /* Set the HASH DMA transfer complete */
1685 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1687 /* Enable the DMA In DMA Stream */
1688 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
1690 /* Enable DMA requests */
1691 HASH->CR |= (HASH_CR_DMAE);
1695 /* Disable the DMA transfer */
1696 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1698 /* Reset the InCount */
1699 hhash->HashInCount = 0;
1701 /* Change HASH peripheral state */
1702 hhash->State = HAL_HASH_STATE_READY;
1704 /* Call Input data transfer complete callback */
1705 HAL_HASH_InCpltCallback(hhash);
1711 * @brief DMA HASH communication error callback.
1712 * @param hdma: DMA handle
1715 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
1717 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1718 hhash->State= HAL_HASH_STATE_READY;
1719 HAL_HASH_ErrorCallback(hhash);
1723 * @brief Writes the input buffer in data register.
1724 * @param pInBuffer: Pointer to input buffer
1725 * @param Size: The size of input buffer
1728 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
1730 uint32_t buffercounter;
1731 uint32_t inputaddr = (uint32_t) pInBuffer;
1733 for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
1735 HASH->DIN = *(uint32_t*)inputaddr;
1741 * @brief Provides the message digest result.
1742 * @param pMsgDigest: Pointer to the message digest
1743 * @param Size: The size of the message digest in bytes
1746 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
1748 uint32_t msgdigest = (uint32_t)pMsgDigest;
1753 /* Read the message digest */
1754 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1756 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1758 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1760 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1763 /* Read the message digest */
1764 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1766 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1768 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1770 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1772 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1775 /* Read the message digest */
1776 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1778 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1780 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1782 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1784 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1786 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1788 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1791 /* Read the message digest */
1792 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1794 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1796 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1798 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1800 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1802 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1804 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1806 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
1816 #endif /* STM32F415xx || STM32F417xx || STM32F437xx || STM32F439xx */
1817 #endif /* HAL_HASH_MODULE_ENABLED */
1826 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/