2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_hash_ex.c
\r
4 * @author MCD Application Team
\r
6 * @date 06-March-2015
\r
7 * @brief HASH HAL Extension module driver.
\r
8 * This file provides firmware functions to manage the following
\r
9 * functionalities of HASH peripheral:
\r
10 * + Extended HASH processing functions based on SHA224 Algorithm
\r
11 * + Extended HASH processing functions based on SHA256 Algorithm
\r
14 ==============================================================================
\r
15 ##### How to use this driver #####
\r
16 ==============================================================================
\r
18 The HASH HAL driver can be used as follows:
\r
19 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
\r
20 (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
\r
21 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMACEx_SHA224_Start())
\r
22 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
\r
23 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
\r
24 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
\r
25 (##) In case of using DMA to control data transfer (e.g. HAL_HMACEx_SH224_Start_DMA())
\r
26 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
\r
27 (+++) Configure and enable one DMA stream one for managing data transfer from
\r
28 memory to peripheral (input stream). Managing data transfer from
\r
29 peripheral to memory can be performed only using CPU
\r
30 (+++) Associate the initialized DMA handle to the HASH DMA handle
\r
31 using __HAL_LINKDMA()
\r
32 (+++) Configure the priority and enable the NVIC for the transfer complete
\r
33 interrupt on the DMA Stream: HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
\r
34 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
\r
35 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
\r
36 (##) For HMAC, the encryption key.
\r
37 (##) For HMAC, the key size used for encryption.
\r
38 (#)Three processing functions are available:
\r
39 (##) Polling mode: processing APIs are blocking functions
\r
40 i.e. they process the data and wait till the digest computation is finished
\r
41 e.g. HAL_HASHEx_SHA224_Start()
\r
42 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
\r
43 i.e. they process the data under interrupt
\r
44 e.g. HAL_HASHEx_SHA224_Start_IT()
\r
45 (##) DMA mode: processing APIs are not blocking functions and the CPU is
\r
46 not used for data transfer i.e. the data transfer is ensured by DMA
\r
47 e.g. HAL_HASHEx_SHA224_Start_DMA()
\r
48 (#)When the processing function is called at first time after HAL_HASH_Init()
\r
49 the HASH peripheral is initialized and processes the buffer in input.
\r
50 After that, the digest computation is started.
\r
51 When processing multi-buffer use the accumulate function to write the
\r
52 data in the peripheral without starting the digest computation. In last
\r
53 buffer use the start function to input the last buffer ans start the digest
\r
55 (##) e.g. HAL_HASHEx_SHA224_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
\r
56 (##) write (n-1)th data buffer in the peripheral without starting the digest computation
\r
57 (##) HAL_HASHEx_SHA224_Start() : write (n)th data buffer in the peripheral and start the digest computation
\r
58 (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
\r
59 (#)In case of using DMA, call the DMA start processing e.g. HAL_HASHEx_SHA224_Start_DMA().
\r
60 After that, call the finish function in order to get the digest value
\r
61 e.g. HAL_HASHEx_SHA224_Finish()
\r
62 (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
\r
65 ******************************************************************************
\r
68 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
70 * Redistribution and use in source and binary forms, with or without modification,
\r
71 * are permitted provided that the following conditions are met:
\r
72 * 1. Redistributions of source code must retain the above copyright notice,
\r
73 * this list of conditions and the following disclaimer.
\r
74 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
75 * this list of conditions and the following disclaimer in the documentation
\r
76 * and/or other materials provided with the distribution.
\r
77 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
78 * may be used to endorse or promote products derived from this software
\r
79 * without specific prior written permission.
\r
81 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
82 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
84 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
87 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
88 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
89 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
90 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
92 ******************************************************************************
\r
95 /* Includes ------------------------------------------------------------------*/
\r
96 #include "stm32f7xx_hal.h"
\r
98 /** @addtogroup STM32F7xx_HAL_Driver
\r
102 /** @defgroup HASHEx HASHEx
\r
103 * @brief HASH Extension HAL module driver.
\r
107 #ifdef HAL_HASH_MODULE_ENABLED
\r
109 #if defined(STM32F756xx)
\r
111 /* Private typedef -----------------------------------------------------------*/
\r
112 /* Private define ------------------------------------------------------------*/
\r
113 /* Private macro -------------------------------------------------------------*/
\r
114 /* Private variables ---------------------------------------------------------*/
\r
115 /* Private function prototypes -----------------------------------------------*/
\r
116 /** @addtogroup HASHEx_Private_Functions
\r
119 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma);
\r
120 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size);
\r
121 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
\r
122 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma);
\r
127 /* Private functions ---------------------------------------------------------*/
\r
129 /** @addtogroup HASHEx_Private_Functions
\r
134 * @brief Writes the input buffer in data register.
\r
135 * @param pInBuffer: Pointer to input buffer
\r
136 * @param Size: The size of input buffer
\r
139 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size)
\r
141 uint32_t buffercounter;
\r
142 uint32_t inputaddr = (uint32_t) pInBuffer;
\r
144 for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
\r
146 HASH->DIN = *(uint32_t*)inputaddr;
\r
152 * @brief Provides the message digest result.
\r
153 * @param pMsgDigest: Pointer to the message digest
\r
154 * @param Size: The size of the message digest in bytes
\r
157 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
\r
159 uint32_t msgdigest = (uint32_t)pMsgDigest;
\r
164 /* Read the message digest */
\r
165 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
167 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
169 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
171 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
174 /* Read the message digest */
\r
175 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
177 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
179 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
181 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
183 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
186 /* Read the message digest */
\r
187 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
189 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
191 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
193 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
195 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
197 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
\r
199 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
\r
202 /* Read the message digest */
\r
203 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
\r
205 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
\r
207 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
\r
209 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
\r
211 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
\r
213 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
\r
215 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
\r
217 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
\r
225 * @brief DMA HASH Input Data complete callback.
\r
226 * @param hdma: DMA handle
\r
229 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma)
\r
231 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
232 uint32_t inputaddr = 0;
\r
233 uint32_t buffersize = 0;
\r
235 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
\r
237 /* Disable the DMA transfer */
\r
238 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
240 /* Change HASH peripheral state */
\r
241 hhash->State = HAL_HASH_STATE_READY;
\r
243 /* Call Input data transfer complete callback */
\r
244 HAL_HASH_InCpltCallback(hhash);
\r
248 /* Increment Interrupt counter */
\r
249 hhash->HashInCount++;
\r
250 /* Disable the DMA transfer before starting the next transfer */
\r
251 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
253 if(hhash->HashInCount <= 2)
\r
255 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
\r
256 if(hhash->HashInCount == 1)
\r
258 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
259 buffersize = hhash->HashBuffSize;
\r
261 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
\r
262 else if(hhash->HashInCount == 2)
\r
264 inputaddr = (uint32_t)hhash->Init.pKey;
\r
265 buffersize = hhash->Init.KeySize;
\r
267 /* Configure the number of valid bits in last word of the message */
\r
268 HASH->STR |= 8 * (buffersize % 4);
\r
270 /* Set the HASH DMA transfer complete */
\r
271 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
273 /* Enable the DMA In DMA Stream */
\r
274 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4 ? (buffersize+3)/4:buffersize/4));
\r
276 /* Enable DMA requests */
\r
277 HASH->CR |= (HASH_CR_DMAE);
\r
281 /* Disable the DMA transfer */
\r
282 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
\r
284 /* Reset the InCount */
\r
285 hhash->HashInCount = 0;
\r
287 /* Change HASH peripheral state */
\r
288 hhash->State = HAL_HASH_STATE_READY;
\r
290 /* Call Input data transfer complete callback */
\r
291 HAL_HASH_InCpltCallback(hhash);
\r
297 * @brief DMA HASH communication error callback.
\r
298 * @param hdma: DMA handle
\r
301 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma)
\r
303 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
304 hhash->State= HAL_HASH_STATE_READY;
\r
305 HAL_HASH_ErrorCallback(hhash);
\r
312 /* Exported functions --------------------------------------------------------*/
\r
313 /** @addtogroup HASHEx_Exported_Functions
\r
317 /** @defgroup HASHEx_Group1 HASH processing functions
\r
318 * @brief processing functions using polling mode
\r
321 ===============================================================================
\r
322 ##### HASH processing using polling mode functions #####
\r
323 ===============================================================================
\r
324 [..] This section provides functions allowing to calculate in polling mode
\r
325 the hash value using one of the following algorithms:
\r
334 * @brief Initializes the HASH peripheral in SHA224 mode
\r
335 * then processes pInBuffer. The digest is available in pOutBuffer
\r
336 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
337 * the configuration information for HASH module
\r
338 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
339 * @param Size: Length of the input buffer in bytes.
\r
340 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
341 * @param pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
\r
342 * @param Timeout: Specify Timeout value
\r
343 * @retval HAL status
\r
345 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
347 uint32_t tickstart = 0;
\r
349 /* Process Locked */
\r
352 /* Change the HASH state */
\r
353 hhash->State = HAL_HASH_STATE_BUSY;
\r
355 /* Check if initialization phase has already been performed */
\r
356 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
358 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
359 the message digest of a new message */
\r
360 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
\r
363 /* Set the phase */
\r
364 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
366 /* Configure the number of valid bits in last word of the message */
\r
367 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
369 /* Write input buffer in data register */
\r
370 HASHEx_WriteData(pInBuffer, Size);
\r
372 /* Start the digest calculation */
\r
373 __HAL_HASH_START_DIGEST();
\r
376 tickstart = HAL_GetTick();
\r
378 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
380 /* Check for the Timeout */
\r
381 if(Timeout != HAL_MAX_DELAY)
\r
383 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
386 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
388 /* Process Unlocked */
\r
389 __HAL_UNLOCK(hhash);
\r
391 return HAL_TIMEOUT;
\r
396 /* Read the message digest */
\r
397 HASHEx_GetDigest(pOutBuffer, 28);
\r
399 /* Change the HASH state */
\r
400 hhash->State = HAL_HASH_STATE_READY;
\r
402 /* Process Unlocked */
\r
403 __HAL_UNLOCK(hhash);
\r
405 /* Return function status */
\r
410 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
\r
411 The digest is available in pOutBuffer.
\r
412 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
413 * the configuration information for HASH module
\r
414 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
415 * @param Size: Length of the input buffer in bytes.
\r
416 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
417 * @param pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
\r
418 * @param Timeout: Specify Timeout value
\r
419 * @retval HAL status
\r
421 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
423 uint32_t tickstart = 0;
\r
425 /* Process Locked */
\r
428 /* Change the HASH state */
\r
429 hhash->State = HAL_HASH_STATE_BUSY;
\r
431 /* Check if initialization phase has already been performed */
\r
432 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
434 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
435 the message digest of a new message */
\r
436 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
\r
439 /* Set the phase */
\r
440 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
442 /* Configure the number of valid bits in last word of the message */
\r
443 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
445 /* Write input buffer in data register */
\r
446 HASHEx_WriteData(pInBuffer, Size);
\r
448 /* Start the digest calculation */
\r
449 __HAL_HASH_START_DIGEST();
\r
452 tickstart = HAL_GetTick();
\r
454 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
456 /* Check for the Timeout */
\r
457 if(Timeout != HAL_MAX_DELAY)
\r
459 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
462 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
464 /* Process Unlocked */
\r
465 __HAL_UNLOCK(hhash);
\r
467 return HAL_TIMEOUT;
\r
472 /* Read the message digest */
\r
473 HASHEx_GetDigest(pOutBuffer, 32);
\r
475 /* Change the HASH state */
\r
476 hhash->State = HAL_HASH_STATE_READY;
\r
478 /* Process Unlocked */
\r
479 __HAL_UNLOCK(hhash);
\r
481 /* Return function status */
\r
487 * @brief Initializes the HASH peripheral in SHA224 mode
\r
488 * then processes pInBuffer. The digest is available in pOutBuffer
\r
489 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
490 * the configuration information for HASH module
\r
491 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
492 * @param Size: Length of the input buffer in bytes.
\r
493 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
494 * @retval HAL status
\r
496 HAL_StatusTypeDef HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
498 /* Process Locked */
\r
501 /* Change the HASH state */
\r
502 hhash->State = HAL_HASH_STATE_BUSY;
\r
504 /* Check if initialization phase has already been performed */
\r
505 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
507 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
508 the message digest of a new message */
\r
509 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
\r
512 /* Set the phase */
\r
513 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
515 /* Configure the number of valid bits in last word of the message */
\r
516 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
518 /* Write input buffer in data register */
\r
519 HASHEx_WriteData(pInBuffer, Size);
\r
521 /* Change the HASH state */
\r
522 hhash->State = HAL_HASH_STATE_READY;
\r
524 /* Process Unlocked */
\r
525 __HAL_UNLOCK(hhash);
\r
527 /* Return function status */
\r
533 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
\r
534 The digest is available in pOutBuffer.
\r
535 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
536 * the configuration information for HASH module
\r
537 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
538 * @param Size: Length of the input buffer in bytes.
\r
539 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
540 * @retval HAL status
\r
542 HAL_StatusTypeDef HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
544 /* Process Locked */
\r
547 /* Change the HASH state */
\r
548 hhash->State = HAL_HASH_STATE_BUSY;
\r
550 /* Check if initialization phase has already been performed */
\r
551 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
553 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
554 the message digest of a new message */
\r
555 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
\r
558 /* Set the phase */
\r
559 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
561 /* Configure the number of valid bits in last word of the message */
\r
562 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
564 /* Write input buffer in data register */
\r
565 HASHEx_WriteData(pInBuffer, Size);
\r
567 /* Change the HASH state */
\r
568 hhash->State = HAL_HASH_STATE_READY;
\r
570 /* Process Unlocked */
\r
571 __HAL_UNLOCK(hhash);
\r
573 /* Return function status */
\r
582 /** @defgroup HASHEx_Group2 HMAC processing functions using polling mode
\r
583 * @brief HMAC processing functions using polling mode .
\r
586 ===============================================================================
\r
587 ##### HMAC processing using polling mode functions #####
\r
588 ===============================================================================
\r
589 [..] This section provides functions allowing to calculate in polling mode
\r
590 the HMAC value using one of the following algorithms:
\r
599 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
\r
600 * then processes pInBuffer. The digest is available in pOutBuffer.
\r
601 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
602 * the configuration information for HASH module
\r
603 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
604 * @param Size: Length of the input buffer in bytes.
\r
605 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
606 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
607 * @param Timeout: Timeout value
\r
608 * @retval HAL status
\r
610 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
612 uint32_t tickstart = 0;
\r
614 /* Process Locked */
\r
617 /* Change the HASH state */
\r
618 hhash->State = HAL_HASH_STATE_BUSY;
\r
620 /* Check if initialization phase has already been performed */
\r
621 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
623 /* Check if key size is greater than 64 bytes */
\r
624 if(hhash->Init.KeySize > 64)
\r
626 /* Select the HMAC SHA224 mode */
\r
627 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
\r
631 /* Select the HMAC SHA224 mode */
\r
632 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
\r
636 /* Set the phase */
\r
637 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
639 /************************** STEP 1 ******************************************/
\r
640 /* Configure the number of valid bits in last word of the message */
\r
641 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
643 /* Write input buffer in data register */
\r
644 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
646 /* Start the digest calculation */
\r
647 __HAL_HASH_START_DIGEST();
\r
650 tickstart = HAL_GetTick();
\r
652 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
654 /* Check for the Timeout */
\r
655 if(Timeout != HAL_MAX_DELAY)
\r
657 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
660 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
662 /* Process Unlocked */
\r
663 __HAL_UNLOCK(hhash);
\r
665 return HAL_TIMEOUT;
\r
669 /************************** STEP 2 ******************************************/
\r
670 /* Configure the number of valid bits in last word of the message */
\r
671 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
673 /* Write input buffer in data register */
\r
674 HASHEx_WriteData(pInBuffer, Size);
\r
676 /* Start the digest calculation */
\r
677 __HAL_HASH_START_DIGEST();
\r
680 tickstart = HAL_GetTick();
\r
682 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
684 /* Check for the Timeout */
\r
685 if(Timeout != HAL_MAX_DELAY)
\r
687 if((HAL_GetTick() - tickstart ) > Timeout)
\r
690 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
692 /* Process Unlocked */
\r
693 __HAL_UNLOCK(hhash);
\r
695 return HAL_TIMEOUT;
\r
699 /************************** STEP 3 ******************************************/
\r
700 /* Configure the number of valid bits in last word of the message */
\r
701 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
703 /* Write input buffer in data register */
\r
704 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
706 /* Start the digest calculation */
\r
707 __HAL_HASH_START_DIGEST();
\r
710 tickstart = HAL_GetTick();
\r
712 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
714 /* Check for the Timeout */
\r
715 if(Timeout != HAL_MAX_DELAY)
\r
717 if((HAL_GetTick() - tickstart ) > Timeout)
\r
720 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
722 /* Process Unlocked */
\r
723 __HAL_UNLOCK(hhash);
\r
725 return HAL_TIMEOUT;
\r
729 /* Read the message digest */
\r
730 HASHEx_GetDigest(pOutBuffer, 28);
\r
732 /* Change the HASH state */
\r
733 hhash->State = HAL_HASH_STATE_READY;
\r
735 /* Process Unlocked */
\r
736 __HAL_UNLOCK(hhash);
\r
738 /* Return function status */
\r
743 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
\r
744 * then processes pInBuffer. The digest is available in pOutBuffer
\r
745 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
746 * the configuration information for HASH module
\r
747 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
748 * @param Size: Length of the input buffer in bytes.
\r
749 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
750 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
751 * @param Timeout: Timeout value
\r
752 * @retval HAL status
\r
754 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
\r
756 uint32_t tickstart = 0;
\r
758 /* Process Locked */
\r
761 /* Change the HASH state */
\r
762 hhash->State = HAL_HASH_STATE_BUSY;
\r
764 /* Check if initialization phase has already been performed */
\r
765 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
767 /* Check if key size is greater than 64 bytes */
\r
768 if(hhash->Init.KeySize > 64)
\r
770 /* Select the HMAC SHA256 mode */
\r
771 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);
\r
775 /* Select the HMAC SHA256 mode */
\r
776 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);
\r
778 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
779 the message digest of a new message */
\r
780 HASH->CR |= HASH_CR_INIT;
\r
783 /* Set the phase */
\r
784 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
786 /************************** STEP 1 ******************************************/
\r
787 /* Configure the number of valid bits in last word of the message */
\r
788 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
790 /* Write input buffer in data register */
\r
791 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
793 /* Start the digest calculation */
\r
794 __HAL_HASH_START_DIGEST();
\r
797 tickstart = HAL_GetTick();
\r
799 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
801 /* Check for the Timeout */
\r
802 if(Timeout != HAL_MAX_DELAY)
\r
804 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
807 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
809 /* Process Unlocked */
\r
810 __HAL_UNLOCK(hhash);
\r
812 return HAL_TIMEOUT;
\r
816 /************************** STEP 2 ******************************************/
\r
817 /* Configure the number of valid bits in last word of the message */
\r
818 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
820 /* Write input buffer in data register */
\r
821 HASHEx_WriteData(pInBuffer, Size);
\r
823 /* Start the digest calculation */
\r
824 __HAL_HASH_START_DIGEST();
\r
827 tickstart = HAL_GetTick();
\r
829 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
831 /* Check for the Timeout */
\r
832 if(Timeout != HAL_MAX_DELAY)
\r
834 if((HAL_GetTick() - tickstart ) > Timeout)
\r
837 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
839 /* Process Unlocked */
\r
840 __HAL_UNLOCK(hhash);
\r
842 return HAL_TIMEOUT;
\r
846 /************************** STEP 3 ******************************************/
\r
847 /* Configure the number of valid bits in last word of the message */
\r
848 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
850 /* Write input buffer in data register */
\r
851 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
\r
853 /* Start the digest calculation */
\r
854 __HAL_HASH_START_DIGEST();
\r
857 tickstart = HAL_GetTick();
\r
859 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
\r
861 /* Check for the Timeout */
\r
862 if(Timeout != HAL_MAX_DELAY)
\r
864 if((HAL_GetTick() - tickstart ) > Timeout)
\r
867 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
869 /* Process Unlocked */
\r
870 __HAL_UNLOCK(hhash);
\r
872 return HAL_TIMEOUT;
\r
876 /* Read the message digest */
\r
877 HASHEx_GetDigest(pOutBuffer, 32);
\r
879 /* Change the HASH state */
\r
880 hhash->State = HAL_HASH_STATE_READY;
\r
882 /* Process Unlocked */
\r
883 __HAL_UNLOCK(hhash);
\r
885 /* Return function status */
\r
893 /** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode
\r
894 * @brief processing functions using interrupt mode.
\r
897 ===============================================================================
\r
898 ##### HASH processing using interrupt functions #####
\r
899 ===============================================================================
\r
900 [..] This section provides functions allowing to calculate in interrupt mode
\r
901 the hash value using one of the following algorithms:
\r
910 * @brief Initializes the HASH peripheral in SHA224 mode then processes pInBuffer.
\r
911 * The digest is available in pOutBuffer.
\r
912 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
913 * the configuration information for HASH module
\r
914 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
915 * @param Size: Length of the input buffer in bytes.
\r
916 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
917 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
918 * @retval HAL status
\r
920 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
\r
922 uint32_t inputaddr;
\r
923 uint32_t buffercounter;
\r
924 uint32_t inputcounter;
\r
926 /* Process Locked */
\r
929 if(hhash->HashITCounter == 0)
\r
931 hhash->HashITCounter = 1;
\r
935 hhash->HashITCounter = 0;
\r
937 if(hhash->State == HAL_HASH_STATE_READY)
\r
939 /* Change the HASH state */
\r
940 hhash->State = HAL_HASH_STATE_BUSY;
\r
942 hhash->HashInCount = Size;
\r
943 hhash->pHashInBuffPtr = pInBuffer;
\r
944 hhash->pHashOutBuffPtr = pOutBuffer;
\r
946 /* Check if initialization phase has already been performed */
\r
947 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
949 /* Select the SHA224 mode */
\r
950 HASH->CR |= HASH_ALGOSELECTION_SHA224;
\r
951 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
952 the message digest of a new message */
\r
953 HASH->CR |= HASH_CR_INIT;
\r
956 /* Set the phase */
\r
957 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
959 /* Process Unlocked */
\r
960 __HAL_UNLOCK(hhash);
\r
962 /* Enable Interrupts */
\r
963 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
\r
965 /* Return function status */
\r
968 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
\r
970 /* Read the message digest */
\r
971 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 28);
\r
972 if(hhash->HashInCount == 0)
\r
974 /* Disable Interrupts */
\r
976 /* Change the HASH state */
\r
977 hhash->State = HAL_HASH_STATE_READY;
\r
978 /* Call digest computation complete callback */
\r
979 HAL_HASH_DgstCpltCallback(hhash);
\r
982 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
\r
984 if(hhash->HashInCount > 64)
\r
986 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
987 /* Write the Input block in the Data IN register */
\r
988 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
\r
990 HASH->DIN = *(uint32_t*)inputaddr;
\r
993 if(hhash->HashITCounter == 0)
\r
995 HASH->DIN = *(uint32_t*)inputaddr;
\r
996 if(hhash->HashInCount >= 68)
\r
998 /* Decrement buffer counter */
\r
999 hhash->HashInCount -= 68;
\r
1000 hhash->pHashInBuffPtr+= 68;
\r
1004 hhash->HashInCount -= 64;
\r
1009 /* Decrement buffer counter */
\r
1010 hhash->HashInCount -= 64;
\r
1011 hhash->pHashInBuffPtr+= 64;
\r
1016 /* Get the buffer address */
\r
1017 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
1018 /* Get the buffer counter */
\r
1019 inputcounter = hhash->HashInCount;
\r
1020 /* Disable Interrupts */
\r
1021 HASH->IMR &= ~(HASH_IT_DINI);
\r
1022 /* Configure the number of valid bits in last word of the message */
\r
1023 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
\r
1025 if((inputcounter > 4) && (inputcounter%4))
\r
1027 inputcounter = (inputcounter+4-inputcounter%4);
\r
1030 /* Write the Input block in the Data IN register */
\r
1031 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
\r
1033 HASH->DIN = *(uint32_t*)inputaddr;
\r
1036 /* Start the digest calculation */
\r
1037 __HAL_HASH_START_DIGEST();
\r
1038 /* Reset buffer counter */
\r
1039 hhash->HashInCount = 0;
\r
1041 /* Call Input data transfer complete callback */
\r
1042 HAL_HASH_InCpltCallback(hhash);
\r
1045 /* Process Unlocked */
\r
1046 __HAL_UNLOCK(hhash);
\r
1048 /* Return function status */
\r
1054 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
\r
1055 * The digest is available in pOutBuffer.
\r
1056 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1057 * the configuration information for HASH module
\r
1058 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1059 * @param Size: Length of the input buffer in bytes.
\r
1060 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1061 * @param pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
\r
1062 * @retval HAL status
\r
1064 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
\r
1066 uint32_t inputaddr;
\r
1067 uint32_t buffercounter;
\r
1068 uint32_t inputcounter;
\r
1070 /* Process Locked */
\r
1071 __HAL_LOCK(hhash);
\r
1073 if(hhash->HashITCounter == 0)
\r
1075 hhash->HashITCounter = 1;
\r
1079 hhash->HashITCounter = 0;
\r
1081 if(hhash->State == HAL_HASH_STATE_READY)
\r
1083 /* Change the HASH state */
\r
1084 hhash->State = HAL_HASH_STATE_BUSY;
\r
1086 hhash->HashInCount = Size;
\r
1087 hhash->pHashInBuffPtr = pInBuffer;
\r
1088 hhash->pHashOutBuffPtr = pOutBuffer;
\r
1090 /* Check if initialization phase has already been performed */
\r
1091 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1093 /* Select the SHA256 mode */
\r
1094 HASH->CR |= HASH_ALGOSELECTION_SHA256;
\r
1095 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
1096 the message digest of a new message */
\r
1097 HASH->CR |= HASH_CR_INIT;
\r
1100 /* Set the phase */
\r
1101 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1103 /* Process Unlocked */
\r
1104 __HAL_UNLOCK(hhash);
\r
1106 /* Enable Interrupts */
\r
1107 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
\r
1109 /* Return function status */
\r
1112 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
\r
1114 /* Read the message digest */
\r
1115 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 32);
\r
1116 if(hhash->HashInCount == 0)
\r
1118 /* Disable Interrupts */
\r
1120 /* Change the HASH state */
\r
1121 hhash->State = HAL_HASH_STATE_READY;
\r
1122 /* Call digest computation complete callback */
\r
1123 HAL_HASH_DgstCpltCallback(hhash);
\r
1126 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
\r
1128 if(hhash->HashInCount > 64)
\r
1130 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
1131 /* Write the Input block in the Data IN register */
\r
1132 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
\r
1134 HASH->DIN = *(uint32_t*)inputaddr;
\r
1137 if(hhash->HashITCounter == 0)
\r
1139 HASH->DIN = *(uint32_t*)inputaddr;
\r
1141 if(hhash->HashInCount >= 68)
\r
1143 /* Decrement buffer counter */
\r
1144 hhash->HashInCount -= 68;
\r
1145 hhash->pHashInBuffPtr+= 68;
\r
1149 hhash->HashInCount -= 64;
\r
1154 /* Decrement buffer counter */
\r
1155 hhash->HashInCount -= 64;
\r
1156 hhash->pHashInBuffPtr+= 64;
\r
1161 /* Get the buffer address */
\r
1162 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
\r
1163 /* Get the buffer counter */
\r
1164 inputcounter = hhash->HashInCount;
\r
1165 /* Disable Interrupts */
\r
1166 HASH->IMR &= ~(HASH_IT_DINI);
\r
1167 /* Configure the number of valid bits in last word of the message */
\r
1168 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
\r
1170 if((inputcounter > 4) && (inputcounter%4))
\r
1172 inputcounter = (inputcounter+4-inputcounter%4);
\r
1175 /* Write the Input block in the Data IN register */
\r
1176 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
\r
1178 HASH->DIN = *(uint32_t*)inputaddr;
\r
1181 /* Start the digest calculation */
\r
1182 __HAL_HASH_START_DIGEST();
\r
1183 /* Reset buffer counter */
\r
1184 hhash->HashInCount = 0;
\r
1186 /* Call Input data transfer complete callback */
\r
1187 HAL_HASH_InCpltCallback(hhash);
\r
1190 /* Process Unlocked */
\r
1191 __HAL_UNLOCK(hhash);
\r
1193 /* Return function status */
\r
1198 * @brief This function handles HASH interrupt request.
\r
1199 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1200 * the configuration information for HASH module
\r
1203 void HAL_HASHEx_IRQHandler(HASH_HandleTypeDef *hhash)
\r
1205 switch(HASH->CR & HASH_CR_ALGO)
\r
1208 case HASH_ALGOSELECTION_SHA224:
\r
1209 HAL_HASHEx_SHA224_Start_IT(hhash, NULL, 0, NULL);
\r
1212 case HASH_ALGOSELECTION_SHA256:
\r
1213 HAL_HASHEx_SHA256_Start_IT(hhash, NULL, 0, NULL);
\r
1225 /** @defgroup HASHEx_Group4 HASH processing functions using DMA mode
\r
1226 * @brief processing functions using DMA mode.
\r
1229 ===============================================================================
\r
1230 ##### HASH processing using DMA functions #####
\r
1231 ===============================================================================
\r
1232 [..] This section provides functions allowing to calculate in DMA mode
\r
1233 the hash value using one of the following algorithms:
\r
1243 * @brief Initializes the HASH peripheral in SHA224 mode then enables DMA to
\r
1244 control data transfer. Use HAL_HASH_SHA224_Finish() to get the digest.
\r
1245 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1246 * the configuration information for HASH module
\r
1247 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1248 * @param Size: Length of the input buffer in bytes.
\r
1249 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1250 * @retval HAL status
\r
1252 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1254 uint32_t inputaddr = (uint32_t)pInBuffer;
\r
1256 /* Process Locked */
\r
1257 __HAL_LOCK(hhash);
\r
1259 /* Change the HASH state */
\r
1260 hhash->State = HAL_HASH_STATE_BUSY;
\r
1262 /* Check if initialization phase has already been performed */
\r
1263 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1265 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
1266 the message digest of a new message */
\r
1267 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
\r
1270 /* Configure the number of valid bits in last word of the message */
\r
1271 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
1273 /* Set the phase */
\r
1274 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1276 /* Set the HASH DMA transfer complete callback */
\r
1277 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
1278 /* Set the DMA error callback */
\r
1279 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
\r
1281 /* Enable the DMA In DMA Stream */
\r
1282 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
\r
1284 /* Enable DMA requests */
\r
1285 HASH->CR |= (HASH_CR_DMAE);
\r
1287 /* Process Unlocked */
\r
1288 __HAL_UNLOCK(hhash);
\r
1290 /* Return function status */
\r
1295 * @brief Returns the computed digest in SHA224
\r
1296 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1297 * the configuration information for HASH module
\r
1298 * @param pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
\r
1299 * @param Timeout: Timeout value
\r
1300 * @retval HAL status
\r
1302 HAL_StatusTypeDef HAL_HASHEx_SHA224_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
\r
1304 uint32_t tickstart = 0;
\r
1306 /* Process Locked */
\r
1307 __HAL_LOCK(hhash);
\r
1309 /* Change HASH peripheral state */
\r
1310 hhash->State = HAL_HASH_STATE_BUSY;
\r
1313 tickstart = HAL_GetTick();
\r
1315 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
\r
1317 /* Check for the Timeout */
\r
1318 if(Timeout != HAL_MAX_DELAY)
\r
1320 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1322 /* Change state */
\r
1323 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1325 /* Process Unlocked */
\r
1326 __HAL_UNLOCK(hhash);
\r
1328 return HAL_TIMEOUT;
\r
1333 /* Read the message digest */
\r
1334 HASHEx_GetDigest(pOutBuffer, 28);
\r
1336 /* Change HASH peripheral state */
\r
1337 hhash->State = HAL_HASH_STATE_READY;
\r
1339 /* Process Unlocked */
\r
1340 __HAL_UNLOCK(hhash);
\r
1342 /* Return function status */
\r
1347 * @brief Initializes the HASH peripheral in SHA256 mode then enables DMA to
\r
1348 control data transfer. Use HAL_HASH_SHA256_Finish() to get the digest.
\r
1349 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1350 * the configuration information for HASH module
\r
1351 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1352 * @param Size: Length of the input buffer in bytes.
\r
1353 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1354 * @retval HAL status
\r
1356 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1358 uint32_t inputaddr = (uint32_t)pInBuffer;
\r
1360 /* Process Locked */
\r
1361 __HAL_LOCK(hhash);
\r
1363 /* Change the HASH state */
\r
1364 hhash->State = HAL_HASH_STATE_BUSY;
\r
1366 /* Check if initialization phase has already been performed */
\r
1367 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1369 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
\r
1370 the message digest of a new message */
\r
1371 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
\r
1374 /* Configure the number of valid bits in last word of the message */
\r
1375 __HAL_HASH_SET_NBVALIDBITS(Size);
\r
1377 /* Set the phase */
\r
1378 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1380 /* Set the HASH DMA transfer complete callback */
\r
1381 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
1382 /* Set the DMA error callback */
\r
1383 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
\r
1385 /* Enable the DMA In DMA Stream */
\r
1386 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4 ? (Size+3)/4:Size/4));
\r
1388 /* Enable DMA requests */
\r
1389 HASH->CR |= (HASH_CR_DMAE);
\r
1391 /* Process UnLock */
\r
1392 __HAL_UNLOCK(hhash);
\r
1394 /* Return function status */
\r
1399 * @brief Returns the computed digest in SHA256.
\r
1400 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1401 * the configuration information for HASH module
\r
1402 * @param pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
\r
1403 * @param Timeout: Timeout value
\r
1404 * @retval HAL status
\r
1406 HAL_StatusTypeDef HAL_HASHEx_SHA256_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
\r
1408 uint32_t tickstart = 0;
\r
1410 /* Process Locked */
\r
1411 __HAL_LOCK(hhash);
\r
1413 /* Change HASH peripheral state */
\r
1414 hhash->State = HAL_HASH_STATE_BUSY;
\r
1417 tickstart = HAL_GetTick();
\r
1419 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
\r
1421 /* Check for the Timeout */
\r
1422 if(Timeout != HAL_MAX_DELAY)
\r
1424 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1426 /* Change state */
\r
1427 hhash->State = HAL_HASH_STATE_TIMEOUT;
\r
1429 /* Process Unlocked */
\r
1430 __HAL_UNLOCK(hhash);
\r
1432 return HAL_TIMEOUT;
\r
1437 /* Read the message digest */
\r
1438 HASHEx_GetDigest(pOutBuffer, 32);
\r
1440 /* Change HASH peripheral state */
\r
1441 hhash->State = HAL_HASH_STATE_READY;
\r
1443 /* Process Unlocked */
\r
1444 __HAL_UNLOCK(hhash);
\r
1446 /* Return function status */
\r
1454 /** @defgroup HASHEx_Group5 HMAC processing functions using DMA mode
\r
1455 * @brief HMAC processing functions using DMA mode .
\r
1458 ===============================================================================
\r
1459 ##### HMAC processing using DMA functions #####
\r
1460 ===============================================================================
\r
1461 [..] This section provides functions allowing to calculate in DMA mode
\r
1462 the HMAC value using one of the following algorithms:
\r
1471 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
\r
1472 * then enables DMA to control data transfer.
\r
1473 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1474 * the configuration information for HASH module
\r
1475 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1476 * @param Size: Length of the input buffer in bytes.
\r
1477 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1478 * @retval HAL status
\r
1480 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1482 uint32_t inputaddr;
\r
1484 /* Process Locked */
\r
1485 __HAL_LOCK(hhash);
\r
1487 /* Change the HASH state */
\r
1488 hhash->State = HAL_HASH_STATE_BUSY;
\r
1490 /* Save buffer pointer and size in handle */
\r
1491 hhash->pHashInBuffPtr = pInBuffer;
\r
1492 hhash->HashBuffSize = Size;
\r
1493 hhash->HashInCount = 0;
\r
1495 /* Check if initialization phase has already been performed */
\r
1496 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1498 /* Check if key size is greater than 64 bytes */
\r
1499 if(hhash->Init.KeySize > 64)
\r
1501 /* Select the HMAC SHA224 mode */
\r
1502 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
\r
1506 /* Select the HMAC SHA224 mode */
\r
1507 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
\r
1511 /* Set the phase */
\r
1512 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1514 /* Configure the number of valid bits in last word of the message */
\r
1515 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1517 /* Get the key address */
\r
1518 inputaddr = (uint32_t)(hhash->Init.pKey);
\r
1520 /* Set the HASH DMA transfer complete callback */
\r
1521 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
1522 /* Set the DMA error callback */
\r
1523 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
\r
1525 /* Enable the DMA In DMA Stream */
\r
1526 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
1527 /* Enable DMA requests */
\r
1528 HASH->CR |= (HASH_CR_DMAE);
\r
1530 /* Process Unlocked */
\r
1531 __HAL_UNLOCK(hhash);
\r
1533 /* Return function status */
\r
1538 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
\r
1539 * then enables DMA to control data transfer.
\r
1540 * @param hhash: pointer to a HASH_HandleTypeDef structure that contains
\r
1541 * the configuration information for HASH module
\r
1542 * @param pInBuffer: Pointer to the input buffer (buffer to be hashed).
\r
1543 * @param Size: Length of the input buffer in bytes.
\r
1544 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
\r
1545 * @retval HAL status
\r
1547 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
\r
1549 uint32_t inputaddr;
\r
1551 /* Process Locked */
\r
1552 __HAL_LOCK(hhash);
\r
1554 /* Change the HASH state */
\r
1555 hhash->State = HAL_HASH_STATE_BUSY;
\r
1557 /* Save buffer pointer and size in handle */
\r
1558 hhash->pHashInBuffPtr = pInBuffer;
\r
1559 hhash->HashBuffSize = Size;
\r
1560 hhash->HashInCount = 0;
\r
1562 /* Check if initialization phase has already been performed */
\r
1563 if(hhash->Phase == HAL_HASH_PHASE_READY)
\r
1565 /* Check if key size is greater than 64 bytes */
\r
1566 if(hhash->Init.KeySize > 64)
\r
1568 /* Select the HMAC SHA256 mode */
\r
1569 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);
\r
1573 /* Select the HMAC SHA256 mode */
\r
1574 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);
\r
1576 /* Reset the HASH processor core, so that the HASH will be ready to compute
\r
1577 the message digest of a new message */
\r
1578 HASH->CR |= HASH_CR_INIT;
\r
1581 /* Set the phase */
\r
1582 hhash->Phase = HAL_HASH_PHASE_PROCESS;
\r
1584 /* Configure the number of valid bits in last word of the message */
\r
1585 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
\r
1587 /* Get the key address */
\r
1588 inputaddr = (uint32_t)(hhash->Init.pKey);
\r
1590 /* Set the HASH DMA transfer complete callback */
\r
1591 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
\r
1592 /* Set the DMA error callback */
\r
1593 hhash->hdmain->XferErrorCallback = HASHEx_DMAError;
\r
1595 /* Enable the DMA In DMA Stream */
\r
1596 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
1597 /* Enable DMA requests */
\r
1598 HASH->CR |= (HASH_CR_DMAE);
\r
1600 /* Process Unlocked */
\r
1601 __HAL_UNLOCK(hhash);
\r
1603 /* Return function status */
\r
1614 #endif /* STM32F756xx */
\r
1616 #endif /* HAL_HASH_MODULE_ENABLED */
\r
1625 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r