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

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

nucleo_f401re依存部の追加

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