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

Merge with FlipDisplay
author heinrichsweikamp
date Thu, 07 Mar 2019 15:06:43 +0100
parents c78bcbd5deda
children
comparison
equal deleted inserted replaced
80:cc2bb7bb8456 160:e3ca52b8e7fa
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_hash_ex.c
4 * @author MCD Application Team
5 * @brief HASH HAL Extension module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of HASH peripheral:
8 * + Extended HASH processing functions based on SHA224 Algorithm
9 * + Extended HASH processing functions based on SHA256 Algorithm
10 *
11 @verbatim
12 ==============================================================================
13 ##### How to use this driver #####
14 ==============================================================================
15 [..]
16 The HASH HAL driver can be used as follows:
17 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
18 (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
19 (##) In case of using processing APIs based on interrupts (e.g. HAL_HMACEx_SHA224_Start())
20 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
21 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
22 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler()
23 (##) In case of using DMA to control data transfer (e.g. HAL_HMACEx_SH224_Start_DMA())
24 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
25 (+++) Configure and enable one DMA stream one for managing data transfer from
26 memory to peripheral (input stream). Managing data transfer from
27 peripheral to memory can be performed only using CPU
28 (+++) Associate the initialized DMA handle to the HASH DMA handle
29 using __HAL_LINKDMA()
30 (+++) Configure the priority and enable the NVIC for the transfer complete
31 interrupt on the DMA Stream: HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
32 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function configures mainly:
33 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit.
34 (##) For HMAC, the encryption key.
35 (##) For HMAC, the key size used for encryption.
36 (#)Three processing functions are available:
37 (##) Polling mode: processing APIs are blocking functions
38 i.e. they process the data and wait till the digest computation is finished
39 e.g. HAL_HASHEx_SHA224_Start()
40 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
41 i.e. they process the data under interrupt
42 e.g. HAL_HASHEx_SHA224_Start_IT()
43 (##) DMA mode: processing APIs are not blocking functions and the CPU is
44 not used for data transfer i.e. the data transfer is ensured by DMA
45 e.g. HAL_HASHEx_SHA224_Start_DMA()
46 (#)When the processing function is called at first time after HAL_HASH_Init()
47 the HASH peripheral is initialized and processes the buffer in input.
48 After that, the digest computation is started.
49 When processing multi-buffer use the accumulate function to write the
50 data in the peripheral without starting the digest computation. In last
51 buffer use the start function to input the last buffer ans start the digest
52 computation.
53 (##) e.g. HAL_HASHEx_SHA224_Accumulate() : write 1st data buffer in the peripheral without starting the digest computation
54 (##) write (n-1)th data buffer in the peripheral without starting the digest computation
55 (##) HAL_HASHEx_SHA224_Start() : write (n)th data buffer in the peripheral and start the digest computation
56 (#)In HMAC mode, there is no Accumulate API. Only Start API is available.
57 (#)In case of using DMA, call the DMA start processing e.g. HAL_HASHEx_SHA224_Start_DMA().
58 After that, call the finish function in order to get the digest value
59 e.g. HAL_HASHEx_SHA224_Finish()
60 (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral.
61
62 @endverbatim
63 ******************************************************************************
64 * @attention
65 *
66 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
67 *
68 * Redistribution and use in source and binary forms, with or without modification,
69 * are permitted provided that the following conditions are met:
70 * 1. Redistributions of source code must retain the above copyright notice,
71 * this list of conditions and the following disclaimer.
72 * 2. Redistributions in binary form must reproduce the above copyright notice,
73 * this list of conditions and the following disclaimer in the documentation
74 * and/or other materials provided with the distribution.
75 * 3. Neither the name of STMicroelectronics nor the names of its contributors
76 * may be used to endorse or promote products derived from this software
77 * without specific prior written permission.
78 *
79 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
80 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
81 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
82 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
83 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
84 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
85 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
86 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
87 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
88 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89 *
90 ******************************************************************************
91 */
92
93 /* Includes ------------------------------------------------------------------*/
94 #include "stm32f4xx_hal.h"
95
96 /** @addtogroup STM32F4xx_HAL_Driver
97 * @{
98 */
99
100 /** @defgroup HASHEx HASHEx
101 * @brief HASH Extension HAL module driver.
102 * @{
103 */
104
105 #ifdef HAL_HASH_MODULE_ENABLED
106
107 #if defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F479xx)
108
109 /* Private typedef -----------------------------------------------------------*/
110 /* Private define ------------------------------------------------------------*/
111 /* Private macro -------------------------------------------------------------*/
112 /* Private variables ---------------------------------------------------------*/
113 /* Private function prototypes -----------------------------------------------*/
114 /** @addtogroup HASHEx_Private_Functions
115 * @{
116 */
117 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma);
118 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size);
119 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
120 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma);
121 /**
122 * @}
123 */
124
125 /* Private functions ---------------------------------------------------------*/
126
127 /** @addtogroup HASHEx_Private_Functions
128 * @{
129 */
130
131 /**
132 * @brief Writes the input buffer in data register.
133 * @param pInBuffer Pointer to input buffer
134 * @param Size The size of input buffer
135 * @retval None
136 */
137 static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size)
138 {
139 uint32_t buffercounter;
140 uint32_t inputaddr = (uint32_t) pInBuffer;
141
142 for(buffercounter = 0U; buffercounter < Size; buffercounter+=4U)
143 {
144 HASH->DIN = *(uint32_t*)inputaddr;
145 inputaddr+=4U;
146 }
147 }
148
149 /**
150 * @brief Provides the message digest result.
151 * @param pMsgDigest Pointer to the message digest
152 * @param Size The size of the message digest in bytes
153 * @retval None
154 */
155 static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
156 {
157 uint32_t msgdigest = (uint32_t)pMsgDigest;
158
159 switch(Size)
160 {
161 case 16U:
162 /* Read the message digest */
163 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
164 msgdigest+=4U;
165 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
166 msgdigest+=4U;
167 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
168 msgdigest+=4U;
169 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
170 break;
171 case 20U:
172 /* Read the message digest */
173 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
174 msgdigest+=4U;
175 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
176 msgdigest+=4U;
177 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
178 msgdigest+=4U;
179 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
180 msgdigest+=4U;
181 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
182 break;
183 case 28U:
184 /* Read the message digest */
185 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
186 msgdigest+=4U;
187 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
188 msgdigest+=4U;
189 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
190 msgdigest+=4U;
191 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
192 msgdigest+=4U;
193 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
194 msgdigest+=4U;
195 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]);
196 msgdigest+=4U;
197 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]);
198 break;
199 case 32U:
200 /* Read the message digest */
201 *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
202 msgdigest+=4U;
203 *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
204 msgdigest+=4U;
205 *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
206 msgdigest+=4U;
207 *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
208 msgdigest+=4U;
209 *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
210 msgdigest+=4U;
211 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]);
212 msgdigest+=4U;
213 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]);
214 msgdigest+=4U;
215 *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7U]);
216 break;
217 default:
218 break;
219 }
220 }
221
222 /**
223 * @brief DMA HASH Input Data complete callback.
224 * @param hdma DMA handle
225 * @retval None
226 */
227 static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma)
228 {
229 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
230 uint32_t inputaddr = 0U;
231 uint32_t buffersize = 0U;
232
233 if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
234 {
235 /* Disable the DMA transfer */
236 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
237
238 /* Change HASH peripheral state */
239 hhash->State = HAL_HASH_STATE_READY;
240
241 /* Call Input data transfer complete callback */
242 HAL_HASH_InCpltCallback(hhash);
243 }
244 else
245 {
246 /* Increment Interrupt counter */
247 hhash->HashInCount++;
248 /* Disable the DMA transfer before starting the next transfer */
249 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
250
251 if(hhash->HashInCount <= 2U)
252 {
253 /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
254 if(hhash->HashInCount == 1U)
255 {
256 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
257 buffersize = hhash->HashBuffSize;
258 }
259 /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
260 else if(hhash->HashInCount == 2U)
261 {
262 inputaddr = (uint32_t)hhash->Init.pKey;
263 buffersize = hhash->Init.KeySize;
264 }
265 /* Configure the number of valid bits in last word of the message */
266 MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8U * (buffersize % 4U));
267
268 /* Set the HASH DMA transfer complete */
269 hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
270
271 /* Enable the DMA In DMA Stream */
272 HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4U ? (buffersize+3U)/4U:buffersize/4U));
273
274 /* Enable DMA requests */
275 HASH->CR |= (HASH_CR_DMAE);
276 }
277 else
278 {
279 /* Disable the DMA transfer */
280 HASH->CR &= (uint32_t)(~HASH_CR_DMAE);
281
282 /* Reset the InCount */
283 hhash->HashInCount = 0U;
284
285 /* Change HASH peripheral state */
286 hhash->State = HAL_HASH_STATE_READY;
287
288 /* Call Input data transfer complete callback */
289 HAL_HASH_InCpltCallback(hhash);
290 }
291 }
292 }
293
294 /**
295 * @brief DMA HASH communication error callback.
296 * @param hdma DMA handle
297 * @retval None
298 */
299 static void HASHEx_DMAError(DMA_HandleTypeDef *hdma)
300 {
301 HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
302 hhash->State= HAL_HASH_STATE_READY;
303 HAL_HASH_ErrorCallback(hhash);
304 }
305
306 /**
307 * @}
308 */
309
310 /* Exported functions --------------------------------------------------------*/
311 /** @addtogroup HASHEx_Exported_Functions
312 * @{
313 */
314
315 /** @defgroup HASHEx_Group1 HASH processing functions
316 * @brief processing functions using polling mode
317 *
318 @verbatim
319 ===============================================================================
320 ##### HASH processing using polling mode functions #####
321 ===============================================================================
322 [..] This section provides functions allowing to calculate in polling mode
323 the hash value using one of the following algorithms:
324 (+) SHA224
325 (+) SHA256
326
327 @endverbatim
328 * @{
329 */
330
331 /**
332 * @brief Initializes the HASH peripheral in SHA224 mode
333 * then processes pInBuffer. The digest is available in pOutBuffer
334 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
335 * the configuration information for HASH module
336 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
337 * @param Size Length of the input buffer in bytes.
338 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
339 * @param pOutBuffer Pointer to the computed digest. Its size must be 28 bytes.
340 * @param Timeout Specify Timeout value
341 * @retval HAL status
342 */
343 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
344 {
345 uint32_t tickstart = 0U;
346
347 /* Process Locked */
348 __HAL_LOCK(hhash);
349
350 /* Change the HASH state */
351 hhash->State = HAL_HASH_STATE_BUSY;
352
353 /* Check if initialization phase has already been performed */
354 if(hhash->Phase == HAL_HASH_PHASE_READY)
355 {
356 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
357 the message digest of a new message */
358 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
359 }
360
361 /* Set the phase */
362 hhash->Phase = HAL_HASH_PHASE_PROCESS;
363
364 /* Configure the number of valid bits in last word of the message */
365 __HAL_HASH_SET_NBVALIDBITS(Size);
366
367 /* Write input buffer in data register */
368 HASHEx_WriteData(pInBuffer, Size);
369
370 /* Start the digest calculation */
371 __HAL_HASH_START_DIGEST();
372
373 /* Get tick */
374 tickstart = HAL_GetTick();
375
376 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
377 {
378 /* Check for the Timeout */
379 if(Timeout != HAL_MAX_DELAY)
380 {
381 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
382 {
383 /* Change state */
384 hhash->State = HAL_HASH_STATE_TIMEOUT;
385
386 /* Process Unlocked */
387 __HAL_UNLOCK(hhash);
388
389 return HAL_TIMEOUT;
390 }
391 }
392 }
393
394 /* Read the message digest */
395 HASHEx_GetDigest(pOutBuffer, 28U);
396
397 /* Change the HASH state */
398 hhash->State = HAL_HASH_STATE_READY;
399
400 /* Process Unlocked */
401 __HAL_UNLOCK(hhash);
402
403 /* Return function status */
404 return HAL_OK;
405 }
406
407 /**
408 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
409 The digest is available in pOutBuffer.
410 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
411 * the configuration information for HASH module
412 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
413 * @param Size Length of the input buffer in bytes.
414 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
415 * @param pOutBuffer Pointer to the computed digest. Its size must be 32 bytes.
416 * @param Timeout Specify Timeout value
417 * @retval HAL status
418 */
419 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
420 {
421 uint32_t tickstart = 0U;
422
423 /* Process Locked */
424 __HAL_LOCK(hhash);
425
426 /* Change the HASH state */
427 hhash->State = HAL_HASH_STATE_BUSY;
428
429 /* Check if initialization phase has already been performed */
430 if(hhash->Phase == HAL_HASH_PHASE_READY)
431 {
432 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
433 the message digest of a new message */
434 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
435 }
436
437 /* Set the phase */
438 hhash->Phase = HAL_HASH_PHASE_PROCESS;
439
440 /* Configure the number of valid bits in last word of the message */
441 __HAL_HASH_SET_NBVALIDBITS(Size);
442
443 /* Write input buffer in data register */
444 HASHEx_WriteData(pInBuffer, Size);
445
446 /* Start the digest calculation */
447 __HAL_HASH_START_DIGEST();
448
449 /* Get tick */
450 tickstart = HAL_GetTick();
451
452 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
453 {
454 /* Check for the Timeout */
455 if(Timeout != HAL_MAX_DELAY)
456 {
457 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
458 {
459 /* Change state */
460 hhash->State = HAL_HASH_STATE_TIMEOUT;
461
462 /* Process Unlocked */
463 __HAL_UNLOCK(hhash);
464
465 return HAL_TIMEOUT;
466 }
467 }
468 }
469
470 /* Read the message digest */
471 HASHEx_GetDigest(pOutBuffer, 32U);
472
473 /* Change the HASH state */
474 hhash->State = HAL_HASH_STATE_READY;
475
476 /* Process Unlocked */
477 __HAL_UNLOCK(hhash);
478
479 /* Return function status */
480 return HAL_OK;
481 }
482
483
484 /**
485 * @brief Initializes the HASH peripheral in SHA224 mode
486 * then processes pInBuffer. The digest is available in pOutBuffer
487 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
488 * the configuration information for HASH module
489 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
490 * @param Size Length of the input buffer in bytes.
491 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
492 * @retval HAL status
493 */
494 HAL_StatusTypeDef HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
495 {
496 /* Process Locked */
497 __HAL_LOCK(hhash);
498
499 /* Change the HASH state */
500 hhash->State = HAL_HASH_STATE_BUSY;
501
502 /* Check if initialization phase has already been performed */
503 if(hhash->Phase == HAL_HASH_PHASE_READY)
504 {
505 /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
506 the message digest of a new message */
507 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
508 }
509
510 /* Set the phase */
511 hhash->Phase = HAL_HASH_PHASE_PROCESS;
512
513 /* Configure the number of valid bits in last word of the message */
514 __HAL_HASH_SET_NBVALIDBITS(Size);
515
516 /* Write input buffer in data register */
517 HASHEx_WriteData(pInBuffer, Size);
518
519 /* Change the HASH state */
520 hhash->State = HAL_HASH_STATE_READY;
521
522 /* Process Unlocked */
523 __HAL_UNLOCK(hhash);
524
525 /* Return function status */
526 return HAL_OK;
527 }
528
529
530 /**
531 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
532 The digest is available in pOutBuffer.
533 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
534 * the configuration information for HASH module
535 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
536 * @param Size Length of the input buffer in bytes.
537 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
538 * @retval HAL status
539 */
540 HAL_StatusTypeDef HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
541 {
542 /* Process Locked */
543 __HAL_LOCK(hhash);
544
545 /* Change the HASH state */
546 hhash->State = HAL_HASH_STATE_BUSY;
547
548 /* Check if initialization phase has already been performed */
549 if(hhash->Phase == HAL_HASH_PHASE_READY)
550 {
551 /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
552 the message digest of a new message */
553 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
554 }
555
556 /* Set the phase */
557 hhash->Phase = HAL_HASH_PHASE_PROCESS;
558
559 /* Configure the number of valid bits in last word of the message */
560 __HAL_HASH_SET_NBVALIDBITS(Size);
561
562 /* Write input buffer in data register */
563 HASHEx_WriteData(pInBuffer, Size);
564
565 /* Change the HASH state */
566 hhash->State = HAL_HASH_STATE_READY;
567
568 /* Process Unlocked */
569 __HAL_UNLOCK(hhash);
570
571 /* Return function status */
572 return HAL_OK;
573 }
574
575
576 /**
577 * @}
578 */
579
580 /** @defgroup HASHEx_Group2 HMAC processing functions using polling mode
581 * @brief HMAC processing functions using polling mode .
582 *
583 @verbatim
584 ===============================================================================
585 ##### HMAC processing using polling mode functions #####
586 ===============================================================================
587 [..] This section provides functions allowing to calculate in polling mode
588 the HMAC value using one of the following algorithms:
589 (+) SHA224
590 (+) SHA256
591
592 @endverbatim
593 * @{
594 */
595
596 /**
597 * @brief Initializes the HASH peripheral in HMAC SHA224 mode
598 * then processes pInBuffer. The digest is available in pOutBuffer.
599 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
600 * the configuration information for HASH module
601 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
602 * @param Size Length of the input buffer in bytes.
603 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
604 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
605 * @param Timeout Timeout value
606 * @retval HAL status
607 */
608 HAL_StatusTypeDef HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
609 {
610 uint32_t tickstart = 0U;
611
612 /* Process Locked */
613 __HAL_LOCK(hhash);
614
615 /* Change the HASH state */
616 hhash->State = HAL_HASH_STATE_BUSY;
617
618 /* Check if initialization phase has already been performed */
619 if(hhash->Phase == HAL_HASH_PHASE_READY)
620 {
621 /* Check if key size is greater than 64 bytes */
622 if(hhash->Init.KeySize > 64U)
623 {
624 /* Select the HMAC SHA224 mode */
625 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
626 }
627 else
628 {
629 /* Select the HMAC SHA224 mode */
630 HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
631 }
632 }
633
634 /* Set the phase */
635 hhash->Phase = HAL_HASH_PHASE_PROCESS;
636
637 /************************** STEP 1 ******************************************/
638 /* Configure the number of valid bits in last word of the message */
639 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
640
641 /* Write input buffer in data register */
642 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
643
644 /* Start the digest calculation */
645 __HAL_HASH_START_DIGEST();
646
647 /* Get tick */
648 tickstart = HAL_GetTick();
649
650 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
651 {
652 /* Check for the Timeout */
653 if(Timeout != HAL_MAX_DELAY)
654 {
655 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
656 {
657 /* Change state */
658 hhash->State = HAL_HASH_STATE_TIMEOUT;
659
660 /* Process Unlocked */
661 __HAL_UNLOCK(hhash);
662
663 return HAL_TIMEOUT;
664 }
665 }
666 }
667 /************************** STEP 2 ******************************************/
668 /* Configure the number of valid bits in last word of the message */
669 __HAL_HASH_SET_NBVALIDBITS(Size);
670
671 /* Write input buffer in data register */
672 HASHEx_WriteData(pInBuffer, Size);
673
674 /* Start the digest calculation */
675 __HAL_HASH_START_DIGEST();
676
677 /* Get tick */
678 tickstart = HAL_GetTick();
679
680 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
681 {
682 /* Check for the Timeout */
683 if(Timeout != HAL_MAX_DELAY)
684 {
685 if((HAL_GetTick() - tickstart ) > Timeout)
686 {
687 /* Change state */
688 hhash->State = HAL_HASH_STATE_TIMEOUT;
689
690 /* Process Unlocked */
691 __HAL_UNLOCK(hhash);
692
693 return HAL_TIMEOUT;
694 }
695 }
696 }
697 /************************** STEP 3 ******************************************/
698 /* Configure the number of valid bits in last word of the message */
699 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
700
701 /* Write input buffer in data register */
702 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
703
704 /* Start the digest calculation */
705 __HAL_HASH_START_DIGEST();
706
707 /* Get tick */
708 tickstart = HAL_GetTick();
709
710 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
711 {
712 /* Check for the Timeout */
713 if(Timeout != HAL_MAX_DELAY)
714 {
715 if((HAL_GetTick() - tickstart ) > Timeout)
716 {
717 /* Change state */
718 hhash->State = HAL_HASH_STATE_TIMEOUT;
719
720 /* Process Unlocked */
721 __HAL_UNLOCK(hhash);
722
723 return HAL_TIMEOUT;
724 }
725 }
726 }
727 /* Read the message digest */
728 HASHEx_GetDigest(pOutBuffer, 28U);
729
730 /* Change the HASH state */
731 hhash->State = HAL_HASH_STATE_READY;
732
733 /* Process Unlocked */
734 __HAL_UNLOCK(hhash);
735
736 /* Return function status */
737 return HAL_OK;
738 }
739
740 /**
741 * @brief Initializes the HASH peripheral in HMAC SHA256 mode
742 * then processes pInBuffer. The digest is available in pOutBuffer
743 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
744 * the configuration information for HASH module
745 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
746 * @param Size Length of the input buffer in bytes.
747 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
748 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
749 * @param Timeout Timeout value
750 * @retval HAL status
751 */
752 HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
753 {
754 uint32_t tickstart = 0U;
755
756 /* Process Locked */
757 __HAL_LOCK(hhash);
758
759 /* Change the HASH state */
760 hhash->State = HAL_HASH_STATE_BUSY;
761
762 /* Check if initialization phase has already been performed */
763 if(hhash->Phase == HAL_HASH_PHASE_READY)
764 {
765 /* Check if key size is greater than 64 bytes */
766 if(hhash->Init.KeySize > 64U)
767 {
768 /* Select the HMAC SHA256 mode */
769 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);
770 }
771 else
772 {
773 /* Select the HMAC SHA256 mode */
774 HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);
775 }
776 /* Reset the HASH processor core, so that the HASH will be ready to compute
777 the message digest of a new message */
778 HASH->CR |= HASH_CR_INIT;
779 }
780
781 /* Set the phase */
782 hhash->Phase = HAL_HASH_PHASE_PROCESS;
783
784 /************************** STEP 1 ******************************************/
785 /* Configure the number of valid bits in last word of the message */
786 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
787
788 /* Write input buffer in data register */
789 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
790
791 /* Start the digest calculation */
792 __HAL_HASH_START_DIGEST();
793
794 /* Get tick */
795 tickstart = HAL_GetTick();
796
797 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
798 {
799 /* Check for the Timeout */
800 if(Timeout != HAL_MAX_DELAY)
801 {
802 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
803 {
804 /* Change state */
805 hhash->State = HAL_HASH_STATE_TIMEOUT;
806
807 /* Process Unlocked */
808 __HAL_UNLOCK(hhash);
809
810 return HAL_TIMEOUT;
811 }
812 }
813 }
814 /************************** STEP 2 ******************************************/
815 /* Configure the number of valid bits in last word of the message */
816 __HAL_HASH_SET_NBVALIDBITS(Size);
817
818 /* Write input buffer in data register */
819 HASHEx_WriteData(pInBuffer, Size);
820
821 /* Start the digest calculation */
822 __HAL_HASH_START_DIGEST();
823
824 /* Get tick */
825 tickstart = HAL_GetTick();
826
827 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
828 {
829 /* Check for the Timeout */
830 if(Timeout != HAL_MAX_DELAY)
831 {
832 if((HAL_GetTick() - tickstart ) > Timeout)
833 {
834 /* Change state */
835 hhash->State = HAL_HASH_STATE_TIMEOUT;
836
837 /* Process Unlocked */
838 __HAL_UNLOCK(hhash);
839
840 return HAL_TIMEOUT;
841 }
842 }
843 }
844 /************************** STEP 3 ******************************************/
845 /* Configure the number of valid bits in last word of the message */
846 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
847
848 /* Write input buffer in data register */
849 HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);
850
851 /* Start the digest calculation */
852 __HAL_HASH_START_DIGEST();
853
854 /* Get tick */
855 tickstart = HAL_GetTick();
856
857 while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
858 {
859 /* Check for the Timeout */
860 if(Timeout != HAL_MAX_DELAY)
861 {
862 if((HAL_GetTick() - tickstart ) > Timeout)
863 {
864 /* Change state */
865 hhash->State = HAL_HASH_STATE_TIMEOUT;
866
867 /* Process Unlocked */
868 __HAL_UNLOCK(hhash);
869
870 return HAL_TIMEOUT;
871 }
872 }
873 }
874 /* Read the message digest */
875 HASHEx_GetDigest(pOutBuffer, 32U);
876
877 /* Change the HASH state */
878 hhash->State = HAL_HASH_STATE_READY;
879
880 /* Process Unlocked */
881 __HAL_UNLOCK(hhash);
882
883 /* Return function status */
884 return HAL_OK;
885 }
886
887 /**
888 * @}
889 */
890
891 /** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode
892 * @brief processing functions using interrupt mode.
893 *
894 @verbatim
895 ===============================================================================
896 ##### HASH processing using interrupt functions #####
897 ===============================================================================
898 [..] This section provides functions allowing to calculate in interrupt mode
899 the hash value using one of the following algorithms:
900 (+) SHA224
901 (+) SHA256
902
903 @endverbatim
904 * @{
905 */
906
907 /**
908 * @brief Initializes the HASH peripheral in SHA224 mode then processes pInBuffer.
909 * The digest is available in pOutBuffer.
910 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
911 * the configuration information for HASH module
912 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
913 * @param Size Length of the input buffer in bytes.
914 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
915 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
916 * @retval HAL status
917 */
918 HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
919 {
920 uint32_t inputaddr;
921 uint32_t buffercounter;
922 uint32_t inputcounter;
923
924 /* Process Locked */
925 __HAL_LOCK(hhash);
926
927 if(hhash->State == HAL_HASH_STATE_READY)
928 {
929 /* Change the HASH state */
930 hhash->State = HAL_HASH_STATE_BUSY;
931
932 hhash->HashInCount = Size;
933 hhash->pHashInBuffPtr = pInBuffer;
934 hhash->pHashOutBuffPtr = pOutBuffer;
935
936 /* Check if initialization phase has already been performed */
937 if(hhash->Phase == HAL_HASH_PHASE_READY)
938 {
939 /* Select the SHA224 mode */
940 HASH->CR |= HASH_ALGOSELECTION_SHA224;
941 /* Reset the HASH processor core, so that the HASH will be ready to compute
942 the message digest of a new message */
943 HASH->CR |= HASH_CR_INIT;
944 }
945 /* Reset interrupt counter */
946 hhash->HashITCounter = 0U;
947
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, 28U);
964 if(hhash->HashInCount == 0U)
965 {
966 /* Disable Interrupts */
967 HASH->IMR = 0U;
968 /* Change the HASH state */
969 hhash->State = HAL_HASH_STATE_READY;
970 /* Call digest computation complete callback */
971 HAL_HASH_DgstCpltCallback(hhash);
972
973 /* Process Unlocked */
974 __HAL_UNLOCK(hhash);
975
976 /* Return function status */
977 return HAL_OK;
978 }
979 }
980 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
981 {
982 if(hhash->HashInCount >= 68U)
983 {
984 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
985 /* Write the Input block in the Data IN register */
986 for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
987 {
988 HASH->DIN = *(uint32_t*)inputaddr;
989 inputaddr+=4U;
990 }
991 if(hhash->HashITCounter == 0U)
992 {
993 HASH->DIN = *(uint32_t*)inputaddr;
994
995 if(hhash->HashInCount >= 68U)
996 {
997 /* Decrement buffer counter */
998 hhash->HashInCount -= 68U;
999 hhash->pHashInBuffPtr+= 68U;
1000 }
1001 else
1002 {
1003 hhash->HashInCount = 0U;
1004 hhash->pHashInBuffPtr+= hhash->HashInCount;
1005 }
1006 /* Set Interrupt counter */
1007 hhash->HashITCounter = 1U;
1008 }
1009 else
1010 {
1011 /* Decrement buffer counter */
1012 hhash->HashInCount -= 64U;
1013 hhash->pHashInBuffPtr+= 64U;
1014 }
1015 }
1016 else
1017 {
1018 /* Get the buffer address */
1019 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1020 /* Get the buffer counter */
1021 inputcounter = hhash->HashInCount;
1022 /* Disable Interrupts */
1023 HASH->IMR &= ~(HASH_IT_DINI);
1024 /* Configure the number of valid bits in last word of the message */
1025 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
1026
1027 if((inputcounter > 4U) && (inputcounter%4U))
1028 {
1029 inputcounter = (inputcounter+4U-inputcounter%4U);
1030 }
1031 else if ((inputcounter < 4U) && (inputcounter != 0U))
1032 {
1033 inputcounter = 4U;
1034 }
1035 /* Write the Input block in the Data IN register */
1036 for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++)
1037 {
1038 HASH->DIN = *(uint32_t*)inputaddr;
1039 inputaddr+=4U;
1040 }
1041 /* Start the digest calculation */
1042 __HAL_HASH_START_DIGEST();
1043 /* Reset buffer counter */
1044 hhash->HashInCount = 0U;
1045 /* Call Input data transfer complete callback */
1046 HAL_HASH_InCpltCallback(hhash);
1047 }
1048 }
1049
1050 /* Process Unlocked */
1051 __HAL_UNLOCK(hhash);
1052
1053 /* Return function status */
1054 return HAL_OK;
1055 }
1056
1057
1058 /**
1059 * @brief Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
1060 * The digest is available in pOutBuffer.
1061 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
1062 * the configuration information for HASH module
1063 * @param pInBuffer Pointer to the input buffer (buffer to be hashed).
1064 * @param Size Length of the input buffer in bytes.
1065 * If the Size is not multiple of 64 bytes, the padding is managed by hardware.
1066 * @param pOutBuffer Pointer to the computed digest. Its size must be 20 bytes.
1067 * @retval HAL status
1068 */
1069 HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
1070 {
1071 uint32_t inputaddr;
1072 uint32_t buffercounter;
1073 uint32_t inputcounter;
1074
1075 /* Process Locked */
1076 __HAL_LOCK(hhash);
1077
1078 if(hhash->State == HAL_HASH_STATE_READY)
1079 {
1080 /* Change the HASH state */
1081 hhash->State = HAL_HASH_STATE_BUSY;
1082
1083 hhash->HashInCount = Size;
1084 hhash->pHashInBuffPtr = pInBuffer;
1085 hhash->pHashOutBuffPtr = pOutBuffer;
1086
1087 /* Check if initialization phase has already been performed */
1088 if(hhash->Phase == HAL_HASH_PHASE_READY)
1089 {
1090 /* Select the SHA256 mode */
1091 HASH->CR |= HASH_ALGOSELECTION_SHA256;
1092 /* Reset the HASH processor core, so that the HASH will be ready to compute
1093 the message digest of a new message */
1094 HASH->CR |= HASH_CR_INIT;
1095 }
1096 /* Reset interrupt counter */
1097 hhash->HashITCounter = 0U;
1098
1099 /* Set the phase */
1100 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1101
1102 /* Process Unlocked */
1103 __HAL_UNLOCK(hhash);
1104
1105 /* Enable Interrupts */
1106 HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);
1107
1108 /* Return function status */
1109 return HAL_OK;
1110 }
1111 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
1112 {
1113 /* Read the message digest */
1114 HASHEx_GetDigest(hhash->pHashOutBuffPtr, 32U);
1115 if(hhash->HashInCount == 0U)
1116 {
1117 /* Disable Interrupts */
1118 HASH->IMR = 0U;
1119 /* Change the HASH state */
1120 hhash->State = HAL_HASH_STATE_READY;
1121 /* Call digest computation complete callback */
1122 HAL_HASH_DgstCpltCallback(hhash);
1123
1124 /* Process Unlocked */
1125 __HAL_UNLOCK(hhash);
1126
1127 /* Return function status */
1128 return HAL_OK;
1129 }
1130 }
1131 if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
1132 {
1133 if(hhash->HashInCount >= 68U)
1134 {
1135 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1136 /* Write the Input block in the Data IN register */
1137 for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
1138 {
1139 HASH->DIN = *(uint32_t*)inputaddr;
1140 inputaddr+=4U;
1141 }
1142 if(hhash->HashITCounter == 0U)
1143 {
1144 HASH->DIN = *(uint32_t*)inputaddr;
1145
1146 if(hhash->HashInCount >= 68U)
1147 {
1148 /* Decrement buffer counter */
1149 hhash->HashInCount -= 68U;
1150 hhash->pHashInBuffPtr+= 68U;
1151 }
1152 else
1153 {
1154 hhash->HashInCount = 0U;
1155 hhash->pHashInBuffPtr+= hhash->HashInCount;
1156 }
1157 /* Set Interrupt counter */
1158 hhash->HashITCounter = 1U;
1159 }
1160 else
1161 {
1162 /* Decrement buffer counter */
1163 hhash->HashInCount -= 64U;
1164 hhash->pHashInBuffPtr+= 64U;
1165 }
1166 }
1167 else
1168 {
1169 /* Get the buffer address */
1170 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
1171 /* Get the buffer counter */
1172 inputcounter = hhash->HashInCount;
1173 /* Disable Interrupts */
1174 HASH->IMR &= ~(HASH_IT_DINI);
1175 /* Configure the number of valid bits in last word of the message */
1176 __HAL_HASH_SET_NBVALIDBITS(inputcounter);
1177
1178 if((inputcounter > 4U) && (inputcounter%4U))
1179 {
1180 inputcounter = (inputcounter+4U-inputcounter%4U);
1181 }
1182 else if ((inputcounter < 4U) && (inputcounter != 0U))
1183 {
1184 inputcounter = 4U;
1185 }
1186 /* Write the Input block in the Data IN register */
1187 for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++)
1188 {
1189 HASH->DIN = *(uint32_t*)inputaddr;
1190 inputaddr+=4U;
1191 }
1192 /* Start the digest calculation */
1193 __HAL_HASH_START_DIGEST();
1194 /* Reset buffer counter */
1195 hhash->HashInCount = 0U;
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, 0U, NULL);
1221 break;
1222
1223 case HASH_ALGOSELECTION_SHA256:
1224 HAL_HASHEx_SHA256_Start_IT(hhash, NULL, 0U, 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%4U ? (Size+3U)/4U:Size/4U));
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 = 0U;
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 == 0U)||((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, 28U);
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%4U ? (Size+3U)/4U:Size/4U));
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 = 0U;
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 == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1436 {
1437 /* Change state */
1438 hhash->State = HAL_HASH_STATE_TIMEOUT;
1439
1440 /* Process Unlocked */
1441 __HAL_UNLOCK(hhash);
1442
1443 return HAL_TIMEOUT;
1444 }
1445 }
1446 }
1447
1448 /* Read the message digest */
1449 HASHEx_GetDigest(pOutBuffer, 32U);
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 = 0U;
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 > 64U)
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%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U));
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 = 0U;
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 > 64U)
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%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U));
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 /* STM32F437xx || STM32F439xx || STM32F479xx */
1626
1627 #endif /* HAL_HASH_MODULE_ENABLED */
1628 /**
1629 * @}
1630 */
1631
1632 /**
1633 * @}
1634 */
1635
1636 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/