2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_hash.c
\r
4 * @author MCD Application Team
\r
6 * @date 06-March-2015
\r
7 * @brief HASH HAL module driver.
\r
8 * This file provides firmware functions to manage the following
\r
9 * functionalities of the HASH peripheral:
\r
10 * + Initialization and de-initialization functions
\r
11 * + HASH/HMAC Processing functions by algorithm using polling mode
\r
12 * + HASH/HMAC functions by algorithm using interrupt mode
\r
13 * + HASH/HMAC functions by algorithm using DMA mode
\r
14 * + Peripheral State functions
\r
17 ==============================================================================
\r
18 ##### How to use this driver #####
\r
19 ==============================================================================
\r
21 The HASH HAL driver can be used as follows:
\r
22 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
\r
23 (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
\r
24 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMAC_SHA1_Start_IT())
\r
25 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
\r
26 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
\r
27 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
\r
28 (##) In case of using DMA to control data transfer (e.g. HAL_HMAC_SHA1_Start_DMA())
\r
29 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
\r
30 (+++) Configure and enable one DMA stream one for managing data transfer from
\r
31 memory to peripheral (input stream). Managing data transfer from
\r
32 peripheral to memory can be performed only using CPU
\r
33 (+++) Associate the initialized DMA handle to the HASH DMA handle
\r
34 using __HAL_LINKDMA()
\r
35 (+++) Configure the priority and enable the NVIC for the transfer complete
\r
36 interrupt on the DMA Stream using HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
\r
37 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
\r
38 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
\r
39 (##) For HMAC, the encryption key.
\r
40 (##) For HMAC, the key size used for encryption.
\r
41 (#)Three processing functions are available:
\r
42 (##) Polling mode: processing APIs are blocking functions
\r
43 i.e. they process the data and wait till the digest computation is finished
\r
44 e.g. HAL_HASH_SHA1_Start()
\r
45 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
\r
46 i.e. they process the data under interrupt
\r
47 e.g. HAL_HASH_SHA1_Start_IT()
\r
48 (##) DMA mode: processing APIs are not blocking functions and the CPU is
\r
49 not used for data transfer i.e. the data transfer is ensured by DMA
\r
50 e.g. HAL_HASH_SHA1_Start_DMA()
\r
51 (#)When the processing function is called at first time after HAL_HASH_Init()
\r
52 the HASH peripheral is initialized and processes the buffer in input.
\r
53 After that, the digest computation is started.
\r
54 When processing multi-buffer use the accumulate function to write the
\r
55 data in the peripheral without starting the digest computation. In last
\r
56 buffer use the start function to input the last buffer ans start the digest
\r
58 (##) e.g. HAL_HASH_SHA1_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
\r
59 (##) write (n-1)th data buffer in the peripheral without starting the digest computation
\r
60 (##) HAL_HASH_SHA1_Start() : write (n)th data buffer in the peripheral and start the digest computation
\r
61 (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
\r
62 (#)In case of using DMA, call the DMA start processing e.g. HAL_HASH_SHA1_Start_DMA().
\r
63 After that, call the finish function in order to get the digest value
\r
64 e.g. HAL_HASH_SHA1_Finish()
\r
65 (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
\r
68 ******************************************************************************
\r
71 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
73 * Redistribution and use in source and binary forms, with or without modification,
\r
74 * are permitted provided that the following conditions are met:
\r
75 * 1. Redistributions of source code must retain the above copyright notice,
\r
76 * this list of conditions and the following disclaimer.
\r
77 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
78 * this list of conditions and the following disclaimer in the documentation
\r
79 * and/or other materials provided with the distribution.
\r
80 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
81 * may be used to endorse or promote products derived from this software
\r
82 * without specific prior written permission.
\r
84 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
85 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
86 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
87 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
88 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
89 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
90 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
91 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
92 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
93 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
95 ******************************************************************************
\r
98 /* Includes ------------------------------------------------------------------*/
\r
99 #include "stm32f7xx_hal.h"
\r
101 /** @addtogroup STM32F7xx_HAL_Driver
\r
105 /** @defgroup HASH HASH
\r
106 * @brief HASH HAL module driver.
\r
110 #ifdef HAL_HASH_MODULE_ENABLED
\r
112 #if defined(STM32F756xx)
\r
114 /* Private typedef -----------------------------------------------------------*/
\r
115 /* Private define ------------------------------------------------------------*/
\r
116 /* Private macro -------------------------------------------------------------*/
\r
117 /* Private variables ---------------------------------------------------------*/
\r
118 /* Private function prototypes -----------------------------------------------*/
\r
119 /** @defgroup HASH_Private_Functions HASH Private Functions
\r
122 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
\r
123 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
\r
124 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
\r
125 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size);
\r
130 /* Private functions ---------------------------------------------------------*/
\r
131 /** @addtogroup HASH_Private_Functions
\r
136 * @brief DMA HASH Input Data complete callback.
\r
137 * @param hdma: DMA handle
\r
140 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
\r
142 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
143 uint32_t inputaddr = 0;
\r
144 uint32_t buffersize = 0;
\r
146 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
\r
148 /* Disable the DMA transfer */
\r
149 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
151 /* Change HASH peripheral state */
\r
152 hhash->State = HAL_HASH_STATE_READY;
\r
154 /* Call Input data transfer complete callback */
\r
155 HAL_HASH_InCpltCallback(hhash);
\r
159 /* Increment Interrupt counter */
\r
160 hhash->HashInCount++;
\r
161 /* Disable the DMA transfer before starting the next transfer */
\r
162 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
164 if(hhash->HashInCount <= 2)
\r
166 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
\r
167 if(hhash->HashInCount == 1)
\r
169 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
170 buffersize = hhash->HashBuffSize;
\r
172 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
\r
173 else if(hhash->HashInCount == 2)
\r
175 inputaddr = (uint32_t)hhash->Init.pKey;
\r
176 buffersize = hhash->Init.KeySize;
\r
178 /* Configure the number of valid bits in last word of the message */
\r
179 HASH->STR |= 8 * (buffersize % 4);
\r
181 /* Set the HASH DMA transfer complete */
\r
182 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
\r
184 /* Enable the DMA In DMA Stream */
\r
185 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
\r
187 /* Enable DMA requests */
\r
188 HASH->CR |= (HASH_CR_DMAE);
\r
192 /* Disable the DMA transfer */
\r
193 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
195 /* Reset the InCount */
\r
196 hhash->HashInCount = 0;
\r
198 /* Change HASH peripheral state */
\r
199 hhash->State = HAL_HASH_STATE_READY;
\r
201 /* Call Input data transfer complete callback */
\r
202 HAL_HASH_InCpltCallback(hhash);
\r
208 * @brief DMA HASH communication error callback.
\r
209 * @param hdma: DMA handle
\r
212 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
\r
214 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
215 hhash->State= HAL_HASH_STATE_READY;
\r
216 HAL_HASH_ErrorCallback(hhash);
\r
220 * @brief Writes the input buffer in data register.
\r
221 * @param pInBuffer: Pointer to input buffer
\r
222 * @param Size: The size of input buffer
\r
225 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
\r
227 uint32_t buffercounter;
\r
228 uint32_t inputaddr = (uint32_t) pInBuffer;
\r
230 for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
\r
232 HASH->DIN = *(uint32_t*)inputaddr;
\r
238 * @brief Provides the message digest result.
\r
239 * @param pMsgDigest: Pointer to the message digest
\r
240 * @param Size: The size of the message digest in bytes
\r
243 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
\r
245 uint32_t msgdigest = (uint32_t)pMsgDigest;
\r
250 /* Read the message digest */
\r
251 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
253 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
255 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
257 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
260 /* Read the message digest */
\r
261 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
263 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
265 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
267 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
269 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
272 /* Read the message digest */
\r
273 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
275 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
277 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
279 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
281 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
283 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
\r
285 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
\r
288 /* Read the message digest */
\r
289 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
291 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
293 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
295 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
297 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
299 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
\r
301 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
\r
303 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
\r
314 /* Exported functions --------------------------------------------------------*/
\r
315 /** @addtogroup HASH_Exported_Functions
\r
320 /** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions
\r
321 * @brief Initialization and Configuration functions.
\r
324 ===============================================================================
\r
325 ##### Initialization and de-initialization functions #####
\r
326 ===============================================================================
\r
327 [..] This section provides functions allowing to:
\r
328 (+) Initialize the HASH according to the specified parameters
\r
329 in the HASH_InitTypeDef and creates the associated handle.
\r
330 (+) DeInitialize the HASH peripheral.
\r
331 (+) Initialize the HASH MSP.
\r
332 (+) DeInitialize HASH MSP.
\r
339 * @brief Initializes the HASH according to the specified parameters in the
\r
340 HASH_HandleTypeDef and creates the associated handle.
\r
341 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
342 * the configuration information for HASH module
\r
343 * @retval HAL status
\r
345 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
\r
347 /* Check the hash handle allocation */
\r
353 /* Check the parameters */
\r
354 assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
\r
356 if(hhash->State == HAL_HASH_STATE_RESET)
\r
358 /* Init the low level hardware */
\r
359 HAL_HASH_MspInit(hhash);
\r
362 /* Change the HASH state */
\r
363 hhash->State = HAL_HASH_STATE_BUSY;
\r
365 /* Reset HashInCount, HashBuffSize and HashITCounter */
\r
366 hhash->HashInCount = 0;
\r
367 hhash->HashBuffSize = 0;
\r
368 hhash->HashITCounter = 0;
\r
370 /* Set the data type */
\r
371 HASH->CR |= (uint32_t) (hhash->Init.DataType);
\r
373 /* Change the HASH state */
\r
374 hhash->State = HAL_HASH_STATE_READY;
\r
376 /* Set the default HASH phase */
\r
377 hhash->Phase = HAL_HASH_PHASE_READY;
\r
379 /* Return function status */
\r
384 * @brief DeInitializes the HASH peripheral.
\r
385 * @note This API must be called before starting a new processing.
\r
386 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
387 * the configuration information for HASH module
\r
388 * @retval HAL status
\r
390 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
\r
392 /* Check the HASH handle allocation */
\r
398 /* Change the HASH state */
\r
399 hhash->State = HAL_HASH_STATE_BUSY;
\r
401 /* Set the default HASH phase */
\r
402 hhash->Phase = HAL_HASH_PHASE_READY;
\r
404 /* Reset HashInCount, HashBuffSize and HashITCounter */
\r
405 hhash->HashInCount = 0;
\r
406 hhash->HashBuffSize = 0;
\r
407 hhash->HashITCounter = 0;
\r
409 /* DeInit the low level hardware */
\r
410 HAL_HASH_MspDeInit(hhash);
\r
412 /* Change the HASH state */
\r
413 hhash->State = HAL_HASH_STATE_RESET;
\r
416 __HAL_UNLOCK(hhash);
\r
418 /* Return function status */
\r
423 * @brief Initializes the HASH MSP.
\r
424 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
425 * the configuration information for HASH module
\r
428 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
\r
430 /* NOTE: This function Should not be modified, when the callback is needed,
\r
431 the HAL_HASH_MspInit could be implemented in the user file
\r
436 * @brief DeInitializes HASH MSP.
\r
437 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
438 * the configuration information for HASH module
\r
441 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
\r
443 /* NOTE: This function Should not be modified, when the callback is needed,
\r
444 the HAL_HASH_MspDeInit could be implemented in the user file
\r
449 * @brief Input data transfer complete callback.
\r
450 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
451 * the configuration information for HASH module
\r
454 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
\r
456 /* NOTE: This function Should not be modified, when the callback is needed,
\r
457 the HAL_HASH_InCpltCallback could be implemented in the user file
\r
462 * @brief Data transfer Error callback.
\r
463 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
464 * the configuration information for HASH module
\r
467 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
\r
469 /* NOTE: This function Should not be modified, when the callback is needed,
\r
470 the HAL_HASH_ErrorCallback could be implemented in the user file
\r
475 * @brief Digest computation complete callback. It is used only with interrupt.
\r
476 * @note This callback is not relevant with DMA.
\r
477 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
478 * the configuration information for HASH module
\r
481 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
\r
483 /* NOTE: This function Should not be modified, when the callback is needed,
\r
484 the HAL_HASH_DgstCpltCallback could be implemented in the user file
\r
492 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions using polling mode
\r
493 * @brief processing functions using polling mode
\r
496 ===============================================================================
\r
497 ##### HASH processing using polling mode functions#####
\r
498 ===============================================================================
\r
499 [..] This section provides functions allowing to calculate in polling mode
\r
500 the hash value using one of the following algorithms:
\r
509 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
\r
510 The digest is available in pOutBuffer.
\r
511 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
512 * the configuration information for HASH module
\r
513 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
514 * @param Size: Length of the input buffer in bytes.
\r
515 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
\r
516 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
\r
517 * and appending the input buffer is no more possible.
\r
518 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
\r
519 * @param Timeout: Timeout value
\r
520 * @retval HAL status
\r
522 HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
524 uint32_t tickstart = 0;
\r
526 /* Process Locked */
\r
529 /* Change the HASH state */
\r
530 hhash->State = HAL_HASH_STATE_BUSY;
\r
532 /* Check if initialization phase has already been performed */
\r
533 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
535 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
536 the message digest of a new message */
\r
537 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
\r
540 /* Set the phase */
\r
541 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
543 /* Configure the number of valid bits in last word of the message */
\r
544 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
546 /* Write input buffer in data register */
\r
547 HASH_WriteData(pInBuffer, Size);
\r
549 /* Start the digest calculation */
\r
550 __HAL_HASH_START_DIGEST();
\r
553 tickstart = HAL_GetTick();
\r
555 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
\r
557 /* Check for the Timeout */
\r
558 if(Timeout != HAL_MAX_DELAY)
\r
560 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
563 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
565 /* Process Unlocked */
\r
566 __HAL_UNLOCK(hhash);
\r
568 return HAL_TIMEOUT;
\r
573 /* Read the message digest */
\r
574 HASH_GetDigest(pOutBuffer, 16);
\r
576 /* Change the HASH state */
\r
577 hhash->State = HAL_HASH_STATE_READY;
\r
579 /* Process Unlocked */
\r
580 __HAL_UNLOCK(hhash);
\r
582 /* Return function status */
\r
587 * @brief Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
\r
588 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
589 * the configuration information for HASH module
\r
590 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
591 * @param Size: Length of the input buffer in bytes.
\r
592 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
\r
593 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
\r
594 * and appending the input buffer is no more possible.
\r
595 * @retval HAL status
\r
597 HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
599 /* Process Locked */
\r
602 /* Change the HASH state */
\r
603 hhash->State = HAL_HASH_STATE_BUSY;
\r
605 /* Check if initialization phase has already been performed */
\r
606 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
608 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
609 the message digest of a new message */
\r
610 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
\r
613 /* Set the phase */
\r
614 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
616 /* Configure the number of valid bits in last word of the message */
\r
617 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
619 /* Write input buffer in data register */
\r
620 HASH_WriteData(pInBuffer, Size);
\r
622 /* Change the HASH state */
\r
623 hhash->State = HAL_HASH_STATE_READY;
\r
625 /* Process Unlocked */
\r
626 __HAL_UNLOCK(hhash);
\r
628 /* Return function status */
\r
633 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
\r
634 The digest is available in pOutBuffer.
\r
635 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
636 * the configuration information for HASH module
\r
637 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
638 * @param Size: Length of the input buffer in bytes.
\r
639 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
640 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
641 * @param Timeout: Timeout value
\r
642 * @retval HAL status
\r
644 HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
646 uint32_t tickstart = 0;
\r
648 /* Process Locked */
\r
651 /* Change the HASH state */
\r
652 hhash->State = HAL_HASH_STATE_BUSY;
\r
654 /* Check if initialization phase has already been performed */
\r
655 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
657 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
658 the message digest of a new message */
\r
659 HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
\r
662 /* Set the phase */
\r
663 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
665 /* Configure the number of valid bits in last word of the message */
\r
666 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
668 /* Write input buffer in data register */
\r
669 HASH_WriteData(pInBuffer, Size);
\r
671 /* Start the digest calculation */
\r
672 __HAL_HASH_START_DIGEST();
\r
675 tickstart = HAL_GetTick();
\r
677 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
\r
679 /* Check for the Timeout */
\r
680 if(Timeout != HAL_MAX_DELAY)
\r
682 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
685 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
687 /* Process Unlocked */
\r
688 __HAL_UNLOCK(hhash);
\r
690 return HAL_TIMEOUT;
\r
695 /* Read the message digest */
\r
696 HASH_GetDigest(pOutBuffer, 20);
\r
698 /* Change the HASH state */
\r
699 hhash->State = HAL_HASH_STATE_READY;
\r
701 /* Process Unlocked */
\r
702 __HAL_UNLOCK(hhash);
\r
704 /* Return function status */
\r
709 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
\r
710 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
711 * the configuration information for HASH module
\r
712 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
713 * @param Size: Length of the input buffer in bytes.
\r
714 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
715 * @retval HAL status
\r
717 HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
719 /* Process Locked */
\r
722 /* Change the HASH state */
\r
723 hhash->State = HAL_HASH_STATE_BUSY;
\r
725 /* Check if initialization phase has already been performed */
\r
726 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
728 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
729 the message digest of a new message */
\r
730 HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
\r
733 /* Set the phase */
\r
734 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
736 /* Configure the number of valid bits in last word of the message */
\r
737 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
739 /* Write input buffer in data register */
\r
740 HASH_WriteData(pInBuffer, Size);
\r
742 /* Change the HASH state */
\r
743 hhash->State = HAL_HASH_STATE_READY;
\r
745 /* Process Unlocked */
\r
746 __HAL_UNLOCK(hhash);
\r
748 /* Return function status */
\r
756 /** @defgroup HASH_Exported_Functions_Group3 HASH processing functions using interrupt mode
\r
757 * @brief processing functions using interrupt mode.
\r
760 ===============================================================================
\r
761 ##### HASH processing using interrupt mode functions #####
\r
762 ===============================================================================
\r
763 [..] This section provides functions allowing to calculate in interrupt mode
\r
764 the hash value using one of the following algorithms:
\r
773 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
\r
774 * The digest is available in pOutBuffer.
\r
775 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
776 * the configuration information for HASH module
\r
777 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
778 * @param Size: Length of the input buffer in bytes.
\r
779 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
780 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
\r
781 * @retval HAL status
\r
783 HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
\r
785 uint32_t inputaddr;
\r
786 uint32_t outputaddr;
\r
787 uint32_t buffercounter;
\r
788 uint32_t inputcounter;
\r
790 /* Process Locked */
\r
793 if(hhash->HashITCounter == 0)
\r
795 hhash->HashITCounter = 1;
\r
799 hhash->HashITCounter = 0;
\r
801 if(hhash->State == HAL_HASH_STATE_READY)
\r
803 /* Change the HASH state */
\r
804 hhash->State = HAL_HASH_STATE_BUSY;
\r
806 hhash->HashInCount = Size;
\r
807 hhash->pHashInBuffPtr = pInBuffer;
\r
808 hhash->pHashOutBuffPtr = pOutBuffer;
\r
810 /* Check if initialization phase has already been performed */
\r
811 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
813 /* Select the SHA1 mode */
\r
814 HASH->CR |= HASH_ALGOSELECTION_MD5;
\r
815 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
816 the message digest of a new message */
\r
817 HASH->CR |= HASH_CR_INIT;
\r
820 /* Set the phase */
\r
821 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
823 /* Process Unlocked */
\r
824 __HAL_UNLOCK(hhash);
\r
826 /* Enable Interrupts */
\r
827 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
\r
829 /* Return function status */
\r
832 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
\r
834 outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
\r
835 /* Read the Output block from the Output FIFO */
\r
836 *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
\r
838 *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
\r
840 *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
\r
842 *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
\r
844 if(hhash->HashInCount == 0)
\r
846 /* Disable Interrupts */
\r
848 /* Change the HASH state */
\r
849 hhash->State = HAL_HASH_STATE_READY;
\r
850 /* Call digest computation complete callback */
\r
851 HAL_HASH_DgstCpltCallback(hhash);
\r
854 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
\r
856 if(hhash->HashInCount > 64)
\r
858 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
859 /* Write the Input block in the Data IN register */
\r
860 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
\r
862 HASH->DIN = *(uint32_t*)inputaddr;
\r
865 if(hhash->HashITCounter == 0)
\r
867 HASH->DIN = *(uint32_t*)inputaddr;
\r
869 if(hhash->HashInCount >= 68)
\r
871 /* Decrement buffer counter */
\r
872 hhash->HashInCount -= 68;
\r
873 hhash->pHashInBuffPtr+= 68;
\r
877 hhash->HashInCount -= 64;
\r
882 /* Decrement buffer counter */
\r
883 hhash->HashInCount -= 64;
\r
884 hhash->pHashInBuffPtr+= 64;
\r
889 /* Get the buffer address */
\r
890 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
891 /* Get the buffer counter */
\r
892 inputcounter = hhash->HashInCount;
\r
893 /* Disable Interrupts */
\r
894 HASH->IMR &= ~(HASH_IT_DINI);
\r
895 /* Configure the number of valid bits in last word of the message */
\r
896 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
\r
898 if((inputcounter > 4) && (inputcounter%4))
\r
900 inputcounter = (inputcounter+4-inputcounter%4);
\r
903 /* Write the Input block in the Data IN register */
\r
904 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
\r
906 HASH->DIN = *(uint32_t*)inputaddr;
\r
909 /* Start the digest calculation */
\r
910 __HAL_HASH_START_DIGEST();
\r
911 /* Reset buffer counter */
\r
912 hhash->HashInCount = 0;
\r
914 /* Call Input data transfer complete callback */
\r
915 HAL_HASH_InCpltCallback(hhash);
\r
918 /* Process Unlocked */
\r
919 __HAL_UNLOCK(hhash);
\r
921 /* Return function status */
\r
926 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
\r
927 * The digest is available in pOutBuffer.
\r
928 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
929 * the configuration information for HASH module
\r
930 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
931 * @param Size: Length of the input buffer in bytes.
\r
932 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
933 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
934 * @retval HAL status
\r
936 HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
\r
938 uint32_t inputaddr;
\r
939 uint32_t outputaddr;
\r
940 uint32_t buffercounter;
\r
941 uint32_t inputcounter;
\r
943 /* Process Locked */
\r
946 if(hhash->HashITCounter == 0)
\r
948 hhash->HashITCounter = 1;
\r
952 hhash->HashITCounter = 0;
\r
954 if(hhash->State == HAL_HASH_STATE_READY)
\r
956 /* Change the HASH state */
\r
957 hhash->State = HAL_HASH_STATE_BUSY;
\r
959 hhash->HashInCount = Size;
\r
960 hhash->pHashInBuffPtr = pInBuffer;
\r
961 hhash->pHashOutBuffPtr = pOutBuffer;
\r
963 /* Check if initialization phase has already been performed */
\r
964 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
966 /* Select the SHA1 mode */
\r
967 HASH->CR |= HASH_ALGOSELECTION_SHA1;
\r
968 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
969 the message digest of a new message */
\r
970 HASH->CR |= HASH_CR_INIT;
\r
973 /* Set the phase */
\r
974 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
976 /* Process Unlocked */
\r
977 __HAL_UNLOCK(hhash);
\r
979 /* Enable Interrupts */
\r
980 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
\r
982 /* Return function status */
\r
985 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
\r
987 outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
\r
988 /* Read the Output block from the Output FIFO */
\r
989 *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
\r
991 *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
\r
993 *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
\r
995 *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
\r
997 *(uint32_t*)(outputaddr) = __REV(HASH->HR[4]);
\r
998 if(hhash->HashInCount == 0)
\r
1000 /* Disable Interrupts */
\r
1002 /* Change the HASH state */
\r
1003 hhash->State = HAL_HASH_STATE_READY;
\r
1004 /* Call digest computation complete callback */
\r
1005 HAL_HASH_DgstCpltCallback(hhash);
\r
1008 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
\r
1010 if(hhash->HashInCount > 64)
\r
1012 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
1013 /* Write the Input block in the Data IN register */
\r
1014 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
\r
1016 HASH->DIN = *(uint32_t*)inputaddr;
\r
1019 if(hhash->HashITCounter == 0)
\r
1021 HASH->DIN = *(uint32_t*)inputaddr;
\r
1023 if(hhash->HashInCount >= 68)
\r
1025 /* Decrement buffer counter */
\r
1026 hhash->HashInCount -= 68;
\r
1027 hhash->pHashInBuffPtr+= 68;
\r
1031 hhash->HashInCount -= 64;
\r
1036 /* Decrement buffer counter */
\r
1037 hhash->HashInCount -= 64;
\r
1038 hhash->pHashInBuffPtr+= 64;
\r
1043 /* Get the buffer address */
\r
1044 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
1045 /* Get the buffer counter */
\r
1046 inputcounter = hhash->HashInCount;
\r
1047 /* Disable Interrupts */
\r
1048 HASH->IMR &= ~(HASH_IT_DINI);
\r
1049 /* Configure the number of valid bits in last word of the message */
\r
1050 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
\r
1052 if((inputcounter > 4) && (inputcounter%4))
\r
1054 inputcounter = (inputcounter+4-inputcounter%4);
\r
1057 /* Write the Input block in the Data IN register */
\r
1058 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
\r
1060 HASH->DIN = *(uint32_t*)inputaddr;
\r
1063 /* Start the digest calculation */
\r
1064 __HAL_HASH_START_DIGEST();
\r
1065 /* Reset buffer counter */
\r
1066 hhash->HashInCount = 0;
\r
1068 /* Call Input data transfer complete callback */
\r
1069 HAL_HASH_InCpltCallback(hhash);
\r
1072 /* Process Unlocked */
\r
1073 __HAL_UNLOCK(hhash);
\r
1075 /* Return function status */
\r
1080 * @brief This function handles HASH interrupt request.
\r
1081 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1082 * the configuration information for HASH module
\r
1085 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
\r
1087 switch(HASH->CR & HASH_CR_ALGO)
\r
1089 case HASH_ALGOSELECTION_MD5:
\r
1090 HAL_HASH_MD5_Start_IT(hhash, NULL, 0, NULL);
\r
1093 case HASH_ALGOSELECTION_SHA1:
\r
1094 HAL_HASH_SHA1_Start_IT(hhash, NULL, 0, NULL);
\r
1106 /** @defgroup HASH_Exported_Functions_Group4 HASH processing functions using DMA mode
\r
1107 * @brief processing functions using DMA mode.
\r
1110 ===============================================================================
\r
1111 ##### HASH processing using DMA mode functions #####
\r
1112 ===============================================================================
\r
1113 [..] This section provides functions allowing to calculate in DMA mode
\r
1114 the hash value using one of the following algorithms:
\r
1123 * @brief Initializes the HASH peripheral in MD5 mode then enables DMA to
\r
1124 control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
\r
1125 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1126 * the configuration information for HASH module
\r
1127 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1128 * @param Size: Length of the input buffer in bytes.
\r
1129 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1130 * @retval HAL status
\r
1132 HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1134 uint32_t inputaddr = (uint32_t)pInBuffer;
\r
1136 /* Process Locked */
\r
1137 __HAL_LOCK(hhash);
\r
1139 /* Change the HASH state */
\r
1140 hhash->State = HAL_HASH_STATE_BUSY;
\r
1142 /* Check if initialization phase has already been performed */
\r
1143 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1145 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
1146 the message digest of a new message */
\r
1147 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
\r
1150 /* Configure the number of valid bits in last word of the message */
\r
1151 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
1153 /* Set the phase */
\r
1154 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1156 /* Set the HASH DMA transfer complete callback */
\r
1157 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
\r
1158 /* Set the DMA error callback */
\r
1159 hhash->hdmain->XferErrorCallback = HASH_DMAError;
\r
1161 /* Enable the DMA In DMA Stream */
\r
1162 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
\r
1164 /* Enable DMA requests */
\r
1165 HASH->CR |= (HASH_CR_DMAE);
\r
1167 /* Process Unlocked */
\r
1168 __HAL_UNLOCK(hhash);
\r
1170 /* Return function status */
\r
1175 * @brief Returns the computed digest in MD5 mode
\r
1176 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1177 * the configuration information for HASH module
\r
1178 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
\r
1179 * @param Timeout: Timeout value
\r
1180 * @retval HAL status
\r
1182 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
\r
1184 uint32_t tickstart = 0;
\r
1186 /* Process Locked */
\r
1187 __HAL_LOCK(hhash);
\r
1189 /* Change HASH peripheral state */
\r
1190 hhash->State = HAL_HASH_STATE_BUSY;
\r
1193 tickstart = HAL_GetTick();
\r
1195 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
\r
1197 /* Check for the Timeout */
\r
1198 if(Timeout != HAL_MAX_DELAY)
\r
1200 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1202 /* Change state */
\r
1203 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1205 /* Process Unlocked */
\r
1206 __HAL_UNLOCK(hhash);
\r
1208 return HAL_TIMEOUT;
\r
1213 /* Read the message digest */
\r
1214 HASH_GetDigest(pOutBuffer, 16);
\r
1216 /* Change HASH peripheral state */
\r
1217 hhash->State = HAL_HASH_STATE_READY;
\r
1219 /* Process Unlocked */
\r
1220 __HAL_UNLOCK(hhash);
\r
1222 /* Return function status */
\r
1227 * @brief Initializes the HASH peripheral in SHA1 mode then enables DMA to
\r
1228 control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
\r
1229 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1230 * the configuration information for HASH module
\r
1231 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1232 * @param Size: Length of the input buffer in bytes.
\r
1233 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1234 * @retval HAL status
\r
1236 HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1238 uint32_t inputaddr = (uint32_t)pInBuffer;
\r
1240 /* Process Locked */
\r
1241 __HAL_LOCK(hhash);
\r
1243 /* Change the HASH state */
\r
1244 hhash->State = HAL_HASH_STATE_BUSY;
\r
1246 /* Check if initialization phase has already been performed */
\r
1247 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1249 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
1250 the message digest of a new message */
\r
1251 HASH->CR |= HASH_ALGOSELECTION_SHA1;
\r
1252 HASH->CR |= HASH_CR_INIT;
\r
1255 /* Configure the number of valid bits in last word of the message */
\r
1256 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
1258 /* Set the phase */
\r
1259 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1261 /* Set the HASH DMA transfer complete callback */
\r
1262 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
\r
1263 /* Set the DMA error callback */
\r
1264 hhash->hdmain->XferErrorCallback = HASH_DMAError;
\r
1266 /* Enable the DMA In DMA Stream */
\r
1267 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
\r
1269 /* Enable DMA requests */
\r
1270 HASH->CR |= (HASH_CR_DMAE);
\r
1272 /* Process Unlocked */
\r
1273 __HAL_UNLOCK(hhash);
\r
1275 /* Return function status */
\r
1280 * @brief Returns the computed digest in SHA1 mode.
\r
1281 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1282 * the configuration information for HASH module
\r
1283 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
1284 * @param Timeout: Timeout value
\r
1285 * @retval HAL status
\r
1287 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
\r
1289 uint32_t tickstart = 0;
\r
1291 /* Process Locked */
\r
1292 __HAL_LOCK(hhash);
\r
1294 /* Change HASH peripheral state */
\r
1295 hhash->State = HAL_HASH_STATE_BUSY;
\r
1298 tickstart = HAL_GetTick();
\r
1299 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
\r
1301 /* Check for the Timeout */
\r
1302 if(Timeout != HAL_MAX_DELAY)
\r
1304 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1306 /* Change state */
\r
1307 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1309 /* Process Unlocked */
\r
1310 __HAL_UNLOCK(hhash);
\r
1312 return HAL_TIMEOUT;
\r
1317 /* Read the message digest */
\r
1318 HASH_GetDigest(pOutBuffer, 20);
\r
1320 /* Change HASH peripheral state */
\r
1321 hhash->State = HAL_HASH_STATE_READY;
\r
1323 /* Process UnLock */
\r
1324 __HAL_UNLOCK(hhash);
\r
1326 /* Return function status */
\r
1335 /** @defgroup HASH_Exported_Functions_Group5 HASH-MAC (HMAC) processing functions using polling mode
\r
1336 * @brief HMAC processing functions using polling mode .
\r
1339 ===============================================================================
\r
1340 ##### HMAC processing using polling mode functions #####
\r
1341 ===============================================================================
\r
1342 [..] This section provides functions allowing to calculate in polling mode
\r
1343 the HMAC value using one of the following algorithms:
\r
1352 * @brief Initializes the HASH peripheral in HMAC MD5 mode
\r
1353 * then processes pInBuffer. The digest is available in pOutBuffer
\r
1354 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1355 * the configuration information for HASH module
\r
1356 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1357 * @param Size: Length of the input buffer in bytes.
\r
1358 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1359 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
1360 * @param Timeout: Timeout value
\r
1361 * @retval HAL status
\r
1363 HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
1365 uint32_t tickstart = 0;
\r
1367 /* Process Locked */
\r
1368 __HAL_LOCK(hhash);
\r
1370 /* Change the HASH state */
\r
1371 hhash->State = HAL_HASH_STATE_BUSY;
\r
1373 /* Check if initialization phase has already been performed */
\r
1374 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1376 /* Check if key size is greater than 64 bytes */
\r
1377 if(hhash->Init.KeySize > 64)
\r
1379 /* Select the HMAC MD5 mode */
\r
1380 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
\r
1384 /* Select the HMAC MD5 mode */
\r
1385 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
\r
1389 /* Set the phase */
\r
1390 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1392 /************************** STEP 1 ******************************************/
\r
1393 /* Configure the number of valid bits in last word of the message */
\r
1394 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1396 /* Write input buffer in data register */
\r
1397 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
1399 /* Start the digest calculation */
\r
1400 __HAL_HASH_START_DIGEST();
\r
1403 tickstart = HAL_GetTick();
\r
1405 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
\r
1407 /* Check for the Timeout */
\r
1408 if(Timeout != HAL_MAX_DELAY)
\r
1410 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1412 /* Change state */
\r
1413 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1415 /* Process Unlocked */
\r
1416 __HAL_UNLOCK(hhash);
\r
1418 return HAL_TIMEOUT;
\r
1422 /************************** STEP 2 ******************************************/
\r
1423 /* Configure the number of valid bits in last word of the message */
\r
1424 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
1426 /* Write input buffer in data register */
\r
1427 HASH_WriteData(pInBuffer, Size);
\r
1429 /* Start the digest calculation */
\r
1430 __HAL_HASH_START_DIGEST();
\r
1433 tickstart = HAL_GetTick();
\r
1435 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
\r
1437 /* Check for the Timeout */
\r
1438 if(Timeout != HAL_MAX_DELAY)
\r
1440 if((HAL_GetTick() - tickstart ) > Timeout)
\r
1442 /* Change state */
\r
1443 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1445 /* Process Unlocked */
\r
1446 __HAL_UNLOCK(hhash);
\r
1448 return HAL_TIMEOUT;
\r
1452 /************************** STEP 3 ******************************************/
\r
1453 /* Configure the number of valid bits in last word of the message */
\r
1454 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1456 /* Write input buffer in data register */
\r
1457 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
1459 /* Start the digest calculation */
\r
1460 __HAL_HASH_START_DIGEST();
\r
1463 tickstart = HAL_GetTick();
\r
1465 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
\r
1467 /* Check for the Timeout */
\r
1468 if(Timeout != HAL_MAX_DELAY)
\r
1470 if((HAL_GetTick() - tickstart ) > Timeout)
\r
1472 /* Change state */
\r
1473 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1475 /* Process Unlocked */
\r
1476 __HAL_UNLOCK(hhash);
\r
1478 return HAL_TIMEOUT;
\r
1483 /* Read the message digest */
\r
1484 HASH_GetDigest(pOutBuffer, 16);
\r
1486 /* Change the HASH state */
\r
1487 hhash->State = HAL_HASH_STATE_READY;
\r
1489 /* Process Unlocked */
\r
1490 __HAL_UNLOCK(hhash);
\r
1492 /* Return function status */
\r
1497 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
\r
1498 * then processes pInBuffer. The digest is available in pOutBuffer.
\r
1499 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1500 * the configuration information for HASH module
\r
1501 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1502 * @param Size: Length of the input buffer in bytes.
\r
1503 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1504 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
1505 * @param Timeout: Timeout value
\r
1506 * @retval HAL status
\r
1508 HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
1510 uint32_t tickstart = 0;
\r
1512 /* Process Locked */
\r
1513 __HAL_LOCK(hhash);
\r
1515 /* Change the HASH state */
\r
1516 hhash->State = HAL_HASH_STATE_BUSY;
\r
1518 /* Check if initialization phase has already been performed */
\r
1519 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1521 /* Check if key size is greater than 64 bytes */
\r
1522 if(hhash->Init.KeySize > 64)
\r
1524 /* Select the HMAC SHA1 mode */
\r
1525 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
\r
1529 /* Select the HMAC SHA1 mode */
\r
1530 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
\r
1534 /* Set the phase */
\r
1535 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1537 /************************** STEP 1 ******************************************/
\r
1538 /* Configure the number of valid bits in last word of the message */
\r
1539 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1541 /* Write input buffer in data register */
\r
1542 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
1544 /* Start the digest calculation */
\r
1545 __HAL_HASH_START_DIGEST();
\r
1548 tickstart = HAL_GetTick();
\r
1550 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
\r
1552 /* Check for the Timeout */
\r
1553 if(Timeout != HAL_MAX_DELAY)
\r
1555 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1557 /* Change state */
\r
1558 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1560 /* Process Unlocked */
\r
1561 __HAL_UNLOCK(hhash);
\r
1563 return HAL_TIMEOUT;
\r
1567 /************************** STEP 2 ******************************************/
\r
1568 /* Configure the number of valid bits in last word of the message */
\r
1569 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
1571 /* Write input buffer in data register */
\r
1572 HASH_WriteData(pInBuffer, Size);
\r
1574 /* Start the digest calculation */
\r
1575 __HAL_HASH_START_DIGEST();
\r
1578 tickstart = HAL_GetTick();
\r
1580 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
\r
1582 /* Check for the Timeout */
\r
1583 if(Timeout != HAL_MAX_DELAY)
\r
1585 if((HAL_GetTick() - tickstart ) > Timeout)
\r
1587 /* Change state */
\r
1588 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1590 /* Process Unlocked */
\r
1591 __HAL_UNLOCK(hhash);
\r
1593 return HAL_TIMEOUT;
\r
1597 /************************** STEP 3 ******************************************/
\r
1598 /* Configure the number of valid bits in last word of the message */
\r
1599 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1601 /* Write input buffer in data register */
\r
1602 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
1604 /* Start the digest calculation */
\r
1605 __HAL_HASH_START_DIGEST();
\r
1608 tickstart = HAL_GetTick();
\r
1610 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
\r
1612 /* Check for the Timeout */
\r
1613 if(Timeout != HAL_MAX_DELAY)
\r
1615 if((HAL_GetTick() - tickstart ) > Timeout)
\r
1617 /* Change state */
\r
1618 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1620 /* Process Unlocked */
\r
1621 __HAL_UNLOCK(hhash);
\r
1623 return HAL_TIMEOUT;
\r
1627 /* Read the message digest */
\r
1628 HASH_GetDigest(pOutBuffer, 20);
\r
1630 /* Change the HASH state */
\r
1631 hhash->State = HAL_HASH_STATE_READY;
\r
1633 /* Process Unlocked */
\r
1634 __HAL_UNLOCK(hhash);
\r
1636 /* Return function status */
\r
1644 /** @defgroup HASH_Exported_Functions_Group6 HASH-MAC (HMAC) processing functions using DMA mode
\r
1645 * @brief HMAC processing functions using DMA mode .
\r
1648 ===============================================================================
\r
1649 ##### HMAC processing using DMA mode functions #####
\r
1650 ===============================================================================
\r
1651 [..] This section provides functions allowing to calculate in DMA mode
\r
1652 the HMAC value using one of the following algorithms:
\r
1661 * @brief Initializes the HASH peripheral in HMAC MD5 mode
\r
1662 * then enables DMA to control data transfer.
\r
1663 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1664 * the configuration information for HASH module
\r
1665 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1666 * @param Size: Length of the input buffer in bytes.
\r
1667 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1668 * @retval HAL status
\r
1670 HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1672 uint32_t inputaddr = 0;
\r
1674 /* Process Locked */
\r
1675 __HAL_LOCK(hhash);
\r
1677 /* Change the HASH state */
\r
1678 hhash->State = HAL_HASH_STATE_BUSY;
\r
1680 /* Save buffer pointer and size in handle */
\r
1681 hhash->pHashInBuffPtr = pInBuffer;
\r
1682 hhash->HashBuffSize = Size;
\r
1683 hhash->HashInCount = 0;
\r
1685 /* Check if initialization phase has already been performed */
\r
1686 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1688 /* Check if key size is greater than 64 bytes */
\r
1689 if(hhash->Init.KeySize > 64)
\r
1691 /* Select the HMAC MD5 mode */
\r
1692 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
\r
1696 /* Select the HMAC MD5 mode */
\r
1697 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
\r
1701 /* Set the phase */
\r
1702 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1704 /* Configure the number of valid bits in last word of the message */
\r
1705 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1707 /* Get the key address */
\r
1708 inputaddr = (uint32_t)(hhash->Init.pKey);
\r
1710 /* Set the HASH DMA transfer complete callback */
\r
1711 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
\r
1712 /* Set the DMA error callback */
\r
1713 hhash->hdmain->XferErrorCallback = HASH_DMAError;
\r
1715 /* Enable the DMA In DMA Stream */
\r
1716 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
1717 /* Enable DMA requests */
\r
1718 HASH->CR |= (HASH_CR_DMAE);
\r
1720 /* Process Unlocked */
\r
1721 __HAL_UNLOCK(hhash);
\r
1723 /* Return function status */
\r
1728 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
\r
1729 * then enables DMA to control data transfer.
\r
1730 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1731 * the configuration information for HASH module
\r
1732 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1733 * @param Size: Length of the input buffer in bytes.
\r
1734 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1735 * @retval HAL status
\r
1737 HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1739 uint32_t inputaddr = 0;
\r
1741 /* Process Locked */
\r
1742 __HAL_LOCK(hhash);
\r
1744 /* Change the HASH state */
\r
1745 hhash->State = HAL_HASH_STATE_BUSY;
\r
1747 /* Save buffer pointer and size in handle */
\r
1748 hhash->pHashInBuffPtr = pInBuffer;
\r
1749 hhash->HashBuffSize = Size;
\r
1750 hhash->HashInCount = 0;
\r
1752 /* Check if initialization phase has already been performed */
\r
1753 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1755 /* Check if key size is greater than 64 bytes */
\r
1756 if(hhash->Init.KeySize > 64)
\r
1758 /* Select the HMAC SHA1 mode */
\r
1759 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
\r
1763 /* Select the HMAC SHA1 mode */
\r
1764 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
\r
1768 /* Set the phase */
\r
1769 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1771 /* Configure the number of valid bits in last word of the message */
\r
1772 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1774 /* Get the key address */
\r
1775 inputaddr = (uint32_t)(hhash->Init.pKey);
\r
1777 /* Set the HASH DMA transfer complete callback */
\r
1778 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
\r
1779 /* Set the DMA error callback */
\r
1780 hhash->hdmain->XferErrorCallback = HASH_DMAError;
\r
1782 /* Enable the DMA In DMA Stream */
\r
1783 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
1784 /* Enable DMA requests */
\r
1785 HASH->CR |= (HASH_CR_DMAE);
\r
1787 /* Process Unlocked */
\r
1788 __HAL_UNLOCK(hhash);
\r
1790 /* Return function status */
\r
1798 /** @defgroup HASH_Exported_Functions_Group7 Peripheral State functions
\r
1799 * @brief Peripheral State functions.
\r
1802 ===============================================================================
\r
1803 ##### Peripheral State functions #####
\r
1804 ===============================================================================
\r
1806 This subsection permits to get in run-time the status of the peripheral.
\r
1813 * @brief return the HASH state
\r
1814 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1815 * the configuration information for HASH module
\r
1816 * @retval HAL state
\r
1818 HAL_HASH_STATETypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
\r
1820 return hhash->State;
\r
1831 #endif /* STM32F756xx */
\r
1832 #endif /* HAL_HASH_MODULE_ENABLED */
\r
1841 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r