Merge pull request #10558 from iNavFlight/MrD_Correct-comments-on-OSD-symbols
[inav.git] / lib / main / STM32F7 / Drivers / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_hash.c
blobbdebab80403697d80d8715aa9d06059cba775318
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_hash.c
4 * @author MCD Application Team
5 * @version V1.2.2
6 * @date 14-April-2017
7 * @brief HASH HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the HASH peripheral:
10 * + Initialization and de-initialization functions
11 * + HASH/HMAC Processing functions by algorithm using polling mode
12 * + HASH/HMAC functions by algorithm using interrupt mode
13 * + HASH/HMAC functions by algorithm using DMA mode
14 * + Peripheral State functions
16 @verbatim
17 ==============================================================================
18 ##### How to use this driver #####
19 ==============================================================================
20 [..]
21 The HASH HAL driver can be used as follows:
22 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
23 (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
24 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMAC_SHA1_Start_IT())
25 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
26 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
27 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
28 (##) In case of using DMA to control data transfer (e.g. HAL_HMAC_SHA1_Start_DMA())
29 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
30 (+++) Configure and enable one DMA stream one for managing data transfer from
31 memory to peripheral (input stream). Managing data transfer from
32 peripheral to memory can be performed only using CPU
33 (+++) Associate the initialized DMA handle to the HASH DMA handle
34 using __HAL_LINKDMA()
35 (+++) Configure the priority and enable the NVIC for the transfer complete
36 interrupt on the DMA Stream using HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
37 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
38 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
39 (##) For HMAC, the encryption key.
40 (##) For HMAC, the key size used for encryption.
41 (#)Three processing functions are available:
42 (##) Polling mode: processing APIs are blocking functions
43 i.e. they process the data and wait till the digest computation is finished
44 e.g. HAL_HASH_SHA1_Start()
45 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
46 i.e. they process the data under interrupt
47 e.g. HAL_HASH_SHA1_Start_IT()
48 (##) DMA mode: processing APIs are not blocking functions and the CPU is
49 not used for data transfer i.e. the data transfer is ensured by DMA
50 e.g. HAL_HASH_SHA1_Start_DMA()
51 (#)When the processing function is called at first time after HAL_HASH_Init()
52 the HASH peripheral is initialized and processes the buffer in input.
53 After that, the digest computation is started.
54 When processing multi-buffer use the accumulate function to write the
55 data in the peripheral without starting the digest computation. In last
56 buffer use the start function to input the last buffer ans start the digest
57 computation.
58 (##) e.g. HAL_HASH_SHA1_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
59 (##) write (n-1)th data buffer in the peripheral without starting the digest computation
60 (##) HAL_HASH_SHA1_Start() : write (n)th data buffer in the peripheral and start the digest computation
61 (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
62 (#)In case of using DMA, call the DMA start processing e.g. HAL_HASH_SHA1_Start_DMA().
63 After that, call the finish function in order to get the digest value
64 e.g. HAL_HASH_SHA1_Finish()
65 (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
67 @endverbatim
68 ******************************************************************************
69 * @attention
71 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
73 * Redistribution and use in source and binary forms, with or without modification,
74 * are permitted provided that the following conditions are met:
75 * 1. Redistributions of source code must retain the above copyright notice,
76 * this list of conditions and the following disclaimer.
77 * 2. Redistributions in binary form must reproduce the above copyright notice,
78 * this list of conditions and the following disclaimer in the documentation
79 * and/or other materials provided with the distribution.
80 * 3. Neither the name of STMicroelectronics nor the names of its contributors
81 * may be used to endorse or promote products derived from this software
82 * without specific prior written permission.
84 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
85 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
86 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
88 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
89 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
90 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
91 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
92 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
93 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95 ******************************************************************************
96 */
98 /* Includes ------------------------------------------------------------------*/
99 #include "stm32f7xx_hal.h"
101 /** @addtogroup STM32F7xx_HAL_Driver
102 * @{
105 #if defined (STM32F756xx) || defined (STM32F777xx) || defined (STM32F779xx)
107 /** @defgroup HASH HASH
108 * @brief HASH HAL module driver.
109 * @{
111 #ifdef HAL_HASH_MODULE_ENABLED
113 /* Private typedef -----------------------------------------------------------*/
114 /* Private define ------------------------------------------------------------*/
115 /* Private macro -------------------------------------------------------------*/
116 /* Private variables ---------------------------------------------------------*/
117 /* Private function prototypes -----------------------------------------------*/
118 /** @defgroup HASH_Private_Functions HASH Private Functions
119 * @{
121 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
122 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
123 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
124 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size);
126 * @}
129 /* Private functions ---------------------------------------------------------*/
130 /** @addtogroup HASH_Private_Functions
131 * @{
135 * @brief DMA HASH Input Data complete callback.
136 * @param hdma: DMA handle
137 * @retval None
139 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
141 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
142 uint32_t inputaddr = 0;
143 uint32_t buffersize = 0;
145 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
147 /* Disable the DMA transfer */
148 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
150 /* Change HASH peripheral state */
151 hhash->State = HAL_HASH_STATE_READY;
153 /* Call Input data transfer complete callback */
154 HAL_HASH_InCpltCallback(hhash);
156 else
158 /* Increment Interrupt counter */
159 hhash->HashInCount++;
160 /* Disable the DMA transfer before starting the next transfer */
161 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
163 if(hhash->HashInCount <= 2)
165 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
166 if(hhash->HashInCount == 1)
168 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
169 buffersize = hhash->HashBuffSize;
171 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
172 else if(hhash->HashInCount == 2)
174 inputaddr = (uint32_t)hhash->Init.pKey;
175 buffersize = hhash->Init.KeySize;
177 /* Configure the number of valid bits in last word of the message */
178 MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8 * (buffersize % 4));
180 /* Set the HASH DMA transfer complete */
181 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
183 /* Enable the DMA In DMA Stream */
184 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
186 /* Enable DMA requests */
187 HASH->CR |= (HASH_CR_DMAE);
189 else
191 /* Disable the DMA transfer */
192 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
194 /* Reset the InCount */
195 hhash->HashInCount = 0;
197 /* Change HASH peripheral state */
198 hhash->State = HAL_HASH_STATE_READY;
200 /* Call Input data transfer complete callback */
201 HAL_HASH_InCpltCallback(hhash);
207 * @brief DMA HASH communication error callback.
208 * @param hdma: DMA handle
209 * @retval None
211 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
213 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
214 hhash->State= HAL_HASH_STATE_READY;
215 HAL_HASH_ErrorCallback(hhash);
219 * @brief Writes the input buffer in data register.
220 * @param pInBuffer: Pointer to input buffer
221 * @param Size: The size of input buffer
222 * @retval None
224 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
226 uint32_t buffercounter;
227 uint32_t inputaddr = (uint32_t) pInBuffer;
229 for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
231 HASH->DIN = *(uint32_t*)inputaddr;
232 inputaddr+=4;
237 * @brief Provides the message digest result.
238 * @param pMsgDigest: Pointer to the message digest
239 * @param Size: The size of the message digest in bytes
240 * @retval None
242 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
244 uint32_t msgdigest = (uint32_t)pMsgDigest;
246 switch(Size)
248 case 16:
249 /* Read the message digest */
250 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
251 msgdigest+=4;
252 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
253 msgdigest+=4;
254 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
255 msgdigest+=4;
256 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
257 break;
258 case 20:
259 /* Read the message digest */
260 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
261 msgdigest+=4;
262 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
263 msgdigest+=4;
264 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
265 msgdigest+=4;
266 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
267 msgdigest+=4;
268 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
269 break;
270 case 28:
271 /* Read the message digest */
272 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
273 msgdigest+=4;
274 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
275 msgdigest+=4;
276 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
277 msgdigest+=4;
278 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
279 msgdigest+=4;
280 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
281 msgdigest+=4;
282 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
283 msgdigest+=4;
284 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
285 break;
286 case 32:
287 /* Read the message digest */
288 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
289 msgdigest+=4;
290 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
291 msgdigest+=4;
292 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
293 msgdigest+=4;
294 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
295 msgdigest+=4;
296 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
297 msgdigest+=4;
298 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
299 msgdigest+=4;
300 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
301 msgdigest+=4;
302 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
303 break;
304 default:
305 break;
310 * @}
313 /* Exported functions --------------------------------------------------------*/
314 /** @addtogroup HASH_Exported_Functions
315 * @{
319 /** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions
320 * @brief Initialization and Configuration functions.
322 @verbatim
323 ===============================================================================
324 ##### Initialization and de-initialization functions #####
325 ===============================================================================
326 [..] This section provides functions allowing to:
327 (+) Initialize the HASH according to the specified parameters
328 in the HASH_InitTypeDef and creates the associated handle.
329 (+) DeInitialize the HASH peripheral.
330 (+) Initialize the HASH MSP.
331 (+) DeInitialize HASH MSP.
333 @endverbatim
334 * @{
338 * @brief Initializes the HASH according to the specified parameters in the
339 HASH_HandleTypeDef and creates the associated handle.
340 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
341 * the configuration information for HASH module
342 * @retval HAL status
344 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
346 /* Check the hash handle allocation */
347 if(hhash == NULL)
349 return HAL_ERROR;
352 /* Check the parameters */
353 assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
355 if(hhash->State == HAL_HASH_STATE_RESET)
357 /* Allocate lock resource and initialize it */
358 hhash->Lock = HAL_UNLOCKED;
359 /* Init the low level hardware */
360 HAL_HASH_MspInit(hhash);
363 /* Change the HASH state */
364 hhash->State = HAL_HASH_STATE_BUSY;
366 /* Reset HashInCount, HashBuffSize and HashITCounter */
367 hhash->HashInCount = 0;
368 hhash->HashBuffSize = 0;
369 hhash->HashITCounter = 0;
371 /* Set the data type */
372 HASH->CR |= (uint32_t) (hhash->Init.DataType);
374 /* Change the HASH state */
375 hhash->State = HAL_HASH_STATE_READY;
377 /* Set the default HASH phase */
378 hhash->Phase = HAL_HASH_PHASE_READY;
380 /* Return function status */
381 return HAL_OK;
385 * @brief DeInitializes the HASH peripheral.
386 * @note This API must be called before starting a new processing.
387 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
388 * the configuration information for HASH module
389 * @retval HAL status
391 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
393 /* Check the HASH handle allocation */
394 if(hhash == NULL)
396 return HAL_ERROR;
399 /* Change the HASH state */
400 hhash->State = HAL_HASH_STATE_BUSY;
402 /* Set the default HASH phase */
403 hhash->Phase = HAL_HASH_PHASE_READY;
405 /* Reset HashInCount, HashBuffSize and HashITCounter */
406 hhash->HashInCount = 0;
407 hhash->HashBuffSize = 0;
408 hhash->HashITCounter = 0;
410 /* DeInit the low level hardware */
411 HAL_HASH_MspDeInit(hhash);
413 /* Change the HASH state */
414 hhash->State = HAL_HASH_STATE_RESET;
416 /* Release Lock */
417 __HAL_UNLOCK(hhash);
419 /* Return function status */
420 return HAL_OK;
424 * @brief Initializes the HASH MSP.
425 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
426 * the configuration information for HASH module
427 * @retval None
429 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
431 /* Prevent unused argument(s) compilation warning */
432 UNUSED(hhash);
434 /* NOTE: This function Should not be modified, when the callback is needed,
435 the HAL_HASH_MspInit could be implemented in the user file
440 * @brief DeInitializes HASH MSP.
441 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
442 * the configuration information for HASH module
443 * @retval None
445 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
447 /* Prevent unused argument(s) compilation warning */
448 UNUSED(hhash);
450 /* NOTE: This function Should not be modified, when the callback is needed,
451 the HAL_HASH_MspDeInit could be implemented in the user file
456 * @brief Input data transfer complete callback.
457 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
458 * the configuration information for HASH module
459 * @retval None
461 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
463 /* Prevent unused argument(s) compilation warning */
464 UNUSED(hhash);
466 /* NOTE: This function Should not be modified, when the callback is needed,
467 the HAL_HASH_InCpltCallback could be implemented in the user file
472 * @brief Data transfer Error callback.
473 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
474 * the configuration information for HASH module
475 * @retval None
477 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
479 /* Prevent unused argument(s) compilation warning */
480 UNUSED(hhash);
482 /* NOTE: This function Should not be modified, when the callback is needed,
483 the HAL_HASH_ErrorCallback could be implemented in the user file
488 * @brief Digest computation complete callback. It is used only with interrupt.
489 * @note This callback is not relevant with DMA.
490 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
491 * the configuration information for HASH module
492 * @retval None
494 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
496 /* Prevent unused argument(s) compilation warning */
497 UNUSED(hhash);
499 /* NOTE: This function Should not be modified, when the callback is needed,
500 the HAL_HASH_DgstCpltCallback could be implemented in the user file
505 * @}
508 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions using polling mode
509 * @brief processing functions using polling mode
511 @verbatim
512 ===============================================================================
513 ##### HASH processing using polling mode functions#####
514 ===============================================================================
515 [..] This section provides functions allowing to calculate in polling mode
516 the hash value using one of the following algorithms:
517 (+) MD5
518 (+) SHA1
520 @endverbatim
521 * @{
525 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
526 The digest is available in pOutBuffer.
527 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
528 * the configuration information for HASH module
529 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
530 * @param Size: Length of the input buffer in bytes.
531 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
532 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
533 * and appending the input buffer is no more possible.
534 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
535 * @param Timeout: Timeout value
536 * @retval HAL status
538 HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
540 uint32_t tickstart = 0;
542 /* Process Locked */
543 __HAL_LOCK(hhash);
545 /* Change the HASH state */
546 hhash->State = HAL_HASH_STATE_BUSY;
548 /* Check if initialization phase has already been performed */
549 if(hhash->Phase == HAL_HASH_PHASE_READY)
551 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
552 the message digest of a new message */
553 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
556 /* Set the phase */
557 hhash->Phase = HAL_HASH_PHASE_PROCESS;
559 /* Configure the number of valid bits in last word of the message */
560 __HAL_HASH_SET_NBVALIDBITS(Size);
562 /* Write input buffer in data register */
563 HASH_WriteData(pInBuffer, Size);
565 /* Start the digest calculation */
566 __HAL_HASH_START_DIGEST();
568 /* Get tick */
569 tickstart = HAL_GetTick();
571 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
573 /* Check for the Timeout */
574 if(Timeout != HAL_MAX_DELAY)
576 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
578 /* Change state */
579 hhash->State = HAL_HASH_STATE_TIMEOUT;
581 /* Process Unlocked */
582 __HAL_UNLOCK(hhash);
584 return HAL_TIMEOUT;
589 /* Read the message digest */
590 HASH_GetDigest(pOutBuffer, 16);
592 /* Change the HASH state */
593 hhash->State = HAL_HASH_STATE_READY;
595 /* Process Unlocked */
596 __HAL_UNLOCK(hhash);
598 /* Return function status */
599 return HAL_OK;
603 * @brief Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
604 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
605 * the configuration information for HASH module
606 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
607 * @param Size: Length of the input buffer in bytes.
608 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
609 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
610 * and appending the input buffer is no more possible.
611 * @retval HAL status
613 HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
615 /* Process Locked */
616 __HAL_LOCK(hhash);
618 /* Change the HASH state */
619 hhash->State = HAL_HASH_STATE_BUSY;
621 /* Check if initialization phase has already been performed */
622 if(hhash->Phase == HAL_HASH_PHASE_READY)
624 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
625 the message digest of a new message */
626 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
629 /* Set the phase */
630 hhash->Phase = HAL_HASH_PHASE_PROCESS;
632 /* Configure the number of valid bits in last word of the message */
633 __HAL_HASH_SET_NBVALIDBITS(Size);
635 /* Write input buffer in data register */
636 HASH_WriteData(pInBuffer, Size);
638 /* Change the HASH state */
639 hhash->State = HAL_HASH_STATE_READY;
641 /* Process Unlocked */
642 __HAL_UNLOCK(hhash);
644 /* Return function status */
645 return HAL_OK;
649 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
650 The digest is available in pOutBuffer.
651 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
652 * the configuration information for HASH module
653 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
654 * @param Size: Length of the input buffer in bytes.
655 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
656 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
657 * @param Timeout: Timeout value
658 * @retval HAL status
660 HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
662 uint32_t tickstart = 0;
664 /* Process Locked */
665 __HAL_LOCK(hhash);
667 /* Change the HASH state */
668 hhash->State = HAL_HASH_STATE_BUSY;
670 /* Check if initialization phase has already been performed */
671 if(hhash->Phase == HAL_HASH_PHASE_READY)
673 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
674 the message digest of a new message */
675 HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
678 /* Set the phase */
679 hhash->Phase = HAL_HASH_PHASE_PROCESS;
681 /* Configure the number of valid bits in last word of the message */
682 __HAL_HASH_SET_NBVALIDBITS(Size);
684 /* Write input buffer in data register */
685 HASH_WriteData(pInBuffer, Size);
687 /* Start the digest calculation */
688 __HAL_HASH_START_DIGEST();
690 /* Get tick */
691 tickstart = HAL_GetTick();
693 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
695 /* Check for the Timeout */
696 if(Timeout != HAL_MAX_DELAY)
698 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
700 /* Change state */
701 hhash->State = HAL_HASH_STATE_TIMEOUT;
703 /* Process Unlocked */
704 __HAL_UNLOCK(hhash);
706 return HAL_TIMEOUT;
711 /* Read the message digest */
712 HASH_GetDigest(pOutBuffer, 20);
714 /* Change the HASH state */
715 hhash->State = HAL_HASH_STATE_READY;
717 /* Process Unlocked */
718 __HAL_UNLOCK(hhash);
720 /* Return function status */
721 return HAL_OK;
725 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
726 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
727 * the configuration information for HASH module
728 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
729 * @param Size: Length of the input buffer in bytes.
730 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
731 * @note Input buffer size in bytes must be a multiple of 4 otherwise the digest computation is corrupted.
732 * @retval HAL status
734 HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
736 /* Check the parameters */
737 assert_param(IS_HASH_SHA1_BUFFER_SIZE(Size));
739 /* Process Locked */
740 __HAL_LOCK(hhash);
742 /* Change the HASH state */
743 hhash->State = HAL_HASH_STATE_BUSY;
745 /* Check if initialization phase has already been performed */
746 if(hhash->Phase == HAL_HASH_PHASE_READY)
748 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
749 the message digest of a new message */
750 HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
753 /* Set the phase */
754 hhash->Phase = HAL_HASH_PHASE_PROCESS;
756 /* Configure the number of valid bits in last word of the message */
757 __HAL_HASH_SET_NBVALIDBITS(Size);
759 /* Write input buffer in data register */
760 HASH_WriteData(pInBuffer, Size);
762 /* Change the HASH state */
763 hhash->State = HAL_HASH_STATE_READY;
765 /* Process Unlocked */
766 __HAL_UNLOCK(hhash);
768 /* Return function status */
769 return HAL_OK;
773 * @}
776 /** @defgroup HASH_Exported_Functions_Group3 HASH processing functions using interrupt mode
777 * @brief processing functions using interrupt mode.
779 @verbatim
780 ===============================================================================
781 ##### HASH processing using interrupt mode functions #####
782 ===============================================================================
783 [..] This section provides functions allowing to calculate in interrupt mode
784 the hash value using one of the following algorithms:
785 (+) MD5
786 (+) SHA1
788 @endverbatim
789 * @{
793 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
794 * The digest is available in pOutBuffer.
795 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
796 * the configuration information for HASH module
797 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
798 * @param Size: Length of the input buffer in bytes.
799 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
800 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
801 * @retval HAL status
803 HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
805 uint32_t inputaddr;
806 uint32_t outputaddr;
807 uint32_t buffercounter;
808 uint32_t inputcounter;
810 /* Process Locked */
811 __HAL_LOCK(hhash);
813 if(hhash->State == HAL_HASH_STATE_READY)
815 /* Change the HASH state */
816 hhash->State = HAL_HASH_STATE_BUSY;
818 hhash->HashInCount = Size;
819 hhash->pHashInBuffPtr = pInBuffer;
820 hhash->pHashOutBuffPtr = pOutBuffer;
822 /* Check if initialization phase has already been performed */
823 if(hhash->Phase == HAL_HASH_PHASE_READY)
825 /* Select the SHA1 mode */
826 HASH->CR |= HASH_ALGOSELECTION_MD5;
827 /* Reset the HASH processor core, so that the HASH will be ready to compute
828 the message digest of a new message */
829 HASH->CR |= HASH_CR_INIT;
832 /* Reset interrupt counter */
833 hhash->HashITCounter = 0;
835 /* Set the phase */
836 hhash->Phase = HAL_HASH_PHASE_PROCESS;
838 /* Process Unlocked */
839 __HAL_UNLOCK(hhash);
841 /* Enable Interrupts */
842 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
844 /* Return function status */
845 return HAL_OK;
847 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
849 outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
850 /* Read the Output block from the Output FIFO */
851 *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
852 outputaddr+=4;
853 *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
854 outputaddr+=4;
855 *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
856 outputaddr+=4;
857 *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
859 if(hhash->HashInCount == 0)
861 /* Disable Interrupts */
862 HASH->IMR = 0;
863 /* Change the HASH state */
864 hhash->State = HAL_HASH_STATE_READY;
865 /* Call digest computation complete callback */
866 HAL_HASH_DgstCpltCallback(hhash);
868 /* Process Unlocked */
869 __HAL_UNLOCK(hhash);
871 /* Return function status */
872 return HAL_OK;
876 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
878 if(hhash->HashInCount >= 68)
880 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
881 /* Write the Input block in the Data IN register */
882 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
884 HASH->DIN = *(uint32_t*)inputaddr;
885 inputaddr+=4;
887 if(hhash->HashITCounter == 0)
889 HASH->DIN = *(uint32_t*)inputaddr;
891 if(hhash->HashInCount >= 68)
893 /* Decrement buffer counter */
894 hhash->HashInCount -= 68;
895 hhash->pHashInBuffPtr+= 68;
897 else
899 hhash->HashInCount = 0;
900 hhash->pHashInBuffPtr+= hhash->HashInCount;
902 /* Set Interrupt counter */
903 hhash->HashITCounter = 1;
905 else
907 /* Decrement buffer counter */
908 hhash->HashInCount -= 64;
909 hhash->pHashInBuffPtr+= 64;
912 else
914 /* Get the buffer address */
915 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
916 /* Get the buffer counter */
917 inputcounter = hhash->HashInCount;
918 /* Disable Interrupts */
919 HASH->IMR &= ~(HASH_IT_DINI);
920 /* Configure the number of valid bits in last word of the message */
921 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
923 if((inputcounter > 4) && (inputcounter%4))
925 inputcounter = (inputcounter+4-inputcounter%4);
927 else if ((inputcounter < 4) && (inputcounter != 0))
929 inputcounter = 4;
932 /* Write the Input block in the Data IN register */
933 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
935 HASH->DIN = *(uint32_t*)inputaddr;
936 inputaddr+=4;
938 /* Start the digest calculation */
939 __HAL_HASH_START_DIGEST();
940 /* Reset buffer counter */
941 hhash->HashInCount = 0;
942 /* Call Input data transfer complete callback */
943 HAL_HASH_InCpltCallback(hhash);
947 /* Process Unlocked */
948 __HAL_UNLOCK(hhash);
950 /* Return function status */
951 return HAL_OK;
955 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
956 * The digest is available in pOutBuffer.
957 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
958 * the configuration information for HASH module
959 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
960 * @param Size: Length of the input buffer in bytes.
961 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
962 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
963 * @retval HAL status
965 HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
967 uint32_t inputaddr;
968 uint32_t outputaddr;
969 uint32_t buffercounter;
970 uint32_t inputcounter;
972 /* Process Locked */
973 __HAL_LOCK(hhash);
975 if(hhash->State == HAL_HASH_STATE_READY)
977 /* Change the HASH state */
978 hhash->State = HAL_HASH_STATE_BUSY;
980 hhash->HashInCount = Size;
981 hhash->pHashInBuffPtr = pInBuffer;
982 hhash->pHashOutBuffPtr = pOutBuffer;
984 /* Check if initialization phase has already been performed */
985 if(hhash->Phase == HAL_HASH_PHASE_READY)
987 /* Select the SHA1 mode */
988 HASH->CR |= HASH_ALGOSELECTION_SHA1;
989 /* Reset the HASH processor core, so that the HASH will be ready to compute
990 the message digest of a new message */
991 HASH->CR |= HASH_CR_INIT;
994 /* Reset interrupt counter */
995 hhash->HashITCounter = 0;
997 /* Set the phase */
998 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1000 /* Process Unlocked */
1001 __HAL_UNLOCK(hhash);
1003 /* Enable Interrupts */
1004 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
1006 /* Return function status */
1007 return HAL_OK;
1009 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
1011 outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
1012 /* Read the Output block from the Output FIFO */
1013 *(uint32_t*)(outputaddr) = __REV(HASH->HR[0]);
1014 outputaddr+=4;
1015 *(uint32_t*)(outputaddr) = __REV(HASH->HR[1]);
1016 outputaddr+=4;
1017 *(uint32_t*)(outputaddr) = __REV(HASH->HR[2]);
1018 outputaddr+=4;
1019 *(uint32_t*)(outputaddr) = __REV(HASH->HR[3]);
1020 outputaddr+=4;
1021 *(uint32_t*)(outputaddr) = __REV(HASH->HR[4]);
1022 if(hhash->HashInCount == 0)
1024 /* Disable Interrupts */
1025 HASH->IMR = 0;
1026 /* Change the HASH state */
1027 hhash->State = HAL_HASH_STATE_READY;
1028 /* Call digest computation complete callback */
1029 HAL_HASH_DgstCpltCallback(hhash);
1031 /* Process Unlocked */
1032 __HAL_UNLOCK(hhash);
1034 /* Return function status */
1035 return HAL_OK;
1038 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
1040 if(hhash->HashInCount >= 68)
1042 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1043 /* Write the Input block in the Data IN register */
1044 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
1046 HASH->DIN = *(uint32_t*)inputaddr;
1047 inputaddr+=4;
1049 if(hhash->HashITCounter == 0)
1051 HASH->DIN = *(uint32_t*)inputaddr;
1053 if(hhash->HashInCount >= 68)
1055 /* Decrement buffer counter */
1056 hhash->HashInCount -= 68;
1057 hhash->pHashInBuffPtr+= 68;
1059 else
1061 hhash->HashInCount = 0;
1062 hhash->pHashInBuffPtr+= hhash->HashInCount;
1064 /* Set Interrupt counter */
1065 hhash->HashITCounter = 1;
1067 else
1069 /* Decrement buffer counter */
1070 hhash->HashInCount -= 64;
1071 hhash->pHashInBuffPtr+= 64;
1074 else
1076 /* Get the buffer address */
1077 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1078 /* Get the buffer counter */
1079 inputcounter = hhash->HashInCount;
1080 /* Disable Interrupts */
1081 HASH->IMR &= ~(HASH_IT_DINI);
1082 /* Configure the number of valid bits in last word of the message */
1083 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
1085 if((inputcounter > 4) && (inputcounter%4))
1087 inputcounter = (inputcounter+4-inputcounter%4);
1089 else if ((inputcounter < 4) && (inputcounter != 0))
1091 inputcounter = 4;
1093 /* Write the Input block in the Data IN register */
1094 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
1096 HASH->DIN = *(uint32_t*)inputaddr;
1097 inputaddr+=4;
1099 /* Start the digest calculation */
1100 __HAL_HASH_START_DIGEST();
1101 /* Reset buffer counter */
1102 hhash->HashInCount = 0;
1103 /* Call Input data transfer complete callback */
1104 HAL_HASH_InCpltCallback(hhash);
1108 /* Process Unlocked */
1109 __HAL_UNLOCK(hhash);
1111 /* Return function status */
1112 return HAL_OK;
1116 * @brief This function handles HASH interrupt request.
1117 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1118 * the configuration information for HASH module
1119 * @retval None
1121 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
1123 switch(HASH->CR & HASH_CR_ALGO)
1125 case HASH_ALGOSELECTION_MD5:
1126 HAL_HASH_MD5_Start_IT(hhash, NULL, 0, NULL);
1127 break;
1129 case HASH_ALGOSELECTION_SHA1:
1130 HAL_HASH_SHA1_Start_IT(hhash, NULL, 0, NULL);
1131 break;
1133 default:
1134 break;
1139 * @}
1142 /** @defgroup HASH_Exported_Functions_Group4 HASH processing functions using DMA mode
1143 * @brief processing functions using DMA mode.
1145 @verbatim
1146 ===============================================================================
1147 ##### HASH processing using DMA mode functions #####
1148 ===============================================================================
1149 [..] This section provides functions allowing to calculate in DMA mode
1150 the hash value using one of the following algorithms:
1151 (+) MD5
1152 (+) SHA1
1154 @endverbatim
1155 * @{
1159 * @brief Initializes the HASH peripheral in MD5 mode then enables DMA to
1160 control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
1161 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1162 * the configuration information for HASH module
1163 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1164 * @param Size: Length of the input buffer in bytes.
1165 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1166 * @retval HAL status
1168 HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1170 uint32_t inputaddr = (uint32_t)pInBuffer;
1172 /* Process Locked */
1173 __HAL_LOCK(hhash);
1175 /* Change the HASH state */
1176 hhash->State = HAL_HASH_STATE_BUSY;
1178 /* Check if initialization phase has already been performed */
1179 if(hhash->Phase == HAL_HASH_PHASE_READY)
1181 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
1182 the message digest of a new message */
1183 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
1186 /* Configure the number of valid bits in last word of the message */
1187 __HAL_HASH_SET_NBVALIDBITS(Size);
1189 /* Set the phase */
1190 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1192 /* Set the HASH DMA transfer complete callback */
1193 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1194 /* Set the DMA error callback */
1195 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1197 /* Enable the DMA In DMA Stream */
1198 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
1200 /* Enable DMA requests */
1201 HASH->CR |= (HASH_CR_DMAE);
1203 /* Process Unlocked */
1204 __HAL_UNLOCK(hhash);
1206 /* Return function status */
1207 return HAL_OK;
1211 * @brief Returns the computed digest in MD5 mode
1212 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1213 * the configuration information for HASH module
1214 * @param pOutBuffer: Pointer to the computed digest. Its size must be 16 bytes.
1215 * @param Timeout: Timeout value
1216 * @retval HAL status
1218 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1220 uint32_t tickstart = 0;
1222 /* Process Locked */
1223 __HAL_LOCK(hhash);
1225 /* Change HASH peripheral state */
1226 hhash->State = HAL_HASH_STATE_BUSY;
1228 /* Get tick */
1229 tickstart = HAL_GetTick();
1231 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1233 /* Check for the Timeout */
1234 if(Timeout != HAL_MAX_DELAY)
1236 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1238 /* Change state */
1239 hhash->State = HAL_HASH_STATE_TIMEOUT;
1241 /* Process Unlocked */
1242 __HAL_UNLOCK(hhash);
1244 return HAL_TIMEOUT;
1249 /* Read the message digest */
1250 HASH_GetDigest(pOutBuffer, 16);
1252 /* Change HASH peripheral state */
1253 hhash->State = HAL_HASH_STATE_READY;
1255 /* Process Unlocked */
1256 __HAL_UNLOCK(hhash);
1258 /* Return function status */
1259 return HAL_OK;
1263 * @brief Initializes the HASH peripheral in SHA1 mode then enables DMA to
1264 control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
1265 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1266 * the configuration information for HASH module
1267 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1268 * @param Size: Length of the input buffer in bytes.
1269 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1270 * @retval HAL status
1272 HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1274 uint32_t inputaddr = (uint32_t)pInBuffer;
1276 /* Process Locked */
1277 __HAL_LOCK(hhash);
1279 /* Change the HASH state */
1280 hhash->State = HAL_HASH_STATE_BUSY;
1282 /* Check if initialization phase has already been performed */
1283 if(hhash->Phase == HAL_HASH_PHASE_READY)
1285 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
1286 the message digest of a new message */
1287 HASH->CR |= HASH_ALGOSELECTION_SHA1;
1288 HASH->CR |= HASH_CR_INIT;
1291 /* Configure the number of valid bits in last word of the message */
1292 __HAL_HASH_SET_NBVALIDBITS(Size);
1294 /* Set the phase */
1295 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1297 /* Set the HASH DMA transfer complete callback */
1298 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1299 /* Set the DMA error callback */
1300 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1302 /* Enable the DMA In DMA Stream */
1303 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
1305 /* Enable DMA requests */
1306 HASH->CR |= (HASH_CR_DMAE);
1308 /* Process Unlocked */
1309 __HAL_UNLOCK(hhash);
1311 /* Return function status */
1312 return HAL_OK;
1316 * @brief Returns the computed digest in SHA1 mode.
1317 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1318 * the configuration information for HASH module
1319 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1320 * @param Timeout: Timeout value
1321 * @retval HAL status
1323 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1325 uint32_t tickstart = 0;
1327 /* Process Locked */
1328 __HAL_LOCK(hhash);
1330 /* Change HASH peripheral state */
1331 hhash->State = HAL_HASH_STATE_BUSY;
1333 /* Get tick */
1334 tickstart = HAL_GetTick();
1335 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1337 /* Check for the Timeout */
1338 if(Timeout != HAL_MAX_DELAY)
1340 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1342 /* Change state */
1343 hhash->State = HAL_HASH_STATE_TIMEOUT;
1345 /* Process Unlocked */
1346 __HAL_UNLOCK(hhash);
1348 return HAL_TIMEOUT;
1353 /* Read the message digest */
1354 HASH_GetDigest(pOutBuffer, 20);
1356 /* Change HASH peripheral state */
1357 hhash->State = HAL_HASH_STATE_READY;
1359 /* Process UnLock */
1360 __HAL_UNLOCK(hhash);
1362 /* Return function status */
1363 return HAL_OK;
1368 * @}
1371 /** @defgroup HASH_Exported_Functions_Group5 HASH-MAC (HMAC) processing functions using polling mode
1372 * @brief HMAC processing functions using polling mode .
1374 @verbatim
1375 ===============================================================================
1376 ##### HMAC processing using polling mode functions #####
1377 ===============================================================================
1378 [..] This section provides functions allowing to calculate in polling mode
1379 the HMAC value using one of the following algorithms:
1380 (+) MD5
1381 (+) SHA1
1383 @endverbatim
1384 * @{
1388 * @brief Initializes the HASH peripheral in HMAC MD5 mode
1389 * then processes pInBuffer. The digest is available in pOutBuffer
1390 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1391 * the configuration information for HASH module
1392 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1393 * @param Size: Length of the input buffer in bytes.
1394 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1395 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1396 * @param Timeout: Timeout value
1397 * @retval HAL status
1399 HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1401 uint32_t tickstart = 0;
1403 /* Process Locked */
1404 __HAL_LOCK(hhash);
1406 /* Change the HASH state */
1407 hhash->State = HAL_HASH_STATE_BUSY;
1409 /* Check if initialization phase has already been performed */
1410 if(hhash->Phase == HAL_HASH_PHASE_READY)
1412 /* Check if key size is greater than 64 bytes */
1413 if(hhash->Init.KeySize > 64)
1415 /* Select the HMAC MD5 mode */
1416 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1418 else
1420 /* Select the HMAC MD5 mode */
1421 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1425 /* Set the phase */
1426 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1428 /************************** STEP 1 ******************************************/
1429 /* Configure the number of valid bits in last word of the message */
1430 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1432 /* Write input buffer in data register */
1433 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1435 /* Start the digest calculation */
1436 __HAL_HASH_START_DIGEST();
1438 /* Get tick */
1439 tickstart = HAL_GetTick();
1441 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1443 /* Check for the Timeout */
1444 if(Timeout != HAL_MAX_DELAY)
1446 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1448 /* Change state */
1449 hhash->State = HAL_HASH_STATE_TIMEOUT;
1451 /* Process Unlocked */
1452 __HAL_UNLOCK(hhash);
1454 return HAL_TIMEOUT;
1458 /************************** STEP 2 ******************************************/
1459 /* Configure the number of valid bits in last word of the message */
1460 __HAL_HASH_SET_NBVALIDBITS(Size);
1462 /* Write input buffer in data register */
1463 HASH_WriteData(pInBuffer, Size);
1465 /* Start the digest calculation */
1466 __HAL_HASH_START_DIGEST();
1468 /* Get tick */
1469 tickstart = HAL_GetTick();
1471 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1473 /* Check for the Timeout */
1474 if(Timeout != HAL_MAX_DELAY)
1476 if((HAL_GetTick() - tickstart ) > Timeout)
1478 /* Change state */
1479 hhash->State = HAL_HASH_STATE_TIMEOUT;
1481 /* Process Unlocked */
1482 __HAL_UNLOCK(hhash);
1484 return HAL_TIMEOUT;
1488 /************************** STEP 3 ******************************************/
1489 /* Configure the number of valid bits in last word of the message */
1490 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1492 /* Write input buffer in data register */
1493 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1495 /* Start the digest calculation */
1496 __HAL_HASH_START_DIGEST();
1498 /* Get tick */
1499 tickstart = HAL_GetTick();
1501 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1503 /* Check for the Timeout */
1504 if(Timeout != HAL_MAX_DELAY)
1506 if((HAL_GetTick() - tickstart ) > Timeout)
1508 /* Change state */
1509 hhash->State = HAL_HASH_STATE_TIMEOUT;
1511 /* Process Unlocked */
1512 __HAL_UNLOCK(hhash);
1514 return HAL_TIMEOUT;
1519 /* Read the message digest */
1520 HASH_GetDigest(pOutBuffer, 16);
1522 /* Change the HASH state */
1523 hhash->State = HAL_HASH_STATE_READY;
1525 /* Process Unlocked */
1526 __HAL_UNLOCK(hhash);
1528 /* Return function status */
1529 return HAL_OK;
1533 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
1534 * then processes pInBuffer. The digest is available in pOutBuffer.
1535 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1536 * the configuration information for HASH module
1537 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1538 * @param Size: Length of the input buffer in bytes.
1539 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1540 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
1541 * @param Timeout: Timeout value
1542 * @retval HAL status
1544 HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1546 uint32_t tickstart = 0;
1548 /* Process Locked */
1549 __HAL_LOCK(hhash);
1551 /* Change the HASH state */
1552 hhash->State = HAL_HASH_STATE_BUSY;
1554 /* Check if initialization phase has already been performed */
1555 if(hhash->Phase == HAL_HASH_PHASE_READY)
1557 /* Check if key size is greater than 64 bytes */
1558 if(hhash->Init.KeySize > 64)
1560 /* Select the HMAC SHA1 mode */
1561 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1563 else
1565 /* Select the HMAC SHA1 mode */
1566 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1570 /* Set the phase */
1571 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1573 /************************** STEP 1 ******************************************/
1574 /* Configure the number of valid bits in last word of the message */
1575 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1577 /* Write input buffer in data register */
1578 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1580 /* Start the digest calculation */
1581 __HAL_HASH_START_DIGEST();
1583 /* Get tick */
1584 tickstart = HAL_GetTick();
1586 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1588 /* Check for the Timeout */
1589 if(Timeout != HAL_MAX_DELAY)
1591 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1593 /* Change state */
1594 hhash->State = HAL_HASH_STATE_TIMEOUT;
1596 /* Process Unlocked */
1597 __HAL_UNLOCK(hhash);
1599 return HAL_TIMEOUT;
1603 /************************** STEP 2 ******************************************/
1604 /* Configure the number of valid bits in last word of the message */
1605 __HAL_HASH_SET_NBVALIDBITS(Size);
1607 /* Write input buffer in data register */
1608 HASH_WriteData(pInBuffer, Size);
1610 /* Start the digest calculation */
1611 __HAL_HASH_START_DIGEST();
1613 /* Get tick */
1614 tickstart = HAL_GetTick();
1616 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1618 /* Check for the Timeout */
1619 if(Timeout != HAL_MAX_DELAY)
1621 if((HAL_GetTick() - tickstart ) > Timeout)
1623 /* Change state */
1624 hhash->State = HAL_HASH_STATE_TIMEOUT;
1626 /* Process Unlocked */
1627 __HAL_UNLOCK(hhash);
1629 return HAL_TIMEOUT;
1633 /************************** STEP 3 ******************************************/
1634 /* Configure the number of valid bits in last word of the message */
1635 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1637 /* Write input buffer in data register */
1638 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1640 /* Start the digest calculation */
1641 __HAL_HASH_START_DIGEST();
1643 /* Get tick */
1644 tickstart = HAL_GetTick();
1646 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1648 /* Check for the Timeout */
1649 if(Timeout != HAL_MAX_DELAY)
1651 if((HAL_GetTick() - tickstart ) > Timeout)
1653 /* Change state */
1654 hhash->State = HAL_HASH_STATE_TIMEOUT;
1656 /* Process Unlocked */
1657 __HAL_UNLOCK(hhash);
1659 return HAL_TIMEOUT;
1663 /* Read the message digest */
1664 HASH_GetDigest(pOutBuffer, 20);
1666 /* Change the HASH state */
1667 hhash->State = HAL_HASH_STATE_READY;
1669 /* Process Unlocked */
1670 __HAL_UNLOCK(hhash);
1672 /* Return function status */
1673 return HAL_OK;
1677 * @}
1680 /** @defgroup HASH_Exported_Functions_Group6 HASH-MAC (HMAC) processing functions using DMA mode
1681 * @brief HMAC processing functions using DMA mode .
1683 @verbatim
1684 ===============================================================================
1685 ##### HMAC processing using DMA mode functions #####
1686 ===============================================================================
1687 [..] This section provides functions allowing to calculate in DMA mode
1688 the HMAC value using one of the following algorithms:
1689 (+) MD5
1690 (+) SHA1
1692 @endverbatim
1693 * @{
1697 * @brief Initializes the HASH peripheral in HMAC MD5 mode
1698 * then enables DMA to control data transfer.
1699 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1700 * the configuration information for HASH module
1701 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1702 * @param Size: Length of the input buffer in bytes.
1703 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1704 * @retval HAL status
1706 HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1708 uint32_t inputaddr = 0;
1710 /* Process Locked */
1711 __HAL_LOCK(hhash);
1713 /* Change the HASH state */
1714 hhash->State = HAL_HASH_STATE_BUSY;
1716 /* Save buffer pointer and size in handle */
1717 hhash->pHashInBuffPtr = pInBuffer;
1718 hhash->HashBuffSize = Size;
1719 hhash->HashInCount = 0;
1721 /* Check if initialization phase has already been performed */
1722 if(hhash->Phase == HAL_HASH_PHASE_READY)
1724 /* Check if key size is greater than 64 bytes */
1725 if(hhash->Init.KeySize > 64)
1727 /* Select the HMAC MD5 mode */
1728 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1730 else
1732 /* Select the HMAC MD5 mode */
1733 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1737 /* Set the phase */
1738 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1740 /* Configure the number of valid bits in last word of the message */
1741 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1743 /* Get the key address */
1744 inputaddr = (uint32_t)(hhash->Init.pKey);
1746 /* Set the HASH DMA transfer complete callback */
1747 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1748 /* Set the DMA error callback */
1749 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1751 /* Enable the DMA In DMA Stream */
1752 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1753 /* Enable DMA requests */
1754 HASH->CR |= (HASH_CR_DMAE);
1756 /* Process Unlocked */
1757 __HAL_UNLOCK(hhash);
1759 /* Return function status */
1760 return HAL_OK;
1764 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
1765 * then enables DMA to control data transfer.
1766 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1767 * the configuration information for HASH module
1768 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
1769 * @param Size: Length of the input buffer in bytes.
1770 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1771 * @retval HAL status
1773 HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1775 uint32_t inputaddr = 0;
1777 /* Process Locked */
1778 __HAL_LOCK(hhash);
1780 /* Change the HASH state */
1781 hhash->State = HAL_HASH_STATE_BUSY;
1783 /* Save buffer pointer and size in handle */
1784 hhash->pHashInBuffPtr = pInBuffer;
1785 hhash->HashBuffSize = Size;
1786 hhash->HashInCount = 0;
1788 /* Check if initialization phase has already been performed */
1789 if(hhash->Phase == HAL_HASH_PHASE_READY)
1791 /* Check if key size is greater than 64 bytes */
1792 if(hhash->Init.KeySize > 64)
1794 /* Select the HMAC SHA1 mode */
1795 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1797 else
1799 /* Select the HMAC SHA1 mode */
1800 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1804 /* Set the phase */
1805 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1807 /* Configure the number of valid bits in last word of the message */
1808 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1810 /* Get the key address */
1811 inputaddr = (uint32_t)(hhash->Init.pKey);
1813 /* Set the HASH DMA transfer complete callback */
1814 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1815 /* Set the DMA error callback */
1816 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1818 /* Enable the DMA In DMA Stream */
1819 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4 ? (hhash->Init.KeySize+3)/4:hhash->Init.KeySize/4));
1820 /* Enable DMA requests */
1821 HASH->CR |= (HASH_CR_DMAE);
1823 /* Process Unlocked */
1824 __HAL_UNLOCK(hhash);
1826 /* Return function status */
1827 return HAL_OK;
1831 * @}
1834 /** @defgroup HASH_Exported_Functions_Group7 Peripheral State functions
1835 * @brief Peripheral State functions.
1837 @verbatim
1838 ===============================================================================
1839 ##### Peripheral State functions #####
1840 ===============================================================================
1841 [..]
1842 This subsection permits to get in run-time the status of the peripheral.
1844 @endverbatim
1845 * @{
1849 * @brief return the HASH state
1850 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
1851 * the configuration information for HASH module
1852 * @retval HAL state
1854 HAL_HASH_StateTypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
1856 return hhash->State;
1860 * @}
1864 * @}
1867 #endif /* HAL_HASH_MODULE_ENABLED */
1870 * @}
1872 #endif /* STM32F756xx || STM32F777xx || STM32F779xx */
1875 * @}
1878 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/