2 ******************************************************************************
3 * @file stm32f7xx_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 __HAL_RCC_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) 2016 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 "stm32f7xx_hal.h"
98 /** @addtogroup STM32F7xx_HAL_Driver
101 #if defined(STM32F756xx) || defined(STM32F777xx) || defined(STM32F779xx)
103 /** @defgroup HASHEx HASHEx
104 * @brief HASH Extension HAL module driver.
108 #ifdef HAL_HASH_MODULE_ENABLED
110 /* Private typedef -----------------------------------------------------------*/
111 /* Private define ------------------------------------------------------------*/
112 /* Private macro -------------------------------------------------------------*/
113 /* Private variables ---------------------------------------------------------*/
114 /* Private function prototypes -----------------------------------------------*/
115 /** @addtogroup HASHEx_Private_Functions
118 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef
*hdma
);
119 static void HASHEx_WriteData(uint8_t *pInBuffer
, uint32_t Size
);
120 static void HASHEx_GetDigest(uint8_t *pMsgDigest
, uint8_t Size
);
121 static void HASHEx_DMAError(DMA_HandleTypeDef
*hdma
);
126 /* Private functions ---------------------------------------------------------*/
128 /** @addtogroup HASHEx_Private_Functions
133 * @brief Writes the input buffer in data register.
134 * @param pInBuffer: Pointer to input buffer
135 * @param Size: The size of input buffer
138 static void HASHEx_WriteData(uint8_t *pInBuffer
, uint32_t Size
)
140 uint32_t buffercounter
;
141 uint32_t inputaddr
= (uint32_t) pInBuffer
;
143 for(buffercounter
= 0; buffercounter
< Size
; buffercounter
+=4)
145 HASH
->DIN
= *(uint32_t*)inputaddr
;
151 * @brief Provides the message digest result.
152 * @param pMsgDigest: Pointer to the message digest
153 * @param Size: The size of the message digest in bytes
156 static void HASHEx_GetDigest(uint8_t *pMsgDigest
, uint8_t Size
)
158 uint32_t msgdigest
= (uint32_t)pMsgDigest
;
163 /* Read the message digest */
164 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[0]);
166 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[1]);
168 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[2]);
170 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[3]);
173 /* Read the message digest */
174 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[0]);
176 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[1]);
178 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[2]);
180 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[3]);
182 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[4]);
185 /* Read the message digest */
186 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[0]);
188 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[1]);
190 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[2]);
192 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[3]);
194 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[4]);
196 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[5]);
198 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[6]);
201 /* Read the message digest */
202 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[0]);
204 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[1]);
206 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[2]);
208 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[3]);
210 *(uint32_t*)(msgdigest
) = __REV(HASH
->HR
[4]);
212 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[5]);
214 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[6]);
216 *(uint32_t*)(msgdigest
) = __REV(HASH_DIGEST
->HR
[7]);
224 * @brief DMA HASH Input Data complete callback.
225 * @param hdma: DMA handle
228 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef
*hdma
)
230 HASH_HandleTypeDef
* hhash
= ( HASH_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
231 uint32_t inputaddr
= 0;
232 uint32_t buffersize
= 0;
234 if((HASH
->CR
& HASH_CR_MODE
) != HASH_CR_MODE
)
236 /* Disable the DMA transfer */
237 HASH
->CR
&= (uint32_t)(~HASH_CR_DMAE
);
239 /* Change HASH peripheral state */
240 hhash
->State
= HAL_HASH_STATE_READY
;
242 /* Call Input data transfer complete callback */
243 HAL_HASH_InCpltCallback(hhash
);
247 /* Increment Interrupt counter */
248 hhash
->HashInCount
++;
249 /* Disable the DMA transfer before starting the next transfer */
250 HASH
->CR
&= (uint32_t)(~HASH_CR_DMAE
);
252 if(hhash
->HashInCount
<= 2)
254 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
255 if(hhash
->HashInCount
== 1)
257 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
258 buffersize
= hhash
->HashBuffSize
;
260 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
261 else if(hhash
->HashInCount
== 2)
263 inputaddr
= (uint32_t)hhash
->Init
.pKey
;
264 buffersize
= hhash
->Init
.KeySize
;
266 /* Configure the number of valid bits in last word of the message */
267 MODIFY_REG(HASH
->STR
, HASH_STR_NBLW
, 8 * (buffersize
% 4));
269 /* Set the HASH DMA transfer complete */
270 hhash
->hdmain
->XferCpltCallback
= HASHEx_DMAXferCplt
;
272 /* Enable the DMA In DMA Stream */
273 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (buffersize
%4 ? (buffersize
+3)/4:buffersize
/4));
275 /* Enable DMA requests */
276 HASH
->CR
|= (HASH_CR_DMAE
);
280 /* Disable the DMA transfer */
281 HASH
->CR
&= (uint32_t)(~HASH_CR_DMAE
);
283 /* Reset the InCount */
284 hhash
->HashInCount
= 0;
286 /* Change HASH peripheral state */
287 hhash
->State
= HAL_HASH_STATE_READY
;
289 /* Call Input data transfer complete callback */
290 HAL_HASH_InCpltCallback(hhash
);
296 * @brief DMA HASH communication error callback.
297 * @param hdma: DMA handle
300 static void HASHEx_DMAError(DMA_HandleTypeDef
*hdma
)
302 HASH_HandleTypeDef
* hhash
= ( HASH_HandleTypeDef
* )((DMA_HandleTypeDef
* )hdma
)->Parent
;
303 hhash
->State
= HAL_HASH_STATE_READY
;
304 HAL_HASH_ErrorCallback(hhash
);
311 /* Exported functions --------------------------------------------------------*/
312 /** @addtogroup HASHEx_Exported_Functions
316 /** @defgroup HASHEx_Group1 HASH processing functions
317 * @brief processing functions using polling mode
320 ===============================================================================
321 ##### HASH processing using polling mode functions #####
322 ===============================================================================
323 [..] This section provides functions allowing to calculate in polling mode
324 the hash value using one of the following algorithms:
333 * @brief Initializes the HASH peripheral in SHA224 mode
334 * then processes pInBuffer. The digest is available in pOutBuffer
335 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
336 * the configuration information for HASH module
337 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
338 * @param Size: Length of the input buffer in bytes.
339 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
340 * @param pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
341 * @param Timeout: Specify Timeout value
344 HAL_StatusTypeDef
HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
, uint32_t Timeout
)
346 uint32_t tickstart
= 0;
351 /* Change the HASH state */
352 hhash
->State
= HAL_HASH_STATE_BUSY
;
354 /* Check if initialization phase has already been performed */
355 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
357 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
358 the message digest of a new message */
359 HASH
->CR
|= HASH_ALGOSELECTION_SHA224
| HASH_CR_INIT
;
363 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
365 /* Configure the number of valid bits in last word of the message */
366 __HAL_HASH_SET_NBVALIDBITS(Size
);
368 /* Write input buffer in data register */
369 HASHEx_WriteData(pInBuffer
, Size
);
371 /* Start the digest calculation */
372 __HAL_HASH_START_DIGEST();
375 tickstart
= HAL_GetTick();
377 while((HASH
->SR
& HASH_FLAG_BUSY
) == HASH_FLAG_BUSY
)
379 /* Check for the Timeout */
380 if(Timeout
!= HAL_MAX_DELAY
)
382 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
385 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
387 /* Process Unlocked */
395 /* Read the message digest */
396 HASHEx_GetDigest(pOutBuffer
, 28);
398 /* Change the HASH state */
399 hhash
->State
= HAL_HASH_STATE_READY
;
401 /* Process Unlocked */
404 /* Return function status */
409 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
410 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 32 bytes.
417 * @param Timeout: Specify Timeout value
420 HAL_StatusTypeDef
HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
, uint32_t Timeout
)
422 uint32_t tickstart
= 0;
427 /* Change the HASH state */
428 hhash
->State
= HAL_HASH_STATE_BUSY
;
430 /* Check if initialization phase has already been performed */
431 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
433 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
434 the message digest of a new message */
435 HASH
->CR
|= HASH_ALGOSELECTION_SHA256
| HASH_CR_INIT
;
439 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
441 /* Configure the number of valid bits in last word of the message */
442 __HAL_HASH_SET_NBVALIDBITS(Size
);
444 /* Write input buffer in data register */
445 HASHEx_WriteData(pInBuffer
, Size
);
447 /* Start the digest calculation */
448 __HAL_HASH_START_DIGEST();
451 tickstart
= HAL_GetTick();
453 while((HASH
->SR
& HASH_FLAG_BUSY
) == HASH_FLAG_BUSY
)
455 /* Check for the Timeout */
456 if(Timeout
!= HAL_MAX_DELAY
)
458 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
461 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
463 /* Process Unlocked */
471 /* Read the message digest */
472 HASHEx_GetDigest(pOutBuffer
, 32);
474 /* Change the HASH state */
475 hhash
->State
= HAL_HASH_STATE_READY
;
477 /* Process Unlocked */
480 /* Return function status */
486 * @brief Initializes the HASH peripheral in SHA224 mode
487 * then processes pInBuffer. The digest is available in pOutBuffer
488 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
489 * the configuration information for HASH module
490 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
491 * @param Size: Length of the input buffer in bytes.
492 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
495 HAL_StatusTypeDef
HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
500 /* Change the HASH state */
501 hhash
->State
= HAL_HASH_STATE_BUSY
;
503 /* Check if initialization phase has already been performed */
504 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
506 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
507 the message digest of a new message */
508 HASH
->CR
|= HASH_ALGOSELECTION_SHA224
| HASH_CR_INIT
;
512 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
514 /* Configure the number of valid bits in last word of the message */
515 __HAL_HASH_SET_NBVALIDBITS(Size
);
517 /* Write input buffer in data register */
518 HASHEx_WriteData(pInBuffer
, Size
);
520 /* Change the HASH state */
521 hhash
->State
= HAL_HASH_STATE_READY
;
523 /* Process Unlocked */
526 /* Return function status */
532 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
533 The digest is available in pOutBuffer.
534 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
535 * the configuration information for HASH module
536 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
537 * @param Size: Length of the input buffer in bytes.
538 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
541 HAL_StatusTypeDef
HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
546 /* Change the HASH state */
547 hhash
->State
= HAL_HASH_STATE_BUSY
;
549 /* Check if initialization phase has already been performed */
550 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
552 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
553 the message digest of a new message */
554 HASH
->CR
|= HASH_ALGOSELECTION_SHA256
| HASH_CR_INIT
;
558 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
560 /* Configure the number of valid bits in last word of the message */
561 __HAL_HASH_SET_NBVALIDBITS(Size
);
563 /* Write input buffer in data register */
564 HASHEx_WriteData(pInBuffer
, Size
);
566 /* Change the HASH state */
567 hhash
->State
= HAL_HASH_STATE_READY
;
569 /* Process Unlocked */
572 /* Return function status */
581 /** @defgroup HASHEx_Group2 HMAC processing functions using polling mode
582 * @brief HMAC processing functions using polling mode .
585 ===============================================================================
586 ##### HMAC processing using polling mode functions #####
587 ===============================================================================
588 [..] This section provides functions allowing to calculate in polling mode
589 the HMAC value using one of the following algorithms:
598 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
599 * then processes pInBuffer. The digest is available in pOutBuffer.
600 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
601 * the configuration information for HASH module
602 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
603 * @param Size: Length of the input buffer in bytes.
604 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
605 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
606 * @param Timeout: Timeout value
609 HAL_StatusTypeDef
HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
, uint32_t Timeout
)
611 uint32_t tickstart
= 0;
616 /* Change the HASH state */
617 hhash
->State
= HAL_HASH_STATE_BUSY
;
619 /* Check if initialization phase has already been performed */
620 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
622 /* Check if key size is greater than 64 bytes */
623 if(hhash
->Init
.KeySize
> 64)
625 /* Select the HMAC SHA224 mode */
626 HASH
->CR
|= (HASH_ALGOSELECTION_SHA224
| HASH_ALGOMODE_HMAC
| HASH_HMAC_KEYTYPE_LONGKEY
| HASH_CR_INIT
);
630 /* Select the HMAC SHA224 mode */
631 HASH
->CR
|= (HASH_ALGOSELECTION_SHA224
| HASH_ALGOMODE_HMAC
| HASH_CR_INIT
);
636 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
638 /************************** STEP 1 ******************************************/
639 /* Configure the number of valid bits in last word of the message */
640 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
642 /* Write input buffer in data register */
643 HASHEx_WriteData(hhash
->Init
.pKey
, hhash
->Init
.KeySize
);
645 /* Start the digest calculation */
646 __HAL_HASH_START_DIGEST();
649 tickstart
= HAL_GetTick();
651 while((HASH
->SR
& HASH_FLAG_BUSY
) == HASH_FLAG_BUSY
)
653 /* Check for the Timeout */
654 if(Timeout
!= HAL_MAX_DELAY
)
656 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
659 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
661 /* Process Unlocked */
668 /************************** STEP 2 ******************************************/
669 /* Configure the number of valid bits in last word of the message */
670 __HAL_HASH_SET_NBVALIDBITS(Size
);
672 /* Write input buffer in data register */
673 HASHEx_WriteData(pInBuffer
, Size
);
675 /* Start the digest calculation */
676 __HAL_HASH_START_DIGEST();
679 tickstart
= HAL_GetTick();
681 while((HASH
->SR
& HASH_FLAG_BUSY
) == HASH_FLAG_BUSY
)
683 /* Check for the Timeout */
684 if(Timeout
!= HAL_MAX_DELAY
)
686 if((HAL_GetTick() - tickstart
) > Timeout
)
689 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
691 /* Process Unlocked */
698 /************************** STEP 3 ******************************************/
699 /* Configure the number of valid bits in last word of the message */
700 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
702 /* Write input buffer in data register */
703 HASHEx_WriteData(hhash
->Init
.pKey
, hhash
->Init
.KeySize
);
705 /* Start the digest calculation */
706 __HAL_HASH_START_DIGEST();
709 tickstart
= HAL_GetTick();
711 while((HASH
->SR
& HASH_FLAG_BUSY
) == HASH_FLAG_BUSY
)
713 /* Check for the Timeout */
714 if(Timeout
!= HAL_MAX_DELAY
)
716 if((HAL_GetTick() - tickstart
) > Timeout
)
719 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
721 /* Process Unlocked */
728 /* Read the message digest */
729 HASHEx_GetDigest(pOutBuffer
, 28);
731 /* Change the HASH state */
732 hhash
->State
= HAL_HASH_STATE_READY
;
734 /* Process Unlocked */
737 /* Return function status */
742 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
743 * then processes pInBuffer. The digest is available in pOutBuffer
744 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
745 * the configuration information for HASH module
746 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
747 * @param Size: Length of the input buffer in bytes.
748 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
749 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
750 * @param Timeout: Timeout value
753 HAL_StatusTypeDef
HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
, uint32_t Timeout
)
755 uint32_t tickstart
= 0;
760 /* Change the HASH state */
761 hhash
->State
= HAL_HASH_STATE_BUSY
;
763 /* Check if initialization phase has already been performed */
764 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
766 /* Check if key size is greater than 64 bytes */
767 if(hhash
->Init
.KeySize
> 64)
769 /* Select the HMAC SHA256 mode */
770 HASH
->CR
|= (HASH_ALGOSELECTION_SHA256
| HASH_ALGOMODE_HMAC
| HASH_HMAC_KEYTYPE_LONGKEY
);
774 /* Select the HMAC SHA256 mode */
775 HASH
->CR
|= (HASH_ALGOSELECTION_SHA256
| HASH_ALGOMODE_HMAC
);
777 /* Reset the HASH processor core, so that the HASH will be ready to compute
778 the message digest of a new message */
779 HASH
->CR
|= HASH_CR_INIT
;
783 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
785 /************************** STEP 1 ******************************************/
786 /* Configure the number of valid bits in last word of the message */
787 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
789 /* Write input buffer in data register */
790 HASHEx_WriteData(hhash
->Init
.pKey
, hhash
->Init
.KeySize
);
792 /* Start the digest calculation */
793 __HAL_HASH_START_DIGEST();
796 tickstart
= HAL_GetTick();
798 while((HASH
->SR
& HASH_FLAG_BUSY
) == HASH_FLAG_BUSY
)
800 /* Check for the Timeout */
801 if(Timeout
!= HAL_MAX_DELAY
)
803 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
806 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
808 /* Process Unlocked */
815 /************************** STEP 2 ******************************************/
816 /* Configure the number of valid bits in last word of the message */
817 __HAL_HASH_SET_NBVALIDBITS(Size
);
819 /* Write input buffer in data register */
820 HASHEx_WriteData(pInBuffer
, Size
);
822 /* Start the digest calculation */
823 __HAL_HASH_START_DIGEST();
826 tickstart
= HAL_GetTick();
828 while((HASH
->SR
& HASH_FLAG_BUSY
) == HASH_FLAG_BUSY
)
830 /* Check for the Timeout */
831 if(Timeout
!= HAL_MAX_DELAY
)
833 if((HAL_GetTick() - tickstart
) > Timeout
)
836 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
838 /* Process Unlocked */
845 /************************** STEP 3 ******************************************/
846 /* Configure the number of valid bits in last word of the message */
847 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
849 /* Write input buffer in data register */
850 HASHEx_WriteData(hhash
->Init
.pKey
, hhash
->Init
.KeySize
);
852 /* Start the digest calculation */
853 __HAL_HASH_START_DIGEST();
856 tickstart
= HAL_GetTick();
858 while((HASH
->SR
& HASH_FLAG_BUSY
) == HASH_FLAG_BUSY
)
860 /* Check for the Timeout */
861 if(Timeout
!= HAL_MAX_DELAY
)
863 if((HAL_GetTick() - tickstart
) > Timeout
)
866 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
868 /* Process Unlocked */
875 /* Read the message digest */
876 HASHEx_GetDigest(pOutBuffer
, 32);
878 /* Change the HASH state */
879 hhash
->State
= HAL_HASH_STATE_READY
;
881 /* Process Unlocked */
884 /* Return function status */
892 /** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode
893 * @brief processing functions using interrupt mode.
896 ===============================================================================
897 ##### HASH processing using interrupt functions #####
898 ===============================================================================
899 [..] This section provides functions allowing to calculate in interrupt mode
900 the hash value using one of the following algorithms:
909 * @brief Initializes the HASH peripheral in SHA224 mode then processes pInBuffer.
910 * The digest is available in pOutBuffer.
911 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
912 * the configuration information for HASH module
913 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
914 * @param Size: Length of the input buffer in bytes.
915 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
916 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
919 HAL_StatusTypeDef
HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
)
922 uint32_t buffercounter
;
923 uint32_t inputcounter
;
928 if(hhash
->State
== HAL_HASH_STATE_READY
)
930 /* Change the HASH state */
931 hhash
->State
= HAL_HASH_STATE_BUSY
;
933 hhash
->HashInCount
= Size
;
934 hhash
->pHashInBuffPtr
= pInBuffer
;
935 hhash
->pHashOutBuffPtr
= pOutBuffer
;
937 /* Check if initialization phase has already been performed */
938 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
940 /* Select the SHA224 mode */
941 HASH
->CR
|= HASH_ALGOSELECTION_SHA224
;
942 /* Reset the HASH processor core, so that the HASH will be ready to compute
943 the message digest of a new message */
944 HASH
->CR
|= HASH_CR_INIT
;
946 /* Reset interrupt counter */
947 hhash
->HashITCounter
= 0;
949 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
951 /* Process Unlocked */
954 /* Enable Interrupts */
955 HASH
->IMR
= (HASH_IT_DINI
| HASH_IT_DCI
);
957 /* Return function status */
960 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS
))
962 /* Read the message digest */
963 HASHEx_GetDigest(hhash
->pHashOutBuffPtr
, 28);
964 if(hhash
->HashInCount
== 0)
966 /* Disable Interrupts */
968 /* Change the HASH state */
969 hhash
->State
= HAL_HASH_STATE_READY
;
970 /* Call digest computation complete callback */
971 HAL_HASH_DgstCpltCallback(hhash
);
972 /* Process Unlocked */
975 /* Return function status */
979 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS
))
981 if(hhash
->HashInCount
>= 68)
983 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
984 /* Write the Input block in the Data IN register */
985 for(buffercounter
= 0; buffercounter
< 64; buffercounter
+=4)
987 HASH
->DIN
= *(uint32_t*)inputaddr
;
990 if(hhash
->HashITCounter
== 0)
992 HASH
->DIN
= *(uint32_t*)inputaddr
;
993 if(hhash
->HashInCount
>= 68)
995 /* Decrement buffer counter */
996 hhash
->HashInCount
-= 68;
997 hhash
->pHashInBuffPtr
+= 68;
1001 hhash
->HashInCount
= 0;
1002 hhash
->pHashInBuffPtr
+= hhash
->HashInCount
;
1004 /* Set Interrupt counter */
1005 hhash
->HashITCounter
= 1;
1009 /* Decrement buffer counter */
1010 hhash
->HashInCount
-= 64;
1011 hhash
->pHashInBuffPtr
+= 64;
1016 /* Get the buffer address */
1017 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
1018 /* Get the buffer counter */
1019 inputcounter
= hhash
->HashInCount
;
1020 /* Disable Interrupts */
1021 HASH
->IMR
&= ~(HASH_IT_DINI
);
1022 /* Configure the number of valid bits in last word of the message */
1023 __HAL_HASH_SET_NBVALIDBITS(inputcounter
);
1025 if((inputcounter
> 4) && (inputcounter
%4))
1027 inputcounter
= (inputcounter
+4-inputcounter
%4);
1029 else if ((inputcounter
< 4) && (inputcounter
!= 0))
1033 /* Write the Input block in the Data IN register */
1034 for(buffercounter
= 0; buffercounter
< inputcounter
/4; buffercounter
++)
1036 HASH
->DIN
= *(uint32_t*)inputaddr
;
1039 /* Start the digest calculation */
1040 __HAL_HASH_START_DIGEST();
1041 /* Reset buffer counter */
1042 hhash
->HashInCount
= 0;
1043 /* Call Input data transfer complete callback */
1044 HAL_HASH_InCpltCallback(hhash
);
1048 /* Process Unlocked */
1049 __HAL_UNLOCK(hhash
);
1051 /* Return function status */
1057 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
1058 * The digest is available in pOutBuffer.
1059 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1060 * the configuration information for HASH module
1061 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1062 * @param Size: Length of the input buffer in bytes.
1063 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1064 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1065 * @retval HAL status
1067 HAL_StatusTypeDef
HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
, uint8_t* pOutBuffer
)
1070 uint32_t buffercounter
;
1071 uint32_t inputcounter
;
1073 /* Process Locked */
1076 if(hhash
->State
== HAL_HASH_STATE_READY
)
1078 /* Change the HASH state */
1079 hhash
->State
= HAL_HASH_STATE_BUSY
;
1081 hhash
->HashInCount
= Size
;
1082 hhash
->pHashInBuffPtr
= pInBuffer
;
1083 hhash
->pHashOutBuffPtr
= pOutBuffer
;
1085 /* Check if initialization phase has already been performed */
1086 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1088 /* Select the SHA256 mode */
1089 HASH
->CR
|= HASH_ALGOSELECTION_SHA256
;
1090 /* Reset the HASH processor core, so that the HASH will be ready to compute
1091 the message digest of a new message */
1092 HASH
->CR
|= HASH_CR_INIT
;
1095 /* Reset interrupt counter */
1096 hhash
->HashITCounter
= 0;
1099 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1101 /* Process Unlocked */
1102 __HAL_UNLOCK(hhash
);
1104 /* Enable Interrupts */
1105 HASH
->IMR
= (HASH_IT_DINI
| HASH_IT_DCI
);
1107 /* Return function status */
1110 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS
))
1112 /* Read the message digest */
1113 HASHEx_GetDigest(hhash
->pHashOutBuffPtr
, 32);
1114 if(hhash
->HashInCount
== 0)
1116 /* Disable Interrupts */
1118 /* Change the HASH state */
1119 hhash
->State
= HAL_HASH_STATE_READY
;
1120 /* Call digest computation complete callback */
1121 HAL_HASH_DgstCpltCallback(hhash
);
1123 /* Process Unlocked */
1124 __HAL_UNLOCK(hhash
);
1126 /* Return function status */
1130 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS
))
1132 if(hhash
->HashInCount
>= 68)
1134 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
1135 /* Write the Input block in the Data IN register */
1136 for(buffercounter
= 0; buffercounter
< 64; buffercounter
+=4)
1138 HASH
->DIN
= *(uint32_t*)inputaddr
;
1141 if(hhash
->HashITCounter
== 0)
1143 HASH
->DIN
= *(uint32_t*)inputaddr
;
1145 if(hhash
->HashInCount
>= 68)
1147 /* Decrement buffer counter */
1148 hhash
->HashInCount
-= 68;
1149 hhash
->pHashInBuffPtr
+= 68;
1153 hhash
->HashInCount
= 0;
1154 hhash
->pHashInBuffPtr
+= hhash
->HashInCount
;
1156 /* Set Interrupt counter */
1157 hhash
->HashITCounter
= 1;
1161 /* Decrement buffer counter */
1162 hhash
->HashInCount
-= 64;
1163 hhash
->pHashInBuffPtr
+= 64;
1168 /* Get the buffer address */
1169 inputaddr
= (uint32_t)hhash
->pHashInBuffPtr
;
1170 /* Get the buffer counter */
1171 inputcounter
= hhash
->HashInCount
;
1172 /* Disable Interrupts */
1173 HASH
->IMR
&= ~(HASH_IT_DINI
);
1174 /* Configure the number of valid bits in last word of the message */
1175 __HAL_HASH_SET_NBVALIDBITS(inputcounter
);
1177 if((inputcounter
> 4) && (inputcounter
%4))
1179 inputcounter
= (inputcounter
+4-inputcounter
%4);
1181 else if ((inputcounter
< 4) && (inputcounter
!= 0))
1186 /* Write the Input block in the Data IN register */
1187 for(buffercounter
= 0; buffercounter
< inputcounter
/4; buffercounter
++)
1189 HASH
->DIN
= *(uint32_t*)inputaddr
;
1192 /* Start the digest calculation */
1193 __HAL_HASH_START_DIGEST();
1194 /* Reset buffer counter */
1195 hhash
->HashInCount
= 0;
1196 /* Call Input data transfer complete callback */
1197 HAL_HASH_InCpltCallback(hhash
);
1201 /* Process Unlocked */
1202 __HAL_UNLOCK(hhash
);
1204 /* Return function status */
1209 * @brief This function handles HASH interrupt request.
1210 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1211 * the configuration information for HASH module
1214 void HAL_HASHEx_IRQHandler(HASH_HandleTypeDef
*hhash
)
1216 switch(HASH
->CR
& HASH_CR_ALGO
)
1219 case HASH_ALGOSELECTION_SHA224
:
1220 HAL_HASHEx_SHA224_Start_IT(hhash
, NULL
, 0, NULL
);
1223 case HASH_ALGOSELECTION_SHA256
:
1224 HAL_HASHEx_SHA256_Start_IT(hhash
, NULL
, 0, NULL
);
1236 /** @defgroup HASHEx_Group4 HASH processing functions using DMA mode
1237 * @brief processing functions using DMA mode.
1240 ===============================================================================
1241 ##### HASH processing using DMA functions #####
1242 ===============================================================================
1243 [..] This section provides functions allowing to calculate in DMA mode
1244 the hash value using one of the following algorithms:
1254 * @brief Initializes the HASH peripheral in SHA224 mode then enables DMA to
1255 control data transfer. Use HAL_HASH_SHA224_Finish() to get the digest.
1256 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1257 * the configuration information for HASH module
1258 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1259 * @param Size: Length of the input buffer in bytes.
1260 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1261 * @retval HAL status
1263 HAL_StatusTypeDef
HAL_HASHEx_SHA224_Start_DMA(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
1265 uint32_t inputaddr
= (uint32_t)pInBuffer
;
1267 /* Process Locked */
1270 /* Change the HASH state */
1271 hhash
->State
= HAL_HASH_STATE_BUSY
;
1273 /* Check if initialization phase has already been performed */
1274 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1276 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
1277 the message digest of a new message */
1278 HASH
->CR
|= HASH_ALGOSELECTION_SHA224
| HASH_CR_INIT
;
1281 /* Configure the number of valid bits in last word of the message */
1282 __HAL_HASH_SET_NBVALIDBITS(Size
);
1285 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1287 /* Set the HASH DMA transfer complete callback */
1288 hhash
->hdmain
->XferCpltCallback
= HASHEx_DMAXferCplt
;
1289 /* Set the DMA error callback */
1290 hhash
->hdmain
->XferErrorCallback
= HASHEx_DMAError
;
1292 /* Enable the DMA In DMA Stream */
1293 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (Size
%4 ? (Size
+3)/4:Size
/4));
1295 /* Enable DMA requests */
1296 HASH
->CR
|= (HASH_CR_DMAE
);
1298 /* Process Unlocked */
1299 __HAL_UNLOCK(hhash
);
1301 /* Return function status */
1306 * @brief Returns the computed digest in SHA224
1307 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1308 * the configuration information for HASH module
1309 * @param pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
1310 * @param Timeout: Timeout value
1311 * @retval HAL status
1313 HAL_StatusTypeDef
HAL_HASHEx_SHA224_Finish(HASH_HandleTypeDef
*hhash
, uint8_t* pOutBuffer
, uint32_t Timeout
)
1315 uint32_t tickstart
= 0;
1317 /* Process Locked */
1320 /* Change HASH peripheral state */
1321 hhash
->State
= HAL_HASH_STATE_BUSY
;
1324 tickstart
= HAL_GetTick();
1326 while(HAL_IS_BIT_CLR(HASH
->SR
, HASH_FLAG_DCIS
))
1328 /* Check for the Timeout */
1329 if(Timeout
!= HAL_MAX_DELAY
)
1331 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1334 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1336 /* Process Unlocked */
1337 __HAL_UNLOCK(hhash
);
1344 /* Read the message digest */
1345 HASHEx_GetDigest(pOutBuffer
, 28);
1347 /* Change HASH peripheral state */
1348 hhash
->State
= HAL_HASH_STATE_READY
;
1350 /* Process Unlocked */
1351 __HAL_UNLOCK(hhash
);
1353 /* Return function status */
1358 * @brief Initializes the HASH peripheral in SHA256 mode then enables DMA to
1359 control data transfer. Use HAL_HASH_SHA256_Finish() to get the digest.
1360 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1361 * the configuration information for HASH module
1362 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1363 * @param Size: Length of the input buffer in bytes.
1364 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1365 * @retval HAL status
1367 HAL_StatusTypeDef
HAL_HASHEx_SHA256_Start_DMA(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
1369 uint32_t inputaddr
= (uint32_t)pInBuffer
;
1371 /* Process Locked */
1374 /* Change the HASH state */
1375 hhash
->State
= HAL_HASH_STATE_BUSY
;
1377 /* Check if initialization phase has already been performed */
1378 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1380 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
1381 the message digest of a new message */
1382 HASH
->CR
|= HASH_ALGOSELECTION_SHA256
| HASH_CR_INIT
;
1385 /* Configure the number of valid bits in last word of the message */
1386 __HAL_HASH_SET_NBVALIDBITS(Size
);
1389 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1391 /* Set the HASH DMA transfer complete callback */
1392 hhash
->hdmain
->XferCpltCallback
= HASHEx_DMAXferCplt
;
1393 /* Set the DMA error callback */
1394 hhash
->hdmain
->XferErrorCallback
= HASHEx_DMAError
;
1396 /* Enable the DMA In DMA Stream */
1397 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (Size
%4 ? (Size
+3)/4:Size
/4));
1399 /* Enable DMA requests */
1400 HASH
->CR
|= (HASH_CR_DMAE
);
1402 /* Process UnLock */
1403 __HAL_UNLOCK(hhash
);
1405 /* Return function status */
1410 * @brief Returns the computed digest in SHA256.
1411 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1412 * the configuration information for HASH module
1413 * @param pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
1414 * @param Timeout: Timeout value
1415 * @retval HAL status
1417 HAL_StatusTypeDef
HAL_HASHEx_SHA256_Finish(HASH_HandleTypeDef
*hhash
, uint8_t* pOutBuffer
, uint32_t Timeout
)
1419 uint32_t tickstart
= 0;
1421 /* Process Locked */
1424 /* Change HASH peripheral state */
1425 hhash
->State
= HAL_HASH_STATE_BUSY
;
1428 tickstart
= HAL_GetTick();
1430 while(HAL_IS_BIT_CLR(HASH
->SR
, HASH_FLAG_DCIS
))
1432 /* Check for the Timeout */
1433 if(Timeout
!= HAL_MAX_DELAY
)
1435 if((Timeout
== 0)||((HAL_GetTick() - tickstart
) > Timeout
))
1438 hhash
->State
= HAL_HASH_STATE_TIMEOUT
;
1440 /* Process Unlocked */
1441 __HAL_UNLOCK(hhash
);
1448 /* Read the message digest */
1449 HASHEx_GetDigest(pOutBuffer
, 32);
1451 /* Change HASH peripheral state */
1452 hhash
->State
= HAL_HASH_STATE_READY
;
1454 /* Process Unlocked */
1455 __HAL_UNLOCK(hhash
);
1457 /* Return function status */
1465 /** @defgroup HASHEx_Group5 HMAC processing functions using DMA mode
1466 * @brief HMAC processing functions using DMA mode .
1469 ===============================================================================
1470 ##### HMAC processing using DMA functions #####
1471 ===============================================================================
1472 [..] This section provides functions allowing to calculate in DMA mode
1473 the HMAC value using one of the following algorithms:
1482 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
1483 * then enables DMA to control data transfer.
1484 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1485 * the configuration information for HASH module
1486 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1487 * @param Size: Length of the input buffer in bytes.
1488 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1489 * @retval HAL status
1491 HAL_StatusTypeDef
HAL_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
1495 /* Process Locked */
1498 /* Change the HASH state */
1499 hhash
->State
= HAL_HASH_STATE_BUSY
;
1501 /* Save buffer pointer and size in handle */
1502 hhash
->pHashInBuffPtr
= pInBuffer
;
1503 hhash
->HashBuffSize
= Size
;
1504 hhash
->HashInCount
= 0;
1506 /* Check if initialization phase has already been performed */
1507 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1509 /* Check if key size is greater than 64 bytes */
1510 if(hhash
->Init
.KeySize
> 64)
1512 /* Select the HMAC SHA224 mode */
1513 HASH
->CR
|= (HASH_ALGOSELECTION_SHA224
| HASH_ALGOMODE_HMAC
| HASH_HMAC_KEYTYPE_LONGKEY
| HASH_CR_INIT
);
1517 /* Select the HMAC SHA224 mode */
1518 HASH
->CR
|= (HASH_ALGOSELECTION_SHA224
| HASH_ALGOMODE_HMAC
| HASH_CR_INIT
);
1523 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1525 /* Configure the number of valid bits in last word of the message */
1526 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
1528 /* Get the key address */
1529 inputaddr
= (uint32_t)(hhash
->Init
.pKey
);
1531 /* Set the HASH DMA transfer complete callback */
1532 hhash
->hdmain
->XferCpltCallback
= HASHEx_DMAXferCplt
;
1533 /* Set the DMA error callback */
1534 hhash
->hdmain
->XferErrorCallback
= HASHEx_DMAError
;
1536 /* Enable the DMA In DMA Stream */
1537 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (hhash
->Init
.KeySize
%4 ? (hhash
->Init
.KeySize
+3)/4:hhash
->Init
.KeySize
/4));
1538 /* Enable DMA requests */
1539 HASH
->CR
|= (HASH_CR_DMAE
);
1541 /* Process Unlocked */
1542 __HAL_UNLOCK(hhash
);
1544 /* Return function status */
1549 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
1550 * then enables DMA to control data transfer.
1551 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1552 * the configuration information for HASH module
1553 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1554 * @param Size: Length of the input buffer in bytes.
1555 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1556 * @retval HAL status
1558 HAL_StatusTypeDef
HAL_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef
*hhash
, uint8_t *pInBuffer
, uint32_t Size
)
1562 /* Process Locked */
1565 /* Change the HASH state */
1566 hhash
->State
= HAL_HASH_STATE_BUSY
;
1568 /* Save buffer pointer and size in handle */
1569 hhash
->pHashInBuffPtr
= pInBuffer
;
1570 hhash
->HashBuffSize
= Size
;
1571 hhash
->HashInCount
= 0;
1573 /* Check if initialization phase has already been performed */
1574 if(hhash
->Phase
== HAL_HASH_PHASE_READY
)
1576 /* Check if key size is greater than 64 bytes */
1577 if(hhash
->Init
.KeySize
> 64)
1579 /* Select the HMAC SHA256 mode */
1580 HASH
->CR
|= (HASH_ALGOSELECTION_SHA256
| HASH_ALGOMODE_HMAC
| HASH_HMAC_KEYTYPE_LONGKEY
);
1584 /* Select the HMAC SHA256 mode */
1585 HASH
->CR
|= (HASH_ALGOSELECTION_SHA256
| HASH_ALGOMODE_HMAC
);
1587 /* Reset the HASH processor core, so that the HASH will be ready to compute
1588 the message digest of a new message */
1589 HASH
->CR
|= HASH_CR_INIT
;
1593 hhash
->Phase
= HAL_HASH_PHASE_PROCESS
;
1595 /* Configure the number of valid bits in last word of the message */
1596 __HAL_HASH_SET_NBVALIDBITS(hhash
->Init
.KeySize
);
1598 /* Get the key address */
1599 inputaddr
= (uint32_t)(hhash
->Init
.pKey
);
1601 /* Set the HASH DMA transfer complete callback */
1602 hhash
->hdmain
->XferCpltCallback
= HASHEx_DMAXferCplt
;
1603 /* Set the DMA error callback */
1604 hhash
->hdmain
->XferErrorCallback
= HASHEx_DMAError
;
1606 /* Enable the DMA In DMA Stream */
1607 HAL_DMA_Start_IT(hhash
->hdmain
, inputaddr
, (uint32_t)&HASH
->DIN
, (hhash
->Init
.KeySize
%4 ? (hhash
->Init
.KeySize
+3)/4:hhash
->Init
.KeySize
/4));
1608 /* Enable DMA requests */
1609 HASH
->CR
|= (HASH_CR_DMAE
);
1611 /* Process Unlocked */
1612 __HAL_UNLOCK(hhash
);
1614 /* Return function status */
1625 #endif /* HAL_HASH_MODULE_ENABLED */
1630 #endif /* STM32F756xx || STM32F777xx || STM32F779xx */
1636 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/