comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c @ 160:e3ca52b8e7fa

Merge with FlipDisplay
author heinrichsweikamp
date Thu, 07 Mar 2019 15:06:43 +0100
parents c78bcbd5deda
children
comparison
equal deleted inserted replaced
80:cc2bb7bb8456 160:e3ca52b8e7fa
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_hash.c
4 * @author MCD Application Team
5 * @brief HASH HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the HASH peripheral:
8 * + Initialization and de-initialization functions
9 * + HASH/HMAC Processing functions by algorithm using polling mode
10 * + HASH/HMAC functions by algorithm using interrupt mode
11 * + HASH/HMAC functions by algorithm using DMA mode
12 * + Peripheral State functions
13 *
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
19 The HASH HAL driver can be used as follows:
20 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
21 (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
22 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMAC_SHA1_Start_IT())
23 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
24 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
25 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
26 (##) In case of using DMA to control data transfer (e.g. HAL_HMAC_SHA1_Start_DMA())
27 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
28 (+++) Configure and enable one DMA stream one for managing data transfer from
29 memory to peripheral (input stream). Managing data transfer from
30 peripheral to memory can be performed only using CPU
31 (+++) Associate the initialized DMA handle to the HASH DMA handle
32 using __HAL_LINKDMA()
33 (+++) Configure the priority and enable the NVIC for the transfer complete
34 interrupt on the DMA Stream using HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
35 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
36 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
37 (##) For HMAC, the encryption key.
38 (##) For HMAC, the key size used for encryption.
39 (#)Three processing functions are available:
40 (##) Polling mode: processing APIs are blocking functions
41 i.e. they process the data and wait till the digest computation is finished
42 e.g. HAL_HASH_SHA1_Start()
43 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
44 i.e. they process the data under interrupt
45 e.g. HAL_HASH_SHA1_Start_IT()
46 (##) DMA mode: processing APIs are not blocking functions and the CPU is
47 not used for data transfer i.e. the data transfer is ensured by DMA
48 e.g. HAL_HASH_SHA1_Start_DMA()
49 (#)When the processing function is called at first time after HAL_HASH_Init()
50 the HASH peripheral is initialized and processes the buffer in input.
51 After that, the digest computation is started.
52 When processing multi-buffer use the accumulate function to write the
53 data in the peripheral without starting the digest computation. In last
54 buffer use the start function to input the last buffer ans start the digest
55 computation.
56 (##) e.g. HAL_HASH_SHA1_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
57 (##) write (n-1)th data buffer in the peripheral without starting the digest computation
58 (##) HAL_HASH_SHA1_Start() : write (n)th data buffer in the peripheral and start the digest computation
59 (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
60 (#)In case of using DMA, call the DMA start processing e.g. HAL_HASH_SHA1_Start_DMA().
61 After that, call the finish function in order to get the digest value
62 e.g. HAL_HASH_SHA1_Finish()
63 (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
64
65 @endverbatim
66 ******************************************************************************
67 * @attention
68 *
69 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
70 *
71 * Redistribution and use in source and binary forms, with or without modification,
72 * are permitted provided that the following conditions are met:
73 * 1. Redistributions of source code must retain the above copyright notice,
74 * this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright notice,
76 * this list of conditions and the following disclaimer in the documentation
77 * and/or other materials provided with the distribution.
78 * 3. Neither the name of STMicroelectronics nor the names of its contributors
79 * may be used to endorse or promote products derived from this software
80 * without specific prior written permission.
81 *
82 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
83 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
85 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
86 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
88 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
89 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
90 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
91 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92 *
93 ******************************************************************************
94 */
95
96 /* Includes ------------------------------------------------------------------*/
97 #include "stm32f4xx_hal.h"
98
99 /** @addtogroup STM32F4xx_HAL_Driver
100 * @{
101 */
102
103 /** @defgroup HASH HASH
104 * @brief HASH HAL module driver.
105 * @{
106 */
107
108 #ifdef HAL_HASH_MODULE_ENABLED
109
110 #if defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F479xx)
111
112 /* Private typedef -----------------------------------------------------------*/
113 /* Private define ------------------------------------------------------------*/
114 /* Private macro -------------------------------------------------------------*/
115 /* Private variables ---------------------------------------------------------*/
116 /* Private function prototypes -----------------------------------------------*/
117 /** @defgroup HASH_Private_Functions HASH Private Functions
118 * @{
119 */
120 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
121 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
122 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
123 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size);
124 /**
125 * @}
126 */
127
128 /* Private functions ---------------------------------------------------------*/
129 /** @addtogroup HASH_Private_Functions
130 * @{
131 */
132
133 /**
134 * @brief DMA HASH Input Data complete callback.
135 * @param hdma DMA handle
136 * @retval None
137 */
138 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
139 {
140 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
141 uint32_t inputaddr = 0U;
142 uint32_t buffersize = 0U;
143
144 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
145 {
146 /* Disable the DMA transfer */
147 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
148
149 /* Change HASH peripheral state */
150 hhash->State = HAL_HASH_STATE_READY;
151
152 /* Call Input data transfer complete callback */
153 HAL_HASH_InCpltCallback(hhash);
154 }
155 else
156 {
157 /* Increment Interrupt counter */
158 hhash->HashInCount++;
159 /* Disable the DMA transfer before starting the next transfer */
160 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
161
162 if(hhash->HashInCount <= 2U)
163 {
164 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
165 if(hhash->HashInCount == 1U)
166 {
167 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
168 buffersize = hhash->HashBuffSize;
169 }
170 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
171 else if(hhash->HashInCount == 2U)
172 {
173 inputaddr = (uint32_t)hhash->Init.pKey;
174 buffersize = hhash->Init.KeySize;
175 }
176 /* Configure the number of valid bits in last word of the message */
177 MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8U * (buffersize % 4U));
178
179 /* Set the HASH DMA transfer complete */
180 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
181
182 /* Enable the DMA In DMA Stream */
183 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4U ? (buffersize+3U)/4U:buffersize/4U));
184
185 /* Enable DMA requests */
186 HASH->CR |= (HASH_CR_DMAE);
187 }
188 else
189 {
190 /* Disable the DMA transfer */
191 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
192
193 /* Reset the InCount */
194 hhash->HashInCount = 0U;
195
196 /* Change HASH peripheral state */
197 hhash->State = HAL_HASH_STATE_READY;
198
199 /* Call Input data transfer complete callback */
200 HAL_HASH_InCpltCallback(hhash);
201 }
202 }
203 }
204
205 /**
206 * @brief DMA HASH communication error callback.
207 * @param hdma DMA handle
208 * @retval None
209 */
210 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
211 {
212 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
213 hhash->State= HAL_HASH_STATE_READY;
214 HAL_HASH_ErrorCallback(hhash);
215 }
216
217 /**
218 * @brief Writes the input buffer in data register.
219 * @param pInBuffer Pointer to input buffer
220 * @param Size The size of input buffer
221 * @retval None
222 */
223 static void HASH_WriteData(uint8_t *pInBuffer, uint32_t Size)
224 {
225 uint32_t buffercounter;
226 uint32_t inputaddr = (uint32_t) pInBuffer;
227
228 for(buffercounter = 0U; buffercounter < Size; buffercounter+=4)
229 {
230 HASH->DIN = *(uint32_t*)inputaddr;
231 inputaddr+=4U;
232 }
233 }
234
235 /**
236 * @brief Provides the message digest result.
237 * @param pMsgDigest Pointer to the message digest
238 * @param Size The size of the message digest in bytes
239 * @retval None
240 */
241 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
242 {
243 uint32_t msgdigest = (uint32_t)pMsgDigest;
244
245 switch(Size)
246 {
247 case 16U:
248 /* Read the message digest */
249 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
250 msgdigest+=4U;
251 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
252 msgdigest+=4U;
253 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
254 msgdigest+=4U;
255 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
256 break;
257 case 20U:
258 /* Read the message digest */
259 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
260 msgdigest+=4U;
261 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
262 msgdigest+=4U;
263 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
264 msgdigest+=4U;
265 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
266 msgdigest+=4U;
267 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
268 break;
269 case 28U:
270 /* Read the message digest */
271 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
272 msgdigest+=4U;
273 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
274 msgdigest+=4U;
275 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
276 msgdigest+=4U;
277 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
278 msgdigest+=4U;
279 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
280 msgdigest+=4U;
281 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]);
282 msgdigest+=4U;
283 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]);
284 break;
285 case 32U:
286 /* Read the message digest */
287 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
288 msgdigest+=4U;
289 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
290 msgdigest+=4U;
291 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
292 msgdigest+=4U;
293 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
294 msgdigest+=4U;
295 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
296 msgdigest+=4U;
297 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]);
298 msgdigest+=4U;
299 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]);
300 msgdigest+=4U;
301 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7U]);
302 break;
303 default:
304 break;
305 }
306 }
307
308 /**
309 * @}
310 */
311
312 /* Exported functions --------------------------------------------------------*/
313 /** @addtogroup HASH_Exported_Functions
314 * @{
315 */
316
317
318 /** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions
319 * @brief Initialization and Configuration functions.
320 *
321 @verbatim
322 ===============================================================================
323 ##### Initialization and de-initialization functions #####
324 ===============================================================================
325 [..] This section provides functions allowing to:
326 (+) Initialize the HASH according to the specified parameters
327 in the HASH_InitTypeDef and creates the associated handle.
328 (+) DeInitialize the HASH peripheral.
329 (+) Initialize the HASH MSP.
330 (+) DeInitialize HASH MSP.
331
332 @endverbatim
333 * @{
334 */
335
336 /**
337 * @brief Initializes the HASH according to the specified parameters in the
338 HASH_HandleTypeDef and creates the associated handle.
339 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
340 * the configuration information for HASH module
341 * @retval HAL status
342 */
343 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
344 {
345 /* Check the hash handle allocation */
346 if(hhash == NULL)
347 {
348 return HAL_ERROR;
349 }
350
351 /* Check the parameters */
352 assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
353
354 if(hhash->State == HAL_HASH_STATE_RESET)
355 {
356 /* Allocate lock resource and initialize it */
357 hhash->Lock = HAL_UNLOCKED;
358 /* Init the low level hardware */
359 HAL_HASH_MspInit(hhash);
360 }
361
362 /* Change the HASH state */
363 hhash->State = HAL_HASH_STATE_BUSY;
364
365 /* Reset HashInCount, HashBuffSize and HashITCounter */
366 hhash->HashInCount = 0U;
367 hhash->HashBuffSize = 0U;
368 hhash->HashITCounter = 0U;
369
370 /* Set the data type */
371 HASH->CR |= (uint32_t) (hhash->Init.DataType);
372
373 /* Change the HASH state */
374 hhash->State = HAL_HASH_STATE_READY;
375
376 /* Set the default HASH phase */
377 hhash->Phase = HAL_HASH_PHASE_READY;
378
379 /* Return function status */
380 return HAL_OK;
381 }
382
383 /**
384 * @brief DeInitializes the HASH peripheral.
385 * @note This API must be called before starting a new processing.
386 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
387 * the configuration information for HASH module
388 * @retval HAL status
389 */
390 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
391 {
392 /* Check the HASH handle allocation */
393 if(hhash == NULL)
394 {
395 return HAL_ERROR;
396 }
397
398 /* Change the HASH state */
399 hhash->State = HAL_HASH_STATE_BUSY;
400
401 /* Set the default HASH phase */
402 hhash->Phase = HAL_HASH_PHASE_READY;
403
404 /* Reset HashInCount, HashBuffSize and HashITCounter */
405 hhash->HashInCount = 0U;
406 hhash->HashBuffSize = 0U;
407 hhash->HashITCounter = 0U;
408
409 /* DeInit the low level hardware */
410 HAL_HASH_MspDeInit(hhash);
411
412 /* Change the HASH state */
413 hhash->State = HAL_HASH_STATE_RESET;
414
415 /* Release Lock */
416 __HAL_UNLOCK(hhash);
417
418 /* Return function status */
419 return HAL_OK;
420 }
421
422 /**
423 * @brief Initializes the HASH MSP.
424 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
425 * the configuration information for HASH module
426 * @retval None
427 */
428 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
429 {
430 /* Prevent unused argument(s) compilation warning */
431 UNUSED(hhash);
432 /* NOTE: This function Should not be modified, when the callback is needed,
433 the HAL_HASH_MspInit could be implemented in the user file
434 */
435 }
436
437 /**
438 * @brief DeInitializes HASH MSP.
439 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
440 * the configuration information for HASH module
441 * @retval None
442 */
443 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
444 {
445 /* Prevent unused argument(s) compilation warning */
446 UNUSED(hhash);
447 /* NOTE: This function Should not be modified, when the callback is needed,
448 the HAL_HASH_MspDeInit could be implemented in the user file
449 */
450 }
451
452 /**
453 * @brief Input data transfer complete callback.
454 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
455 * the configuration information for HASH module
456 * @retval None
457 */
458 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
459 {
460 /* Prevent unused argument(s) compilation warning */
461 UNUSED(hhash);
462 /* NOTE: This function Should not be modified, when the callback is needed,
463 the HAL_HASH_InCpltCallback could be implemented in the user file
464 */
465 }
466
467 /**
468 * @brief Data transfer Error callback.
469 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
470 * the configuration information for HASH module
471 * @retval None
472 */
473 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
474 {
475 /* Prevent unused argument(s) compilation warning */
476 UNUSED(hhash);
477 /* NOTE: This function Should not be modified, when the callback is needed,
478 the HAL_HASH_ErrorCallback could be implemented in the user file
479 */
480 }
481
482 /**
483 * @brief Digest computation complete callback. It is used only with interrupt.
484 * @note This callback is not relevant with DMA.
485 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
486 * the configuration information for HASH module
487 * @retval None
488 */
489 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
490 {
491 /* Prevent unused argument(s) compilation warning */
492 UNUSED(hhash);
493 /* NOTE: This function Should not be modified, when the callback is needed,
494 the HAL_HASH_DgstCpltCallback could be implemented in the user file
495 */
496 }
497
498 /**
499 * @}
500 */
501
502 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions using polling mode
503 * @brief processing functions using polling mode
504 *
505 @verbatim
506 ===============================================================================
507 ##### HASH processing using polling mode functions#####
508 ===============================================================================
509 [..] This section provides functions allowing to calculate in polling mode
510 the hash value using one of the following algorithms:
511 (+) MD5
512 (+) SHA1
513
514 @endverbatim
515 * @{
516 */
517
518 /**
519 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
520 The digest is available in pOutBuffer.
521 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
522 * the configuration information for HASH module
523 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
524 * @param Size Length of the input buffer in bytes.
525 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
526 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
527 * and appending the input buffer is no more possible.
528 * @param pOutBuffer Pointer to the computed digest. Its size must be 16 bytes.
529 * @param Timeout Timeout value
530 * @retval HAL status
531 */
532 HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
533 {
534 uint32_t tickstart = 0U;
535
536 /* Process Locked */
537 __HAL_LOCK(hhash);
538
539 /* Change the HASH state */
540 hhash->State = HAL_HASH_STATE_BUSY;
541
542 /* Check if initialization phase has already been performed */
543 if(hhash->Phase == HAL_HASH_PHASE_READY)
544 {
545 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
546 the message digest of a new message */
547 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
548 }
549
550 /* Set the phase */
551 hhash->Phase = HAL_HASH_PHASE_PROCESS;
552
553 /* Configure the number of valid bits in last word of the message */
554 __HAL_HASH_SET_NBVALIDBITS(Size);
555
556 /* Write input buffer in data register */
557 HASH_WriteData(pInBuffer, Size);
558
559 /* Start the digest calculation */
560 __HAL_HASH_START_DIGEST();
561
562 /* Get tick */
563 tickstart = HAL_GetTick();
564
565 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
566 {
567 /* Check for the Timeout */
568 if(Timeout != HAL_MAX_DELAY)
569 {
570 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
571 {
572 /* Change state */
573 hhash->State = HAL_HASH_STATE_TIMEOUT;
574
575 /* Process Unlocked */
576 __HAL_UNLOCK(hhash);
577
578 return HAL_TIMEOUT;
579 }
580 }
581 }
582
583 /* Read the message digest */
584 HASH_GetDigest(pOutBuffer, 16U);
585
586 /* Change the HASH state */
587 hhash->State = HAL_HASH_STATE_READY;
588
589 /* Process Unlocked */
590 __HAL_UNLOCK(hhash);
591
592 /* Return function status */
593 return HAL_OK;
594 }
595
596 /**
597 * @brief Initializes the HASH peripheral in MD5 mode then writes the pInBuffer.
598 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
599 * the configuration information for HASH module
600 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
601 * @param Size Length of the input buffer in bytes.
602 * If the Size is multiple of 64 bytes, appending the input buffer is possible.
603 * If the Size is not multiple of 64 bytes, the padding is managed by hardware
604 * and appending the input buffer is no more possible.
605 * @retval HAL status
606 */
607 HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
608 {
609 /* Process Locked */
610 __HAL_LOCK(hhash);
611
612 /* Change the HASH state */
613 hhash->State = HAL_HASH_STATE_BUSY;
614
615 /* Check if initialization phase has already been performed */
616 if(hhash->Phase == HAL_HASH_PHASE_READY)
617 {
618 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
619 the message digest of a new message */
620 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
621 }
622
623 /* Set the phase */
624 hhash->Phase = HAL_HASH_PHASE_PROCESS;
625
626 /* Configure the number of valid bits in last word of the message */
627 __HAL_HASH_SET_NBVALIDBITS(Size);
628
629 /* Write input buffer in data register */
630 HASH_WriteData(pInBuffer, Size);
631
632 /* Change the HASH state */
633 hhash->State = HAL_HASH_STATE_READY;
634
635 /* Process Unlocked */
636 __HAL_UNLOCK(hhash);
637
638 /* Return function status */
639 return HAL_OK;
640 }
641
642 /**
643 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
644 The digest is available in pOutBuffer.
645 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
646 * the configuration information for HASH module
647 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
648 * @param Size Length of the input buffer in bytes.
649 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
650 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
651 * @param Timeout Timeout value
652 * @retval HAL status
653 */
654 HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
655 {
656 uint32_t tickstart = 0U;
657
658 /* Process Locked */
659 __HAL_LOCK(hhash);
660
661 /* Change the HASH state */
662 hhash->State = HAL_HASH_STATE_BUSY;
663
664 /* Check if initialization phase has already been performed */
665 if(hhash->Phase == HAL_HASH_PHASE_READY)
666 {
667 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
668 the message digest of a new message */
669 HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
670 }
671
672 /* Set the phase */
673 hhash->Phase = HAL_HASH_PHASE_PROCESS;
674
675 /* Configure the number of valid bits in last word of the message */
676 __HAL_HASH_SET_NBVALIDBITS(Size);
677
678 /* Write input buffer in data register */
679 HASH_WriteData(pInBuffer, Size);
680
681 /* Start the digest calculation */
682 __HAL_HASH_START_DIGEST();
683
684 /* Get tick */
685 tickstart = HAL_GetTick();
686
687 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
688 {
689 /* Check for the Timeout */
690 if(Timeout != HAL_MAX_DELAY)
691 {
692 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
693 {
694 /* Change state */
695 hhash->State = HAL_HASH_STATE_TIMEOUT;
696
697 /* Process Unlocked */
698 __HAL_UNLOCK(hhash);
699
700 return HAL_TIMEOUT;
701 }
702 }
703 }
704
705 /* Read the message digest */
706 HASH_GetDigest(pOutBuffer, 20U);
707
708 /* Change the HASH state */
709 hhash->State = HAL_HASH_STATE_READY;
710
711 /* Process Unlocked */
712 __HAL_UNLOCK(hhash);
713
714 /* Return function status */
715 return HAL_OK;
716 }
717
718 /**
719 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
720 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
721 * the configuration information for HASH module
722 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
723 * @param Size Length of the input buffer in bytes.
724 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
725 * @note Input buffer size in bytes must be a multiple of 4 otherwise the digest computation is corrupted.
726 * @retval HAL status
727 */
728 HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
729 {
730 /* Check the parameters */
731 assert_param(IS_HASH_SHA1_BUFFER_SIZE(Size));
732
733 /* Process Locked */
734 __HAL_LOCK(hhash);
735
736 /* Change the HASH state */
737 hhash->State = HAL_HASH_STATE_BUSY;
738
739 /* Check if initialization phase has already been performed */
740 if(hhash->Phase == HAL_HASH_PHASE_READY)
741 {
742 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
743 the message digest of a new message */
744 HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
745 }
746
747 /* Set the phase */
748 hhash->Phase = HAL_HASH_PHASE_PROCESS;
749
750 /* Configure the number of valid bits in last word of the message */
751 __HAL_HASH_SET_NBVALIDBITS(Size);
752
753 /* Write input buffer in data register */
754 HASH_WriteData(pInBuffer, Size);
755
756 /* Change the HASH state */
757 hhash->State = HAL_HASH_STATE_READY;
758
759 /* Process Unlocked */
760 __HAL_UNLOCK(hhash);
761
762 /* Return function status */
763 return HAL_OK;
764 }
765
766 /**
767 * @}
768 */
769
770 /** @defgroup HASH_Exported_Functions_Group3 HASH processing functions using interrupt mode
771 * @brief processing functions using interrupt mode.
772 *
773 @verbatim
774 ===============================================================================
775 ##### HASH processing using interrupt mode functions #####
776 ===============================================================================
777 [..] This section provides functions allowing to calculate in interrupt mode
778 the hash value using one of the following algorithms:
779 (+) MD5
780 (+) SHA1
781
782 @endverbatim
783 * @{
784 */
785
786 /**
787 * @brief Initializes the HASH peripheral in MD5 mode then processes pInBuffer.
788 * The digest is available in pOutBuffer.
789 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
790 * the configuration information for HASH module
791 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
792 * @param Size Length of the input buffer in bytes.
793 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
794 * @param pOutBuffer Pointer to the computed digest. Its size must be 16 bytes.
795 * @retval HAL status
796 */
797 HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
798 {
799 uint32_t inputaddr;
800 uint32_t outputaddr;
801 uint32_t buffercounter;
802 uint32_t inputcounter;
803
804 /* Process Locked */
805 __HAL_LOCK(hhash);
806
807 if(hhash->State == HAL_HASH_STATE_READY)
808 {
809 /* Change the HASH state */
810 hhash->State = HAL_HASH_STATE_BUSY;
811
812 hhash->HashInCount = Size;
813 hhash->pHashInBuffPtr = pInBuffer;
814 hhash->pHashOutBuffPtr = pOutBuffer;
815
816 /* Check if initialization phase has already been performed */
817 if(hhash->Phase == HAL_HASH_PHASE_READY)
818 {
819 /* Select the SHA1 mode */
820 HASH->CR |= HASH_ALGOSELECTION_MD5;
821 /* Reset the HASH processor core, so that the HASH will be ready to compute
822 the message digest of a new message */
823 HASH->CR |= HASH_CR_INIT;
824 }
825 /* Reset interrupt counter */
826 hhash->HashITCounter = 0U;
827
828 /* Set the phase */
829 hhash->Phase = HAL_HASH_PHASE_PROCESS;
830
831 /* Process Unlocked */
832 __HAL_UNLOCK(hhash);
833
834 /* Enable Interrupts */
835 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
836
837 /* Return function status */
838 return HAL_OK;
839 }
840 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
841 {
842 outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
843 /* Read the Output block from the Output FIFO */
844 *(uint32_t*)(outputaddr) = __REV(HASH->HR[0U]);
845 outputaddr+=4U;
846 *(uint32_t*)(outputaddr) = __REV(HASH->HR[1U]);
847 outputaddr+=4U;
848 *(uint32_t*)(outputaddr) = __REV(HASH->HR[2U]);
849 outputaddr+=4U;
850 *(uint32_t*)(outputaddr) = __REV(HASH->HR[3U]);
851
852 if(hhash->HashInCount == 0U)
853 {
854 /* Disable Interrupts */
855 HASH->IMR = 0U;
856 /* Change the HASH state */
857 hhash->State = HAL_HASH_STATE_READY;
858 /* Call digest computation complete callback */
859 HAL_HASH_DgstCpltCallback(hhash);
860
861 /* Process Unlocked */
862 __HAL_UNLOCK(hhash);
863
864 /* Return function status */
865 return HAL_OK;
866 }
867 }
868 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
869 {
870 if(hhash->HashInCount >= 68U)
871 {
872 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
873 /* Write the Input block in the Data IN register */
874 for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
875 {
876 HASH->DIN = *(uint32_t*)inputaddr;
877 inputaddr+=4U;
878 }
879 if(hhash->HashITCounter == 0U)
880 {
881 HASH->DIN = *(uint32_t*)inputaddr;
882
883 if(hhash->HashInCount >= 68U)
884 {
885 /* Decrement buffer counter */
886 hhash->HashInCount -= 68U;
887 hhash->pHashInBuffPtr+= 68U;
888 }
889 else
890 {
891 hhash->HashInCount = 0U;
892 hhash->pHashInBuffPtr+= hhash->HashInCount;
893 }
894 /* Set Interrupt counter */
895 hhash->HashITCounter = 1U;
896 }
897 else
898 {
899 /* Decrement buffer counter */
900 hhash->HashInCount -= 64U;
901 hhash->pHashInBuffPtr+= 64U;
902 }
903 }
904 else
905 {
906 /* Get the buffer address */
907 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
908 /* Get the buffer counter */
909 inputcounter = hhash->HashInCount;
910 /* Disable Interrupts */
911 HASH->IMR &= ~(HASH_IT_DINI);
912 /* Configure the number of valid bits in last word of the message */
913 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
914
915 if((inputcounter > 4U) && (inputcounter%4U))
916 {
917 inputcounter = (inputcounter+4U-inputcounter%4U);
918 }
919 else if ((inputcounter < 4U) && (inputcounter != 0U))
920 {
921 inputcounter = 4U;
922 }
923 /* Write the Input block in the Data IN register */
924 for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++)
925 {
926 HASH->DIN = *(uint32_t*)inputaddr;
927 inputaddr+=4U;
928 }
929 /* Start the digest calculation */
930 __HAL_HASH_START_DIGEST();
931 /* Reset buffer counter */
932 hhash->HashInCount = 0U;
933 /* Call Input data transfer complete callback */
934 HAL_HASH_InCpltCallback(hhash);
935 }
936 }
937
938 /* Process Unlocked */
939 __HAL_UNLOCK(hhash);
940
941 /* Return function status */
942 return HAL_OK;
943 }
944
945 /**
946 * @brief Initializes the HASH peripheral in SHA1 mode then processes pInBuffer.
947 * The digest is available in pOutBuffer.
948 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
949 * the configuration information for HASH module
950 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
951 * @param Size Length of the input buffer in bytes.
952 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
953 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
954 * @retval HAL status
955 */
956 HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
957 {
958 uint32_t inputaddr;
959 uint32_t outputaddr;
960 uint32_t buffercounter;
961 uint32_t inputcounter;
962
963 /* Process Locked */
964 __HAL_LOCK(hhash);
965
966 if(hhash->State == HAL_HASH_STATE_READY)
967 {
968 /* Change the HASH state */
969 hhash->State = HAL_HASH_STATE_BUSY;
970
971 hhash->HashInCount = Size;
972 hhash->pHashInBuffPtr = pInBuffer;
973 hhash->pHashOutBuffPtr = pOutBuffer;
974
975 /* Check if initialization phase has already been performed */
976 if(hhash->Phase == HAL_HASH_PHASE_READY)
977 {
978 /* Select the SHA1 mode */
979 HASH->CR |= HASH_ALGOSELECTION_SHA1;
980 /* Reset the HASH processor core, so that the HASH will be ready to compute
981 the message digest of a new message */
982 HASH->CR |= HASH_CR_INIT;
983 }
984 /* Reset interrupt counter */
985 hhash->HashITCounter = 0U;
986
987 /* Set the phase */
988 hhash->Phase = HAL_HASH_PHASE_PROCESS;
989
990 /* Process Unlocked */
991 __HAL_UNLOCK(hhash);
992
993 /* Enable Interrupts */
994 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
995
996 /* Return function status */
997 return HAL_OK;
998 }
999 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
1000 {
1001 outputaddr = (uint32_t)hhash->pHashOutBuffPtr;
1002 /* Read the Output block from the Output FIFO */
1003 *(uint32_t*)(outputaddr) = __REV(HASH->HR[0U]);
1004 outputaddr+=4U;
1005 *(uint32_t*)(outputaddr) = __REV(HASH->HR[1U]);
1006 outputaddr+=4U;
1007 *(uint32_t*)(outputaddr) = __REV(HASH->HR[2U]);
1008 outputaddr+=4U;
1009 *(uint32_t*)(outputaddr) = __REV(HASH->HR[3U]);
1010 outputaddr+=4U;
1011 *(uint32_t*)(outputaddr) = __REV(HASH->HR[4U]);
1012 if(hhash->HashInCount == 0U)
1013 {
1014 /* Disable Interrupts */
1015 HASH->IMR = 0U;
1016 /* Change the HASH state */
1017 hhash->State = HAL_HASH_STATE_READY;
1018 /* Call digest computation complete callback */
1019 HAL_HASH_DgstCpltCallback(hhash);
1020
1021 /* Process Unlocked */
1022 __HAL_UNLOCK(hhash);
1023
1024 /* Return function status */
1025 return HAL_OK;
1026 }
1027 }
1028 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
1029 {
1030 if(hhash->HashInCount >= 68U)
1031 {
1032 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1033 /* Write the Input block in the Data IN register */
1034 for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
1035 {
1036 HASH->DIN = *(uint32_t*)inputaddr;
1037 inputaddr+=4U;
1038 }
1039 if(hhash->HashITCounter == 0U)
1040 {
1041 HASH->DIN = *(uint32_t*)inputaddr;
1042 if(hhash->HashInCount >= 68U)
1043 {
1044 /* Decrement buffer counter */
1045 hhash->HashInCount -= 68U;
1046 hhash->pHashInBuffPtr+= 68U;
1047 }
1048 else
1049 {
1050 hhash->HashInCount = 0U;
1051 hhash->pHashInBuffPtr+= hhash->HashInCount;
1052 }
1053 /* Set Interrupt counter */
1054 hhash->HashITCounter = 1U;
1055 }
1056 else
1057 {
1058 /* Decrement buffer counter */
1059 hhash->HashInCount -= 64U;
1060 hhash->pHashInBuffPtr+= 64U;
1061 }
1062 }
1063 else
1064 {
1065 /* Get the buffer address */
1066 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1067 /* Get the buffer counter */
1068 inputcounter = hhash->HashInCount;
1069 /* Disable Interrupts */
1070 HASH->IMR &= ~(HASH_IT_DINI);
1071 /* Configure the number of valid bits in last word of the message */
1072 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
1073
1074 if((inputcounter > 4U) && (inputcounter%4U))
1075 {
1076 inputcounter = (inputcounter+4U-inputcounter%4U);
1077 }
1078 else if ((inputcounter < 4U) && (inputcounter != 0U))
1079 {
1080 inputcounter = 4U;
1081 }
1082 /* Write the Input block in the Data IN register */
1083 for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++)
1084 {
1085 HASH->DIN = *(uint32_t*)inputaddr;
1086 inputaddr+=4U;
1087 }
1088 /* Start the digest calculation */
1089 __HAL_HASH_START_DIGEST();
1090 /* Reset buffer counter */
1091 hhash->HashInCount = 0U;
1092 /* Call Input data transfer complete callback */
1093 HAL_HASH_InCpltCallback(hhash);
1094 }
1095 }
1096
1097 /* Process Unlocked */
1098 __HAL_UNLOCK(hhash);
1099
1100 /* Return function status */
1101 return HAL_OK;
1102 }
1103
1104 /**
1105 * @brief This function handles HASH interrupt request.
1106 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1107 * the configuration information for HASH module
1108 * @retval None
1109 */
1110 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
1111 {
1112 switch(HASH->CR & HASH_CR_ALGO)
1113 {
1114 case HASH_ALGOSELECTION_MD5:
1115 HAL_HASH_MD5_Start_IT(hhash, NULL, 0U, NULL);
1116 break;
1117
1118 case HASH_ALGOSELECTION_SHA1:
1119 HAL_HASH_SHA1_Start_IT(hhash, NULL, 0U, NULL);
1120 break;
1121
1122 default:
1123 break;
1124 }
1125 }
1126
1127 /**
1128 * @}
1129 */
1130
1131 /** @defgroup HASH_Exported_Functions_Group4 HASH processing functions using DMA mode
1132 * @brief processing functions using DMA mode.
1133 *
1134 @verbatim
1135 ===============================================================================
1136 ##### HASH processing using DMA mode functions #####
1137 ===============================================================================
1138 [..] This section provides functions allowing to calculate in DMA mode
1139 the hash value using one of the following algorithms:
1140 (+) MD5
1141 (+) SHA1
1142
1143 @endverbatim
1144 * @{
1145 */
1146
1147 /**
1148 * @brief Initializes the HASH peripheral in MD5 mode then enables DMA to
1149 control data transfer. Use HAL_HASH_MD5_Finish() to get the digest.
1150 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1151 * the configuration information for HASH module
1152 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
1153 * @param Size Length of the input buffer in bytes.
1154 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1155 * @retval HAL status
1156 */
1157 HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1158 {
1159 uint32_t inputaddr = (uint32_t)pInBuffer;
1160
1161 /* Process Locked */
1162 __HAL_LOCK(hhash);
1163
1164 /* Change the HASH state */
1165 hhash->State = HAL_HASH_STATE_BUSY;
1166
1167 /* Check if initialization phase has already been performed */
1168 if(hhash->Phase == HAL_HASH_PHASE_READY)
1169 {
1170 /* Select the MD5 mode and reset the HASH processor core, so that the HASH will be ready to compute
1171 the message digest of a new message */
1172 HASH->CR |= HASH_ALGOSELECTION_MD5 | HASH_CR_INIT;
1173 }
1174
1175 /* Configure the number of valid bits in last word of the message */
1176 __HAL_HASH_SET_NBVALIDBITS(Size);
1177
1178 /* Set the phase */
1179 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1180
1181 /* Set the HASH DMA transfer complete callback */
1182 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1183 /* Set the DMA error callback */
1184 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1185
1186 /* Enable the DMA In DMA Stream */
1187 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4U ? (Size+3U)/4U:Size/4U));
1188
1189 /* Enable DMA requests */
1190 HASH->CR |= (HASH_CR_DMAE);
1191
1192 /* Process Unlocked */
1193 __HAL_UNLOCK(hhash);
1194
1195 /* Return function status */
1196 return HAL_OK;
1197 }
1198
1199 /**
1200 * @brief Returns the computed digest in MD5 mode
1201 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1202 * the configuration information for HASH module
1203 * @param pOutBuffer Pointer to the computed digest. Its size must be 16 bytes.
1204 * @param Timeout Timeout value
1205 * @retval HAL status
1206 */
1207 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1208 {
1209 uint32_t tickstart = 0U;
1210
1211 /* Process Locked */
1212 __HAL_LOCK(hhash);
1213
1214 /* Change HASH peripheral state */
1215 hhash->State = HAL_HASH_STATE_BUSY;
1216
1217 /* Get tick */
1218 tickstart = HAL_GetTick();
1219
1220 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1221 {
1222 /* Check for the Timeout */
1223 if(Timeout != HAL_MAX_DELAY)
1224 {
1225 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1226 {
1227 /* Change state */
1228 hhash->State = HAL_HASH_STATE_TIMEOUT;
1229
1230 /* Process Unlocked */
1231 __HAL_UNLOCK(hhash);
1232
1233 return HAL_TIMEOUT;
1234 }
1235 }
1236 }
1237
1238 /* Read the message digest */
1239 HASH_GetDigest(pOutBuffer, 16U);
1240
1241 /* Change HASH peripheral state */
1242 hhash->State = HAL_HASH_STATE_READY;
1243
1244 /* Process Unlocked */
1245 __HAL_UNLOCK(hhash);
1246
1247 /* Return function status */
1248 return HAL_OK;
1249 }
1250
1251 /**
1252 * @brief Initializes the HASH peripheral in SHA1 mode then enables DMA to
1253 control data transfer. Use HAL_HASH_SHA1_Finish() to get the digest.
1254 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1255 * the configuration information for HASH module
1256 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
1257 * @param Size Length of the input buffer in bytes.
1258 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1259 * @retval HAL status
1260 */
1261 HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1262 {
1263 uint32_t inputaddr = (uint32_t)pInBuffer;
1264
1265 /* Process Locked */
1266 __HAL_LOCK(hhash);
1267
1268 /* Change the HASH state */
1269 hhash->State = HAL_HASH_STATE_BUSY;
1270
1271 /* Check if initialization phase has already been performed */
1272 if(hhash->Phase == HAL_HASH_PHASE_READY)
1273 {
1274 /* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
1275 the message digest of a new message */
1276 HASH->CR |= HASH_ALGOSELECTION_SHA1;
1277 HASH->CR |= HASH_CR_INIT;
1278 }
1279
1280 /* Configure the number of valid bits in last word of the message */
1281 __HAL_HASH_SET_NBVALIDBITS(Size);
1282
1283 /* Set the phase */
1284 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1285
1286 /* Set the HASH DMA transfer complete callback */
1287 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1288 /* Set the DMA error callback */
1289 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1290
1291 /* Enable the DMA In DMA Stream */
1292 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4U ? (Size+3U)/4U:Size/4U));
1293
1294 /* Enable DMA requests */
1295 HASH->CR |= (HASH_CR_DMAE);
1296
1297 /* Process Unlocked */
1298 __HAL_UNLOCK(hhash);
1299
1300 /* Return function status */
1301 return HAL_OK;
1302 }
1303
1304 /**
1305 * @brief Returns the computed digest in SHA1 mode.
1306 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1307 * the configuration information for HASH module
1308 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
1309 * @param Timeout Timeout value
1310 * @retval HAL status
1311 */
1312 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
1313 {
1314 uint32_t tickstart = 0U;
1315
1316 /* Process Locked */
1317 __HAL_LOCK(hhash);
1318
1319 /* Change HASH peripheral state */
1320 hhash->State = HAL_HASH_STATE_BUSY;
1321
1322 /* Get tick */
1323 tickstart = HAL_GetTick();
1324 while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
1325 {
1326 /* Check for the Timeout */
1327 if(Timeout != HAL_MAX_DELAY)
1328 {
1329 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1330 {
1331 /* Change state */
1332 hhash->State = HAL_HASH_STATE_TIMEOUT;
1333
1334 /* Process Unlocked */
1335 __HAL_UNLOCK(hhash);
1336
1337 return HAL_TIMEOUT;
1338 }
1339 }
1340 }
1341
1342 /* Read the message digest */
1343 HASH_GetDigest(pOutBuffer, 20U);
1344
1345 /* Change HASH peripheral state */
1346 hhash->State = HAL_HASH_STATE_READY;
1347
1348 /* Process UnLock */
1349 __HAL_UNLOCK(hhash);
1350
1351 /* Return function status */
1352 return HAL_OK;
1353 }
1354
1355
1356 /**
1357 * @}
1358 */
1359
1360 /** @defgroup HASH_Exported_Functions_Group5 HASH-MAC (HMAC) processing functions using polling mode
1361 * @brief HMAC processing functions using polling mode .
1362 *
1363 @verbatim
1364 ===============================================================================
1365 ##### HMAC processing using polling mode functions #####
1366 ===============================================================================
1367 [..] This section provides functions allowing to calculate in polling mode
1368 the HMAC value using one of the following algorithms:
1369 (+) MD5
1370 (+) SHA1
1371
1372 @endverbatim
1373 * @{
1374 */
1375
1376 /**
1377 * @brief Initializes the HASH peripheral in HMAC MD5 mode
1378 * then processes pInBuffer. The digest is available in pOutBuffer
1379 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1380 * the configuration information for HASH module
1381 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
1382 * @param Size Length of the input buffer in bytes.
1383 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1384 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
1385 * @param Timeout Timeout value
1386 * @retval HAL status
1387 */
1388 HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1389 {
1390 uint32_t tickstart = 0U;
1391
1392 /* Process Locked */
1393 __HAL_LOCK(hhash);
1394
1395 /* Change the HASH state */
1396 hhash->State = HAL_HASH_STATE_BUSY;
1397
1398 /* Check if initialization phase has already been performed */
1399 if(hhash->Phase == HAL_HASH_PHASE_READY)
1400 {
1401 /* Check if key size is greater than 64 bytes */
1402 if(hhash->Init.KeySize > 64U)
1403 {
1404 /* Select the HMAC MD5 mode */
1405 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1406 }
1407 else
1408 {
1409 /* Select the HMAC MD5 mode */
1410 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1411 }
1412 }
1413
1414 /* Set the phase */
1415 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1416
1417 /************************** STEP 1 ******************************************/
1418 /* Configure the number of valid bits in last word of the message */
1419 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1420
1421 /* Write input buffer in data register */
1422 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1423
1424 /* Start the digest calculation */
1425 __HAL_HASH_START_DIGEST();
1426
1427 /* Get tick */
1428 tickstart = HAL_GetTick();
1429
1430 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1431 {
1432 /* Check for the Timeout */
1433 if(Timeout != HAL_MAX_DELAY)
1434 {
1435 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1436 {
1437 /* Change state */
1438 hhash->State = HAL_HASH_STATE_TIMEOUT;
1439
1440 /* Process Unlocked */
1441 __HAL_UNLOCK(hhash);
1442
1443 return HAL_TIMEOUT;
1444 }
1445 }
1446 }
1447 /************************** STEP 2 ******************************************/
1448 /* Configure the number of valid bits in last word of the message */
1449 __HAL_HASH_SET_NBVALIDBITS(Size);
1450
1451 /* Write input buffer in data register */
1452 HASH_WriteData(pInBuffer, Size);
1453
1454 /* Start the digest calculation */
1455 __HAL_HASH_START_DIGEST();
1456
1457 /* Get tick */
1458 tickstart = HAL_GetTick();
1459
1460 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1461 {
1462 /* Check for the Timeout */
1463 if(Timeout != HAL_MAX_DELAY)
1464 {
1465 if((HAL_GetTick() - tickstart ) > Timeout)
1466 {
1467 /* Change state */
1468 hhash->State = HAL_HASH_STATE_TIMEOUT;
1469
1470 /* Process Unlocked */
1471 __HAL_UNLOCK(hhash);
1472
1473 return HAL_TIMEOUT;
1474 }
1475 }
1476 }
1477 /************************** STEP 3 ******************************************/
1478 /* Configure the number of valid bits in last word of the message */
1479 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1480
1481 /* Write input buffer in data register */
1482 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1483
1484 /* Start the digest calculation */
1485 __HAL_HASH_START_DIGEST();
1486
1487 /* Get tick */
1488 tickstart = HAL_GetTick();
1489
1490 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1491 {
1492 /* Check for the Timeout */
1493 if(Timeout != HAL_MAX_DELAY)
1494 {
1495 if((HAL_GetTick() - tickstart ) > Timeout)
1496 {
1497 /* Change state */
1498 hhash->State = HAL_HASH_STATE_TIMEOUT;
1499
1500 /* Process Unlocked */
1501 __HAL_UNLOCK(hhash);
1502
1503 return HAL_TIMEOUT;
1504 }
1505 }
1506 }
1507
1508 /* Read the message digest */
1509 HASH_GetDigest(pOutBuffer, 16U);
1510
1511 /* Change the HASH state */
1512 hhash->State = HAL_HASH_STATE_READY;
1513
1514 /* Process Unlocked */
1515 __HAL_UNLOCK(hhash);
1516
1517 /* Return function status */
1518 return HAL_OK;
1519 }
1520
1521 /**
1522 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
1523 * then processes pInBuffer. The digest is available in pOutBuffer.
1524 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1525 * the configuration information for HASH module
1526 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
1527 * @param Size Length of the input buffer in bytes.
1528 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1529 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
1530 * @param Timeout Timeout value
1531 * @retval HAL status
1532 */
1533 HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
1534 {
1535 uint32_t tickstart = 0U;
1536
1537 /* Process Locked */
1538 __HAL_LOCK(hhash);
1539
1540 /* Change the HASH state */
1541 hhash->State = HAL_HASH_STATE_BUSY;
1542
1543 /* Check if initialization phase has already been performed */
1544 if(hhash->Phase == HAL_HASH_PHASE_READY)
1545 {
1546 /* Check if key size is greater than 64 bytes */
1547 if(hhash->Init.KeySize > 64U)
1548 {
1549 /* Select the HMAC SHA1 mode */
1550 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1551 }
1552 else
1553 {
1554 /* Select the HMAC SHA1 mode */
1555 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1556 }
1557 }
1558
1559 /* Set the phase */
1560 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1561
1562 /************************** STEP 1 ******************************************/
1563 /* Configure the number of valid bits in last word of the message */
1564 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1565
1566 /* Write input buffer in data register */
1567 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1568
1569 /* Start the digest calculation */
1570 __HAL_HASH_START_DIGEST();
1571
1572 /* Get tick */
1573 tickstart = HAL_GetTick();
1574
1575 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1576 {
1577 /* Check for the Timeout */
1578 if(Timeout != HAL_MAX_DELAY)
1579 {
1580 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1581 {
1582 /* Change state */
1583 hhash->State = HAL_HASH_STATE_TIMEOUT;
1584
1585 /* Process Unlocked */
1586 __HAL_UNLOCK(hhash);
1587
1588 return HAL_TIMEOUT;
1589 }
1590 }
1591 }
1592 /************************** STEP 2 ******************************************/
1593 /* Configure the number of valid bits in last word of the message */
1594 __HAL_HASH_SET_NBVALIDBITS(Size);
1595
1596 /* Write input buffer in data register */
1597 HASH_WriteData(pInBuffer, Size);
1598
1599 /* Start the digest calculation */
1600 __HAL_HASH_START_DIGEST();
1601
1602 /* Get tick */
1603 tickstart = HAL_GetTick();
1604
1605 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1606 {
1607 /* Check for the Timeout */
1608 if(Timeout != HAL_MAX_DELAY)
1609 {
1610 if((HAL_GetTick() - tickstart ) > Timeout)
1611 {
1612 /* Change state */
1613 hhash->State = HAL_HASH_STATE_TIMEOUT;
1614
1615 /* Process Unlocked */
1616 __HAL_UNLOCK(hhash);
1617
1618 return HAL_TIMEOUT;
1619 }
1620 }
1621 }
1622 /************************** STEP 3 ******************************************/
1623 /* Configure the number of valid bits in last word of the message */
1624 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1625
1626 /* Write input buffer in data register */
1627 HASH_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
1628
1629 /* Start the digest calculation */
1630 __HAL_HASH_START_DIGEST();
1631
1632 /* Get tick */
1633 tickstart = HAL_GetTick();
1634
1635 while(HAL_IS_BIT_SET(HASH->SR, HASH_FLAG_BUSY))
1636 {
1637 /* Check for the Timeout */
1638 if(Timeout != HAL_MAX_DELAY)
1639 {
1640 if((HAL_GetTick() - tickstart ) > Timeout)
1641 {
1642 /* Change state */
1643 hhash->State = HAL_HASH_STATE_TIMEOUT;
1644
1645 /* Process Unlocked */
1646 __HAL_UNLOCK(hhash);
1647
1648 return HAL_TIMEOUT;
1649 }
1650 }
1651 }
1652 /* Read the message digest */
1653 HASH_GetDigest(pOutBuffer, 20U);
1654
1655 /* Change the HASH state */
1656 hhash->State = HAL_HASH_STATE_READY;
1657
1658 /* Process Unlocked */
1659 __HAL_UNLOCK(hhash);
1660
1661 /* Return function status */
1662 return HAL_OK;
1663 }
1664
1665 /**
1666 * @}
1667 */
1668
1669 /** @defgroup HASH_Exported_Functions_Group6 HASH-MAC (HMAC) processing functions using DMA mode
1670 * @brief HMAC processing functions using DMA mode .
1671 *
1672 @verbatim
1673 ===============================================================================
1674 ##### HMAC processing using DMA mode functions #####
1675 ===============================================================================
1676 [..] This section provides functions allowing to calculate in DMA mode
1677 the HMAC value using one of the following algorithms:
1678 (+) MD5
1679 (+) SHA1
1680
1681 @endverbatim
1682 * @{
1683 */
1684
1685 /**
1686 * @brief Initializes the HASH peripheral in HMAC MD5 mode
1687 * then enables DMA to control data transfer.
1688 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1689 * the configuration information for HASH module
1690 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
1691 * @param Size Length of the input buffer in bytes.
1692 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1693 * @retval HAL status
1694 */
1695 HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1696 {
1697 uint32_t inputaddr = 0U;
1698
1699 /* Process Locked */
1700 __HAL_LOCK(hhash);
1701
1702 /* Change the HASH state */
1703 hhash->State = HAL_HASH_STATE_BUSY;
1704
1705 /* Save buffer pointer and size in handle */
1706 hhash->pHashInBuffPtr = pInBuffer;
1707 hhash->HashBuffSize = Size;
1708 hhash->HashInCount = 0U;
1709
1710 /* Check if initialization phase has already been performed */
1711 if(hhash->Phase == HAL_HASH_PHASE_READY)
1712 {
1713 /* Check if key size is greater than 64 bytes */
1714 if(hhash->Init.KeySize > 64U)
1715 {
1716 /* Select the HMAC MD5 mode */
1717 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1718 }
1719 else
1720 {
1721 /* Select the HMAC MD5 mode */
1722 HASH->CR |= (HASH_ALGOSELECTION_MD5 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1723 }
1724 }
1725
1726 /* Set the phase */
1727 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1728
1729 /* Configure the number of valid bits in last word of the message */
1730 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1731
1732 /* Get the key address */
1733 inputaddr = (uint32_t)(hhash->Init.pKey);
1734
1735 /* Set the HASH DMA transfer complete callback */
1736 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1737 /* Set the DMA error callback */
1738 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1739
1740 /* Enable the DMA In DMA Stream */
1741 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U));
1742 /* Enable DMA requests */
1743 HASH->CR |= (HASH_CR_DMAE);
1744
1745 /* Process Unlocked */
1746 __HAL_UNLOCK(hhash);
1747
1748 /* Return function status */
1749 return HAL_OK;
1750 }
1751
1752 /**
1753 * @brief Initializes the HASH peripheral in HMAC SHA1 mode
1754 * then enables DMA to control data transfer.
1755 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1756 * the configuration information for HASH module
1757 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
1758 * @param Size Length of the input buffer in bytes.
1759 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1760 * @retval HAL status
1761 */
1762 HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1763 {
1764 uint32_t inputaddr = 0U;
1765
1766 /* Process Locked */
1767 __HAL_LOCK(hhash);
1768
1769 /* Change the HASH state */
1770 hhash->State = HAL_HASH_STATE_BUSY;
1771
1772 /* Save buffer pointer and size in handle */
1773 hhash->pHashInBuffPtr = pInBuffer;
1774 hhash->HashBuffSize = Size;
1775 hhash->HashInCount = 0U;
1776
1777 /* Check if initialization phase has already been performed */
1778 if(hhash->Phase == HAL_HASH_PHASE_READY)
1779 {
1780 /* Check if key size is greater than 64 bytes */
1781 if(hhash->Init.KeySize > 64U)
1782 {
1783 /* Select the HMAC SHA1 mode */
1784 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
1785 }
1786 else
1787 {
1788 /* Select the HMAC SHA1 mode */
1789 HASH->CR |= (HASH_ALGOSELECTION_SHA1 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1790 }
1791 }
1792
1793 /* Set the phase */
1794 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1795
1796 /* Configure the number of valid bits in last word of the message */
1797 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
1798
1799 /* Get the key address */
1800 inputaddr = (uint32_t)(hhash->Init.pKey);
1801
1802 /* Set the HASH DMA transfer complete callback */
1803 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1804 /* Set the DMA error callback */
1805 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1806
1807 /* Enable the DMA In DMA Stream */
1808 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U));
1809 /* Enable DMA requests */
1810 HASH->CR |= (HASH_CR_DMAE);
1811
1812 /* Process Unlocked */
1813 __HAL_UNLOCK(hhash);
1814
1815 /* Return function status */
1816 return HAL_OK;
1817 }
1818
1819 /**
1820 * @}
1821 */
1822
1823 /** @defgroup HASH_Exported_Functions_Group7 Peripheral State functions
1824 * @brief Peripheral State functions.
1825 *
1826 @verbatim
1827 ===============================================================================
1828 ##### Peripheral State functions #####
1829 ===============================================================================
1830 [..]
1831 This subsection permits to get in run-time the status of the peripheral.
1832
1833 @endverbatim
1834 * @{
1835 */
1836
1837 /**
1838 * @brief return the HASH state
1839 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1840 * the configuration information for HASH module
1841 * @retval HAL state
1842 */
1843 HAL_HASH_StateTypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
1844 {
1845 return hhash->State;
1846 }
1847
1848 /**
1849 * @}
1850 */
1851
1852 /**
1853 * @}
1854 */
1855
1856 #endif /* STM32F415xx || STM32F417xx || STM32F437xx || STM32F439xx || STM32F479xx */
1857 #endif /* HAL_HASH_MODULE_ENABLED */
1858 /**
1859 * @}
1860 */
1861
1862 /**
1863 * @}
1864 */
1865
1866 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/