b6bd942570cf7d7016f17829c1a51897003fef65
[mTask.git] / int / com / lib / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_hash.c
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_hash.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 22-April-2016
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
15 *
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.
66
67 @endverbatim
68 ******************************************************************************
69 * @attention
70 *
71 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
72 *
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.
83 *
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.
94 *
95 ******************************************************************************
96 */
97
98 /* Includes ------------------------------------------------------------------*/
99 #include "stm32f7xx_hal.h"
100
101 /** @addtogroup STM32F7xx_HAL_Driver
102 * @{
103 */
104
105 #if defined (STM32F756xx) || defined (STM32F777xx) || defined (STM32F779xx)
106
107 /** @defgroup HASH HASH
108 * @brief HASH HAL module driver.
109 * @{
110 */
111 #ifdef HAL_HASH_MODULE_ENABLED
112
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 * @{
120 */
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);
125 /**
126 * @}
127 */
128
129 /* Private functions ---------------------------------------------------------*/
130 /** @addtogroup HASH_Private_Functions
131 * @{
132 */
133
134 /**
135 * @brief DMA HASH Input Data complete callback.
136 * @param hdma: DMA handle
137 * @retval None
138 */
139 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
140 {
141 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
142 uint32_t inputaddr = 0;
143 uint32_t buffersize = 0;
144
145 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
146 {
147 /* Disable the DMA transfer */
148 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
149
150 /* Change HASH peripheral state */
151 hhash->State = HAL_HASH_STATE_READY;
152
153 /* Call Input data transfer complete callback */
154 HAL_HASH_InCpltCallback(hhash);
155 }
156 else
157 {
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);
162
163 if(hhash->HashInCount <= 2)
164 {
165 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
166 if(hhash->HashInCount == 1)
167 {
168 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
169 buffersize = hhash->HashBuffSize;
170 }
171 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
172 else if(hhash->HashInCount == 2)
173 {
174 inputaddr = (uint32_t)hhash->Init.pKey;
175 buffersize = hhash->Init.KeySize;
176 }
177 /* Configure the number of valid bits in last word of the message */
178 MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8 * (buffersize % 4));
179
180 /* Set the HASH DMA transfer complete */
181 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
182
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));
185
186 /* Enable DMA requests */
187 HASH->CR |= (HASH_CR_DMAE);
188 }
189 else
190 {
191 /* Disable the DMA transfer */
192 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
193
194 /* Reset the InCount */
195 hhash->HashInCount = 0;
196
197 /* Change HASH peripheral state */
198 hhash->State = HAL_HASH_STATE_READY;
199
200 /* Call Input data transfer complete callback */
201 HAL_HASH_InCpltCallback(hhash);
202 }
203 }
204 }
205
206 /**
207 * @brief DMA HASH communication error callback.
208 * @param hdma: DMA handle
209 * @retval None
210 */
211 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
212 {
213 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
214 hhash->State= HAL_HASH_STATE_READY;
215 HAL_HASH_ErrorCallback(hhash);
216 }
217
218 /**
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
223 */
224 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
225 {
226 uint32_t buffercounter;
227 uint32_t inputaddr = (uint32_t) pInBuffer;
228
229 for(buffercounter = 0; buffercounter < Size; buffercounter+=4)
230 {
231 HASH->DIN = *(uint32_t*)inputaddr;
232 inputaddr+=4;
233 }
234 }
235
236 /**
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
241 */
242 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
243 {
244 uint32_t msgdigest = (uint32_t)pMsgDigest;
245
246 switch(Size)
247 {
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;
306 }
307 }
308
309 /**
310 * @}
311 */
312
313 /* Exported functions --------------------------------------------------------*/
314 /** @addtogroup HASH_Exported_Functions
315 * @{
316 */
317
318
319 /** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions
320 * @brief Initialization and Configuration functions.
321 *
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.
332
333 @endverbatim
334 * @{
335 */
336
337 /**
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
343 */
344 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
345 {
346 /* Check the hash handle allocation */
347 if(hhash == NULL)
348 {
349 return HAL_ERROR;
350 }
351
352 /* Check the parameters */
353 assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
354
355 if(hhash->State == HAL_HASH_STATE_RESET)
356 {
357 /* Allocate lock resource and initialize it */
358 hhash->Lock = HAL_UNLOCKED;
359 /* Init the low level hardware */
360 HAL_HASH_MspInit(hhash);
361 }
362
363 /* Change the HASH state */
364 hhash->State = HAL_HASH_STATE_BUSY;
365
366 /* Reset HashInCount, HashBuffSize and HashITCounter */
367 hhash->HashInCount = 0;
368 hhash->HashBuffSize = 0;
369 hhash->HashITCounter = 0;
370
371 /* Set the data type */
372 HASH->CR |= (uint32_t) (hhash->Init.DataType);
373
374 /* Change the HASH state */
375 hhash->State = HAL_HASH_STATE_READY;
376
377 /* Set the default HASH phase */
378 hhash->Phase = HAL_HASH_PHASE_READY;
379
380 /* Return function status */
381 return HAL_OK;
382 }
383
384 /**
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
390 */
391 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
392 {
393 /* Check the HASH handle allocation */
394 if(hhash == NULL)
395 {
396 return HAL_ERROR;
397 }
398
399 /* Change the HASH state */
400 hhash->State = HAL_HASH_STATE_BUSY;
401
402 /* Set the default HASH phase */
403 hhash->Phase = HAL_HASH_PHASE_READY;
404
405 /* Reset HashInCount, HashBuffSize and HashITCounter */
406 hhash->HashInCount = 0;
407 hhash->HashBuffSize = 0;
408 hhash->HashITCounter = 0;
409
410 /* DeInit the low level hardware */
411 HAL_HASH_MspDeInit(hhash);
412
413 /* Change the HASH state */
414 hhash->State = HAL_HASH_STATE_RESET;
415
416 /* Release Lock */
417 __HAL_UNLOCK(hhash);
418
419 /* Return function status */
420 return HAL_OK;
421 }
422
423 /**
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
428 */
429 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
430 {
431 /* Prevent unused argument(s) compilation warning */
432 UNUSED(hhash);
433
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
436 */
437 }
438
439 /**
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
444 */
445 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
446 {
447 /* Prevent unused argument(s) compilation warning */
448 UNUSED(hhash);
449
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
452 */
453 }
454
455 /**
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
460 */
461 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
462 {
463 /* Prevent unused argument(s) compilation warning */
464 UNUSED(hhash);
465
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
468 */
469 }
470
471 /**
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
476 */
477 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
478 {
479 /* Prevent unused argument(s) compilation warning */
480 UNUSED(hhash);
481
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
484 */
485 }
486
487 /**
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
493 */
494 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
495 {
496 /* Prevent unused argument(s) compilation warning */
497 UNUSED(hhash);
498
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
501 */
502 }
503
504 /**
505 * @}
506 */
507
508 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions using polling mode
509 * @brief processing functions using polling mode
510 *
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
519
520 @endverbatim
521 * @{
522 */
523
524 /**
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
537 */
538 HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
539 {
540 uint32_t tickstart = 0;
541
542 /* Process Locked */
543 __HAL_LOCK(hhash);
544
545 /* Change the HASH state */
546 hhash->State = HAL_HASH_STATE_BUSY;
547
548 /* Check if initialization phase has already been performed */
549 if(hhash->Phase == HAL_HASH_PHASE_READY)
550 {
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;
554 }
555
556 /* Set the phase */
557 hhash->Phase = HAL_HASH_PHASE_PROCESS;
558
559 /* Configure the number of valid bits in last word of the message */
560 __HAL_HASH_SET_NBVALIDBITS(Size);
561
562 /* Write input buffer in data register */
563 HASH_WriteData(pInBuffer, Size);
564
565 /* Start the digest calculation */
566 __HAL_HASH_START_DIGEST();
567
568 /* Get tick */
569 tickstart = HAL_GetTick();
570
571 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
572 {
573 /* Check for the Timeout */
574 if(Timeout != HAL_MAX_DELAY)
575 {
576 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
577 {
578 /* Change state */
579 hhash->State = HAL_HASH_STATE_TIMEOUT;
580
581 /* Process Unlocked */
582 __HAL_UNLOCK(hhash);
583
584 return HAL_TIMEOUT;
585 }
586 }
587 }
588
589 /* Read the message digest */
590 HASH_GetDigest(pOutBuffer, 16);
591
592 /* Change the HASH state */
593 hhash->State = HAL_HASH_STATE_READY;
594
595 /* Process Unlocked */
596 __HAL_UNLOCK(hhash);
597
598 /* Return function status */
599 return HAL_OK;
600 }
601
602 /**
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
612 */
613 HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
614 {
615 /* Process Locked */
616 __HAL_LOCK(hhash);
617
618 /* Change the HASH state */
619 hhash->State = HAL_HASH_STATE_BUSY;
620
621 /* Check if initialization phase has already been performed */
622 if(hhash->Phase == HAL_HASH_PHASE_READY)
623 {
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;
627 }
628
629 /* Set the phase */
630 hhash->Phase = HAL_HASH_PHASE_PROCESS;
631
632 /* Configure the number of valid bits in last word of the message */
633 __HAL_HASH_SET_NBVALIDBITS(Size);
634
635 /* Write input buffer in data register */
636 HASH_WriteData(pInBuffer, Size);
637
638 /* Change the HASH state */
639 hhash->State = HAL_HASH_STATE_READY;
640
641 /* Process Unlocked */
642 __HAL_UNLOCK(hhash);
643
644 /* Return function status */
645 return HAL_OK;
646 }
647
648 /**
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
659 */
660 HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
661 {
662 uint32_t tickstart = 0;
663
664 /* Process Locked */
665 __HAL_LOCK(hhash);
666
667 /* Change the HASH state */
668 hhash->State = HAL_HASH_STATE_BUSY;
669
670 /* Check if initialization phase has already been performed */
671 if(hhash->Phase == HAL_HASH_PHASE_READY)
672 {
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;
676 }
677
678 /* Set the phase */
679 hhash->Phase = HAL_HASH_PHASE_PROCESS;
680
681 /* Configure the number of valid bits in last word of the message */
682 __HAL_HASH_SET_NBVALIDBITS(Size);
683
684 /* Write input buffer in data register */
685 HASH_WriteData(pInBuffer, Size);
686
687 /* Start the digest calculation */
688 __HAL_HASH_START_DIGEST();
689
690 /* Get tick */
691 tickstart = HAL_GetTick();
692
693 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
694 {
695 /* Check for the Timeout */
696 if(Timeout != HAL_MAX_DELAY)
697 {
698 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
699 {
700 /* Change state */
701 hhash->State = HAL_HASH_STATE_TIMEOUT;
702
703 /* Process Unlocked */
704 __HAL_UNLOCK(hhash);
705
706 return HAL_TIMEOUT;
707 }
708 }
709 }
710
711 /* Read the message digest */
712 HASH_GetDigest(pOutBuffer, 20);
713
714 /* Change the HASH state */
715 hhash->State = HAL_HASH_STATE_READY;
716
717 /* Process Unlocked */
718 __HAL_UNLOCK(hhash);
719
720 /* Return function status */
721 return HAL_OK;
722 }
723
724 /**
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
733 */
734 HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
735 {
736 /* Check the parameters */
737 assert_param(IS_HASH_SHA1_BUFFER_SIZE(Size));
738
739 /* Process Locked */
740 __HAL_LOCK(hhash);
741
742 /* Change the HASH state */
743 hhash->State = HAL_HASH_STATE_BUSY;
744
745 /* Check if initialization phase has already been performed */
746 if(hhash->Phase == HAL_HASH_PHASE_READY)
747 {
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;
751 }
752
753 /* Set the phase */
754 hhash->Phase = HAL_HASH_PHASE_PROCESS;
755
756 /* Configure the number of valid bits in last word of the message */
757 __HAL_HASH_SET_NBVALIDBITS(Size);
758
759 /* Write input buffer in data register */
760 HASH_WriteData(pInBuffer, Size);
761
762 /* Change the HASH state */
763 hhash->State = HAL_HASH_STATE_READY;
764
765 /* Process Unlocked */
766 __HAL_UNLOCK(hhash);
767
768 /* Return function status */
769 return HAL_OK;
770 }
771
772 /**
773 * @}
774 */
775
776 /** @defgroup HASH_Exported_Functions_Group3 HASH processing functions using interrupt mode
777 * @brief processing functions using interrupt mode.
778 *
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
787
788 @endverbatim
789 * @{
790 */
791
792 /**
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
802 */
803 HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
804 {
805 uint32_t inputaddr;
806 uint32_t outputaddr;
807 uint32_t buffercounter;
808 uint32_t inputcounter;
809
810 /* Process Locked */
811 __HAL_LOCK(hhash);
812
813 if(hhash->State == HAL_HASH_STATE_READY)
814 {
815 /* Change the HASH state */
816 hhash->State = HAL_HASH_STATE_BUSY;
817
818 hhash->HashInCount = Size;
819 hhash->pHashInBuffPtr = pInBuffer;
820 hhash->pHashOutBuffPtr = pOutBuffer;
821
822 /* Check if initialization phase has already been performed */
823 if(hhash->Phase == HAL_HASH_PHASE_READY)
824 {
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;
830 }
831
832 /* Reset interrupt counter */
833 hhash->HashITCounter = 0;
834
835 /* Set the phase */
836 hhash->Phase = HAL_HASH_PHASE_PROCESS;
837
838 /* Process Unlocked */
839 __HAL_UNLOCK(hhash);
840
841 /* Enable Interrupts */
842 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
843
844 /* Return function status */
845 return HAL_OK;
846 }
847 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
848 {
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]);
858
859 if(hhash->HashInCount == 0)
860 {
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);
867
868 /* Process Unlocked */
869 __HAL_UNLOCK(hhash);
870
871 /* Return function status */
872 return HAL_OK;
873 }
874 }
875
876 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
877 {
878 if(hhash->HashInCount >= 68)
879 {
880 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
881 /* Write the Input block in the Data IN register */
882 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
883 {
884 HASH->DIN = *(uint32_t*)inputaddr;
885 inputaddr+=4;
886 }
887 if(hhash->HashITCounter == 0)
888 {
889 HASH->DIN = *(uint32_t*)inputaddr;
890
891 if(hhash->HashInCount >= 68)
892 {
893 /* Decrement buffer counter */
894 hhash->HashInCount -= 68;
895 hhash->pHashInBuffPtr+= 68;
896 }
897 else
898 {
899 hhash->HashInCount = 0;
900 hhash->pHashInBuffPtr+= hhash->HashInCount;
901 }
902 /* Set Interrupt counter */
903 hhash->HashITCounter = 1;
904 }
905 else
906 {
907 /* Decrement buffer counter */
908 hhash->HashInCount -= 64;
909 hhash->pHashInBuffPtr+= 64;
910 }
911 }
912 else
913 {
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);
922
923 if((inputcounter > 4) && (inputcounter%4))
924 {
925 inputcounter = (inputcounter+4-inputcounter%4);
926 }
927 else if ((inputcounter < 4) && (inputcounter != 0))
928 {
929 inputcounter = 4;
930 }
931
932 /* Write the Input block in the Data IN register */
933 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
934 {
935 HASH->DIN = *(uint32_t*)inputaddr;
936 inputaddr+=4;
937 }
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);
944 }
945 }
946
947 /* Process Unlocked */
948 __HAL_UNLOCK(hhash);
949
950 /* Return function status */
951 return HAL_OK;
952 }
953
954 /**
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
964 */
965 HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
966 {
967 uint32_t inputaddr;
968 uint32_t outputaddr;
969 uint32_t buffercounter;
970 uint32_t inputcounter;
971
972 /* Process Locked */
973 __HAL_LOCK(hhash);
974
975 if(hhash->State == HAL_HASH_STATE_READY)
976 {
977 /* Change the HASH state */
978 hhash->State = HAL_HASH_STATE_BUSY;
979
980 hhash->HashInCount = Size;
981 hhash->pHashInBuffPtr = pInBuffer;
982 hhash->pHashOutBuffPtr = pOutBuffer;
983
984 /* Check if initialization phase has already been performed */
985 if(hhash->Phase == HAL_HASH_PHASE_READY)
986 {
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;
992 }
993
994 /* Reset interrupt counter */
995 hhash->HashITCounter = 0;
996
997 /* Set the phase */
998 hhash->Phase = HAL_HASH_PHASE_PROCESS;
999
1000 /* Process Unlocked */
1001 __HAL_UNLOCK(hhash);
1002
1003 /* Enable Interrupts */
1004 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
1005
1006 /* Return function status */
1007 return HAL_OK;
1008 }
1009 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
1010 {
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)
1023 {
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);
1030
1031 /* Process Unlocked */
1032 __HAL_UNLOCK(hhash);
1033
1034 /* Return function status */
1035 return HAL_OK;
1036 }
1037 }
1038 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
1039 {
1040 if(hhash->HashInCount >= 68)
1041 {
1042 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1043 /* Write the Input block in the Data IN register */
1044 for(buffercounter = 0; buffercounter < 64; buffercounter+=4)
1045 {
1046 HASH->DIN = *(uint32_t*)inputaddr;
1047 inputaddr+=4;
1048 }
1049 if(hhash->HashITCounter == 0)
1050 {
1051 HASH->DIN = *(uint32_t*)inputaddr;
1052
1053 if(hhash->HashInCount >= 68)
1054 {
1055 /* Decrement buffer counter */
1056 hhash->HashInCount -= 68;
1057 hhash->pHashInBuffPtr+= 68;
1058 }
1059 else
1060 {
1061 hhash->HashInCount = 0;
1062 hhash->pHashInBuffPtr+= hhash->HashInCount;
1063 }
1064 /* Set Interrupt counter */
1065 hhash->HashITCounter = 1;
1066 }
1067 else
1068 {
1069 /* Decrement buffer counter */
1070 hhash->HashInCount -= 64;
1071 hhash->pHashInBuffPtr+= 64;
1072 }
1073 }
1074 else
1075 {
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);
1084
1085 if((inputcounter > 4) && (inputcounter%4))
1086 {
1087 inputcounter = (inputcounter+4-inputcounter%4);
1088 }
1089 else if ((inputcounter < 4) && (inputcounter != 0))
1090 {
1091 inputcounter = 4;
1092 }
1093 /* Write the Input block in the Data IN register */
1094 for(buffercounter = 0; buffercounter < inputcounter/4; buffercounter++)
1095 {
1096 HASH->DIN = *(uint32_t*)inputaddr;
1097 inputaddr+=4;
1098 }
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);
1105 }
1106 }
1107
1108 /* Process Unlocked */
1109 __HAL_UNLOCK(hhash);
1110
1111 /* Return function status */
1112 return HAL_OK;
1113 }
1114
1115 /**
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
1120 */
1121 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
1122 {
1123 switch(HASH->CR & HASH_CR_ALGO)
1124 {
1125 case HASH_ALGOSELECTION_MD5:
1126 HAL_HASH_MD5_Start_IT(hhash, NULL, 0, NULL);
1127 break;
1128
1129 case HASH_ALGOSELECTION_SHA1:
1130 HAL_HASH_SHA1_Start_IT(hhash, NULL, 0, NULL);
1131 break;
1132
1133 default:
1134 break;
1135 }
1136 }
1137
1138 /**
1139 * @}
1140 */
1141
1142 /** @defgroup HASH_Exported_Functions_Group4 HASH processing functions using DMA mode
1143 * @brief processing functions using DMA mode.
1144 *
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
1153
1154 @endverbatim
1155 * @{
1156 */
1157
1158 /**
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
1167 */
1168 HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1169 {
1170 uint32_t inputaddr = (uint32_t)pInBuffer;
1171
1172 /* Process Locked */
1173 __HAL_LOCK(hhash);
1174
1175 /* Change the HASH state */
1176 hhash->State = HAL_HASH_STATE_BUSY;
1177
1178 /* Check if initialization phase has already been performed */
1179 if(hhash->Phase == HAL_HASH_PHASE_READY)
1180 {
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;
1184 }
1185
1186 /* Configure the number of valid bits in last word of the message */
1187 __HAL_HASH_SET_NBVALIDBITS(Size);
1188
1189 /* Set the phase */
1190 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1191
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;
1196
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));
1199
1200 /* Enable DMA requests */
1201 HASH->CR |= (HASH_CR_DMAE);
1202
1203 /* Process Unlocked */
1204 __HAL_UNLOCK(hhash);
1205
1206 /* Return function status */
1207 return HAL_OK;
1208 }
1209
1210 /**
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
1217 */
1218 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1219 {
1220 uint32_t tickstart = 0;
1221
1222 /* Process Locked */
1223 __HAL_LOCK(hhash);
1224
1225 /* Change HASH peripheral state */
1226 hhash->State = HAL_HASH_STATE_BUSY;
1227
1228 /* Get tick */
1229 tickstart = HAL_GetTick();
1230
1231 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1232 {
1233 /* Check for the Timeout */
1234 if(Timeout != HAL_MAX_DELAY)
1235 {
1236 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1237 {
1238 /* Change state */
1239 hhash->State = HAL_HASH_STATE_TIMEOUT;
1240
1241 /* Process Unlocked */
1242 __HAL_UNLOCK(hhash);
1243
1244 return HAL_TIMEOUT;
1245 }
1246 }
1247 }
1248
1249 /* Read the message digest */
1250 HASH_GetDigest(pOutBuffer, 16);
1251
1252 /* Change HASH peripheral state */
1253 hhash->State = HAL_HASH_STATE_READY;
1254
1255 /* Process Unlocked */
1256 __HAL_UNLOCK(hhash);
1257
1258 /* Return function status */
1259 return HAL_OK;
1260 }
1261
1262 /**
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
1271 */
1272 HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1273 {
1274 uint32_t inputaddr = (uint32_t)pInBuffer;
1275
1276 /* Process Locked */
1277 __HAL_LOCK(hhash);
1278
1279 /* Change the HASH state */
1280 hhash->State = HAL_HASH_STATE_BUSY;
1281
1282 /* Check if initialization phase has already been performed */
1283 if(hhash->Phase == HAL_HASH_PHASE_READY)
1284 {
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;
1289 }
1290
1291 /* Configure the number of valid bits in last word of the message */
1292 __HAL_HASH_SET_NBVALIDBITS(Size);
1293
1294 /* Set the phase */
1295 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1296
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;
1301
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));
1304
1305 /* Enable DMA requests */
1306 HASH->CR |= (HASH_CR_DMAE);
1307
1308 /* Process Unlocked */
1309 __HAL_UNLOCK(hhash);
1310
1311 /* Return function status */
1312 return HAL_OK;
1313 }
1314
1315 /**
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
1322 */
1323 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1324 {
1325 uint32_t tickstart = 0;
1326
1327 /* Process Locked */
1328 __HAL_LOCK(hhash);
1329
1330 /* Change HASH peripheral state */
1331 hhash->State = HAL_HASH_STATE_BUSY;
1332
1333 /* Get tick */
1334 tickstart = HAL_GetTick();
1335 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1336 {
1337 /* Check for the Timeout */
1338 if(Timeout != HAL_MAX_DELAY)
1339 {
1340 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1341 {
1342 /* Change state */
1343 hhash->State = HAL_HASH_STATE_TIMEOUT;
1344
1345 /* Process Unlocked */
1346 __HAL_UNLOCK(hhash);
1347
1348 return HAL_TIMEOUT;
1349 }
1350 }
1351 }
1352
1353 /* Read the message digest */
1354 HASH_GetDigest(pOutBuffer, 20);
1355
1356 /* Change HASH peripheral state */
1357 hhash->State = HAL_HASH_STATE_READY;
1358
1359 /* Process UnLock */
1360 __HAL_UNLOCK(hhash);
1361
1362 /* Return function status */
1363 return HAL_OK;
1364 }
1365
1366
1367 /**
1368 * @}
1369 */
1370
1371 /** @defgroup HASH_Exported_Functions_Group5 HASH-MAC (HMAC) processing functions using polling mode
1372 * @brief HMAC processing functions using polling mode .
1373 *
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
1382
1383 @endverbatim
1384 * @{
1385 */
1386
1387 /**
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
1398 */
1399 HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1400 {
1401 uint32_t tickstart = 0;
1402
1403 /* Process Locked */
1404 __HAL_LOCK(hhash);
1405
1406 /* Change the HASH state */
1407 hhash->State = HAL_HASH_STATE_BUSY;
1408
1409 /* Check if initialization phase has already been performed */
1410 if(hhash->Phase == HAL_HASH_PHASE_READY)
1411 {
1412 /* Check if key size is greater than 64 bytes */
1413 if(hhash->Init.KeySize > 64)
1414 {
1415 /* Select the HMAC MD5 mode */
1416 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1417 }
1418 else
1419 {
1420 /* Select the HMAC MD5 mode */
1421 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1422 }
1423 }
1424
1425 /* Set the phase */
1426 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1427
1428 /************************** STEP 1 ******************************************/
1429 /* Configure the number of valid bits in last word of the message */
1430 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1431
1432 /* Write input buffer in data register */
1433 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1434
1435 /* Start the digest calculation */
1436 __HAL_HASH_START_DIGEST();
1437
1438 /* Get tick */
1439 tickstart = HAL_GetTick();
1440
1441 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1442 {
1443 /* Check for the Timeout */
1444 if(Timeout != HAL_MAX_DELAY)
1445 {
1446 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1447 {
1448 /* Change state */
1449 hhash->State = HAL_HASH_STATE_TIMEOUT;
1450
1451 /* Process Unlocked */
1452 __HAL_UNLOCK(hhash);
1453
1454 return HAL_TIMEOUT;
1455 }
1456 }
1457 }
1458 /************************** STEP 2 ******************************************/
1459 /* Configure the number of valid bits in last word of the message */
1460 __HAL_HASH_SET_NBVALIDBITS(Size);
1461
1462 /* Write input buffer in data register */
1463 HASH_WriteData(pInBuffer, Size);
1464
1465 /* Start the digest calculation */
1466 __HAL_HASH_START_DIGEST();
1467
1468 /* Get tick */
1469 tickstart = HAL_GetTick();
1470
1471 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1472 {
1473 /* Check for the Timeout */
1474 if(Timeout != HAL_MAX_DELAY)
1475 {
1476 if((HAL_GetTick() - tickstart ) > Timeout)
1477 {
1478 /* Change state */
1479 hhash->State = HAL_HASH_STATE_TIMEOUT;
1480
1481 /* Process Unlocked */
1482 __HAL_UNLOCK(hhash);
1483
1484 return HAL_TIMEOUT;
1485 }
1486 }
1487 }
1488 /************************** STEP 3 ******************************************/
1489 /* Configure the number of valid bits in last word of the message */
1490 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1491
1492 /* Write input buffer in data register */
1493 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1494
1495 /* Start the digest calculation */
1496 __HAL_HASH_START_DIGEST();
1497
1498 /* Get tick */
1499 tickstart = HAL_GetTick();
1500
1501 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1502 {
1503 /* Check for the Timeout */
1504 if(Timeout != HAL_MAX_DELAY)
1505 {
1506 if((HAL_GetTick() - tickstart ) > Timeout)
1507 {
1508 /* Change state */
1509 hhash->State = HAL_HASH_STATE_TIMEOUT;
1510
1511 /* Process Unlocked */
1512 __HAL_UNLOCK(hhash);
1513
1514 return HAL_TIMEOUT;
1515 }
1516 }
1517 }
1518
1519 /* Read the message digest */
1520 HASH_GetDigest(pOutBuffer, 16);
1521
1522 /* Change the HASH state */
1523 hhash->State = HAL_HASH_STATE_READY;
1524
1525 /* Process Unlocked */
1526 __HAL_UNLOCK(hhash);
1527
1528 /* Return function status */
1529 return HAL_OK;
1530 }
1531
1532 /**
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
1543 */
1544 HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1545 {
1546 uint32_t tickstart = 0;
1547
1548 /* Process Locked */
1549 __HAL_LOCK(hhash);
1550
1551 /* Change the HASH state */
1552 hhash->State = HAL_HASH_STATE_BUSY;
1553
1554 /* Check if initialization phase has already been performed */
1555 if(hhash->Phase == HAL_HASH_PHASE_READY)
1556 {
1557 /* Check if key size is greater than 64 bytes */
1558 if(hhash->Init.KeySize > 64)
1559 {
1560 /* Select the HMAC SHA1 mode */
1561 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1562 }
1563 else
1564 {
1565 /* Select the HMAC SHA1 mode */
1566 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1567 }
1568 }
1569
1570 /* Set the phase */
1571 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1572
1573 /************************** STEP 1 ******************************************/
1574 /* Configure the number of valid bits in last word of the message */
1575 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1576
1577 /* Write input buffer in data register */
1578 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1579
1580 /* Start the digest calculation */
1581 __HAL_HASH_START_DIGEST();
1582
1583 /* Get tick */
1584 tickstart = HAL_GetTick();
1585
1586 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1587 {
1588 /* Check for the Timeout */
1589 if(Timeout != HAL_MAX_DELAY)
1590 {
1591 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1592 {
1593 /* Change state */
1594 hhash->State = HAL_HASH_STATE_TIMEOUT;
1595
1596 /* Process Unlocked */
1597 __HAL_UNLOCK(hhash);
1598
1599 return HAL_TIMEOUT;
1600 }
1601 }
1602 }
1603 /************************** STEP 2 ******************************************/
1604 /* Configure the number of valid bits in last word of the message */
1605 __HAL_HASH_SET_NBVALIDBITS(Size);
1606
1607 /* Write input buffer in data register */
1608 HASH_WriteData(pInBuffer, Size);
1609
1610 /* Start the digest calculation */
1611 __HAL_HASH_START_DIGEST();
1612
1613 /* Get tick */
1614 tickstart = HAL_GetTick();
1615
1616 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1617 {
1618 /* Check for the Timeout */
1619 if(Timeout != HAL_MAX_DELAY)
1620 {
1621 if((HAL_GetTick() - tickstart ) > Timeout)
1622 {
1623 /* Change state */
1624 hhash->State = HAL_HASH_STATE_TIMEOUT;
1625
1626 /* Process Unlocked */
1627 __HAL_UNLOCK(hhash);
1628
1629 return HAL_TIMEOUT;
1630 }
1631 }
1632 }
1633 /************************** STEP 3 ******************************************/
1634 /* Configure the number of valid bits in last word of the message */
1635 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1636
1637 /* Write input buffer in data register */
1638 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1639
1640 /* Start the digest calculation */
1641 __HAL_HASH_START_DIGEST();
1642
1643 /* Get tick */
1644 tickstart = HAL_GetTick();
1645
1646 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1647 {
1648 /* Check for the Timeout */
1649 if(Timeout != HAL_MAX_DELAY)
1650 {
1651 if((HAL_GetTick() - tickstart ) > Timeout)
1652 {
1653 /* Change state */
1654 hhash->State = HAL_HASH_STATE_TIMEOUT;
1655
1656 /* Process Unlocked */
1657 __HAL_UNLOCK(hhash);
1658
1659 return HAL_TIMEOUT;
1660 }
1661 }
1662 }
1663 /* Read the message digest */
1664 HASH_GetDigest(pOutBuffer, 20);
1665
1666 /* Change the HASH state */
1667 hhash->State = HAL_HASH_STATE_READY;
1668
1669 /* Process Unlocked */
1670 __HAL_UNLOCK(hhash);
1671
1672 /* Return function status */
1673 return HAL_OK;
1674 }
1675
1676 /**
1677 * @}
1678 */
1679
1680 /** @defgroup HASH_Exported_Functions_Group6 HASH-MAC (HMAC) processing functions using DMA mode
1681 * @brief HMAC processing functions using DMA mode .
1682 *
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
1691
1692 @endverbatim
1693 * @{
1694 */
1695
1696 /**
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
1705 */
1706 HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1707 {
1708 uint32_t inputaddr = 0;
1709
1710 /* Process Locked */
1711 __HAL_LOCK(hhash);
1712
1713 /* Change the HASH state */
1714 hhash->State = HAL_HASH_STATE_BUSY;
1715
1716 /* Save buffer pointer and size in handle */
1717 hhash->pHashInBuffPtr = pInBuffer;
1718 hhash->HashBuffSize = Size;
1719 hhash->HashInCount = 0;
1720
1721 /* Check if initialization phase has already been performed */
1722 if(hhash->Phase == HAL_HASH_PHASE_READY)
1723 {
1724 /* Check if key size is greater than 64 bytes */
1725 if(hhash->Init.KeySize > 64)
1726 {
1727 /* Select the HMAC MD5 mode */
1728 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1729 }
1730 else
1731 {
1732 /* Select the HMAC MD5 mode */
1733 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1734 }
1735 }
1736
1737 /* Set the phase */
1738 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1739
1740 /* Configure the number of valid bits in last word of the message */
1741 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1742
1743 /* Get the key address */
1744 inputaddr = (uint32_t)(hhash->Init.pKey);
1745
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;
1750
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);
1755
1756 /* Process Unlocked */
1757 __HAL_UNLOCK(hhash);
1758
1759 /* Return function status */
1760 return HAL_OK;
1761 }
1762
1763 /**
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
1772 */
1773 HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1774 {
1775 uint32_t inputaddr = 0;
1776
1777 /* Process Locked */
1778 __HAL_LOCK(hhash);
1779
1780 /* Change the HASH state */
1781 hhash->State = HAL_HASH_STATE_BUSY;
1782
1783 /* Save buffer pointer and size in handle */
1784 hhash->pHashInBuffPtr = pInBuffer;
1785 hhash->HashBuffSize = Size;
1786 hhash->HashInCount = 0;
1787
1788 /* Check if initialization phase has already been performed */
1789 if(hhash->Phase == HAL_HASH_PHASE_READY)
1790 {
1791 /* Check if key size is greater than 64 bytes */
1792 if(hhash->Init.KeySize > 64)
1793 {
1794 /* Select the HMAC SHA1 mode */
1795 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1796 }
1797 else
1798 {
1799 /* Select the HMAC SHA1 mode */
1800 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1801 }
1802 }
1803
1804 /* Set the phase */
1805 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1806
1807 /* Configure the number of valid bits in last word of the message */
1808 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1809
1810 /* Get the key address */
1811 inputaddr = (uint32_t)(hhash->Init.pKey);
1812
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;
1817
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);
1822
1823 /* Process Unlocked */
1824 __HAL_UNLOCK(hhash);
1825
1826 /* Return function status */
1827 return HAL_OK;
1828 }
1829
1830 /**
1831 * @}
1832 */
1833
1834 /** @defgroup HASH_Exported_Functions_Group7 Peripheral State functions
1835 * @brief Peripheral State functions.
1836 *
1837 @verbatim
1838 ===============================================================================
1839 ##### Peripheral State functions #####
1840 ===============================================================================
1841 [..]
1842 This subsection permits to get in run-time the status of the peripheral.
1843
1844 @endverbatim
1845 * @{
1846 */
1847
1848 /**
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
1853 */
1854 HAL_HASH_StateTypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
1855 {
1856 return hhash->State;
1857 }
1858
1859 /**
1860 * @}
1861 */
1862
1863 /**
1864 * @}
1865 */
1866
1867 #endif /* HAL_HASH_MODULE_ENABLED */
1868
1869 /**
1870 * @}
1871 */
1872 #endif /* STM32F756xx || STM32F777xx || STM32F779xx */
1873
1874 /**
1875 * @}
1876 */
1877
1878 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/