source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

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