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