2 ******************************************************************************
3 * @file stm32f7xx_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 __HAL_RCC_HASH_CLK_ENABLE()
24 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMAC_SHA1_Start_IT())
25 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
26 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
27 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
28 (##) In case of using DMA to control data transfer (e.g. HAL_HMAC_SHA1_Start_DMA())
29 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
30 (+++) Configure and enable one DMA stream one for managing data transfer from
31 memory to peripheral (input stream). Managing data transfer from
32 peripheral to memory can be performed only using CPU
33 (+++) Associate the initialized DMA handle to the HASH DMA handle
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) 2017 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 "stm32f7xx_hal.h"
101 /** @addtogroup STM32F7xx_HAL_Driver
105 #if defined (STM32F756xx) || defined (STM32F777xx) || defined (STM32F779xx)
107 /** @defgroup HASH HASH
108 * @brief HASH HAL module driver.
111 #ifdef HAL_HASH_MODULE_ENABLED
113 /* Private typedef -----------------------------------------------------------*/
114 /* Private define ------------------------------------------------------------*/
115 /* Private macro -------------------------------------------------------------*/
116 /* Private variables ---------------------------------------------------------*/
117 /* Private function prototypes -----------------------------------------------*/
118 /** @defgroup HASH_Private_Functions HASH Private Functions
121 static void HASH_DMAXferCplt(DMA_HandleTypeDef
*hdma
);
122 static void HASH_DMAError(DMA_HandleTypeDef
*hdma
);
123 static void HASH_GetDigest(uint8_t *pMsgDigest
, uint8_t Size
);
124 static void HASH_WriteData(uint8_t *pInBuffer
, uint32_t Size
);
129 /* Private functions ---------------------------------------------------------*/
130 /** @addtogroup HASH_Private_Functions
135 * @brief DMA HASH Input Data complete callback.
136 * @param hdma: DMA handle
139 static void HASH_DMAXferCplt(DMA_HandleTypeDef
*hdma
)
141 HASH_HandleTypeDef
* hhash
= ( HASH_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
142 uint32_t inputaddr
= 0;
143 uint32_t buffersize
= 0;
145 if((HASH
->CR
& HASH_CR_MODE
) != HASH_CR_MODE
)
147 /* Disable the DMA transfer */
148 HASH
->CR
&= (uint32_t)(~HASH_CR_DMAE
);
150 /* Change HASH peripheral state */
151 hhash
->State
= HAL_HASH_STATE_READY
;
153 /* Call Input data transfer complete callback */
154 HAL_HASH_InCpltCallback(hhash
);
158 /* Increment Interrupt counter */
159 hhash
->HashInCount
++;
160 /* Disable the DMA transfer before starting the next transfer */
161 HASH
->CR
&= (uint32_t)(~HASH_CR_DMAE
);
163 if(hhash
->HashInCount
<= 2)
165 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
166 if(hhash
->HashInCount
== 1)
168 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
169 buffersize
= hhash
->HashBuffSize
;
171 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
172 else if(hhash
->HashInCount
== 2)
174 inputaddr
= (uint32_t)hhash
->Init
.pKey
;
175 buffersize
= hhash
->Init
.KeySize
;
177 /* Configure the number of valid bits in last word of the message */
178 MODIFY_REG(HASH
->STR
, HASH_STR_NBLW
, 8 * (buffersize
% 4));
180 /* Set the HASH DMA transfer complete */
181 hhash
->hdmain
->XferCpltCallback
= HASH_DMAXferCplt
;
183 /* Enable the DMA In DMA Stream */
184 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (buffersize
%4 ? (buffersize
+3)/4:buffersize
/4));
186 /* Enable DMA requests */
187 HASH
->CR
|= (HASH_CR_DMAE
);
191 /* Disable the DMA transfer */
192 HASH
->CR
&= (uint32_t)(~HASH_CR_DMAE
);
194 /* Reset the InCount */
195 hhash
->HashInCount
= 0;
197 /* Change HASH peripheral state */
198 hhash
->State
= HAL_HASH_STATE_READY
;
200 /* Call Input data transfer complete callback */
201 HAL_HASH_InCpltCallback(hhash
);
207 * @brief DMA HASH communication error callback.
208 * @param hdma: DMA handle
211 static void HASH_DMAError(DMA_HandleTypeDef
*hdma
)
213 HASH_HandleTypeDef
* hhash
= ( HASH_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
214 hhash
->State
= HAL_HASH_STATE_READY
;
215 HAL_HASH_ErrorCallback(hhash
);
219 * @brief Writes the input buffer in data register.
220 * @param pInBuffer: Pointer to input buffer
221 * @param Size: The size of input buffer
224 static void HASH_WriteData(uint8_t *pInBuffer
, uint32_t Size
)
226 uint32_t buffercounter
;
227 uint32_t inputaddr
= (uint32_t) pInBuffer
;
229 for(buffercounter
= 0; buffercounter
< Size
; buffercounter
+=4)
231 HASH
->DIN
= *(uint32_t*)inputaddr
;
237 * @brief Provides the message digest result.
238 * @param pMsgDigest: Pointer to the message digest
239 * @param Size: The size of the message digest in bytes
242 static void HASH_GetDigest(uint8_t *pMsgDigest
, uint8_t Size
)
244 uint32_t msgdigest
= (uint32_t)pMsgDigest
;
249 /* Read the message digest */
250 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[0]);
252 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[1]);
254 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[2]);
256 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[3]);
259 /* Read the message digest */
260 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[0]);
262 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[1]);
264 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[2]);
266 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[3]);
268 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[4]);
271 /* Read the message digest */
272 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[0]);
274 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[1]);
276 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[2]);
278 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[3]);
280 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[4]);
282 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[5]);
284 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[6]);
287 /* Read the message digest */
288 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[0]);
290 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[1]);
292 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[2]);
294 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[3]);
296 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[4]);
298 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[5]);
300 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[6]);
302 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[7]);
313 /* Exported functions --------------------------------------------------------*/
314 /** @addtogroup HASH_Exported_Functions
319 /** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions
320 * @brief Initialization and Configuration functions.
323 ===============================================================================
324 ##### Initialization and de-initialization functions #####
325 ===============================================================================
326 [..] This section provides functions allowing to:
327 (+) Initialize the HASH according to the specified parameters
328 in the HASH_InitTypeDef and creates the associated handle.
329 (+) DeInitialize the HASH peripheral.
330 (+) Initialize the HASH MSP.
331 (+) DeInitialize HASH MSP.
338 * @brief Initializes the HASH according to the specified parameters in the
339 HASH_HandleTypeDef and creates the associated handle.
340 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
341 * the configuration information for HASH module
344 HAL_StatusTypeDef
HAL_HASH_Init(HASH_HandleTypeDef
*hhash
)
346 /* Check the hash handle allocation */
352 /* Check the parameters */
353 assert_param(IS_HASH_DATATYPE(hhash
->Init
.DataType
));
355 if(hhash
->State
== HAL_HASH_STATE_RESET
)
357 /* Allocate lock resource and initialize it */
358 hhash
->Lock
= HAL_UNLOCKED
;
359 /* Init the low level hardware */
360 HAL_HASH_MspInit(hhash
);
363 /* Change the HASH state */
364 hhash
->State
= HAL_HASH_STATE_BUSY
;
366 /* Reset HashInCount, HashBuffSize and HashITCounter */
367 hhash
->HashInCount
= 0;
368 hhash
->HashBuffSize
= 0;
369 hhash
->HashITCounter
= 0;
371 /* Set the data type */
372 HASH
->CR
|= (uint32_t) (hhash
->Init
.DataType
);
374 /* Change the HASH state */
375 hhash
->State
= HAL_HASH_STATE_READY
;
377 /* Set the default HASH phase */
378 hhash
->Phase
= HAL_HASH_PHASE_READY
;
380 /* Return function status */
385 * @brief DeInitializes the HASH peripheral.
386 * @note This API must be called before starting a new processing.
387 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
388 * the configuration information for HASH module
391 HAL_StatusTypeDef
HAL_HASH_DeInit(HASH_HandleTypeDef
*hhash
)
393 /* Check the HASH handle allocation */
399 /* Change the HASH state */
400 hhash
->State
= HAL_HASH_STATE_BUSY
;
402 /* Set the default HASH phase */
403 hhash
->Phase
= HAL_HASH_PHASE_READY
;
405 /* Reset HashInCount, HashBuffSize and HashITCounter */
406 hhash
->HashInCount
= 0;
407 hhash
->HashBuffSize
= 0;
408 hhash
->HashITCounter
= 0;
410 /* DeInit the low level hardware */
411 HAL_HASH_MspDeInit(hhash
);
413 /* Change the HASH state */
414 hhash
->State
= HAL_HASH_STATE_RESET
;
419 /* Return function status */
424 * @brief Initializes the HASH MSP.
425 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
426 * the configuration information for HASH module
429 __weak
void HAL_HASH_MspInit(HASH_HandleTypeDef
*hhash
)
431 /* Prevent unused argument(s) compilation warning */
434 /* NOTE: This function Should not be modified, when the callback is needed,
435 the HAL_HASH_MspInit could be implemented in the user file
440 * @brief DeInitializes HASH MSP.
441 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
442 * the configuration information for HASH module
445 __weak
void HAL_HASH_MspDeInit(HASH_HandleTypeDef
*hhash
)
447 /* Prevent unused argument(s) compilation warning */
450 /* NOTE: This function Should not be modified, when the callback is needed,
451 the HAL_HASH_MspDeInit could be implemented in the user file
456 * @brief Input data transfer complete callback.
457 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
458 * the configuration information for HASH module
461 __weak
void HAL_HASH_InCpltCallback(HASH_HandleTypeDef
*hhash
)
463 /* Prevent unused argument(s) compilation warning */
466 /* NOTE: This function Should not be modified, when the callback is needed,
467 the HAL_HASH_InCpltCallback could be implemented in the user file
472 * @brief Data transfer Error callback.
473 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
474 * the configuration information for HASH module
477 __weak
void HAL_HASH_ErrorCallback(HASH_HandleTypeDef
*hhash
)
479 /* Prevent unused argument(s) compilation warning */
482 /* NOTE: This function Should not be modified, when the callback is needed,
483 the HAL_HASH_ErrorCallback could be implemented in the user file
488 * @brief Digest computation complete callback. It is used only with interrupt.
489 * @note This callback is not relevant with DMA.
490 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
491 * the configuration information for HASH module
494 __weak
void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef
*hhash
)
496 /* Prevent unused argument(s) compilation warning */
499 /* NOTE: This function Should not be modified, when the callback is needed,
500 the HAL_HASH_DgstCpltCallback could be implemented in the user file
508 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions using polling mode
509 * @brief processing functions using polling mode
512 ===============================================================================
513 ##### HASH processing using polling mode functions#####
514 ===============================================================================
515 [..] This section provides functions allowing to calculate in polling mode
516 the hash value using one of the following algorithms:
525 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
526 The digest is available in pOutBuffer.
527 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
528 * the configuration information for HASH module
529 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
530 * @param Size: Length of the input buffer in bytes.
531 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
532 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
533 * and appending the input buffer is no more possible.
534 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
535 * @param Timeout: Timeout value
538 HAL_StatusTypeDef
HAL_HASH_MD5_Start(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
, uint32_t Timeout
)
540 uint32_t tickstart
= 0;
545 /* Change the HASH state */
546 hhash
->State
= HAL_HASH_STATE_BUSY
;
548 /* Check if initialization phase has already been performed */
549 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
551 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
552 the message digest of a new message */
553 HASH
->CR
|= HASH_ALGOSELECTION_MD5
| HASH_CR_INIT
;
557 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
559 /* Configure the number of valid bits in last word of the message */
560 __HAL_HASH_SET_NBVALIDBITS(Size
);
562 /* Write input buffer in data register */
563 HASH_WriteData(pInBuffer
, Size
);
565 /* Start the digest calculation */
566 __HAL_HASH_START_DIGEST();
569 tickstart
= HAL_GetTick();
571 while(HAL_IS_BIT_SET(HASH
->SR
, HASH_FLAG_BUSY
))
573 /* Check for the Timeout */
574 if(Timeout
!= HAL_MAX_DELAY
)
576 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
579 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
581 /* Process Unlocked */
589 /* Read the message digest */
590 HASH_GetDigest(pOutBuffer
, 16);
592 /* Change the HASH state */
593 hhash
->State
= HAL_HASH_STATE_READY
;
595 /* Process Unlocked */
598 /* Return function status */
603 * @brief Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
604 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
605 * the configuration information for HASH module
606 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
607 * @param Size: Length of the input buffer in bytes.
608 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
609 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
610 * and appending the input buffer is no more possible.
613 HAL_StatusTypeDef
HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
618 /* Change the HASH state */
619 hhash
->State
= HAL_HASH_STATE_BUSY
;
621 /* Check if initialization phase has already been performed */
622 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
624 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
625 the message digest of a new message */
626 HASH
->CR
|= HASH_ALGOSELECTION_MD5
| HASH_CR_INIT
;
630 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
632 /* Configure the number of valid bits in last word of the message */
633 __HAL_HASH_SET_NBVALIDBITS(Size
);
635 /* Write input buffer in data register */
636 HASH_WriteData(pInBuffer
, Size
);
638 /* Change the HASH state */
639 hhash
->State
= HAL_HASH_STATE_READY
;
641 /* Process Unlocked */
644 /* Return function status */
649 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
650 The digest is available in pOutBuffer.
651 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
652 * the configuration information for HASH module
653 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
654 * @param Size: Length of the input buffer in bytes.
655 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
656 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
657 * @param Timeout: Timeout value
660 HAL_StatusTypeDef
HAL_HASH_SHA1_Start(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
, uint32_t Timeout
)
662 uint32_t tickstart
= 0;
667 /* Change the HASH state */
668 hhash
->State
= HAL_HASH_STATE_BUSY
;
670 /* Check if initialization phase has already been performed */
671 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
673 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
674 the message digest of a new message */
675 HASH
->CR
|= HASH_ALGOSELECTION_SHA1
| HASH_CR_INIT
;
679 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
681 /* Configure the number of valid bits in last word of the message */
682 __HAL_HASH_SET_NBVALIDBITS(Size
);
684 /* Write input buffer in data register */
685 HASH_WriteData(pInBuffer
, Size
);
687 /* Start the digest calculation */
688 __HAL_HASH_START_DIGEST();
691 tickstart
= HAL_GetTick();
693 while(HAL_IS_BIT_SET(HASH
->SR
, HASH_FLAG_BUSY
))
695 /* Check for the Timeout */
696 if(Timeout
!= HAL_MAX_DELAY
)
698 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
701 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
703 /* Process Unlocked */
711 /* Read the message digest */
712 HASH_GetDigest(pOutBuffer
, 20);
714 /* Change the HASH state */
715 hhash
->State
= HAL_HASH_STATE_READY
;
717 /* Process Unlocked */
720 /* Return function status */
725 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
726 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
727 * the configuration information for HASH module
728 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
729 * @param Size: Length of the input buffer in bytes.
730 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
731 * @note Input buffer size in bytes must be a multiple of 4 otherwise the digest computation is corrupted.
734 HAL_StatusTypeDef
HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
736 /* Check the parameters */
737 assert_param(IS_HASH_SHA1_BUFFER_SIZE(Size
));
742 /* Change the HASH state */
743 hhash
->State
= HAL_HASH_STATE_BUSY
;
745 /* Check if initialization phase has already been performed */
746 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
748 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
749 the message digest of a new message */
750 HASH
->CR
|= HASH_ALGOSELECTION_SHA1
| HASH_CR_INIT
;
754 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
756 /* Configure the number of valid bits in last word of the message */
757 __HAL_HASH_SET_NBVALIDBITS(Size
);
759 /* Write input buffer in data register */
760 HASH_WriteData(pInBuffer
, Size
);
762 /* Change the HASH state */
763 hhash
->State
= HAL_HASH_STATE_READY
;
765 /* Process Unlocked */
768 /* Return function status */
776 /** @defgroup HASH_Exported_Functions_Group3 HASH processing functions using interrupt mode
777 * @brief processing functions using interrupt mode.
780 ===============================================================================
781 ##### HASH processing using interrupt mode functions #####
782 ===============================================================================
783 [..] This section provides functions allowing to calculate in interrupt mode
784 the hash value using one of the following algorithms:
793 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
794 * The digest is available in pOutBuffer.
795 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
796 * the configuration information for HASH module
797 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
798 * @param Size: Length of the input buffer in bytes.
799 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
800 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
803 HAL_StatusTypeDef
HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
)
807 uint32_t buffercounter
;
808 uint32_t inputcounter
;
813 if(hhash
->State
== HAL_HASH_STATE_READY
)
815 /* Change the HASH state */
816 hhash
->State
= HAL_HASH_STATE_BUSY
;
818 hhash
->HashInCount
= Size
;
819 hhash
->pHashInBuffPtr
= pInBuffer
;
820 hhash
->pHashOutBuffPtr
= pOutBuffer
;
822 /* Check if initialization phase has already been performed */
823 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
825 /* Select the SHA1 mode */
826 HASH
->CR
|= HASH_ALGOSELECTION_MD5
;
827 /* Reset the HASH processor core, so that the HASH will be ready to compute
828 the message digest of a new message */
829 HASH
->CR
|= HASH_CR_INIT
;
832 /* Reset interrupt counter */
833 hhash
->HashITCounter
= 0;
836 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
838 /* Process Unlocked */
841 /* Enable Interrupts */
842 HASH
->IMR
= (HASH_IT_DINI
| HASH_IT_DCI
);
844 /* Return function status */
847 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS
))
849 outputaddr
= (uint32_t)hhash
->pHashOutBuffPtr
;
850 /* Read the Output block from the Output FIFO */
851 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[0]);
853 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[1]);
855 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[2]);
857 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[3]);
859 if(hhash
->HashInCount
== 0)
861 /* Disable Interrupts */
863 /* Change the HASH state */
864 hhash
->State
= HAL_HASH_STATE_READY
;
865 /* Call digest computation complete callback */
866 HAL_HASH_DgstCpltCallback(hhash
);
868 /* Process Unlocked */
871 /* Return function status */
876 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS
))
878 if(hhash
->HashInCount
>= 68)
880 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
881 /* Write the Input block in the Data IN register */
882 for(buffercounter
= 0; buffercounter
< 64; buffercounter
+=4)
884 HASH
->DIN
= *(uint32_t*)inputaddr
;
887 if(hhash
->HashITCounter
== 0)
889 HASH
->DIN
= *(uint32_t*)inputaddr
;
891 if(hhash
->HashInCount
>= 68)
893 /* Decrement buffer counter */
894 hhash
->HashInCount
-= 68;
895 hhash
->pHashInBuffPtr
+= 68;
899 hhash
->HashInCount
= 0;
900 hhash
->pHashInBuffPtr
+= hhash
->HashInCount
;
902 /* Set Interrupt counter */
903 hhash
->HashITCounter
= 1;
907 /* Decrement buffer counter */
908 hhash
->HashInCount
-= 64;
909 hhash
->pHashInBuffPtr
+= 64;
914 /* Get the buffer address */
915 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
916 /* Get the buffer counter */
917 inputcounter
= hhash
->HashInCount
;
918 /* Disable Interrupts */
919 HASH
->IMR
&= ~(HASH_IT_DINI
);
920 /* Configure the number of valid bits in last word of the message */
921 __HAL_HASH_SET_NBVALIDBITS(inputcounter
);
923 if((inputcounter
> 4) && (inputcounter
%4))
925 inputcounter
= (inputcounter
+4-inputcounter
%4);
927 else if ((inputcounter
< 4) && (inputcounter
!= 0))
932 /* Write the Input block in the Data IN register */
933 for(buffercounter
= 0; buffercounter
< inputcounter
/4; buffercounter
++)
935 HASH
->DIN
= *(uint32_t*)inputaddr
;
938 /* Start the digest calculation */
939 __HAL_HASH_START_DIGEST();
940 /* Reset buffer counter */
941 hhash
->HashInCount
= 0;
942 /* Call Input data transfer complete callback */
943 HAL_HASH_InCpltCallback(hhash
);
947 /* Process Unlocked */
950 /* Return function status */
955 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
956 * The digest is available in pOutBuffer.
957 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
958 * the configuration information for HASH module
959 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
960 * @param Size: Length of the input buffer in bytes.
961 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
962 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
965 HAL_StatusTypeDef
HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
)
969 uint32_t buffercounter
;
970 uint32_t inputcounter
;
975 if(hhash
->State
== HAL_HASH_STATE_READY
)
977 /* Change the HASH state */
978 hhash
->State
= HAL_HASH_STATE_BUSY
;
980 hhash
->HashInCount
= Size
;
981 hhash
->pHashInBuffPtr
= pInBuffer
;
982 hhash
->pHashOutBuffPtr
= pOutBuffer
;
984 /* Check if initialization phase has already been performed */
985 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
987 /* Select the SHA1 mode */
988 HASH
->CR
|= HASH_ALGOSELECTION_SHA1
;
989 /* Reset the HASH processor core, so that the HASH will be ready to compute
990 the message digest of a new message */
991 HASH
->CR
|= HASH_CR_INIT
;
994 /* Reset interrupt counter */
995 hhash
->HashITCounter
= 0;
998 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1000 /* Process Unlocked */
1001 __HAL_UNLOCK(hhash
);
1003 /* Enable Interrupts */
1004 HASH
->IMR
= (HASH_IT_DINI
| HASH_IT_DCI
);
1006 /* Return function status */
1009 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS
))
1011 outputaddr
= (uint32_t)hhash
->pHashOutBuffPtr
;
1012 /* Read the Output block from the Output FIFO */
1013 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[0]);
1015 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[1]);
1017 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[2]);
1019 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[3]);
1021 *(uint32_t*)(outputaddr
) = __REV(HASH
->HR
[4]);
1022 if(hhash
->HashInCount
== 0)
1024 /* Disable Interrupts */
1026 /* Change the HASH state */
1027 hhash
->State
= HAL_HASH_STATE_READY
;
1028 /* Call digest computation complete callback */
1029 HAL_HASH_DgstCpltCallback(hhash
);
1031 /* Process Unlocked */
1032 __HAL_UNLOCK(hhash
);
1034 /* Return function status */
1038 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS
))
1040 if(hhash
->HashInCount
>= 68)
1042 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
1043 /* Write the Input block in the Data IN register */
1044 for(buffercounter
= 0; buffercounter
< 64; buffercounter
+=4)
1046 HASH
->DIN
= *(uint32_t*)inputaddr
;
1049 if(hhash
->HashITCounter
== 0)
1051 HASH
->DIN
= *(uint32_t*)inputaddr
;
1053 if(hhash
->HashInCount
>= 68)
1055 /* Decrement buffer counter */
1056 hhash
->HashInCount
-= 68;
1057 hhash
->pHashInBuffPtr
+= 68;
1061 hhash
->HashInCount
= 0;
1062 hhash
->pHashInBuffPtr
+= hhash
->HashInCount
;
1064 /* Set Interrupt counter */
1065 hhash
->HashITCounter
= 1;
1069 /* Decrement buffer counter */
1070 hhash
->HashInCount
-= 64;
1071 hhash
->pHashInBuffPtr
+= 64;
1076 /* Get the buffer address */
1077 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
1078 /* Get the buffer counter */
1079 inputcounter
= hhash
->HashInCount
;
1080 /* Disable Interrupts */
1081 HASH
->IMR
&= ~(HASH_IT_DINI
);
1082 /* Configure the number of valid bits in last word of the message */
1083 __HAL_HASH_SET_NBVALIDBITS(inputcounter
);
1085 if((inputcounter
> 4) && (inputcounter
%4))
1087 inputcounter
= (inputcounter
+4-inputcounter
%4);
1089 else if ((inputcounter
< 4) && (inputcounter
!= 0))
1093 /* Write the Input block in the Data IN register */
1094 for(buffercounter
= 0; buffercounter
< inputcounter
/4; buffercounter
++)
1096 HASH
->DIN
= *(uint32_t*)inputaddr
;
1099 /* Start the digest calculation */
1100 __HAL_HASH_START_DIGEST();
1101 /* Reset buffer counter */
1102 hhash
->HashInCount
= 0;
1103 /* Call Input data transfer complete callback */
1104 HAL_HASH_InCpltCallback(hhash
);
1108 /* Process Unlocked */
1109 __HAL_UNLOCK(hhash
);
1111 /* Return function status */
1116 * @brief This function handles HASH interrupt request.
1117 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1118 * the configuration information for HASH module
1121 void HAL_HASH_IRQHandler(HASH_HandleTypeDef
*hhash
)
1123 switch(HASH
->CR
& HASH_CR_ALGO
)
1125 case HASH_ALGOSELECTION_MD5
:
1126 HAL_HASH_MD5_Start_IT(hhash
, NULL
, 0, NULL
);
1129 case HASH_ALGOSELECTION_SHA1
:
1130 HAL_HASH_SHA1_Start_IT(hhash
, NULL
, 0, NULL
);
1142 /** @defgroup HASH_Exported_Functions_Group4 HASH processing functions using DMA mode
1143 * @brief processing functions using DMA mode.
1146 ===============================================================================
1147 ##### HASH processing using DMA mode functions #####
1148 ===============================================================================
1149 [..] This section provides functions allowing to calculate in DMA mode
1150 the hash value using one of the following algorithms:
1159 * @brief Initializes the HASH peripheral in MD5 mode then enables DMA to
1160 control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
1161 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1162 * the configuration information for HASH module
1163 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1164 * @param Size: Length of the input buffer in bytes.
1165 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1166 * @retval HAL status
1168 HAL_StatusTypeDef
HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
1170 uint32_t inputaddr
= (uint32_t)pInBuffer
;
1172 /* Process Locked */
1175 /* Change the HASH state */
1176 hhash
->State
= HAL_HASH_STATE_BUSY
;
1178 /* Check if initialization phase has already been performed */
1179 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1181 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
1182 the message digest of a new message */
1183 HASH
->CR
|= HASH_ALGOSELECTION_MD5
| HASH_CR_INIT
;
1186 /* Configure the number of valid bits in last word of the message */
1187 __HAL_HASH_SET_NBVALIDBITS(Size
);
1190 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1192 /* Set the HASH DMA transfer complete callback */
1193 hhash
->hdmain
->XferCpltCallback
= HASH_DMAXferCplt
;
1194 /* Set the DMA error callback */
1195 hhash
->hdmain
->XferErrorCallback
= HASH_DMAError
;
1197 /* Enable the DMA In DMA Stream */
1198 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (Size
%4 ? (Size
+3)/4:Size
/4));
1200 /* Enable DMA requests */
1201 HASH
->CR
|= (HASH_CR_DMAE
);
1203 /* Process Unlocked */
1204 __HAL_UNLOCK(hhash
);
1206 /* Return function status */
1211 * @brief Returns the computed digest in MD5 mode
1212 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1213 * the configuration information for HASH module
1214 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
1215 * @param Timeout: Timeout value
1216 * @retval HAL status
1218 HAL_StatusTypeDef
HAL_HASH_MD5_Finish(HASH_HandleTypeDef
*hhash
, uint8_t* pOutBuffer
, uint32_t Timeout
)
1220 uint32_t tickstart
= 0;
1222 /* Process Locked */
1225 /* Change HASH peripheral state */
1226 hhash
->State
= HAL_HASH_STATE_BUSY
;
1229 tickstart
= HAL_GetTick();
1231 while(HAL_IS_BIT_CLR(HASH
->SR
, HASH_FLAG_DCIS
))
1233 /* Check for the Timeout */
1234 if(Timeout
!= HAL_MAX_DELAY
)
1236 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1239 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1241 /* Process Unlocked */
1242 __HAL_UNLOCK(hhash
);
1249 /* Read the message digest */
1250 HASH_GetDigest(pOutBuffer
, 16);
1252 /* Change HASH peripheral state */
1253 hhash
->State
= HAL_HASH_STATE_READY
;
1255 /* Process Unlocked */
1256 __HAL_UNLOCK(hhash
);
1258 /* Return function status */
1263 * @brief Initializes the HASH peripheral in SHA1 mode then enables DMA to
1264 control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
1265 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1266 * the configuration information for HASH module
1267 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1268 * @param Size: Length of the input buffer in bytes.
1269 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1270 * @retval HAL status
1272 HAL_StatusTypeDef
HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
1274 uint32_t inputaddr
= (uint32_t)pInBuffer
;
1276 /* Process Locked */
1279 /* Change the HASH state */
1280 hhash
->State
= HAL_HASH_STATE_BUSY
;
1282 /* Check if initialization phase has already been performed */
1283 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1285 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
1286 the message digest of a new message */
1287 HASH
->CR
|= HASH_ALGOSELECTION_SHA1
;
1288 HASH
->CR
|= HASH_CR_INIT
;
1291 /* Configure the number of valid bits in last word of the message */
1292 __HAL_HASH_SET_NBVALIDBITS(Size
);
1295 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1297 /* Set the HASH DMA transfer complete callback */
1298 hhash
->hdmain
->XferCpltCallback
= HASH_DMAXferCplt
;
1299 /* Set the DMA error callback */
1300 hhash
->hdmain
->XferErrorCallback
= HASH_DMAError
;
1302 /* Enable the DMA In DMA Stream */
1303 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (Size
%4 ? (Size
+3)/4:Size
/4));
1305 /* Enable DMA requests */
1306 HASH
->CR
|= (HASH_CR_DMAE
);
1308 /* Process Unlocked */
1309 __HAL_UNLOCK(hhash
);
1311 /* Return function status */
1316 * @brief Returns the computed digest in SHA1 mode.
1317 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1318 * the configuration information for HASH module
1319 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1320 * @param Timeout: Timeout value
1321 * @retval HAL status
1323 HAL_StatusTypeDef
HAL_HASH_SHA1_Finish(HASH_HandleTypeDef
*hhash
, uint8_t* pOutBuffer
, uint32_t Timeout
)
1325 uint32_t tickstart
= 0;
1327 /* Process Locked */
1330 /* Change HASH peripheral state */
1331 hhash
->State
= HAL_HASH_STATE_BUSY
;
1334 tickstart
= HAL_GetTick();
1335 while(HAL_IS_BIT_CLR(HASH
->SR
, HASH_FLAG_DCIS
))
1337 /* Check for the Timeout */
1338 if(Timeout
!= HAL_MAX_DELAY
)
1340 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1343 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1345 /* Process Unlocked */
1346 __HAL_UNLOCK(hhash
);
1353 /* Read the message digest */
1354 HASH_GetDigest(pOutBuffer
, 20);
1356 /* Change HASH peripheral state */
1357 hhash
->State
= HAL_HASH_STATE_READY
;
1359 /* Process UnLock */
1360 __HAL_UNLOCK(hhash
);
1362 /* Return function status */
1371 /** @defgroup HASH_Exported_Functions_Group5 HASH-MAC (HMAC) processing functions using polling mode
1372 * @brief HMAC processing functions using polling mode .
1375 ===============================================================================
1376 ##### HMAC processing using polling mode functions #####
1377 ===============================================================================
1378 [..] This section provides functions allowing to calculate in polling mode
1379 the HMAC value using one of the following algorithms:
1388 * @brief Initializes the HASH peripheral in HMAC MD5 mode
1389 * then processes pInBuffer. The digest is available in pOutBuffer
1390 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1391 * the configuration information for HASH module
1392 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1393 * @param Size: Length of the input buffer in bytes.
1394 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1395 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1396 * @param Timeout: Timeout value
1397 * @retval HAL status
1399 HAL_StatusTypeDef
HAL_HMAC_MD5_Start(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
, uint32_t Timeout
)
1401 uint32_t tickstart
= 0;
1403 /* Process Locked */
1406 /* Change the HASH state */
1407 hhash
->State
= HAL_HASH_STATE_BUSY
;
1409 /* Check if initialization phase has already been performed */
1410 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1412 /* Check if key size is greater than 64 bytes */
1413 if(hhash
->Init
.KeySize
> 64)
1415 /* Select the HMAC MD5 mode */
1416 HASH
->CR
|= (HASH_ALGOSELECTION_MD5
| HASH_ALGOMODE_HMAC
| HASH_HMAC_KEYTYPE_LONGKEY
| HASH_CR_INIT
);
1420 /* Select the HMAC MD5 mode */
1421 HASH
->CR
|= (HASH_ALGOSELECTION_MD5
| HASH_ALGOMODE_HMAC
| HASH_CR_INIT
);
1426 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1428 /************************** STEP 1 ******************************************/
1429 /* Configure the number of valid bits in last word of the message */
1430 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
1432 /* Write input buffer in data register */
1433 HASH_WriteData(hhash
->Init
.pKey
, hhash
->Init
.KeySize
);
1435 /* Start the digest calculation */
1436 __HAL_HASH_START_DIGEST();
1439 tickstart
= HAL_GetTick();
1441 while(HAL_IS_BIT_SET(HASH
->SR
, HASH_FLAG_BUSY
))
1443 /* Check for the Timeout */
1444 if(Timeout
!= HAL_MAX_DELAY
)
1446 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1449 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1451 /* Process Unlocked */
1452 __HAL_UNLOCK(hhash
);
1458 /************************** STEP 2 ******************************************/
1459 /* Configure the number of valid bits in last word of the message */
1460 __HAL_HASH_SET_NBVALIDBITS(Size
);
1462 /* Write input buffer in data register */
1463 HASH_WriteData(pInBuffer
, Size
);
1465 /* Start the digest calculation */
1466 __HAL_HASH_START_DIGEST();
1469 tickstart
= HAL_GetTick();
1471 while(HAL_IS_BIT_SET(HASH
->SR
, HASH_FLAG_BUSY
))
1473 /* Check for the Timeout */
1474 if(Timeout
!= HAL_MAX_DELAY
)
1476 if((HAL_GetTick() - tickstart
) > Timeout
)
1479 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1481 /* Process Unlocked */
1482 __HAL_UNLOCK(hhash
);
1488 /************************** STEP 3 ******************************************/
1489 /* Configure the number of valid bits in last word of the message */
1490 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
1492 /* Write input buffer in data register */
1493 HASH_WriteData(hhash
->Init
.pKey
, hhash
->Init
.KeySize
);
1495 /* Start the digest calculation */
1496 __HAL_HASH_START_DIGEST();
1499 tickstart
= HAL_GetTick();
1501 while(HAL_IS_BIT_SET(HASH
->SR
, HASH_FLAG_BUSY
))
1503 /* Check for the Timeout */
1504 if(Timeout
!= HAL_MAX_DELAY
)
1506 if((HAL_GetTick() - tickstart
) > Timeout
)
1509 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1511 /* Process Unlocked */
1512 __HAL_UNLOCK(hhash
);
1519 /* Read the message digest */
1520 HASH_GetDigest(pOutBuffer
, 16);
1522 /* Change the HASH state */
1523 hhash
->State
= HAL_HASH_STATE_READY
;
1525 /* Process Unlocked */
1526 __HAL_UNLOCK(hhash
);
1528 /* Return function status */
1533 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
1534 * then processes pInBuffer. The digest is available in pOutBuffer.
1535 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1536 * the configuration information for HASH module
1537 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1538 * @param Size: Length of the input buffer in bytes.
1539 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1540 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1541 * @param Timeout: Timeout value
1542 * @retval HAL status
1544 HAL_StatusTypeDef
HAL_HMAC_SHA1_Start(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
, uint32_t Timeout
)
1546 uint32_t tickstart
= 0;
1548 /* Process Locked */
1551 /* Change the HASH state */
1552 hhash
->State
= HAL_HASH_STATE_BUSY
;
1554 /* Check if initialization phase has already been performed */
1555 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1557 /* Check if key size is greater than 64 bytes */
1558 if(hhash
->Init
.KeySize
> 64)
1560 /* Select the HMAC SHA1 mode */
1561 HASH
->CR
|= (HASH_ALGOSELECTION_SHA1
| HASH_ALGOMODE_HMAC
| HASH_HMAC_KEYTYPE_LONGKEY
| HASH_CR_INIT
);
1565 /* Select the HMAC SHA1 mode */
1566 HASH
->CR
|= (HASH_ALGOSELECTION_SHA1
| HASH_ALGOMODE_HMAC
| HASH_CR_INIT
);
1571 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1573 /************************** STEP 1 ******************************************/
1574 /* Configure the number of valid bits in last word of the message */
1575 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
1577 /* Write input buffer in data register */
1578 HASH_WriteData(hhash
->Init
.pKey
, hhash
->Init
.KeySize
);
1580 /* Start the digest calculation */
1581 __HAL_HASH_START_DIGEST();
1584 tickstart
= HAL_GetTick();
1586 while(HAL_IS_BIT_SET(HASH
->SR
, HASH_FLAG_BUSY
))
1588 /* Check for the Timeout */
1589 if(Timeout
!= HAL_MAX_DELAY
)
1591 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1594 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1596 /* Process Unlocked */
1597 __HAL_UNLOCK(hhash
);
1603 /************************** STEP 2 ******************************************/
1604 /* Configure the number of valid bits in last word of the message */
1605 __HAL_HASH_SET_NBVALIDBITS(Size
);
1607 /* Write input buffer in data register */
1608 HASH_WriteData(pInBuffer
, Size
);
1610 /* Start the digest calculation */
1611 __HAL_HASH_START_DIGEST();
1614 tickstart
= HAL_GetTick();
1616 while(HAL_IS_BIT_SET(HASH
->SR
, HASH_FLAG_BUSY
))
1618 /* Check for the Timeout */
1619 if(Timeout
!= HAL_MAX_DELAY
)
1621 if((HAL_GetTick() - tickstart
) > Timeout
)
1624 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1626 /* Process Unlocked */
1627 __HAL_UNLOCK(hhash
);
1633 /************************** STEP 3 ******************************************/
1634 /* Configure the number of valid bits in last word of the message */
1635 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
1637 /* Write input buffer in data register */
1638 HASH_WriteData(hhash
->Init
.pKey
, hhash
->Init
.KeySize
);
1640 /* Start the digest calculation */
1641 __HAL_HASH_START_DIGEST();
1644 tickstart
= HAL_GetTick();
1646 while(HAL_IS_BIT_SET(HASH
->SR
, HASH_FLAG_BUSY
))
1648 /* Check for the Timeout */
1649 if(Timeout
!= HAL_MAX_DELAY
)
1651 if((HAL_GetTick() - tickstart
) > Timeout
)
1654 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1656 /* Process Unlocked */
1657 __HAL_UNLOCK(hhash
);
1663 /* Read the message digest */
1664 HASH_GetDigest(pOutBuffer
, 20);
1666 /* Change the HASH state */
1667 hhash
->State
= HAL_HASH_STATE_READY
;
1669 /* Process Unlocked */
1670 __HAL_UNLOCK(hhash
);
1672 /* Return function status */
1680 /** @defgroup HASH_Exported_Functions_Group6 HASH-MAC (HMAC) processing functions using DMA mode
1681 * @brief HMAC processing functions using DMA mode .
1684 ===============================================================================
1685 ##### HMAC processing using DMA mode functions #####
1686 ===============================================================================
1687 [..] This section provides functions allowing to calculate in DMA mode
1688 the HMAC value using one of the following algorithms:
1697 * @brief Initializes the HASH peripheral in HMAC MD5 mode
1698 * then enables DMA to control data transfer.
1699 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1700 * the configuration information for HASH module
1701 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1702 * @param Size: Length of the input buffer in bytes.
1703 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1704 * @retval HAL status
1706 HAL_StatusTypeDef
HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
1708 uint32_t inputaddr
= 0;
1710 /* Process Locked */
1713 /* Change the HASH state */
1714 hhash
->State
= HAL_HASH_STATE_BUSY
;
1716 /* Save buffer pointer and size in handle */
1717 hhash
->pHashInBuffPtr
= pInBuffer
;
1718 hhash
->HashBuffSize
= Size
;
1719 hhash
->HashInCount
= 0;
1721 /* Check if initialization phase has already been performed */
1722 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1724 /* Check if key size is greater than 64 bytes */
1725 if(hhash
->Init
.KeySize
> 64)
1727 /* Select the HMAC MD5 mode */
1728 HASH
->CR
|= (HASH_ALGOSELECTION_MD5
| HASH_ALGOMODE_HMAC
| HASH_HMAC_KEYTYPE_LONGKEY
| HASH_CR_INIT
);
1732 /* Select the HMAC MD5 mode */
1733 HASH
->CR
|= (HASH_ALGOSELECTION_MD5
| HASH_ALGOMODE_HMAC
| HASH_CR_INIT
);
1738 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1740 /* Configure the number of valid bits in last word of the message */
1741 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
1743 /* Get the key address */
1744 inputaddr
= (uint32_t)(hhash
->Init
.pKey
);
1746 /* Set the HASH DMA transfer complete callback */
1747 hhash
->hdmain
->XferCpltCallback
= HASH_DMAXferCplt
;
1748 /* Set the DMA error callback */
1749 hhash
->hdmain
->XferErrorCallback
= HASH_DMAError
;
1751 /* Enable the DMA In DMA Stream */
1752 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (hhash
->Init
.KeySize
%4 ? (hhash
->Init
.KeySize
+3)/4:hhash
->Init
.KeySize
/4));
1753 /* Enable DMA requests */
1754 HASH
->CR
|= (HASH_CR_DMAE
);
1756 /* Process Unlocked */
1757 __HAL_UNLOCK(hhash
);
1759 /* Return function status */
1764 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
1765 * then enables DMA to control data transfer.
1766 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1767 * the configuration information for HASH module
1768 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1769 * @param Size: Length of the input buffer in bytes.
1770 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1771 * @retval HAL status
1773 HAL_StatusTypeDef
HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
1775 uint32_t inputaddr
= 0;
1777 /* Process Locked */
1780 /* Change the HASH state */
1781 hhash
->State
= HAL_HASH_STATE_BUSY
;
1783 /* Save buffer pointer and size in handle */
1784 hhash
->pHashInBuffPtr
= pInBuffer
;
1785 hhash
->HashBuffSize
= Size
;
1786 hhash
->HashInCount
= 0;
1788 /* Check if initialization phase has already been performed */
1789 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1791 /* Check if key size is greater than 64 bytes */
1792 if(hhash
->Init
.KeySize
> 64)
1794 /* Select the HMAC SHA1 mode */
1795 HASH
->CR
|= (HASH_ALGOSELECTION_SHA1
| HASH_ALGOMODE_HMAC
| HASH_HMAC_KEYTYPE_LONGKEY
| HASH_CR_INIT
);
1799 /* Select the HMAC SHA1 mode */
1800 HASH
->CR
|= (HASH_ALGOSELECTION_SHA1
| HASH_ALGOMODE_HMAC
| HASH_CR_INIT
);
1805 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1807 /* Configure the number of valid bits in last word of the message */
1808 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
1810 /* Get the key address */
1811 inputaddr
= (uint32_t)(hhash
->Init
.pKey
);
1813 /* Set the HASH DMA transfer complete callback */
1814 hhash
->hdmain
->XferCpltCallback
= HASH_DMAXferCplt
;
1815 /* Set the DMA error callback */
1816 hhash
->hdmain
->XferErrorCallback
= HASH_DMAError
;
1818 /* Enable the DMA In DMA Stream */
1819 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (hhash
->Init
.KeySize
%4 ? (hhash
->Init
.KeySize
+3)/4:hhash
->Init
.KeySize
/4));
1820 /* Enable DMA requests */
1821 HASH
->CR
|= (HASH_CR_DMAE
);
1823 /* Process Unlocked */
1824 __HAL_UNLOCK(hhash
);
1826 /* Return function status */
1834 /** @defgroup HASH_Exported_Functions_Group7 Peripheral State functions
1835 * @brief Peripheral State functions.
1838 ===============================================================================
1839 ##### Peripheral State functions #####
1840 ===============================================================================
1842 This subsection permits to get in run-time the status of the peripheral.
1849 * @brief return the HASH state
1850 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1851 * the configuration information for HASH module
1854 HAL_HASH_StateTypeDef
HAL_HASH_GetState(HASH_HandleTypeDef
*hhash
)
1856 return hhash
->State
;
1867 #endif /* HAL_HASH_MODULE_ENABLED */
1872 #endif /* STM32F756xx || STM32F777xx || STM32F779xx */
1878 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/