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