2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_hash_ex.c
\r
4 * @author MCD Application Team
\r
7 * @brief HASH HAL Extension module driver.
\r
8 * This file provides firmware functions to manage the following
\r
9 * functionalities of HASH peripheral:
\r
10 * + Extended HASH processing functions based on SHA224 Algorithm
\r
11 * + Extended HASH processing functions based on SHA256 Algorithm
\r
14 ==============================================================================
\r
15 ##### How to use this driver #####
\r
16 ==============================================================================
\r
18 The HASH HAL driver can be used as follows:
\r
19 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
\r
20 (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
\r
21 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMACEx_SHA224_Start())
\r
22 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
\r
23 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
\r
24 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
\r
25 (##) In case of using DMA to control data transfer (e.g. HAL_HMACEx_SH224_Start_DMA())
\r
26 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
\r
27 (+++) Configure and enable one DMA stream one for managing data transfer from
\r
28 memory to peripheral (input stream). Managing data transfer from
\r
29 peripheral to memory can be performed only using CPU
\r
30 (+++) Associate the initialized DMA handle to the HASH DMA handle
\r
31 using __HAL_LINKDMA()
\r
32 (+++) Configure the priority and enable the NVIC for the transfer complete
\r
33 interrupt on the DMA Stream: HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
\r
34 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
\r
35 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
\r
36 (##) For HMAC, the encryption key.
\r
37 (##) For HMAC, the key size used for encryption.
\r
38 (#)Three processing functions are available:
\r
39 (##) Polling mode: processing APIs are blocking functions
\r
40 i.e. they process the data and wait till the digest computation is finished
\r
41 e.g. HAL_HASHEx_SHA224_Start()
\r
42 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
\r
43 i.e. they process the data under interrupt
\r
44 e.g. HAL_HASHEx_SHA224_Start_IT()
\r
45 (##) DMA mode: processing APIs are not blocking functions and the CPU is
\r
46 not used for data transfer i.e. the data transfer is ensured by DMA
\r
47 e.g. HAL_HASHEx_SHA224_Start_DMA()
\r
48 (#)When the processing function is called at first time after HAL_HASH_Init()
\r
49 the HASH peripheral is initialized and processes the buffer in input.
\r
50 After that, the digest computation is started.
\r
51 When processing multi-buffer use the accumulate function to write the
\r
52 data in the peripheral without starting the digest computation. In last
\r
53 buffer use the start function to input the last buffer ans start the digest
\r
55 (##) e.g. HAL_HASHEx_SHA224_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
\r
56 (##) write (n-1)th data buffer in the peripheral without starting the digest computation
\r
57 (##) HAL_HASHEx_SHA224_Start() : write (n)th data buffer in the peripheral and start the digest computation
\r
58 (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
\r
59 (#)In case of using DMA, call the DMA start processing e.g. HAL_HASHEx_SHA224_Start_DMA().
\r
60 After that, call the finish function in order to get the digest value
\r
61 e.g. HAL_HASHEx_SHA224_Finish()
\r
62 (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
\r
65 ******************************************************************************
\r
68 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
70 * Redistribution and use in source and binary forms, with or without modification,
\r
71 * are permitted provided that the following conditions are met:
\r
72 * 1. Redistributions of source code must retain the above copyright notice,
\r
73 * this list of conditions and the following disclaimer.
\r
74 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
75 * this list of conditions and the following disclaimer in the documentation
\r
76 * and/or other materials provided with the distribution.
\r
77 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
78 * may be used to endorse or promote products derived from this software
\r
79 * without specific prior written permission.
\r
81 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
82 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
84 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
87 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
88 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
89 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
90 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
92 ******************************************************************************
\r
95 /* Includes ------------------------------------------------------------------*/
\r
96 #include "stm32f7xx_hal.h"
\r
98 /** @addtogroup STM32F7xx_HAL_Driver
\r
101 #if defined(STM32F756xx)
\r
103 /** @defgroup HASHEx HASHEx
\r
104 * @brief HASH Extension HAL module driver.
\r
108 #ifdef HAL_HASH_MODULE_ENABLED
\r
110 /* Private typedef -----------------------------------------------------------*/
\r
111 /* Private define ------------------------------------------------------------*/
\r
112 /* Private macro -------------------------------------------------------------*/
\r
113 /* Private variables ---------------------------------------------------------*/
\r
114 /* Private function prototypes -----------------------------------------------*/
\r
115 /** @addtogroup HASHEx_Private_Functions
\r
118 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma);
\r
119 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size);
\r
120 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
\r
121 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma);
\r
126 /* Private functions ---------------------------------------------------------*/
\r
128 /** @addtogroup HASHEx_Private_Functions
\r
133 * @brief Writes the input buffer in data register.
\r
134 * @param pInBuffer: Pointer to input buffer
\r
135 * @param Size: The size of input buffer
\r
138 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size)
\r
140 uint32_t buffercounter;
\r
141 uint32_t inputaddr = (uint32_t) pInBuffer;
\r
143 for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
\r
145 HASH->DIN = *(uint32_t*)inputaddr;
\r
151 * @brief Provides the message digest result.
\r
152 * @param pMsgDigest: Pointer to the message digest
\r
153 * @param Size: The size of the message digest in bytes
\r
156 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
\r
158 uint32_t msgdigest = (uint32_t)pMsgDigest;
\r
163 /* Read the message digest */
\r
164 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
166 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
168 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
170 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
173 /* Read the message digest */
\r
174 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
176 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
178 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
180 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
182 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
185 /* Read the message digest */
\r
186 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
188 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
190 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
192 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
194 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
196 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
\r
198 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
\r
201 /* Read the message digest */
\r
202 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
204 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
206 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
208 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
210 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
212 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
\r
214 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
\r
216 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
\r
224 * @brief DMA HASH Input Data complete callback.
\r
225 * @param hdma: DMA handle
\r
228 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma)
\r
230 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
231 uint32_t inputaddr = 0;
\r
232 uint32_t buffersize = 0;
\r
234 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
\r
236 /* Disable the DMA transfer */
\r
237 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
239 /* Change HASH peripheral state */
\r
240 hhash->State = HAL_HASH_STATE_READY;
\r
242 /* Call Input data transfer complete callback */
\r
243 HAL_HASH_InCpltCallback(hhash);
\r
247 /* Increment Interrupt counter */
\r
248 hhash->HashInCount++;
\r
249 /* Disable the DMA transfer before starting the next transfer */
\r
250 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
252 if(hhash->HashInCount <= 2)
\r
254 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
\r
255 if(hhash->HashInCount == 1)
\r
257 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
258 buffersize = hhash->HashBuffSize;
\r
260 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
\r
261 else if(hhash->HashInCount == 2)
\r
263 inputaddr = (uint32_t)hhash->Init.pKey;
\r
264 buffersize = hhash->Init.KeySize;
\r
266 /* Configure the number of valid bits in last word of the message */
\r
267 HASH->STR |= 8 * (buffersize % 4);
\r
269 /* Set the HASH DMA transfer complete */
\r
270 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
272 /* Enable the DMA In DMA Stream */
\r
273 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
\r
275 /* Enable DMA requests */
\r
276 HASH->CR |= (HASH_CR_DMAE);
\r
280 /* Disable the DMA transfer */
\r
281 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
283 /* Reset the InCount */
\r
284 hhash->HashInCount = 0;
\r
286 /* Change HASH peripheral state */
\r
287 hhash->State = HAL_HASH_STATE_READY;
\r
289 /* Call Input data transfer complete callback */
\r
290 HAL_HASH_InCpltCallback(hhash);
\r
296 * @brief DMA HASH communication error callback.
\r
297 * @param hdma: DMA handle
\r
300 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma)
\r
302 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
303 hhash->State= HAL_HASH_STATE_READY;
\r
304 HAL_HASH_ErrorCallback(hhash);
\r
311 /* Exported functions --------------------------------------------------------*/
\r
312 /** @addtogroup HASHEx_Exported_Functions
\r
316 /** @defgroup HASHEx_Group1 HASH processing functions
\r
317 * @brief processing functions using polling mode
\r
320 ===============================================================================
\r
321 ##### HASH processing using polling mode functions #####
\r
322 ===============================================================================
\r
323 [..] This section provides functions allowing to calculate in polling mode
\r
324 the hash value using one of the following algorithms:
\r
333 * @brief Initializes the HASH peripheral in SHA224 mode
\r
334 * then processes pInBuffer. The digest is available in pOutBuffer
\r
335 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
336 * the configuration information for HASH module
\r
337 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
338 * @param Size: Length of the input buffer in bytes.
\r
339 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
340 * @param pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
\r
341 * @param Timeout: Specify Timeout value
\r
342 * @retval HAL status
\r
344 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
346 uint32_t tickstart = 0;
\r
348 /* Process Locked */
\r
351 /* Change the HASH state */
\r
352 hhash->State = HAL_HASH_STATE_BUSY;
\r
354 /* Check if initialization phase has already been performed */
\r
355 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
357 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
358 the message digest of a new message */
\r
359 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
\r
362 /* Set the phase */
\r
363 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
365 /* Configure the number of valid bits in last word of the message */
\r
366 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
368 /* Write input buffer in data register */
\r
369 HASHEx_WriteData(pInBuffer, Size);
\r
371 /* Start the digest calculation */
\r
372 __HAL_HASH_START_DIGEST();
\r
375 tickstart = HAL_GetTick();
\r
377 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
379 /* Check for the Timeout */
\r
380 if(Timeout != HAL_MAX_DELAY)
\r
382 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
385 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
387 /* Process Unlocked */
\r
388 __HAL_UNLOCK(hhash);
\r
390 return HAL_TIMEOUT;
\r
395 /* Read the message digest */
\r
396 HASHEx_GetDigest(pOutBuffer, 28);
\r
398 /* Change the HASH state */
\r
399 hhash->State = HAL_HASH_STATE_READY;
\r
401 /* Process Unlocked */
\r
402 __HAL_UNLOCK(hhash);
\r
404 /* Return function status */
\r
409 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
\r
410 The digest is available in pOutBuffer.
\r
411 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
412 * the configuration information for HASH module
\r
413 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
414 * @param Size: Length of the input buffer in bytes.
\r
415 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
416 * @param pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
\r
417 * @param Timeout: Specify Timeout value
\r
418 * @retval HAL status
\r
420 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
422 uint32_t tickstart = 0;
\r
424 /* Process Locked */
\r
427 /* Change the HASH state */
\r
428 hhash->State = HAL_HASH_STATE_BUSY;
\r
430 /* Check if initialization phase has already been performed */
\r
431 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
433 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
434 the message digest of a new message */
\r
435 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
\r
438 /* Set the phase */
\r
439 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
441 /* Configure the number of valid bits in last word of the message */
\r
442 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
444 /* Write input buffer in data register */
\r
445 HASHEx_WriteData(pInBuffer, Size);
\r
447 /* Start the digest calculation */
\r
448 __HAL_HASH_START_DIGEST();
\r
451 tickstart = HAL_GetTick();
\r
453 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
455 /* Check for the Timeout */
\r
456 if(Timeout != HAL_MAX_DELAY)
\r
458 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
461 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
463 /* Process Unlocked */
\r
464 __HAL_UNLOCK(hhash);
\r
466 return HAL_TIMEOUT;
\r
471 /* Read the message digest */
\r
472 HASHEx_GetDigest(pOutBuffer, 32);
\r
474 /* Change the HASH state */
\r
475 hhash->State = HAL_HASH_STATE_READY;
\r
477 /* Process Unlocked */
\r
478 __HAL_UNLOCK(hhash);
\r
480 /* Return function status */
\r
486 * @brief Initializes the HASH peripheral in SHA224 mode
\r
487 * then processes pInBuffer. The digest is available in pOutBuffer
\r
488 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
489 * the configuration information for HASH module
\r
490 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
491 * @param Size: Length of the input buffer in bytes.
\r
492 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
493 * @retval HAL status
\r
495 HAL_StatusTypeDef HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
497 /* Process Locked */
\r
500 /* Change the HASH state */
\r
501 hhash->State = HAL_HASH_STATE_BUSY;
\r
503 /* Check if initialization phase has already been performed */
\r
504 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
506 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
507 the message digest of a new message */
\r
508 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
\r
511 /* Set the phase */
\r
512 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
514 /* Configure the number of valid bits in last word of the message */
\r
515 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
517 /* Write input buffer in data register */
\r
518 HASHEx_WriteData(pInBuffer, Size);
\r
520 /* Change the HASH state */
\r
521 hhash->State = HAL_HASH_STATE_READY;
\r
523 /* Process Unlocked */
\r
524 __HAL_UNLOCK(hhash);
\r
526 /* Return function status */
\r
532 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
\r
533 The digest is available in pOutBuffer.
\r
534 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
535 * the configuration information for HASH module
\r
536 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
537 * @param Size: Length of the input buffer in bytes.
\r
538 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
539 * @retval HAL status
\r
541 HAL_StatusTypeDef HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
543 /* Process Locked */
\r
546 /* Change the HASH state */
\r
547 hhash->State = HAL_HASH_STATE_BUSY;
\r
549 /* Check if initialization phase has already been performed */
\r
550 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
552 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
553 the message digest of a new message */
\r
554 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
\r
557 /* Set the phase */
\r
558 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
560 /* Configure the number of valid bits in last word of the message */
\r
561 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
563 /* Write input buffer in data register */
\r
564 HASHEx_WriteData(pInBuffer, Size);
\r
566 /* Change the HASH state */
\r
567 hhash->State = HAL_HASH_STATE_READY;
\r
569 /* Process Unlocked */
\r
570 __HAL_UNLOCK(hhash);
\r
572 /* Return function status */
\r
581 /** @defgroup HASHEx_Group2 HMAC processing functions using polling mode
\r
582 * @brief HMAC processing functions using polling mode .
\r
585 ===============================================================================
\r
586 ##### HMAC processing using polling mode functions #####
\r
587 ===============================================================================
\r
588 [..] This section provides functions allowing to calculate in polling mode
\r
589 the HMAC value using one of the following algorithms:
\r
598 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
\r
599 * then processes pInBuffer. The digest is available in pOutBuffer.
\r
600 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
601 * the configuration information for HASH module
\r
602 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
603 * @param Size: Length of the input buffer in bytes.
\r
604 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
605 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
606 * @param Timeout: Timeout value
\r
607 * @retval HAL status
\r
609 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
611 uint32_t tickstart = 0;
\r
613 /* Process Locked */
\r
616 /* Change the HASH state */
\r
617 hhash->State = HAL_HASH_STATE_BUSY;
\r
619 /* Check if initialization phase has already been performed */
\r
620 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
622 /* Check if key size is greater than 64 bytes */
\r
623 if(hhash->Init.KeySize > 64)
\r
625 /* Select the HMAC SHA224 mode */
\r
626 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
\r
630 /* Select the HMAC SHA224 mode */
\r
631 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
\r
635 /* Set the phase */
\r
636 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
638 /************************** STEP 1 ******************************************/
\r
639 /* Configure the number of valid bits in last word of the message */
\r
640 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
642 /* Write input buffer in data register */
\r
643 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
645 /* Start the digest calculation */
\r
646 __HAL_HASH_START_DIGEST();
\r
649 tickstart = HAL_GetTick();
\r
651 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
653 /* Check for the Timeout */
\r
654 if(Timeout != HAL_MAX_DELAY)
\r
656 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
659 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
661 /* Process Unlocked */
\r
662 __HAL_UNLOCK(hhash);
\r
664 return HAL_TIMEOUT;
\r
668 /************************** STEP 2 ******************************************/
\r
669 /* Configure the number of valid bits in last word of the message */
\r
670 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
672 /* Write input buffer in data register */
\r
673 HASHEx_WriteData(pInBuffer, Size);
\r
675 /* Start the digest calculation */
\r
676 __HAL_HASH_START_DIGEST();
\r
679 tickstart = HAL_GetTick();
\r
681 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
683 /* Check for the Timeout */
\r
684 if(Timeout != HAL_MAX_DELAY)
\r
686 if((HAL_GetTick() - tickstart ) > Timeout)
\r
689 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
691 /* Process Unlocked */
\r
692 __HAL_UNLOCK(hhash);
\r
694 return HAL_TIMEOUT;
\r
698 /************************** STEP 3 ******************************************/
\r
699 /* Configure the number of valid bits in last word of the message */
\r
700 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
702 /* Write input buffer in data register */
\r
703 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
705 /* Start the digest calculation */
\r
706 __HAL_HASH_START_DIGEST();
\r
709 tickstart = HAL_GetTick();
\r
711 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
713 /* Check for the Timeout */
\r
714 if(Timeout != HAL_MAX_DELAY)
\r
716 if((HAL_GetTick() - tickstart ) > Timeout)
\r
719 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
721 /* Process Unlocked */
\r
722 __HAL_UNLOCK(hhash);
\r
724 return HAL_TIMEOUT;
\r
728 /* Read the message digest */
\r
729 HASHEx_GetDigest(pOutBuffer, 28);
\r
731 /* Change the HASH state */
\r
732 hhash->State = HAL_HASH_STATE_READY;
\r
734 /* Process Unlocked */
\r
735 __HAL_UNLOCK(hhash);
\r
737 /* Return function status */
\r
742 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
\r
743 * then processes pInBuffer. The digest is available in pOutBuffer
\r
744 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
745 * the configuration information for HASH module
\r
746 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
747 * @param Size: Length of the input buffer in bytes.
\r
748 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
749 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
750 * @param Timeout: Timeout value
\r
751 * @retval HAL status
\r
753 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
755 uint32_t tickstart = 0;
\r
757 /* Process Locked */
\r
760 /* Change the HASH state */
\r
761 hhash->State = HAL_HASH_STATE_BUSY;
\r
763 /* Check if initialization phase has already been performed */
\r
764 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
766 /* Check if key size is greater than 64 bytes */
\r
767 if(hhash->Init.KeySize > 64)
\r
769 /* Select the HMAC SHA256 mode */
\r
770 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);
\r
774 /* Select the HMAC SHA256 mode */
\r
775 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);
\r
777 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
778 the message digest of a new message */
\r
779 HASH->CR |= HASH_CR_INIT;
\r
782 /* Set the phase */
\r
783 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
785 /************************** STEP 1 ******************************************/
\r
786 /* Configure the number of valid bits in last word of the message */
\r
787 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
789 /* Write input buffer in data register */
\r
790 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
792 /* Start the digest calculation */
\r
793 __HAL_HASH_START_DIGEST();
\r
796 tickstart = HAL_GetTick();
\r
798 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
800 /* Check for the Timeout */
\r
801 if(Timeout != HAL_MAX_DELAY)
\r
803 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
806 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
808 /* Process Unlocked */
\r
809 __HAL_UNLOCK(hhash);
\r
811 return HAL_TIMEOUT;
\r
815 /************************** STEP 2 ******************************************/
\r
816 /* Configure the number of valid bits in last word of the message */
\r
817 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
819 /* Write input buffer in data register */
\r
820 HASHEx_WriteData(pInBuffer, Size);
\r
822 /* Start the digest calculation */
\r
823 __HAL_HASH_START_DIGEST();
\r
826 tickstart = HAL_GetTick();
\r
828 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
830 /* Check for the Timeout */
\r
831 if(Timeout != HAL_MAX_DELAY)
\r
833 if((HAL_GetTick() - tickstart ) > Timeout)
\r
836 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
838 /* Process Unlocked */
\r
839 __HAL_UNLOCK(hhash);
\r
841 return HAL_TIMEOUT;
\r
845 /************************** STEP 3 ******************************************/
\r
846 /* Configure the number of valid bits in last word of the message */
\r
847 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
849 /* Write input buffer in data register */
\r
850 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
852 /* Start the digest calculation */
\r
853 __HAL_HASH_START_DIGEST();
\r
856 tickstart = HAL_GetTick();
\r
858 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
860 /* Check for the Timeout */
\r
861 if(Timeout != HAL_MAX_DELAY)
\r
863 if((HAL_GetTick() - tickstart ) > Timeout)
\r
866 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
868 /* Process Unlocked */
\r
869 __HAL_UNLOCK(hhash);
\r
871 return HAL_TIMEOUT;
\r
875 /* Read the message digest */
\r
876 HASHEx_GetDigest(pOutBuffer, 32);
\r
878 /* Change the HASH state */
\r
879 hhash->State = HAL_HASH_STATE_READY;
\r
881 /* Process Unlocked */
\r
882 __HAL_UNLOCK(hhash);
\r
884 /* Return function status */
\r
892 /** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode
\r
893 * @brief processing functions using interrupt mode.
\r
896 ===============================================================================
\r
897 ##### HASH processing using interrupt functions #####
\r
898 ===============================================================================
\r
899 [..] This section provides functions allowing to calculate in interrupt mode
\r
900 the hash value using one of the following algorithms:
\r
909 * @brief Initializes the HASH peripheral in SHA224 mode then processes pInBuffer.
\r
910 * The digest is available in pOutBuffer.
\r
911 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
912 * the configuration information for HASH module
\r
913 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
914 * @param Size: Length of the input buffer in bytes.
\r
915 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
916 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
917 * @retval HAL status
\r
919 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
\r
921 uint32_t inputaddr;
\r
922 uint32_t buffercounter;
\r
923 uint32_t inputcounter;
\r
925 /* Process Locked */
\r
928 if(hhash->HashITCounter == 0)
\r
930 hhash->HashITCounter = 1;
\r
934 hhash->HashITCounter = 0;
\r
936 if(hhash->State == HAL_HASH_STATE_READY)
\r
938 /* Change the HASH state */
\r
939 hhash->State = HAL_HASH_STATE_BUSY;
\r
941 hhash->HashInCount = Size;
\r
942 hhash->pHashInBuffPtr = pInBuffer;
\r
943 hhash->pHashOutBuffPtr = pOutBuffer;
\r
945 /* Check if initialization phase has already been performed */
\r
946 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
948 /* Select the SHA224 mode */
\r
949 HASH->CR |= HASH_ALGOSELECTION_SHA224;
\r
950 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
951 the message digest of a new message */
\r
952 HASH->CR |= HASH_CR_INIT;
\r
955 /* Set the phase */
\r
956 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
958 /* Process Unlocked */
\r
959 __HAL_UNLOCK(hhash);
\r
961 /* Enable Interrupts */
\r
962 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
\r
964 /* Return function status */
\r
967 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
\r
969 /* Read the message digest */
\r
970 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 28);
\r
971 if(hhash->HashInCount == 0)
\r
973 /* Disable Interrupts */
\r
975 /* Change the HASH state */
\r
976 hhash->State = HAL_HASH_STATE_READY;
\r
977 /* Call digest computation complete callback */
\r
978 HAL_HASH_DgstCpltCallback(hhash);
\r
981 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
\r
983 if(hhash->HashInCount > 64)
\r
985 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
986 /* Write the Input block in the Data IN register */
\r
987 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
\r
989 HASH->DIN = *(uint32_t*)inputaddr;
\r
992 if(hhash->HashITCounter == 0)
\r
994 HASH->DIN = *(uint32_t*)inputaddr;
\r
995 if(hhash->HashInCount >= 68)
\r
997 /* Decrement buffer counter */
\r
998 hhash->HashInCount -= 68;
\r
999 hhash->pHashInBuffPtr+= 68;
\r
1003 hhash->HashInCount -= 64;
\r
1008 /* Decrement buffer counter */
\r
1009 hhash->HashInCount -= 64;
\r
1010 hhash->pHashInBuffPtr+= 64;
\r
1015 /* Get the buffer address */
\r
1016 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
1017 /* Get the buffer counter */
\r
1018 inputcounter = hhash->HashInCount;
\r
1019 /* Disable Interrupts */
\r
1020 HASH->IMR &= ~(HASH_IT_DINI);
\r
1021 /* Configure the number of valid bits in last word of the message */
\r
1022 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
\r
1024 if((inputcounter > 4) && (inputcounter%4))
\r
1026 inputcounter = (inputcounter+4-inputcounter%4);
\r
1029 /* Write the Input block in the Data IN register */
\r
1030 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
\r
1032 HASH->DIN = *(uint32_t*)inputaddr;
\r
1035 /* Start the digest calculation */
\r
1036 __HAL_HASH_START_DIGEST();
\r
1037 /* Reset buffer counter */
\r
1038 hhash->HashInCount = 0;
\r
1040 /* Call Input data transfer complete callback */
\r
1041 HAL_HASH_InCpltCallback(hhash);
\r
1044 /* Process Unlocked */
\r
1045 __HAL_UNLOCK(hhash);
\r
1047 /* Return function status */
\r
1053 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
\r
1054 * The digest is available in pOutBuffer.
\r
1055 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1056 * the configuration information for HASH module
\r
1057 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1058 * @param Size: Length of the input buffer in bytes.
\r
1059 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1060 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
1061 * @retval HAL status
\r
1063 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
\r
1065 uint32_t inputaddr;
\r
1066 uint32_t buffercounter;
\r
1067 uint32_t inputcounter;
\r
1069 /* Process Locked */
\r
1070 __HAL_LOCK(hhash);
\r
1072 if(hhash->HashITCounter == 0)
\r
1074 hhash->HashITCounter = 1;
\r
1078 hhash->HashITCounter = 0;
\r
1080 if(hhash->State == HAL_HASH_STATE_READY)
\r
1082 /* Change the HASH state */
\r
1083 hhash->State = HAL_HASH_STATE_BUSY;
\r
1085 hhash->HashInCount = Size;
\r
1086 hhash->pHashInBuffPtr = pInBuffer;
\r
1087 hhash->pHashOutBuffPtr = pOutBuffer;
\r
1089 /* Check if initialization phase has already been performed */
\r
1090 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1092 /* Select the SHA256 mode */
\r
1093 HASH->CR |= HASH_ALGOSELECTION_SHA256;
\r
1094 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
1095 the message digest of a new message */
\r
1096 HASH->CR |= HASH_CR_INIT;
\r
1099 /* Set the phase */
\r
1100 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1102 /* Process Unlocked */
\r
1103 __HAL_UNLOCK(hhash);
\r
1105 /* Enable Interrupts */
\r
1106 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
\r
1108 /* Return function status */
\r
1111 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
\r
1113 /* Read the message digest */
\r
1114 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 32);
\r
1115 if(hhash->HashInCount == 0)
\r
1117 /* Disable Interrupts */
\r
1119 /* Change the HASH state */
\r
1120 hhash->State = HAL_HASH_STATE_READY;
\r
1121 /* Call digest computation complete callback */
\r
1122 HAL_HASH_DgstCpltCallback(hhash);
\r
1125 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
\r
1127 if(hhash->HashInCount > 64)
\r
1129 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
1130 /* Write the Input block in the Data IN register */
\r
1131 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
\r
1133 HASH->DIN = *(uint32_t*)inputaddr;
\r
1136 if(hhash->HashITCounter == 0)
\r
1138 HASH->DIN = *(uint32_t*)inputaddr;
\r
1140 if(hhash->HashInCount >= 68)
\r
1142 /* Decrement buffer counter */
\r
1143 hhash->HashInCount -= 68;
\r
1144 hhash->pHashInBuffPtr+= 68;
\r
1148 hhash->HashInCount -= 64;
\r
1153 /* Decrement buffer counter */
\r
1154 hhash->HashInCount -= 64;
\r
1155 hhash->pHashInBuffPtr+= 64;
\r
1160 /* Get the buffer address */
\r
1161 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
1162 /* Get the buffer counter */
\r
1163 inputcounter = hhash->HashInCount;
\r
1164 /* Disable Interrupts */
\r
1165 HASH->IMR &= ~(HASH_IT_DINI);
\r
1166 /* Configure the number of valid bits in last word of the message */
\r
1167 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
\r
1169 if((inputcounter > 4) && (inputcounter%4))
\r
1171 inputcounter = (inputcounter+4-inputcounter%4);
\r
1174 /* Write the Input block in the Data IN register */
\r
1175 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
\r
1177 HASH->DIN = *(uint32_t*)inputaddr;
\r
1180 /* Start the digest calculation */
\r
1181 __HAL_HASH_START_DIGEST();
\r
1182 /* Reset buffer counter */
\r
1183 hhash->HashInCount = 0;
\r
1185 /* Call Input data transfer complete callback */
\r
1186 HAL_HASH_InCpltCallback(hhash);
\r
1189 /* Process Unlocked */
\r
1190 __HAL_UNLOCK(hhash);
\r
1192 /* Return function status */
\r
1197 * @brief This function handles HASH interrupt request.
\r
1198 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1199 * the configuration information for HASH module
\r
1202 void HAL_HASHEx_IRQHandler(HASH_HandleTypeDef *hhash)
\r
1204 switch(HASH->CR & HASH_CR_ALGO)
\r
1207 case HASH_ALGOSELECTION_SHA224:
\r
1208 HAL_HASHEx_SHA224_Start_IT(hhash, NULL, 0, NULL);
\r
1211 case HASH_ALGOSELECTION_SHA256:
\r
1212 HAL_HASHEx_SHA256_Start_IT(hhash, NULL, 0, NULL);
\r
1224 /** @defgroup HASHEx_Group4 HASH processing functions using DMA mode
\r
1225 * @brief processing functions using DMA mode.
\r
1228 ===============================================================================
\r
1229 ##### HASH processing using DMA functions #####
\r
1230 ===============================================================================
\r
1231 [..] This section provides functions allowing to calculate in DMA mode
\r
1232 the hash value using one of the following algorithms:
\r
1242 * @brief Initializes the HASH peripheral in SHA224 mode then enables DMA to
\r
1243 control data transfer. Use HAL_HASH_SHA224_Finish() to get the digest.
\r
1244 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1245 * the configuration information for HASH module
\r
1246 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1247 * @param Size: Length of the input buffer in bytes.
\r
1248 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1249 * @retval HAL status
\r
1251 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1253 uint32_t inputaddr = (uint32_t)pInBuffer;
\r
1255 /* Process Locked */
\r
1256 __HAL_LOCK(hhash);
\r
1258 /* Change the HASH state */
\r
1259 hhash->State = HAL_HASH_STATE_BUSY;
\r
1261 /* Check if initialization phase has already been performed */
\r
1262 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1264 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
1265 the message digest of a new message */
\r
1266 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
\r
1269 /* Configure the number of valid bits in last word of the message */
\r
1270 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
1272 /* Set the phase */
\r
1273 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1275 /* Set the HASH DMA transfer complete callback */
\r
1276 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
1277 /* Set the DMA error callback */
\r
1278 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
\r
1280 /* Enable the DMA In DMA Stream */
\r
1281 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
\r
1283 /* Enable DMA requests */
\r
1284 HASH->CR |= (HASH_CR_DMAE);
\r
1286 /* Process Unlocked */
\r
1287 __HAL_UNLOCK(hhash);
\r
1289 /* Return function status */
\r
1294 * @brief Returns the computed digest in SHA224
\r
1295 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1296 * the configuration information for HASH module
\r
1297 * @param pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
\r
1298 * @param Timeout: Timeout value
\r
1299 * @retval HAL status
\r
1301 HAL_StatusTypeDef HAL_HASHEx_SHA224_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
\r
1303 uint32_t tickstart = 0;
\r
1305 /* Process Locked */
\r
1306 __HAL_LOCK(hhash);
\r
1308 /* Change HASH peripheral state */
\r
1309 hhash->State = HAL_HASH_STATE_BUSY;
\r
1312 tickstart = HAL_GetTick();
\r
1314 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
\r
1316 /* Check for the Timeout */
\r
1317 if(Timeout != HAL_MAX_DELAY)
\r
1319 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1321 /* Change state */
\r
1322 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1324 /* Process Unlocked */
\r
1325 __HAL_UNLOCK(hhash);
\r
1327 return HAL_TIMEOUT;
\r
1332 /* Read the message digest */
\r
1333 HASHEx_GetDigest(pOutBuffer, 28);
\r
1335 /* Change HASH peripheral state */
\r
1336 hhash->State = HAL_HASH_STATE_READY;
\r
1338 /* Process Unlocked */
\r
1339 __HAL_UNLOCK(hhash);
\r
1341 /* Return function status */
\r
1346 * @brief Initializes the HASH peripheral in SHA256 mode then enables DMA to
\r
1347 control data transfer. Use HAL_HASH_SHA256_Finish() to get the digest.
\r
1348 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1349 * the configuration information for HASH module
\r
1350 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1351 * @param Size: Length of the input buffer in bytes.
\r
1352 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1353 * @retval HAL status
\r
1355 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1357 uint32_t inputaddr = (uint32_t)pInBuffer;
\r
1359 /* Process Locked */
\r
1360 __HAL_LOCK(hhash);
\r
1362 /* Change the HASH state */
\r
1363 hhash->State = HAL_HASH_STATE_BUSY;
\r
1365 /* Check if initialization phase has already been performed */
\r
1366 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1368 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
1369 the message digest of a new message */
\r
1370 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
\r
1373 /* Configure the number of valid bits in last word of the message */
\r
1374 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
1376 /* Set the phase */
\r
1377 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1379 /* Set the HASH DMA transfer complete callback */
\r
1380 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
1381 /* Set the DMA error callback */
\r
1382 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
\r
1384 /* Enable the DMA In DMA Stream */
\r
1385 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
\r
1387 /* Enable DMA requests */
\r
1388 HASH->CR |= (HASH_CR_DMAE);
\r
1390 /* Process UnLock */
\r
1391 __HAL_UNLOCK(hhash);
\r
1393 /* Return function status */
\r
1398 * @brief Returns the computed digest in SHA256.
\r
1399 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1400 * the configuration information for HASH module
\r
1401 * @param pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
\r
1402 * @param Timeout: Timeout value
\r
1403 * @retval HAL status
\r
1405 HAL_StatusTypeDef HAL_HASHEx_SHA256_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
\r
1407 uint32_t tickstart = 0;
\r
1409 /* Process Locked */
\r
1410 __HAL_LOCK(hhash);
\r
1412 /* Change HASH peripheral state */
\r
1413 hhash->State = HAL_HASH_STATE_BUSY;
\r
1416 tickstart = HAL_GetTick();
\r
1418 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
\r
1420 /* Check for the Timeout */
\r
1421 if(Timeout != HAL_MAX_DELAY)
\r
1423 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1425 /* Change state */
\r
1426 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1428 /* Process Unlocked */
\r
1429 __HAL_UNLOCK(hhash);
\r
1431 return HAL_TIMEOUT;
\r
1436 /* Read the message digest */
\r
1437 HASHEx_GetDigest(pOutBuffer, 32);
\r
1439 /* Change HASH peripheral state */
\r
1440 hhash->State = HAL_HASH_STATE_READY;
\r
1442 /* Process Unlocked */
\r
1443 __HAL_UNLOCK(hhash);
\r
1445 /* Return function status */
\r
1453 /** @defgroup HASHEx_Group5 HMAC processing functions using DMA mode
\r
1454 * @brief HMAC processing functions using DMA mode .
\r
1457 ===============================================================================
\r
1458 ##### HMAC processing using DMA functions #####
\r
1459 ===============================================================================
\r
1460 [..] This section provides functions allowing to calculate in DMA mode
\r
1461 the HMAC value using one of the following algorithms:
\r
1470 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
\r
1471 * then enables DMA to control data transfer.
\r
1472 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1473 * the configuration information for HASH module
\r
1474 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1475 * @param Size: Length of the input buffer in bytes.
\r
1476 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1477 * @retval HAL status
\r
1479 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1481 uint32_t inputaddr;
\r
1483 /* Process Locked */
\r
1484 __HAL_LOCK(hhash);
\r
1486 /* Change the HASH state */
\r
1487 hhash->State = HAL_HASH_STATE_BUSY;
\r
1489 /* Save buffer pointer and size in handle */
\r
1490 hhash->pHashInBuffPtr = pInBuffer;
\r
1491 hhash->HashBuffSize = Size;
\r
1492 hhash->HashInCount = 0;
\r
1494 /* Check if initialization phase has already been performed */
\r
1495 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1497 /* Check if key size is greater than 64 bytes */
\r
1498 if(hhash->Init.KeySize > 64)
\r
1500 /* Select the HMAC SHA224 mode */
\r
1501 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
\r
1505 /* Select the HMAC SHA224 mode */
\r
1506 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
\r
1510 /* Set the phase */
\r
1511 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1513 /* Configure the number of valid bits in last word of the message */
\r
1514 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1516 /* Get the key address */
\r
1517 inputaddr = (uint32_t)(hhash->Init.pKey);
\r
1519 /* Set the HASH DMA transfer complete callback */
\r
1520 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
1521 /* Set the DMA error callback */
\r
1522 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
\r
1524 /* Enable the DMA In DMA Stream */
\r
1525 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
\r
1526 /* Enable DMA requests */
\r
1527 HASH->CR |= (HASH_CR_DMAE);
\r
1529 /* Process Unlocked */
\r
1530 __HAL_UNLOCK(hhash);
\r
1532 /* Return function status */
\r
1537 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
\r
1538 * then enables DMA to control data transfer.
\r
1539 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1540 * the configuration information for HASH module
\r
1541 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1542 * @param Size: Length of the input buffer in bytes.
\r
1543 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1544 * @retval HAL status
\r
1546 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1548 uint32_t inputaddr;
\r
1550 /* Process Locked */
\r
1551 __HAL_LOCK(hhash);
\r
1553 /* Change the HASH state */
\r
1554 hhash->State = HAL_HASH_STATE_BUSY;
\r
1556 /* Save buffer pointer and size in handle */
\r
1557 hhash->pHashInBuffPtr = pInBuffer;
\r
1558 hhash->HashBuffSize = Size;
\r
1559 hhash->HashInCount = 0;
\r
1561 /* Check if initialization phase has already been performed */
\r
1562 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1564 /* Check if key size is greater than 64 bytes */
\r
1565 if(hhash->Init.KeySize > 64)
\r
1567 /* Select the HMAC SHA256 mode */
\r
1568 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);
\r
1572 /* Select the HMAC SHA256 mode */
\r
1573 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);
\r
1575 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
1576 the message digest of a new message */
\r
1577 HASH->CR |= HASH_CR_INIT;
\r
1580 /* Set the phase */
\r
1581 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1583 /* Configure the number of valid bits in last word of the message */
\r
1584 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1586 /* Get the key address */
\r
1587 inputaddr = (uint32_t)(hhash->Init.pKey);
\r
1589 /* Set the HASH DMA transfer complete callback */
\r
1590 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
1591 /* Set the DMA error callback */
\r
1592 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
\r
1594 /* Enable the DMA In DMA Stream */
\r
1595 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
\r
1596 /* Enable DMA requests */
\r
1597 HASH->CR |= (HASH_CR_DMAE);
\r
1599 /* Process Unlocked */
\r
1600 __HAL_UNLOCK(hhash);
\r
1602 /* Return function status */
\r
1613 #endif /* HAL_HASH_MODULE_ENABLED */
\r
1618 #endif /* STM32F756xx */
\r
1624 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r