comparison Common/Drivers/STM32F4xx_HAL_DRIVER_v120/Src/stm32f4xx_hal_hash_ex.c @ 38:5f11787b4f42

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