2 ******************************************************************************
3 * @file stm32f4xx_hal_hash_ex.c
4 * @author MCD Application Team
7 * @brief HASH HAL Extension module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of HASH peripheral:
10 * + Extended HASH processing functions based on SHA224 Algorithm
11 * + Extended HASH processing functions based on SHA256 Algorithm
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
18 The HASH HAL driver can be used as follows:
19 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
20 (##) Enable the HASH interface clock using __HASH_CLK_ENABLE()
21 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMACEx_SHA224_Start())
22 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
23 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
24 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
25 (##) In case of using DMA to control data transfer (e.g. HAL_HMACEx_SH224_Start_DMA())
26 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
27 (+++) Configure and enable one DMA stream one for managing data transfer from
28 memory to peripheral (input stream). Managing data transfer from
29 peripheral to memory can be performed only using CPU
30 (+++) Associate the initialized DMA handle to the HASH DMA handle
32 (+++) Configure the priority and enable the NVIC for the transfer complete
33 interrupt on the DMA Stream: HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
34 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
35 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
36 (##) For HMAC, the encryption key.
37 (##) For HMAC, the key size used for encryption.
38 (#)Three processing functions are available:
39 (##) Polling mode: processing APIs are blocking functions
40 i.e. they process the data and wait till the digest computation is finished
41 e.g. HAL_HASHEx_SHA224_Start()
42 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
43 i.e. they process the data under interrupt
44 e.g. HAL_HASHEx_SHA224_Start_IT()
45 (##) DMA mode: processing APIs are not blocking functions and the CPU is
46 not used for data transfer i.e. the data transfer is ensured by DMA
47 e.g. HAL_HASHEx_SHA224_Start_DMA()
48 (#)When the processing function is called at first time after HAL_HASH_Init()
49 the HASH peripheral is initialized and processes the buffer in input.
50 After that, the digest computation is started.
51 When processing multi-buffer use the accumulate function to write the
52 data in the peripheral without starting the digest computation. In last
53 buffer use the start function to input the last buffer ans start the digest
55 (##) e.g. HAL_HASHEx_SHA224_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
56 (##) write (n-1)th data buffer in the peripheral without starting the digest computation
57 (##) HAL_HASHEx_SHA224_Start() : write (n)th data buffer in the peripheral and start the digest computation
58 (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
59 (#)In case of using DMA, call the DMA start processing e.g. HAL_HASHEx_SHA224_Start_DMA().
60 After that, call the finish function in order to get the digest value
61 e.g. HAL_HASHEx_SHA224_Finish()
62 (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
65 ******************************************************************************
68 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
70 * Redistribution and use in source and binary forms, with or without modification,
71 * are permitted provided that the following conditions are met:
72 * 1. Redistributions of source code must retain the above copyright notice,
73 * this list of conditions and the following disclaimer.
74 * 2. Redistributions in binary form must reproduce the above copyright notice,
75 * this list of conditions and the following disclaimer in the documentation
76 * and/or other materials provided with the distribution.
77 * 3. Neither the name of STMicroelectronics nor the names of its contributors
78 * may be used to endorse or promote products derived from this software
79 * without specific prior written permission.
81 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
82 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
87 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
88 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
89 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
90 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92 ******************************************************************************
95 /* Includes ------------------------------------------------------------------*/
96 #include "stm32f4xx_hal.h"
98 /** @addtogroup STM32F4xx_HAL_Driver
103 * @brief HASH Extension HAL module driver.
107 #ifdef HAL_HASH_MODULE_ENABLED
109 #if defined(STM32F437xx) || defined(STM32F439xx)
111 /* Private typedef -----------------------------------------------------------*/
112 /* Private define ------------------------------------------------------------*/
113 /* Private macro -------------------------------------------------------------*/
114 /* Private variables ---------------------------------------------------------*/
115 /* Private function prototypes -----------------------------------------------*/
116 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma);
117 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size);
118 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
119 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma);
121 /* Private functions ---------------------------------------------------------*/
123 /** @defgroup HASHEx_Private_Functions
127 /** @defgroup HASHEx_Group1 HASH processing functions
128 * @brief processing functions using polling mode
131 ===============================================================================
132 ##### HASH processing using polling mode functions #####
133 ===============================================================================
134 [..] This section provides functions allowing to calculate in polling mode
135 the hash value using one of the following algorithms:
144 * @brief Initializes the HASH peripheral in SHA224 mode
145 * then processes pInBuffer. The digest is available in pOutBuffer
146 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
147 * the configuration information for HASH module
148 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
149 * @param Size: Length of the input buffer in bytes.
150 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
151 * @param pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
152 * @param Timeout: Specify Timeout value
155 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
157 uint32_t tickstart = 0;
162 /* Change the HASH state */
163 hhash->State = HAL_HASH_STATE_BUSY;
165 /* Check if initialization phase has already been performed */
166 if(hhash->Phase == HAL_HASH_PHASE_READY)
168 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
169 the message digest of a new message */
170 HASH->CR |= HASH_AlgoSelection_SHA224 | HASH_CR_INIT;
174 hhash->Phase = HAL_HASH_PHASE_PROCESS;
176 /* Configure the number of valid bits in last word of the message */
177 __HAL_HASH_SET_NBVALIDBITS(Size);
179 /* Write input buffer in data register */
180 HASHEx_WriteData(pInBuffer, Size);
182 /* Start the digest calculation */
183 __HAL_HASH_START_DIGEST();
186 tickstart = HAL_GetTick();
188 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
190 /* Check for the Timeout */
191 if(Timeout != HAL_MAX_DELAY)
193 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
196 hhash->State = HAL_HASH_STATE_TIMEOUT;
198 /* Process Unlocked */
206 /* Read the message digest */
207 HASHEx_GetDigest(pOutBuffer, 28);
209 /* Change the HASH state */
210 hhash->State = HAL_HASH_STATE_READY;
212 /* Process Unlocked */
215 /* Return function status */
220 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
221 The digest is available in pOutBuffer.
222 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
223 * the configuration information for HASH module
224 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
225 * @param Size: Length of the input buffer in bytes.
226 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
227 * @param pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
228 * @param Timeout: Specify Timeout value
231 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
233 uint32_t tickstart = 0;
238 /* Change the HASH state */
239 hhash->State = HAL_HASH_STATE_BUSY;
241 /* Check if initialization phase has already been performed */
242 if(hhash->Phase == HAL_HASH_PHASE_READY)
244 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
245 the message digest of a new message */
246 HASH->CR |= HASH_AlgoSelection_SHA256 | HASH_CR_INIT;
250 hhash->Phase = HAL_HASH_PHASE_PROCESS;
252 /* Configure the number of valid bits in last word of the message */
253 __HAL_HASH_SET_NBVALIDBITS(Size);
255 /* Write input buffer in data register */
256 HASHEx_WriteData(pInBuffer, Size);
258 /* Start the digest calculation */
259 __HAL_HASH_START_DIGEST();
262 tickstart = HAL_GetTick();
264 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
266 /* Check for the Timeout */
267 if(Timeout != HAL_MAX_DELAY)
269 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
272 hhash->State = HAL_HASH_STATE_TIMEOUT;
274 /* Process Unlocked */
282 /* Read the message digest */
283 HASHEx_GetDigest(pOutBuffer, 32);
285 /* Change the HASH state */
286 hhash->State = HAL_HASH_STATE_READY;
288 /* Process Unlocked */
291 /* Return function status */
297 * @brief Initializes the HASH peripheral in SHA224 mode
298 * then processes pInBuffer. The digest is available in pOutBuffer
299 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
300 * the configuration information for HASH module
301 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
302 * @param Size: Length of the input buffer in bytes.
303 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
306 HAL_StatusTypeDef HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
311 /* Change the HASH state */
312 hhash->State = HAL_HASH_STATE_BUSY;
314 /* Check if initialization phase has already been performed */
315 if(hhash->Phase == HAL_HASH_PHASE_READY)
317 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
318 the message digest of a new message */
319 HASH->CR |= HASH_AlgoSelection_SHA224 | HASH_CR_INIT;
323 hhash->Phase = HAL_HASH_PHASE_PROCESS;
325 /* Configure the number of valid bits in last word of the message */
326 __HAL_HASH_SET_NBVALIDBITS(Size);
328 /* Write input buffer in data register */
329 HASHEx_WriteData(pInBuffer, Size);
331 /* Change the HASH state */
332 hhash->State = HAL_HASH_STATE_READY;
334 /* Process Unlocked */
337 /* Return function status */
343 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
344 The digest is available in pOutBuffer.
345 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
346 * the configuration information for HASH module
347 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
348 * @param Size: Length of the input buffer in bytes.
349 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
352 HAL_StatusTypeDef HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
357 /* Change the HASH state */
358 hhash->State = HAL_HASH_STATE_BUSY;
360 /* Check if initialization phase has already been performed */
361 if(hhash->Phase == HAL_HASH_PHASE_READY)
363 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
364 the message digest of a new message */
365 HASH->CR |= HASH_AlgoSelection_SHA256 | HASH_CR_INIT;
369 hhash->Phase = HAL_HASH_PHASE_PROCESS;
371 /* Configure the number of valid bits in last word of the message */
372 __HAL_HASH_SET_NBVALIDBITS(Size);
374 /* Write input buffer in data register */
375 HASHEx_WriteData(pInBuffer, Size);
377 /* Change the HASH state */
378 hhash->State = HAL_HASH_STATE_READY;
380 /* Process Unlocked */
383 /* Return function status */
392 /** @defgroup HASHEx_Group2 HMAC processing functions using polling mode
393 * @brief HMAC processing functions using polling mode .
396 ===============================================================================
397 ##### HMAC processing using polling mode functions #####
398 ===============================================================================
399 [..] This section provides functions allowing to calculate in polling mode
400 the HMAC value using one of the following algorithms:
409 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
410 * then processes pInBuffer. The digest is available in pOutBuffer.
411 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
412 * the configuration information for HASH module
413 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
414 * @param Size: Length of the input buffer in bytes.
415 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
416 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
419 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
421 uint32_t tickstart = 0;
426 /* Change the HASH state */
427 hhash->State = HAL_HASH_STATE_BUSY;
429 /* Check if initialization phase has already been performed */
430 if(hhash->Phase == HAL_HASH_PHASE_READY)
432 /* Check if key size is greater than 64 bytes */
433 if(hhash->Init.KeySize > 64)
435 /* Select the HMAC SHA224 mode */
436 HASH->CR |= (HASH_AlgoSelection_SHA224 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
440 /* Select the HMAC SHA224 mode */
441 HASH->CR |= (HASH_AlgoSelection_SHA224 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
446 hhash->Phase = HAL_HASH_PHASE_PROCESS;
448 /************************** STEP 1 ******************************************/
449 /* Configure the number of valid bits in last word of the message */
450 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
452 /* Write input buffer in data register */
453 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
455 /* Start the digest calculation */
456 __HAL_HASH_START_DIGEST();
459 tickstart = HAL_GetTick();
461 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
463 /* Check for the Timeout */
464 if(Timeout != HAL_MAX_DELAY)
466 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
469 hhash->State = HAL_HASH_STATE_TIMEOUT;
471 /* Process Unlocked */
478 /************************** STEP 2 ******************************************/
479 /* Configure the number of valid bits in last word of the message */
480 __HAL_HASH_SET_NBVALIDBITS(Size);
482 /* Write input buffer in data register */
483 HASHEx_WriteData(pInBuffer, Size);
485 /* Start the digest calculation */
486 __HAL_HASH_START_DIGEST();
489 tickstart = HAL_GetTick();
491 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
493 /* Check for the Timeout */
494 if(Timeout != HAL_MAX_DELAY)
496 if((HAL_GetTick() - tickstart ) > Timeout)
499 hhash->State = HAL_HASH_STATE_TIMEOUT;
501 /* Process Unlocked */
508 /************************** STEP 3 ******************************************/
509 /* Configure the number of valid bits in last word of the message */
510 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
512 /* Write input buffer in data register */
513 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
515 /* Start the digest calculation */
516 __HAL_HASH_START_DIGEST();
519 tickstart = HAL_GetTick();
521 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
523 /* Check for the Timeout */
524 if(Timeout != HAL_MAX_DELAY)
526 if((HAL_GetTick() - tickstart ) > Timeout)
529 hhash->State = HAL_HASH_STATE_TIMEOUT;
531 /* Process Unlocked */
538 /* Read the message digest */
539 HASHEx_GetDigest(pOutBuffer, 28);
541 /* Change the HASH state */
542 hhash->State = HAL_HASH_STATE_READY;
544 /* Process Unlocked */
547 /* Return function status */
552 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
553 * then processes pInBuffer. The digest is available in pOutBuffer
554 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
555 * the configuration information for HASH module
556 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
557 * @param Size: Length of the input buffer in bytes.
558 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
559 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
562 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
564 uint32_t tickstart = 0;
569 /* Change the HASH state */
570 hhash->State = HAL_HASH_STATE_BUSY;
572 /* Check if initialization phase has already been performed */
573 if(hhash->Phase == HAL_HASH_PHASE_READY)
575 /* Check if key size is greater than 64 bytes */
576 if(hhash->Init.KeySize > 64)
578 /* Select the HMAC SHA256 mode */
579 HASH->CR |= (HASH_AlgoSelection_SHA256 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey);
583 /* Select the HMAC SHA256 mode */
584 HASH->CR |= (HASH_AlgoSelection_SHA256 | HASH_AlgoMode_HMAC);
586 /* Reset the HASH processor core, so that the HASH will be ready to compute
587 the message digest of a new message */
588 HASH->CR |= HASH_CR_INIT;
592 hhash->Phase = HAL_HASH_PHASE_PROCESS;
594 /************************** STEP 1 ******************************************/
595 /* Configure the number of valid bits in last word of the message */
596 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
598 /* Write input buffer in data register */
599 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
601 /* Start the digest calculation */
602 __HAL_HASH_START_DIGEST();
605 tickstart = HAL_GetTick();
607 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
609 /* Check for the Timeout */
610 if(Timeout != HAL_MAX_DELAY)
612 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
615 hhash->State = HAL_HASH_STATE_TIMEOUT;
617 /* Process Unlocked */
624 /************************** STEP 2 ******************************************/
625 /* Configure the number of valid bits in last word of the message */
626 __HAL_HASH_SET_NBVALIDBITS(Size);
628 /* Write input buffer in data register */
629 HASHEx_WriteData(pInBuffer, Size);
631 /* Start the digest calculation */
632 __HAL_HASH_START_DIGEST();
635 tickstart = HAL_GetTick();
637 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
639 /* Check for the Timeout */
640 if(Timeout != HAL_MAX_DELAY)
642 if((HAL_GetTick() - tickstart ) > Timeout)
645 hhash->State = HAL_HASH_STATE_TIMEOUT;
647 /* Process Unlocked */
654 /************************** STEP 3 ******************************************/
655 /* Configure the number of valid bits in last word of the message */
656 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
658 /* Write input buffer in data register */
659 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
661 /* Start the digest calculation */
662 __HAL_HASH_START_DIGEST();
665 tickstart = HAL_GetTick();
667 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
669 /* Check for the Timeout */
670 if(Timeout != HAL_MAX_DELAY)
672 if((HAL_GetTick() - tickstart ) > Timeout)
675 hhash->State = HAL_HASH_STATE_TIMEOUT;
677 /* Process Unlocked */
684 /* Read the message digest */
685 HASHEx_GetDigest(pOutBuffer, 32);
687 /* Change the HASH state */
688 hhash->State = HAL_HASH_STATE_READY;
690 /* Process Unlocked */
693 /* Return function status */
701 /** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode
702 * @brief processing functions using interrupt mode.
705 ===============================================================================
706 ##### HASH processing using interrupt functions #####
707 ===============================================================================
708 [..] This section provides functions allowing to calculate in interrupt mode
709 the hash value using one of the following algorithms:
718 * @brief Initializes the HASH peripheral in SHA224 mode then processes pInBuffer.
719 * The digest is available in pOutBuffer.
720 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
721 * the configuration information for HASH module
722 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
723 * @param Size: Length of the input buffer in bytes.
724 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
725 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
728 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
731 uint32_t buffercounter;
732 uint32_t inputcounter;
737 if(hhash->HashITCounter == 0)
739 hhash->HashITCounter = 1;
743 hhash->HashITCounter = 0;
745 if(hhash->State == HAL_HASH_STATE_READY)
747 /* Change the HASH state */
748 hhash->State = HAL_HASH_STATE_BUSY;
750 hhash->HashInCount = Size;
751 hhash->pHashInBuffPtr = pInBuffer;
752 hhash->pHashOutBuffPtr = pOutBuffer;
754 /* Check if initialization phase has already been performed */
755 if(hhash->Phase == HAL_HASH_PHASE_READY)
757 /* Select the SHA224 mode */
758 HASH->CR |= HASH_AlgoSelection_SHA224;
759 /* Reset the HASH processor core, so that the HASH will be ready to compute
760 the message digest of a new message */
761 HASH->CR |= HASH_CR_INIT;
765 hhash->Phase = HAL_HASH_PHASE_PROCESS;
767 /* Process Unlocked */
770 /* Enable Interrupts */
771 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
773 /* Return function status */
776 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
778 /* Read the message digest */
779 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 28);
780 if(hhash->HashInCount == 0)
782 /* Disable Interrupts */
784 /* Change the HASH state */
785 hhash->State = HAL_HASH_STATE_READY;
786 /* Call digest computation complete callback */
787 HAL_HASH_DgstCpltCallback(hhash);
790 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
792 if(hhash->HashInCount > 64)
794 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
795 /* Write the Input block in the Data IN register */
796 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
798 HASH->DIN = *(uint32_t*)inputaddr;
801 if(hhash->HashITCounter == 0)
803 HASH->DIN = *(uint32_t*)inputaddr;
804 if(hhash->HashInCount >= 68)
806 /* Decrement buffer counter */
807 hhash->HashInCount -= 68;
808 hhash->pHashInBuffPtr+= 68;
812 hhash->HashInCount -= 64;
817 /* Decrement buffer counter */
818 hhash->HashInCount -= 64;
819 hhash->pHashInBuffPtr+= 64;
824 /* Get the buffer address */
825 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
826 /* Get the buffer counter */
827 inputcounter = hhash->HashInCount;
828 /* Disable Interrupts */
829 HASH->IMR &= ~(HASH_IT_DINI);
830 /* Configure the number of valid bits in last word of the message */
831 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
833 if((inputcounter > 4) && (inputcounter%4))
835 inputcounter = (inputcounter+4-inputcounter%4);
838 /* Write the Input block in the Data IN register */
839 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
841 HASH->DIN = *(uint32_t*)inputaddr;
844 /* Start the digest calculation */
845 __HAL_HASH_START_DIGEST();
846 /* Reset buffer counter */
847 hhash->HashInCount = 0;
849 /* Call Input data transfer complete callback */
850 HAL_HASH_InCpltCallback(hhash);
853 /* Process Unlocked */
856 /* Return function status */
862 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
863 * The digest is available in pOutBuffer.
864 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
865 * the configuration information for HASH module
866 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
867 * @param Size: Length of the input buffer in bytes.
868 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
869 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
872 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
875 uint32_t buffercounter;
876 uint32_t inputcounter;
881 if(hhash->HashITCounter == 0)
883 hhash->HashITCounter = 1;
887 hhash->HashITCounter = 0;
889 if(hhash->State == HAL_HASH_STATE_READY)
891 /* Change the HASH state */
892 hhash->State = HAL_HASH_STATE_BUSY;
894 hhash->HashInCount = Size;
895 hhash->pHashInBuffPtr = pInBuffer;
896 hhash->pHashOutBuffPtr = pOutBuffer;
898 /* Check if initialization phase has already been performed */
899 if(hhash->Phase == HAL_HASH_PHASE_READY)
901 /* Select the SHA256 mode */
902 HASH->CR |= HASH_AlgoSelection_SHA256;
903 /* Reset the HASH processor core, so that the HASH will be ready to compute
904 the message digest of a new message */
905 HASH->CR |= HASH_CR_INIT;
909 hhash->Phase = HAL_HASH_PHASE_PROCESS;
911 /* Process Unlocked */
914 /* Enable Interrupts */
915 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
917 /* Return function status */
920 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
922 /* Read the message digest */
923 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 32);
924 if(hhash->HashInCount == 0)
926 /* Disable Interrupts */
928 /* Change the HASH state */
929 hhash->State = HAL_HASH_STATE_READY;
930 /* Call digest computation complete callback */
931 HAL_HASH_DgstCpltCallback(hhash);
934 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
936 if(hhash->HashInCount > 64)
938 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
939 /* Write the Input block in the Data IN register */
940 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
942 HASH->DIN = *(uint32_t*)inputaddr;
945 if(hhash->HashITCounter == 0)
947 HASH->DIN = *(uint32_t*)inputaddr;
949 if(hhash->HashInCount >= 68)
951 /* Decrement buffer counter */
952 hhash->HashInCount -= 68;
953 hhash->pHashInBuffPtr+= 68;
957 hhash->HashInCount -= 64;
962 /* Decrement buffer counter */
963 hhash->HashInCount -= 64;
964 hhash->pHashInBuffPtr+= 64;
969 /* Get the buffer address */
970 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
971 /* Get the buffer counter */
972 inputcounter = hhash->HashInCount;
973 /* Disable Interrupts */
974 HASH->IMR &= ~(HASH_IT_DINI);
975 /* Configure the number of valid bits in last word of the message */
976 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
978 if((inputcounter > 4) && (inputcounter%4))
980 inputcounter = (inputcounter+4-inputcounter%4);
983 /* Write the Input block in the Data IN register */
984 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
986 HASH->DIN = *(uint32_t*)inputaddr;
989 /* Start the digest calculation */
990 __HAL_HASH_START_DIGEST();
991 /* Reset buffer counter */
992 hhash->HashInCount = 0;
994 /* Call Input data transfer complete callback */
995 HAL_HASH_InCpltCallback(hhash);
998 /* Process Unlocked */
1001 /* Return function status */
1006 * @brief This function handles HASH interrupt request.
1007 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1008 * the configuration information for HASH module
1011 void HAL_HASHEx_IRQHandler(HASH_HandleTypeDef *hhash)
1013 switch(HASH->CR & HASH_CR_ALGO)
1016 case HASH_AlgoSelection_SHA224:
1017 HAL_HASHEx_SHA224_Start_IT(hhash, HAL_NULL, 0, HAL_NULL);
1020 case HASH_AlgoSelection_SHA256:
1021 HAL_HASHEx_SHA256_Start_IT(hhash, HAL_NULL, 0, HAL_NULL);
1033 /** @defgroup HASHEx_Group4 HASH processing functions using DMA mode
1034 * @brief processing functions using DMA mode.
1037 ===============================================================================
1038 ##### HASH processing using DMA functions #####
1039 ===============================================================================
1040 [..] This section provides functions allowing to calculate in DMA mode
1041 the hash value using one of the following algorithms:
1051 * @brief Initializes the HASH peripheral in SHA224 mode then enables DMA to
1052 control data transfer. Use HAL_HASH_SHA224_Finish() to get the digest.
1053 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1054 * the configuration information for HASH module
1055 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1056 * @param Size: Length of the input buffer in bytes.
1057 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1058 * @retval HAL status
1060 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1062 uint32_t inputaddr = (uint32_t)pInBuffer;
1064 /* Process Locked */
1067 /* Change the HASH state */
1068 hhash->State = HAL_HASH_STATE_BUSY;
1070 /* Check if initialization phase has already been performed */
1071 if(hhash->Phase == HAL_HASH_PHASE_READY)
1073 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
1074 the message digest of a new message */
1075 HASH->CR |= HASH_AlgoSelection_SHA224 | HASH_CR_INIT;
1078 /* Configure the number of valid bits in last word of the message */
1079 __HAL_HASH_SET_NBVALIDBITS(Size);
1082 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1084 /* Set the HASH DMA transfer complete callback */
1085 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
1086 /* Set the DMA error callback */
1087 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
1089 /* Enable the DMA In DMA Stream */
1090 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
1092 /* Enable DMA requests */
1093 HASH->CR |= (HASH_CR_DMAE);
1095 /* Process Unlocked */
1096 __HAL_UNLOCK(hhash);
1098 /* Return function status */
1103 * @brief Returns the computed digest in SHA224
1104 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1105 * the configuration information for HASH module
1106 * @param pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
1107 * @param Timeout: Timeout value
1108 * @retval HAL status
1110 HAL_StatusTypeDef HAL_HASHEx_SHA224_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1112 uint32_t tickstart = 0;
1114 /* Process Locked */
1117 /* Change HASH peripheral state */
1118 hhash->State = HAL_HASH_STATE_BUSY;
1121 tickstart = HAL_GetTick();
1123 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1125 /* Check for the Timeout */
1126 if(Timeout != HAL_MAX_DELAY)
1128 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1131 hhash->State = HAL_HASH_STATE_TIMEOUT;
1133 /* Process Unlocked */
1134 __HAL_UNLOCK(hhash);
1141 /* Read the message digest */
1142 HASHEx_GetDigest(pOutBuffer, 28);
1144 /* Change HASH peripheral state */
1145 hhash->State = HAL_HASH_STATE_READY;
1147 /* Process Unlocked */
1148 __HAL_UNLOCK(hhash);
1150 /* Return function status */
1155 * @brief Initializes the HASH peripheral in SHA256 mode then enables DMA to
1156 control data transfer. Use HAL_HASH_SHA256_Finish() to get the digest.
1157 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1158 * the configuration information for HASH module
1159 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1160 * @param Size: Length of the input buffer in bytes.
1161 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1162 * @retval HAL status
1164 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1166 uint32_t inputaddr = (uint32_t)pInBuffer;
1168 /* Process Locked */
1171 /* Change the HASH state */
1172 hhash->State = HAL_HASH_STATE_BUSY;
1174 /* Check if initialization phase has already been performed */
1175 if(hhash->Phase == HAL_HASH_PHASE_READY)
1177 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
1178 the message digest of a new message */
1179 HASH->CR |= HASH_AlgoSelection_SHA256 | HASH_CR_INIT;
1182 /* Configure the number of valid bits in last word of the message */
1183 __HAL_HASH_SET_NBVALIDBITS(Size);
1186 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1188 /* Set the HASH DMA transfer complete callback */
1189 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
1190 /* Set the DMA error callback */
1191 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
1193 /* Enable the DMA In DMA Stream */
1194 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
1196 /* Enable DMA requests */
1197 HASH->CR |= (HASH_CR_DMAE);
1199 /* Process UnLock */
1200 __HAL_UNLOCK(hhash);
1202 /* Return function status */
1207 * @brief Returns the computed digest in SHA256.
1208 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1209 * the configuration information for HASH module
1210 * @param pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
1211 * @param Timeout: Timeout value
1212 * @retval HAL status
1214 HAL_StatusTypeDef HAL_HASHEx_SHA256_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1216 uint32_t tickstart = 0;
1218 /* Process Locked */
1221 /* Change HASH peripheral state */
1222 hhash->State = HAL_HASH_STATE_BUSY;
1225 tickstart = HAL_GetTick();
1227 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1229 /* Check for the Timeout */
1230 if(Timeout != HAL_MAX_DELAY)
1232 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1235 hhash->State = HAL_HASH_STATE_TIMEOUT;
1237 /* Process Unlocked */
1238 __HAL_UNLOCK(hhash);
1245 /* Read the message digest */
1246 HASHEx_GetDigest(pOutBuffer, 32);
1248 /* Change HASH peripheral state */
1249 hhash->State = HAL_HASH_STATE_READY;
1251 /* Process Unlocked */
1252 __HAL_UNLOCK(hhash);
1254 /* Return function status */
1262 /** @defgroup HASHEx_Group5 HMAC processing functions using DMA mode
1263 * @brief HMAC processing functions using DMA mode .
1266 ===============================================================================
1267 ##### HMAC processing using DMA functions #####
1268 ===============================================================================
1269 [..] This section provides functions allowing to calculate in DMA mode
1270 the HMAC value using one of the following algorithms:
1279 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
1280 * then enables DMA to control data transfer.
1281 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1282 * the configuration information for HASH module
1283 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1284 * @param Size: Length of the input buffer in bytes.
1285 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1286 * @retval HAL status
1288 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1292 /* Process Locked */
1295 /* Change the HASH state */
1296 hhash->State = HAL_HASH_STATE_BUSY;
1298 /* Save buffer pointer and size in handle */
1299 hhash->pHashInBuffPtr = pInBuffer;
1300 hhash->HashBuffSize = Size;
1301 hhash->HashInCount = 0;
1303 /* Check if initialization phase has already been performed */
1304 if(hhash->Phase == HAL_HASH_PHASE_READY)
1306 /* Check if key size is greater than 64 bytes */
1307 if(hhash->Init.KeySize > 64)
1309 /* Select the HMAC SHA224 mode */
1310 HASH->CR |= (HASH_AlgoSelection_SHA224 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey | HASH_CR_INIT);
1314 /* Select the HMAC SHA224 mode */
1315 HASH->CR |= (HASH_AlgoSelection_SHA224 | HASH_AlgoMode_HMAC | HASH_CR_INIT);
1320 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1322 /* Configure the number of valid bits in last word of the message */
1323 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1325 /* Get the key address */
1326 inputaddr = (uint32_t)(hhash->Init.pKey);
1328 /* Set the HASH DMA transfer complete callback */
1329 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
1330 /* Set the DMA error callback */
1331 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
1333 /* Enable the DMA In DMA Stream */
1334 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1335 /* Enable DMA requests */
1336 HASH->CR |= (HASH_CR_DMAE);
1338 /* Process Unlocked */
1339 __HAL_UNLOCK(hhash);
1341 /* Return function status */
1346 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
1347 * then enables DMA to control data transfer.
1348 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1349 * the configuration information for HASH module
1350 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1351 * @param Size: Length of the input buffer in bytes.
1352 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1353 * @retval HAL status
1355 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1359 /* Process Locked */
1362 /* Change the HASH state */
1363 hhash->State = HAL_HASH_STATE_BUSY;
1365 /* Save buffer pointer and size in handle */
1366 hhash->pHashInBuffPtr = pInBuffer;
1367 hhash->HashBuffSize = Size;
1368 hhash->HashInCount = 0;
1370 /* Check if initialization phase has already been performed */
1371 if(hhash->Phase == HAL_HASH_PHASE_READY)
1373 /* Check if key size is greater than 64 bytes */
1374 if(hhash->Init.KeySize > 64)
1376 /* Select the HMAC SHA256 mode */
1377 HASH->CR |= (HASH_AlgoSelection_SHA256 | HASH_AlgoMode_HMAC | HASH_HMACKeyType_LongKey);
1381 /* Select the HMAC SHA256 mode */
1382 HASH->CR |= (HASH_AlgoSelection_SHA256 | HASH_AlgoMode_HMAC);
1384 /* Reset the HASH processor core, so that the HASH will be ready to compute
1385 the message digest of a new message */
1386 HASH->CR |= HASH_CR_INIT;
1390 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1392 /* Configure the number of valid bits in last word of the message */
1393 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1395 /* Get the key address */
1396 inputaddr = (uint32_t)(hhash->Init.pKey);
1398 /* Set the HASH DMA transfer complete callback */
1399 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
1400 /* Set the DMA error callback */
1401 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
1403 /* Enable the DMA In DMA Stream */
1404 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1405 /* Enable DMA requests */
1406 HASH->CR |= (HASH_CR_DMAE);
1408 /* Process Unlocked */
1409 __HAL_UNLOCK(hhash);
1411 /* Return function status */
1420 * @brief Writes the input buffer in data register.
1421 * @param pInBuffer: Pointer to input buffer
1422 * @param Size: The size of input buffer
1425 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size)
1427 uint32_t buffercounter;
1428 uint32_t inputaddr = (uint32_t) pInBuffer;
1430 for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
1432 HASH->DIN = *(uint32_t*)inputaddr;
1438 * @brief Provides the message digest result.
1439 * @param pMsgDigest: Pointer to the message digest
1440 * @param Size: The size of the message digest in bytes
1443 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
1445 uint32_t msgdigest = (uint32_t)pMsgDigest;
1450 /* Read the message digest */
1451 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1453 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1455 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1457 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1460 /* Read the message digest */
1461 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1463 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1465 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1467 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1469 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1472 /* Read the message digest */
1473 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1475 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1477 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1479 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1481 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1483 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1485 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1488 /* Read the message digest */
1489 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1491 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1493 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1495 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1497 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1499 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1501 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1503 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
1511 * @brief DMA HASH Input Data complete callback.
1512 * @param hdma: DMA handle
1515 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma)
1517 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1518 uint32_t inputaddr = 0;
1519 uint32_t buffersize = 0;
1521 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
1523 /* Disable the DMA transfer */
1524 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1526 /* Change HASH peripheral state */
1527 hhash->State = HAL_HASH_STATE_READY;
1529 /* Call Input data transfer complete callback */
1530 HAL_HASH_InCpltCallback(hhash);
1534 /* Increment Interrupt counter */
1535 hhash->HashInCount++;
1536 /* Disable the DMA transfer before starting the next transfer */
1537 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1539 if(hhash->HashInCount <= 2)
1541 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
1542 if(hhash->HashInCount == 1)
1544 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1545 buffersize = hhash->HashBuffSize;
1547 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
1548 else if(hhash->HashInCount == 2)
1550 inputaddr = (uint32_t)hhash->Init.pKey;
1551 buffersize = hhash->Init.KeySize;
1553 /* Configure the number of valid bits in last word of the message */
1554 HASH->STR |= 8 * (buffersize % 4);
1556 /* Set the HASH DMA transfer complete */
1557 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
1559 /* Enable the DMA In DMA Stream */
1560 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
1562 /* Enable DMA requests */
1563 HASH->CR |= (HASH_CR_DMAE);
1567 /* Disable the DMA transfer */
1568 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
1570 /* Reset the InCount */
1571 hhash->HashInCount = 0;
1573 /* Change HASH peripheral state */
1574 hhash->State = HAL_HASH_STATE_READY;
1576 /* Call Input data transfer complete callback */
1577 HAL_HASH_InCpltCallback(hhash);
1583 * @brief DMA HASH communication error callback.
1584 * @param hdma: DMA handle
1587 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma)
1589 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1590 hhash->State= HAL_HASH_STATE_READY;
1591 HAL_HASH_ErrorCallback(hhash);
1598 #endif /* STM32F437xx || STM32F439xx */
1600 #endif /* HAL_HASH_MODULE_ENABLED */
1609 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/