1 /**
2 ******************************************************************************
3 * @file stm32h5xx_hal_hash.c
4 * @author MCD Application Team
5 * @brief HASH HAL module driver.
6 * This file provides firmware functions to manage HASH peripheral
7 *
8 ******************************************************************************
9 * @attention
10 *
11 * Copyright (c) 2022 STMicroelectronics.
12 * All rights reserved.
13 *
14 * This software is licensed under terms that can be found in the LICENSE file
15 * in the root directory of this software component.
16 * If no LICENSE file comes with this software, it is provided AS-IS.
17 *
18 ******************************************************************************
19 @verbatim
20 ===============================================================================
21 ##### How to use this driver #####
22 ===============================================================================
23 [..]
24 The HASH HAL driver can be used as follows:
25
26 (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit():
27 (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE()
28 (##) When resorting to interrupt-based APIs (e.g. HAL_HASH_Start_IT())
29 (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority()
30 (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ()
31 (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler() API
32 (##) When resorting to DMA-based APIs (e.g. HAL_HASH_Start_DMA())
33 (+++) Enable the DMA interface clock
34 (+++) Configure and enable one DMA to manage data transfer from
35 memory to peripheral (input DMA). Managing data transfer from
36 peripheral to memory can be performed only using CPU.
37 (+++) Associate the initialized DMA handle to the HASH DMA handle
38 using __HAL_LINKDMA()
39 (+++) Configure the priority and enable the NVIC for the transfer complete
40 interrupt on the DMA: use
41 HAL_NVIC_SetPriority() and
42 HAL_NVIC_EnableIRQ()
43
44 (#)Initialize the HASH HAL using HAL_HASH_Init(). This function:
45 (##) resorts to HAL_HASH_MspInit() for low-level initialization,
46 (##) configures the data type: no swap, half word swap, bit swap or byte swap,
47 (##) configures the Algorithm : MD5, SHA1 or SHA2
48
49 (#)Three processing schemes are available:
50 (##) Polling mode: processing APIs are blocking functions
51 i.e. they process the data and wait till the digest computation is finished,
52 e.g. HAL_HASH_Start() for HASH or HAL_HMAC_Start() for HMAC
53 (##) Interrupt mode: processing APIs are not blocking functions
54 i.e. they process the data under interrupt,
55 e.g. HAL_HASH_Start_IT() for HASH or HAL_HMAC_Start_IT() for HMAC
56 (##) DMA mode: processing APIs are not blocking functions and the CPU is
57 not used for data transfer i.e. the data transfer is ensured by DMA,
58 e.g. HAL_HASH_Start_DMA() for HASH or HAL_HMAC_Start_DMA() for HMAC.
59
60 (#)When the processing function is called after HAL_HASH_Init(), the HASH peripheral is
61 initialized and processes the buffer fed in input. When the input data have all been
62 fed to the Peripheral, the digest computation can start.
63
64 (#)Multi-buffer processing HASH and HMAC are possible in polling, interrupt and DMA modes.
65 (##) In polling mode, API HAL_HASH_Accumulate()/HAL_HASH_HMAC_Accumulate() must be called
66 for each input buffer, except for the last one.
67 User must resort to HAL_HASH_AccumulateLast()/HAL_HASH_HMAC_AccumulateLast()
68 to enter the last one and retrieve as well the computed digest.
69
70 (##) In interrupt mode, API HAL_HASH_Accumulate_IT()/HAL_HASH_HMAC_Accumulate_IT() must
71 be called for each input buffer, except for the last one.
72 User must resort to HAL_HASH_AccumulateLast_IT()/HAL_HASH_HMAC_AccumulateLast_IT()
73 to enter the last one and retrieve as well the computed digest.
74
75 (##) In DMA mode, once initialization is done, MDMAT bit must be set through
76 __HAL_HASH_SET_MDMAT() macro.
77 From that point, each buffer can be fed to the Peripheral through HAL_HASH_Start_DMA() API
78 for HASH and HAL_HASH_HMAC_Start_DMA() API for HMAC .
79 Before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT()
80 macro then wrap-up the HASH processing in feeding the last input buffer through the
81 same API HAL_HASH_Start_DMA()for HASH and HAL_HASH_HMAC_Start_DMA() API for HMAC and
82 retrieve as well the computed digest.
83
84 (#)To use this driver (version 2.0.0) with application developed with old driver (version 1.0.0) user have to:
85 (##) Add Algorithm as parameter like DataType or KeySize.
86 (##) Use new API HAL_HASH_Start() for HASH and HAL_HASH_HMAC_Start() for HMAC processing instead of old API
87 like HAL_HASH_SHA1_Start and HAL_HMAC_SHA1_Start.
88
89
90 @endverbatim
91 ******************************************************************************
92 */
93
94 /* Includes ------------------------------------------------------------------*/
95 #include "stm32h5xx_hal.h"
96
97
98 /** @addtogroup STM32H5xx_HAL_Driver
99 * @{
100 */
101
102 #if defined (HASH)
103
104 /** @defgroup HASH HASH
105 * @brief HASH HAL module driver.
106 * @{
107 */
108
109 #ifdef HAL_HASH_MODULE_ENABLED
110
111 /* Private typedef -----------------------------------------------------------*/
112 /* Private define ------------------------------------------------------------*/
113 /** @defgroup HASH_Private_Defines HASH Private Defines
114 * @{
115 */
116 #define HASH_TIMEOUTVALUE 1000U /*!< Time-out value */
117 /**
118 * @}
119 */
120
121 /** @defgroup HASH_Number_Of_CSR_Registers HASH Number of Context Swap Registers
122 * @{
123 */
124 #if defined(HASH_ALGOSELECTION_SHA512)
125 #define HASH_NUMBER_OF_CSR_REGISTERS 103U /*!< Number of Context Swap Registers */
126 #else
127 #define HASH_NUMBER_OF_CSR_REGISTERS 54U /*!< Number of Context Swap Registers */
128 #endif /* HASH_ALGOSELECTION_SHA512 */
129 /**
130 * @}
131 */
132
133 /* Private Constants ---------------------------------------------------------*/
134 /* Private macro -------------------------------------------------------------*/
135 /* Private variables ---------------------------------------------------------*/
136 /* Private function prototypes -----------------------------------------------*/
137 /** @defgroup HASH_Private_Functions HASH Private Functions
138 * @{
139 */
140 static void HASH_GetDigest(HASH_HandleTypeDef *hhash, uint8_t *pMsgDigest, uint8_t Size);
141 static void HASH_WriteData(HASH_HandleTypeDef *hhash, const uint8_t *pInBuffer, uint32_t Size);
142 static HAL_StatusTypeDef HASH_WriteData_IT(HASH_HandleTypeDef *hhash);
143 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
144 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
145 static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status,
146 uint32_t Timeout);
147 /**
148 * @}
149 */
150
151 /* Exported functions ---------------------------------------------------------*/
152
153 /** @defgroup HASH_Exported_Functions HASH Exported Functions
154 * @{
155 */
156
157 /** @defgroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions
158 * @brief Initialization and configuration functions.
159 *
160 @verbatim
161 ===============================================================================
162 ##### Initialization and de-initialization functions #####
163 ===============================================================================
164 [..] This section provides functions allowing to:
165 (+) Initialize the HASH according to the specified parameters
166 in the HASH_InitTypeDef and create the associated handle
167 (+) DeInitialize the HASH peripheral
168 (+) Initialize the HASH MCU Specific Package (MSP)
169 (+) DeInitialize the HASH MSP
170 (+) Configure HASH (HAL_HASH_SetConfig) with the specified parameters in the HASH_ConfigTypeDef
171 Parameters which are configured in This section are :
172 (+) Data Type : no swap, half word swap, bit swap or byte swap
173 (+) Algorithm : MD5,SHA1 or SHA2
174 (+) Get HASH configuration (HAL_HASH_GetConfig) from the specified parameters in the HASH_HandleTypeDef
175
176 @endverbatim
177 * @{
178 */
179
180 /**
181 * @brief Initializes the HASH according to the specified parameters in the
182 HASH_HandleTypeDef and create the associated handle.
183 * @note Only Algorithm and DATATYPE bits of HASH Peripheral are set by HAL_HASH_Init(),
184 * other configuration bits are set by HASH or HMAC processing APIs.
185 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
186 * the configuration information for HASH module.
187 * @retval HAL status
188 */
HAL_HASH_Init(HASH_HandleTypeDef * hhash)189 HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
190 {
191 uint32_t cr_value;
192
193 /* Check the hash handle allocation */
194 if (hhash == NULL)
195 {
196 return HAL_ERROR;
197 }
198
199 /* Check the parameters */
200 assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
201 assert_param(IS_HASH_ALGORITHM(hhash->Init.Algorithm));
202
203 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
204 if (hhash->State == HAL_HASH_STATE_RESET)
205 {
206 /* Allocate lock resource and initialize it */
207 hhash->Lock = HAL_UNLOCKED;
208
209 /* Reset Callback pointers in HAL_HASH_STATE_RESET only */
210 hhash->InCpltCallback = HAL_HASH_InCpltCallback; /* Legacy weak InCpltCallback */
211 hhash->DgstCpltCallback = HAL_HASH_DgstCpltCallback; /* Legacy weak DgstCpltCallback */
212 hhash->ErrorCallback = HAL_HASH_ErrorCallback; /* Legacy weak ErrorCallback */
213 if (hhash->MspInitCallback == NULL)
214 {
215 hhash->MspInitCallback = HAL_HASH_MspInit;
216 }
217
218 /* Init the low level hardware */
219 hhash->MspInitCallback(hhash);
220 }
221 #else
222 if (hhash->State == HAL_HASH_STATE_RESET)
223 {
224 /* Allocate lock resource and initialize it */
225 hhash->Lock = HAL_UNLOCKED;
226
227 /* Init the low level hardware */
228 HAL_HASH_MspInit(hhash);
229 }
230 #endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */
231
232 /* Set the key size, data type and Algorithm */
233 cr_value = (uint32_t)(hhash->Init.DataType | hhash->Init.Algorithm);
234 /* Set the key size, data type, algorithm and mode */
235 MODIFY_REG(hhash->Instance->CR, HASH_CR_DATATYPE | HASH_CR_ALGO | HASH_CR_INIT, cr_value);
236
237 /* Change HASH phase to Ready */
238 hhash->Phase = HAL_HASH_PHASE_READY;
239
240 /* Change HASH state to Ready */
241 hhash->State = HAL_HASH_STATE_READY;
242
243 /* Reset error code field */
244 hhash->ErrorCode = HAL_HASH_ERROR_NONE;
245
246 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
247 /* Reset suspension request flag */
248 hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
249 #endif /* (USE_HAL_HASH_SUSPEND_RESUME) */
250 /* Return function status */
251 return HAL_OK;
252 }
253
254 /**
255 * @brief DeInitialize the HASH peripheral.
256 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
257 * the configuration information for HASH module.
258 * @retval HAL status
259 */
HAL_HASH_DeInit(HASH_HandleTypeDef * hhash)260 HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
261 {
262 /* Check the HASH handle allocation */
263 if (hhash == NULL)
264 {
265 return HAL_ERROR;
266 }
267
268 /* Change the default HASH phase */
269 hhash->Phase = HAL_HASH_PHASE_READY;
270
271 /* Reset HashInCount */
272 hhash->HashInCount = 0U;
273
274 /* Reset multi buffers accumulation flag */
275 hhash->Accumulation = 0U;
276
277 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
278 if (hhash->MspDeInitCallback == NULL)
279 {
280 hhash->MspDeInitCallback = HAL_HASH_MspDeInit;
281 }
282
283 /* DeInit the low level hardware */
284 hhash->MspDeInitCallback(hhash);
285 #else
286 /* DeInit the low level hardware: CLOCK, NVIC */
287 HAL_HASH_MspDeInit(hhash);
288 #endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */
289
290 /* Set the HASH state to Ready */
291 hhash->State = HAL_HASH_STATE_RESET;
292
293 __HAL_UNLOCK(hhash);
294
295 return HAL_OK;
296 }
297
298 /**
299 * @brief Configure the HASH according to the specified
300 * parameters in the HASH_ConfigTypeDef
301 * @param hcryp pointer to a HASH_HandleTypeDef structure
302 * @param pConf pointer to a HASH_ConfigTypeDef structure that contains
303 * the configuration information for HASH module
304 * @retval HAL status
305 */
HAL_HASH_SetConfig(HASH_HandleTypeDef * hhash,HASH_ConfigTypeDef * pConf)306 HAL_StatusTypeDef HAL_HASH_SetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf)
307 {
308 uint32_t cr_value;
309
310 /* Check the HASH handle allocation */
311 if ((hhash == NULL) || (pConf == NULL))
312 {
313 return HAL_ERROR;
314 }
315
316 /* Check parameters */
317 assert_param(IS_HASH_DATATYPE(pConf->DataType));
318 assert_param(IS_HASH_ALGORITHM(pConf->Algorithm));
319
320 if (hhash->State == HAL_HASH_STATE_READY)
321 {
322 /* Change the HASH state */
323 hhash->State = HAL_HASH_STATE_BUSY;
324 __HAL_LOCK(hhash);
325
326 /* Set HASH parameters */
327 hhash->Init.DataType = pConf->DataType;
328 hhash->Init.pKey = pConf->pKey;
329 hhash->Init.Algorithm = pConf->Algorithm;
330 hhash->Init.KeySize = pConf->KeySize;
331
332 /* Set the key size, data type and Algorithm */
333 cr_value = (uint32_t)(hhash->Init.DataType | hhash->Init.Algorithm);
334 /* Set the key size, data type, algorithm and mode */
335 MODIFY_REG(hhash->Instance->CR, HASH_CR_DATATYPE | HASH_CR_ALGO | HASH_CR_INIT, cr_value);
336
337 /* Change HASH phase to Ready */
338 hhash->Phase = HAL_HASH_PHASE_READY;
339
340 /* Change HASH state to Ready */
341 hhash->State = HAL_HASH_STATE_READY;
342
343 /* Reset error code field */
344 hhash->ErrorCode = HAL_HASH_ERROR_NONE;
345
346 __HAL_UNLOCK(hhash);
347
348 return HAL_OK;
349
350 }
351 else
352 {
353 /* Busy error code field */
354 hhash->ErrorCode |= HAL_HASH_ERROR_BUSY;
355 return HAL_ERROR;
356 }
357 }
358
359 /**
360 * @brief Get HASH Configuration parameters in associated handle
361 * @param pConf pointer to a HASH_HandleTypeDef structure
362 * @param hhash pointer to a HASH_ConfigTypeDef structure that contains
363 * the configuration information for HASH module
364 * @retval HAL status
365 */
HAL_HASH_GetConfig(HASH_HandleTypeDef * hhash,HASH_ConfigTypeDef * pConf)366 HAL_StatusTypeDef HAL_HASH_GetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf)
367 {
368
369 /* Check the HASH handle allocation */
370 if ((hhash == NULL) || (pConf == NULL))
371 {
372 return HAL_ERROR;
373 }
374
375 if (hhash->State == HAL_HASH_STATE_READY)
376 {
377 /* Change the HASH state */
378 hhash->State = HAL_HASH_STATE_BUSY;
379 __HAL_LOCK(hhash);
380
381 /* Set HASH parameters */
382 pConf->DataType = hhash->Init.DataType;
383 pConf->pKey = hhash->Init.pKey;
384 pConf->Algorithm = hhash->Init.Algorithm;
385 pConf->KeySize = hhash->Init.KeySize;
386
387 /* Change HASH state to Ready */
388 hhash->State = HAL_HASH_STATE_READY;
389 __HAL_UNLOCK(hhash);
390
391 return HAL_OK;
392
393 }
394 else
395 {
396 /* Busy error code field */
397 hhash->ErrorCode |= HAL_HASH_ERROR_BUSY;
398 return HAL_ERROR;
399 }
400 }
401
402 /**
403 * @brief Initialize the HASH MSP.
404 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
405 * the configuration information for HASH module.
406 * @retval None
407 */
HAL_HASH_MspInit(HASH_HandleTypeDef * hhash)408 __weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
409 {
410 /* Prevent unused argument(s) compilation warning */
411 UNUSED(hhash);
412
413 /* NOTE : This function should not be modified; when the callback is needed,
414 HAL_HASH_MspInit() can be implemented in the user file.
415 */
416 }
417
418 /**
419 * @brief DeInitialize the HASH MSP.
420 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
421 * the configuration information for HASH module.
422 * @retval None
423 */
HAL_HASH_MspDeInit(HASH_HandleTypeDef * hhash)424 __weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
425 {
426 /* Prevent unused argument(s) compilation warning */
427 UNUSED(hhash);
428
429 /* NOTE : This function should not be modified; when the callback is needed,
430 HAL_HASH_MspDeInit() can be implemented in the user file.
431 */
432 }
433
434
435 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
436 /**
437 * @brief Register a User HASH Callback
438 * To be used instead of the weak (surcharged) predefined callback
439 * @param hhash HASH handle
440 * @param CallbackID ID of the callback to be registered
441 * This parameter can be one of the following values:
442 * @arg HAL_HASH_INPUTCPLT_CB_ID input completion callback ID
443 * @arg HAL_HASH_DGSTCPLT_CB_ID digest computation completion callback ID
444 * @arg HAL_HASH_ERROR_CB_ID error callback ID
445 * @arg HAL_HASH_MSPINIT_CB_ID MspInit callback ID
446 * @arg HAL_HASH_MSPDEINIT_CB_ID MspDeInit callback ID
447 * @param pCallback pointer to the Callback function
448 * @retval status
449 */
HAL_HASH_RegisterCallback(HASH_HandleTypeDef * hhash,HAL_HASH_CallbackIDTypeDef CallbackID,pHASH_CallbackTypeDef pCallback)450 HAL_StatusTypeDef HAL_HASH_RegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID,
451 pHASH_CallbackTypeDef pCallback)
452 {
453 HAL_StatusTypeDef status = HAL_OK;
454
455 if (pCallback == NULL)
456 {
457 /* Update the error code */
458 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
459 return HAL_ERROR;
460 }
461
462 if (hhash->State == HAL_HASH_STATE_READY)
463 {
464 switch (CallbackID)
465 {
466 case HAL_HASH_INPUTCPLT_CB_ID :
467 hhash->InCpltCallback = pCallback;
468 break;
469
470 case HAL_HASH_DGSTCPLT_CB_ID :
471 hhash->DgstCpltCallback = pCallback;
472 break;
473
474 case HAL_HASH_ERROR_CB_ID :
475 hhash->ErrorCallback = pCallback;
476 break;
477
478 case HAL_HASH_MSPINIT_CB_ID :
479 hhash->MspInitCallback = pCallback;
480 break;
481
482 case HAL_HASH_MSPDEINIT_CB_ID :
483 hhash->MspDeInitCallback = pCallback;
484 break;
485
486 default :
487 /* Update the error code */
488 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
489 /* update return status */
490 status = HAL_ERROR;
491 break;
492 }
493 }
494 else if (hhash->State == HAL_HASH_STATE_RESET)
495 {
496 switch (CallbackID)
497 {
498 case HAL_HASH_MSPINIT_CB_ID :
499 hhash->MspInitCallback = pCallback;
500 break;
501
502 case HAL_HASH_MSPDEINIT_CB_ID :
503 hhash->MspDeInitCallback = pCallback;
504 break;
505
506 default :
507 /* Update the error code */
508 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
509 /* update return status */
510 status = HAL_ERROR;
511 break;
512 }
513 }
514 else
515 {
516 /* Update the error code */
517 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
518 /* update return status */
519 status = HAL_ERROR;
520 }
521
522 return status;
523 }
524
525 /**
526 * @brief Unregister a HASH Callback
527 * HASH Callback is redirected to the weak (surcharged) predefined callback
528 * @param hhash HASH handle
529 * @param CallbackID ID of the callback to be unregistered
530 * This parameter can be one of the following values:
531 * @arg HAL_HASH_INPUTCPLT_CB_ID HASH input completion Callback ID
532 * @arg HAL_HASH_DGSTCPLT_CB_ID HASH digest computation completion Callback ID
533 * @arg HAL_HASH_ERROR_CB_ID HASH error Callback ID
534 * @arg HAL_HASH_MSPINIT_CB_ID HASH MspInit callback ID
535 * @arg HAL_HASH_MSPDEINIT_CB_ID HASH MspDeInit callback ID
536 * @retval status
537 */
HAL_HASH_UnRegisterCallback(HASH_HandleTypeDef * hhash,HAL_HASH_CallbackIDTypeDef CallbackID)538 HAL_StatusTypeDef HAL_HASH_UnRegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID)
539 {
540 HAL_StatusTypeDef status = HAL_OK;
541
542
543 if (hhash->State == HAL_HASH_STATE_READY)
544 {
545 switch (CallbackID)
546 {
547 case HAL_HASH_INPUTCPLT_CB_ID :
548 hhash->InCpltCallback = HAL_HASH_InCpltCallback; /* Legacy weak input completion callback */
549 break;
550
551 case HAL_HASH_DGSTCPLT_CB_ID :
552 hhash->DgstCpltCallback = HAL_HASH_DgstCpltCallback; /* Legacy weak digest computation
553 completion callback */
554 break;
555
556 case HAL_HASH_ERROR_CB_ID :
557 hhash->ErrorCallback = HAL_HASH_ErrorCallback; /* Legacy weak error callback */
558 break;
559
560 case HAL_HASH_MSPINIT_CB_ID :
561 hhash->MspInitCallback = HAL_HASH_MspInit; /* Legacy weak MspInit Callback */
562 break;
563
564 case HAL_HASH_MSPDEINIT_CB_ID :
565 hhash->MspDeInitCallback = HAL_HASH_MspDeInit; /* Legacy weak MspDeInit Callback */
566 break;
567
568 default :
569 /* Update the error code */
570 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
571 /* update return status */
572 status = HAL_ERROR;
573 break;
574 }
575 }
576 else if (hhash->State == HAL_HASH_STATE_RESET)
577 {
578 switch (CallbackID)
579 {
580 case HAL_HASH_MSPINIT_CB_ID :
581 hhash->MspInitCallback = HAL_HASH_MspInit; /* Legacy weak MspInit Callback */
582 break;
583
584 case HAL_HASH_MSPDEINIT_CB_ID :
585 hhash->MspDeInitCallback = HAL_HASH_MspDeInit; /* Legacy weak MspDeInit Callback */
586 break;
587
588 default :
589 /* Update the error code */
590 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
591 /* update return status */
592 status = HAL_ERROR;
593 break;
594 }
595 }
596 else
597 {
598 /* Update the error code */
599 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
600 /* update return status */
601 status = HAL_ERROR;
602 }
603
604 return status;
605 }
606 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
607
608 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
609 /**
610 * @brief Save the HASH context in case of processing suspension.
611 * @param hhash HASH handle.
612 * @param pMemBuffer pointer to the memory buffer where the HASH context
613 * is saved.
614 * @note The IMR, STR, CR then all the CSR registers are saved
615 * in that order. Only the r/w bits are read to be restored later on.
616 * @note By default, all the context swap registers (there are
617 * HASH_NUMBER_OF_CSR_REGISTERS of those) are saved.
618 * @note pMemBuffer points to a buffer allocated by the user. The buffer size
619 * must be at least (HASH_NUMBER_OF_CSR_REGISTERS + 3) * 4 uint8 long.
620 * @retval None
621 */
HAL_HASH_Suspend(HASH_HandleTypeDef * hhash,uint8_t * pMemBuffer)622 void HAL_HASH_Suspend(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer)
623 {
624 uint32_t mem_ptr = (uint32_t)pMemBuffer;
625 uint32_t csr_ptr = (uint32_t)(hhash->Instance->CSR);
626 uint32_t i;
627
628 /* Prevent unused argument(s) compilation warning */
629 UNUSED(hhash);
630
631 /* Save IMR register content */
632 *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->IMR, HASH_IT_DINI | HASH_IT_DCI);
633 mem_ptr += 4U;
634 /* Save STR register content */
635 *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->STR, HASH_STR_NBLW);
636 mem_ptr += 4U;
637 /* Save CR register content */
638 *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->CR, HASH_CR_DMAE | HASH_CR_DATATYPE | HASH_CR_MODE | HASH_CR_ALGO |
639 HASH_CR_LKEY | HASH_CR_MDMAT);
640
641 mem_ptr += 4U;
642 /* By default, save all CSRs registers */
643 for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--)
644 {
645 *(uint32_t *)(mem_ptr) = *(uint32_t *)(csr_ptr);
646 mem_ptr += 4U;
647 csr_ptr += 4U;
648 }
649 /* Save low-priority block HASH handle parameters */
650 hhash->Init_saved = hhash->Init;
651 hhash->pHashOutBuffPtr_saved = hhash->pHashOutBuffPtr;
652 hhash->HashInCount_saved = hhash->HashInCount;
653 hhash->Size_saved = hhash->Size;
654 hhash->pHashInBuffPtr_saved = hhash->pHashInBuffPtr;
655 hhash->Phase_saved = hhash->Phase;
656 hhash->pHashKeyBuffPtr_saved = hhash->pHashKeyBuffPtr;
657 }
658
659
660 /**
661 * @brief Restore the HASH context in case of processing resumption.
662 * @param hhash HASH handle.
663 * @param pMemBuffer pointer to the memory buffer where the HASH context
664 * is stored.
665 * @note The IMR, STR, CR then all the CSR registers are restored
666 * in that order. Only the r/w bits are restored.
667 * @note By default, all the context swap registers (HASH_NUMBER_OF_CSR_REGISTERS
668 * of those) are restored (all of them have been saved by default
669 * beforehand).
670 * @retval None
671 */
HAL_HASH_Resume(HASH_HandleTypeDef * hhash,uint8_t * pMemBuffer)672 void HAL_HASH_Resume(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer)
673 {
674 uint32_t mem_ptr = (uint32_t)pMemBuffer;
675 uint32_t csr_ptr = (uint32_t)(hhash->Instance->CSR);
676 uint32_t i;
677
678 /* Prevent unused argument(s) compilation warning */
679 UNUSED(hhash);
680
681 /* Restore IMR register content */
682 WRITE_REG(hhash->Instance->IMR, (*(uint32_t *)(mem_ptr)));
683 mem_ptr += 4U;
684 /* Restore STR register content */
685 WRITE_REG(hhash->Instance->STR, (*(uint32_t *)(mem_ptr)));
686 mem_ptr += 4U;
687 /* Restore CR register content */
688 WRITE_REG(hhash->Instance->CR, (*(uint32_t *)(mem_ptr)));
689 mem_ptr += 4U;
690
691 /* Reset the HASH processor before restoring the Context
692 Swap Registers (CSR) */
693 SET_BIT(hhash->Instance->CR, HASH_CR_INIT);
694
695
696 /* By default, restore all CSR registers */
697 for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--)
698 {
699 WRITE_REG((*(uint32_t *)(csr_ptr)), (*(uint32_t *)(mem_ptr)));
700 mem_ptr += 4U;
701 csr_ptr += 4U;
702 }
703
704 /* Restore low-priority block HASH handle parameters */
705 hhash->Init = hhash->Init_saved;
706 hhash->pHashOutBuffPtr = hhash->pHashOutBuffPtr_saved;
707 hhash->HashInCount = hhash->HashInCount_saved;
708 hhash->Size = hhash->Size_saved;
709 hhash->pHashInBuffPtr = hhash->pHashInBuffPtr_saved;
710 hhash->Phase = hhash->Phase_saved;
711 hhash->State = HAL_HASH_STATE_SUSPENDED;
712 hhash->pHashKeyBuffPtr = hhash->pHashKeyBuffPtr_saved;
713 }
714
715 /**
716 * @brief Initiate HASH processing suspension when in interruption mode.
717 * @param hhash HASH handle.
718 * @note Set the handle field SuspendRequest to the appropriate value so that
719 * the on-going HASH processing is suspended as soon as the required
720 * conditions are met. Note that the actual suspension is carried out
721 * by the functions HASH_WriteData() in polling mode and HASH_IT() in
722 * interruption mode.
723 * @retval None
724 */
HAL_HASH_ProcessSuspend(HASH_HandleTypeDef * hhash)725 HAL_StatusTypeDef HAL_HASH_ProcessSuspend(HASH_HandleTypeDef *hhash)
726 {
727 uint32_t remainingwords; /*remaining number in of source block to be transferred.*/
728 uint32_t nbbytePartialHash = (((hhash->Instance->SR) >> 16U) * 4U); /* Nb byte to enter in HASH fifo
729 to trig a partial HASH computation*/
730 uint32_t sizeinwords;/* number in word of source block to be transferred.*/
731
732 /* suspension in DMA mode*/
733 if (__HAL_HASH_GET_FLAG(hhash, HASH_FLAG_DMAS) != RESET)
734 {
735 if (hhash->State == HAL_HASH_STATE_READY)
736 {
737 return HAL_ERROR;
738 }
739 else
740 {
741
742 /* Clear the DMAE bit to disable the DMA interface */
743 CLEAR_BIT(HASH->CR, HASH_CR_DMAE);
744
745 /* Wait until the last DMA transfer is complete (DMAS = 0 in the HASH_SR register) */
746 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DMAS, SET, HASH_TIMEOUTVALUE) != HAL_OK)
747 {
748 return HAL_TIMEOUT;
749 }
750
751 /* At this point, DMA interface is disabled and no transfer is on-going */
752 /* Retrieve from the DMA handle how many words remain to be written */
753 /* DMA3 used, DMA_CBR1_BNDT in bytes, DMA_CSR_FIFOL in words */
754 remainingwords = ((((DMA_Channel_TypeDef *)hhash->hdmain->Instance)->CBR1) \
755 & DMA_CBR1_BNDT) / 4U;
756 remainingwords += ((((DMA_Channel_TypeDef *)hhash->hdmain->Instance)->CSR) \
757 & DMA_CSR_FIFOL) >> DMA_CSR_FIFOL_Pos;
758
759 if (remainingwords <= nbbytePartialHash)
760 {
761 /* No suspension attempted since almost to the end of the transferred data. */
762 /* Best option for user code is to wrap up low priority message hashing */
763 return HAL_ERROR;
764 }
765
766 /* Disable DMA channel */
767 /* Note that the Abort function will
768 - Clear the transfer error flags
769 - Unlock
770 - Set the State
771 */
772 if (HAL_DMA_Abort(hhash->hdmain) != HAL_OK)
773 {
774 return HAL_ERROR;
775 }
776
777 if (__HAL_HASH_GET_FLAG(hhash, HASH_FLAG_DCIS) != RESET)
778 {
779 return HAL_ERROR;
780 }
781
782 /* Wait until the hash processor is ready (no block is being processed), that is wait for DINIS=1 in HASH_SR */
783 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DINIS, RESET, HASH_TIMEOUTVALUE) != HAL_OK)
784 {
785 return HAL_TIMEOUT;
786 }
787
788 /* Compute how many words were supposed to be transferred by DMA */
789 sizeinwords = (((hhash->Size % 4U) != 0U) ? \
790 ((hhash->Size + 3U) / 4U) : (hhash->Size / 4U));
791 /* Accordingly, update the input pointer that points at the next word to be
792 transferred to the Peripheral by DMA */
793 hhash->pHashInBuffPtr += 4U * (sizeinwords - remainingwords) ;
794
795 /* And store in HashInCount the remaining size to transfer (in bytes) */
796 hhash->HashInCount = 4U * remainingwords;
797
798
799 hhash->State = HAL_HASH_STATE_SUSPENDED;
800 __HAL_UNLOCK(hhash);
801 return HAL_OK;
802 }
803
804 }
805 else /* suspension when in interruption mode*/
806 {
807 /* Set Handle Suspend Request field */
808 hhash->SuspendRequest = HAL_HASH_SUSPEND;
809 return HAL_OK;
810 }
811 }
812 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
813 /**
814 * @}
815 */
816
817
818 /** @defgroup HASH_Exported_Functions_Group2 HASH processing functions
819 * @brief HASH processing functions using different mode.
820 *
821 @verbatim
822 ===============================================================================
823 ##### HASH processing functions #####
824 ===============================================================================
825 [..] This section provides API allowing to calculate the hash value using
826 one of the HASH algorithms supported by the peripheral.
827
828 [..] For a single buffer to be hashed, user can resort to one of three processing
829 functions available .
830 (+) Polling mode : HAL_HASH_Start()
831 (+) Interrupt mode : HAL_HASH_Start_IT()
832 (+) DMA mode : HAL_HASH_Start_DMA()
833
834 [..] In case of multi-buffer HASH processing (a single digest is computed while
835 several buffers are fed to the Peripheral), the user can resort to successive calls
836 to :
837 (+) Polling mode : HAL_HASH_Accumulate() and wrap-up the digest computation by a call
838 to HAL_HASH_AccumulateLast()
839 (+) Interrupt mode : HAL_HASH_Accumulate_IT() and wrap-up the digest computation by a call
840 to HAL_HASH_AccumulateLast_IT()
841 (+) DMA mode : HAL_HASH_Start_DMA(), MDMAT bit must be set through __HAL_HASH_SET_MDMAT() macro,
842 before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT()
843 macro then wrap-up the HASH processing in feeding the last input buffer through the
844 same API HAL_HASH_Start_DMA()
845
846 @endverbatim
847 * @{
848 */
849
850 /**
851 * @brief HASH peripheral processes in polling mode pInBuffer then reads the computed digest.
852 * @param hhash HASH handle.
853 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
854 * @param Size length of the input buffer in bytes.
855 * @param pOutBuffer pointer to the computed digest.
856 * @param Timeout specify timeout value
857 * @retval HAL status
858 */
HAL_HASH_Start(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer,uint32_t Timeout)859 HAL_StatusTypeDef HAL_HASH_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
860 uint8_t *const pOutBuffer, uint32_t Timeout)
861 {
862 /* Check the hash handle allocation */
863 if (hhash == NULL)
864 {
865 return HAL_ERROR;
866 }
867
868 /* Check if peripheral is ready to start process */
869 if (hhash->State == HAL_HASH_STATE_READY)
870 {
871 /* Process Locked */
872 __HAL_LOCK(hhash);
873
874 /* Change the HASH state */
875 hhash->State = HAL_HASH_STATE_BUSY;
876
877 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
878 hhash->pHashInBuffPtr = pInBuffer;
879 hhash->pHashOutBuffPtr = pOutBuffer;
880 hhash->HashInCount = 0U;
881 hhash->Size = Size;
882
883 /* Set HASH mode */
884 CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
885 /* Reset the HASH processor core */
886 MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
887
888 /* Configure the number of valid bits in last word of the message */
889 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
890
891 /* Set the phase */
892 hhash->Phase = HAL_HASH_PHASE_PROCESS;
893
894 HASH_WriteData(hhash, pInBuffer, Size);
895
896 /* Start the message padding then the Digest calculation */
897 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
898
899 /* Wait for digest calculation completion status(DCIS) flag to be set */
900 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
901 {
902 return HAL_ERROR;
903 }
904
905 /* Read the message digest */
906 HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash));
907
908 /* Change the HASH state */
909 hhash->State = HAL_HASH_STATE_READY;
910
911 /* Reset HASH state machine */
912 hhash->Phase = HAL_HASH_PHASE_READY;
913
914 /* Process Unlocked */
915 __HAL_UNLOCK(hhash);
916
917 /* Return function status */
918 return HAL_OK;
919 }
920 else
921 {
922 return HAL_BUSY;
923 }
924 }
925
926
927 /**
928 * @brief HASH peripheral processes in interrupt mode pInBuffer then reads the computed digest.
929 * @param hhash HASH handle.
930 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
931 * @param Size length of the input buffer in bytes.
932 * @param pOutBuffer pointer to the computed digest.
933 * @retval HAL status
934 */
HAL_HASH_Start_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)935 HAL_StatusTypeDef HAL_HASH_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
936 uint8_t *const pOutBuffer)
937 {
938 HAL_StatusTypeDef status;
939 HAL_HASH_StateTypeDef temp_state;
940
941 /* Check the hash handle allocation */
942 if (hhash == NULL)
943 {
944 return HAL_ERROR;
945 }
946
947 /* Check if peripheral is ready to start process or suspended */
948 temp_state = hhash->State;
949 if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED))
950 {
951 /* Process Locked */
952 __HAL_LOCK(hhash);
953
954 if (hhash->State == HAL_HASH_STATE_READY)
955 {
956 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
957 hhash->HashInCount = 0U;
958 hhash->pHashInBuffPtr = pInBuffer;
959 hhash->pHashOutBuffPtr = pOutBuffer;
960 hhash->Size = Size;
961
962 /* Set HASH mode */
963 CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
964 /* Reset the HASH processor core */
965 MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
966
967 /* Configure the number of valid bits in last word of the message */
968 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
969 }
970 /* Change the HASH state */
971 hhash->State = HAL_HASH_STATE_BUSY;
972 /* Set the phase */
973 hhash->Phase = HAL_HASH_PHASE_PROCESS;
974
975 /* Enable the specified HASH interrupt*/
976 __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
977
978 status = HASH_WriteData_IT(hhash);
979 }
980 else
981 {
982 status = HAL_BUSY;
983 }
984 /* Return function status */
985 return status;
986 }
987
988 /**
989 * @brief HASH peripheral processes in DMA mode pInBuffer then reads the computed digest.
990 * @note Multi-buffer HASH processing is possible, consecutive calls to HAL_HASH_Start_DMA
991 * (MDMAT bit must be set) can be used to feed several input buffers
992 * back-to-back to the Peripheral that will yield a single
993 * HASH signature once all buffers have been entered. Wrap-up of input
994 * buffers feeding and retrieval of digest is done by a call to
995 * HAL_HASH_Start_DMA (MDMAT bit must be reset).
996 * @param hhash HASH handle.
997 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
998 * @param Size length of the input buffer in bytes (must be a multiple of 4 in
999 * case of Multi-buffer and not last buffer).
1000 * @param pOutBuffer pointer to the computed digest.
1001 * @retval HAL status
1002 */
HAL_HASH_Start_DMA(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)1003 HAL_StatusTypeDef HAL_HASH_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1004 uint8_t *const pOutBuffer)
1005 {
1006 HAL_StatusTypeDef status;
1007 HAL_HASH_StateTypeDef temp_state;
1008
1009 /* Check the hash handle allocation */
1010 if (hhash == NULL)
1011 {
1012 return HAL_ERROR;
1013 }
1014
1015 /* Check if peripheral is ready to start process or suspended */
1016 temp_state = hhash->State;
1017 if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED))
1018 {
1019
1020 /* Process Locked */
1021 __HAL_LOCK(hhash);
1022
1023 /* Check if initialization phase has not been already performed */
1024 if (hhash->State == HAL_HASH_STATE_READY)
1025 {
1026 /* Change the HASH state */
1027 hhash->State = HAL_HASH_STATE_BUSY;
1028
1029 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1030 hhash->HashInCount = 0U;
1031 hhash->pHashInBuffPtr = pInBuffer;
1032 hhash->pHashOutBuffPtr = pOutBuffer;
1033 hhash->HashInCount = 0U;
1034 hhash->Size = Size;
1035
1036 /* Check if initialization phase has already been performed.
1037 If Phase is already set to HAL_HASH_PHASE_PROCESS, this means the
1038 API is processing a new input data message in case of multi-buffer HASH
1039 computation. */
1040 if (hhash->Phase == HAL_HASH_PHASE_READY)
1041 {
1042 /* Set HASH mode */
1043 CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1044 /* Reset the HASH processor core */
1045 MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1046
1047 /* Set the phase */
1048 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1049 }
1050 /* Configure the number of valid bits in last word of the message */
1051 if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U)
1052 {
1053 /* Configure the number of valid bits in last word of the message */
1054 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Size) % 4U));
1055 }
1056 else
1057 {
1058 /* Configure the number of valid bits in last word of the message */
1059 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U);
1060 }
1061
1062 }
1063 else /* HAL_HASH_STATE_SUSPENDED */
1064 {
1065 /* Change the HASH state */
1066 hhash->State = HAL_HASH_STATE_BUSY;
1067 /*only part not yet hashed to compute */
1068 hhash->Size = hhash->HashInCount;
1069 }
1070 /* Set the HASH DMA transfer complete callback */
1071 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1072 /* Set the DMA error callback */
1073 hhash->hdmain->XferErrorCallback = HASH_DMAError;
1074
1075 if ((hhash->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1076 {
1077 if ((hhash->hdmain->LinkedListQueue != NULL) && (hhash->hdmain->LinkedListQueue->Head != NULL))
1078 {
1079 /* Enable the DMA channel */
1080 hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET]\
1081 = ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : (hhash->Size));
1082 hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET]\
1083 = (uint32_t)(hhash->pHashInBuffPtr); /* Set DMA source address */
1084 hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET]\
1085 = (uint32_t)&hhash->Instance->DIN; /* Set DMA destination address */
1086
1087 status = HAL_DMAEx_List_Start_IT(hhash->hdmain);
1088 }
1089 else
1090 {
1091 /* Return error status */
1092 status = HAL_ERROR;
1093 }
1094 }
1095 else
1096 {
1097 status = HAL_DMA_Start_IT(hhash->hdmain, (uint32_t)pInBuffer, (uint32_t)&hhash->Instance->DIN, \
1098 ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : \
1099 (hhash->Size)));
1100 }
1101 if (status != HAL_OK)
1102 {
1103 /* DMA error code field */
1104 hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
1105
1106 /* Return error */
1107 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
1108 /*Call registered error callback*/
1109 hhash->ErrorCallback(hhash);
1110 #else
1111 /*Call legacy weak error callback*/
1112 HAL_HASH_ErrorCallback(hhash);
1113 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1114 }
1115 else
1116 {
1117 /* Enable DMA requests */
1118 SET_BIT(hhash->Instance->CR, HASH_CR_DMAE);
1119 }
1120 }
1121 else
1122 {
1123 status = HAL_BUSY;
1124
1125 }
1126
1127 /* Return function status */
1128 return status;
1129 }
1130
1131
1132 /**
1133 * @brief HASH peripheral processes in polling mode several input buffers.
1134 * @note Consecutive calls to HAL_HASH_Accumulate() can be used to feed
1135 * several input buffers back-to-back to the Peripheral that will yield a single
1136 * HASH signature once all buffers have been entered. Wrap-up of input
1137 * buffers feeding and retrieval of digest is done by a call to
1138 * HAL_HASH_AccumulateLast()
1139 * @param hhash HASH handle.
1140 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1141 * @param Size length of the input buffer in bytes and a multiple of 4.
1142 * @param Timeout specify timeout value
1143 * @retval HAL status
1144 */
HAL_HASH_Accumulate(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint32_t Timeout)1145 HAL_StatusTypeDef HAL_HASH_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1146 uint32_t Timeout)
1147 {
1148 HAL_HASH_StateTypeDef temp_state;
1149
1150 /* Check the hash handle allocation and buffer length multiple of 4 */
1151 if ((hhash == NULL) || ((Size % 4U) != 0U))
1152 {
1153 return HAL_ERROR;
1154 }
1155
1156 /* Check if peripheral is ready to start process or suspended */
1157 temp_state = hhash->State;
1158 if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED))
1159 {
1160 /* Process Locked */
1161 __HAL_LOCK(hhash);
1162
1163 /* Change the HASH state */
1164 hhash->State = HAL_HASH_STATE_BUSY;
1165
1166 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1167 hhash->pHashInBuffPtr = pInBuffer;
1168 hhash->HashInCount = 0U;
1169 hhash->Size = Size;
1170
1171 if (hhash->Phase == HAL_HASH_PHASE_READY)
1172 {
1173 /* Set HASH mode */
1174 CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1175 /* Reset the HASH processor core */
1176 MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1177
1178 /* Set the phase */
1179 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1180 }
1181 HASH_WriteData(hhash, pInBuffer, Size);
1182
1183 /* Wait for BUSY flag to be cleared */
1184 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1185 {
1186 return HAL_ERROR;
1187 }
1188 /* Change the HASH state */
1189 hhash->State = HAL_HASH_STATE_READY;
1190
1191 /* Process Unlocked */
1192 __HAL_UNLOCK(hhash);
1193
1194 return HAL_OK;
1195 }
1196 else
1197 {
1198 return HAL_BUSY;
1199 }
1200 }
1201
1202
1203 /**
1204 * @brief End computation of a single HASH signature after several calls to HAL_HASH_Accumulate() API.
1205 * @note Digest is available in pOutBuffer
1206 * @param hhash HASH handle.
1207 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1208 * @param Size length of the input buffer in bytes.
1209 * @param pOutBuffer pointer to the computed digest.
1210 * @param Timeout specify timeout value
1211 * @retval HAL status
1212 */
HAL_HASH_AccumulateLast(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer,uint32_t Timeout)1213 HAL_StatusTypeDef HAL_HASH_AccumulateLast(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1214 uint8_t *const pOutBuffer, uint32_t Timeout)
1215 {
1216 HAL_HASH_StateTypeDef temp_state;
1217
1218 /* Check the hash handle allocation */
1219 if (hhash == NULL)
1220 {
1221 return HAL_ERROR;
1222 }
1223
1224 /* Check if peripheral is ready to start process or suspended */
1225 temp_state = hhash->State;
1226 if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED))
1227 {
1228 /* Process Locked */
1229 __HAL_LOCK(hhash);
1230
1231 /* Change the HASH state */
1232 hhash->State = HAL_HASH_STATE_BUSY;
1233
1234 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1235 hhash->pHashInBuffPtr = pInBuffer;
1236 hhash->pHashOutBuffPtr = pOutBuffer;
1237 hhash->HashInCount = 0U;
1238 hhash->Size = Size;
1239
1240 if (hhash->Phase == HAL_HASH_PHASE_READY)
1241 {
1242 /* Set HASH mode */
1243 CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1244 /* Reset the HASH processor core */
1245 MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1246
1247 /* Set the phase */
1248 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1249 }
1250 /* Configure the number of valid bits in last word of the message */
1251 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
1252
1253
1254 HASH_WriteData(hhash, pInBuffer, Size);
1255
1256 /* Start the message padding then the Digest calculation */
1257 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1258
1259 /* Wait for digest calculation completion status(DCIS) flag to be set */
1260 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
1261 {
1262 return HAL_ERROR;
1263 }
1264 /* Read the message digest */
1265 HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash));
1266
1267 /* Change the HASH state */
1268 hhash->State = HAL_HASH_STATE_READY;
1269
1270 /* Reset HASH state machine */
1271 hhash->Phase = HAL_HASH_PHASE_READY;
1272 hhash->Accumulation = 0;
1273 /* Process Unlocked */
1274 __HAL_UNLOCK(hhash);
1275
1276 return HAL_OK;
1277 }
1278 else
1279 {
1280 return HAL_BUSY;
1281 }
1282 }
1283
1284 /**
1285 * @brief HASH peripheral processes in interrupt mode several input buffers.
1286 * @note Consecutive calls to HAL_HASH_Accumulate_IT() can be used to feed
1287 * several input buffers back-to-back to the Peripheral that will yield a single
1288 * HASH signature once all buffers have been entered. Wrap-up of input
1289 * buffers feeding and retrieval of digest is done by a call to
1290 * HAL_HASH_AccumulateLast_IT()
1291 * @param hhash HASH handle.
1292 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1293 * @param Size length of the input buffer in bytes and a multiple of 4.
1294 * @retval HAL status
1295 */
HAL_HASH_Accumulate_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size)1296 HAL_StatusTypeDef HAL_HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1297 {
1298 HAL_StatusTypeDef status;
1299
1300 /* Check the hash handle allocation */
1301 if ((hhash == NULL) || ((Size % 4U) != 0U))
1302 {
1303 return HAL_ERROR;
1304 }
1305
1306 /* Check if peripheral is ready to start process */
1307 if (hhash->State == HAL_HASH_STATE_READY)
1308 {
1309 /* Process Locked */
1310 __HAL_LOCK(hhash);
1311
1312 /* Change the HASH state */
1313 hhash->State = HAL_HASH_STATE_BUSY;
1314
1315 /* Reset HashInCount and Initialize Size and pHashInBuffPtr parameters */
1316 hhash->pHashInBuffPtr = pInBuffer;
1317 hhash->HashInCount = 0U;
1318 hhash->Size = Size;
1319 /* Set multi buffers accumulation flag */
1320 hhash->Accumulation = 1U;
1321
1322 if (hhash->Phase == HAL_HASH_PHASE_READY)
1323 {
1324 /* Set HASH mode */
1325 CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1326 /* Reset the HASH processor core */
1327 MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1328 /* Set the phase */
1329 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1330 }
1331 /* Enable the specified HASH interrupt*/
1332 __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI);
1333
1334 status = HASH_WriteData_IT(hhash);
1335
1336 /* Change the HASH state */
1337 hhash->State = HAL_HASH_STATE_READY;
1338
1339 /* Process Unlocked */
1340 __HAL_UNLOCK(hhash);
1341 }
1342 else
1343 {
1344 status = HAL_BUSY;
1345 }
1346 /* Return function status */
1347 return status;
1348 }
1349
1350
1351 /**
1352 * @brief End computation of a single HASH signature after several calls to HAL_HASH_Accumulate_IT() API.
1353 * @note Digest is available in pOutBuffer
1354 * @param hhash HASH handle.
1355 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1356 * @param Size length of the input buffer in bytes.
1357 * @param pOutBuffer pointer to the computed digest.
1358 * @retval HAL status
1359 */
HAL_HASH_AccumulateLast_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)1360 HAL_StatusTypeDef HAL_HASH_AccumulateLast_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1361 uint8_t *const pOutBuffer)
1362 {
1363 HAL_StatusTypeDef status;
1364
1365 /* Check the hash handle allocation */
1366 if (hhash == NULL)
1367 {
1368 return HAL_ERROR;
1369 }
1370
1371 /* Check if peripheral is ready to start process */
1372 if (hhash->State == HAL_HASH_STATE_READY)
1373 {
1374 /* Process Locked */
1375 __HAL_LOCK(hhash);
1376
1377 /* Change the HASH state */
1378 hhash->State = HAL_HASH_STATE_BUSY;
1379
1380 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1381 hhash->pHashInBuffPtr = pInBuffer;
1382 hhash->pHashOutBuffPtr = pOutBuffer;
1383 hhash->HashInCount = 0U;
1384 hhash->Size = Size;
1385 if (hhash->Phase == HAL_HASH_PHASE_READY)
1386 {
1387 /* Set HASH mode */
1388 CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE);
1389 /* Reset the HASH processor core */
1390 MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT);
1391
1392 /* Set the phase */
1393 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1394 }
1395 /* Configure the number of valid bits in last word of the message */
1396 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
1397
1398 /* Enable the specified HASH interrupt*/
1399 __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
1400
1401 status = HASH_WriteData_IT(hhash);
1402
1403 /* Change the HASH state */
1404 hhash->State = HAL_HASH_STATE_READY;
1405
1406 /* Reset HASH state machine */
1407 hhash->Phase = HAL_HASH_PHASE_READY;
1408
1409 /* Process Unlocked */
1410 __HAL_UNLOCK(hhash);
1411 }
1412 else
1413 {
1414 status = HAL_BUSY;
1415 }
1416 /* Return function status */
1417 return status;
1418 }
1419
1420 /**
1421 * @}
1422 */
1423
1424
1425 /** @defgroup HASH_Exported_Functions_Group3 HMAC processing functions
1426 * @brief HMAC processing functions using different mode.
1427 *
1428 @verbatim
1429 ===============================================================================
1430 ##### HMAC processing functions #####
1431 ===============================================================================
1432 [..] This section provides API allowing to calculate the HMAC (keyed-hash
1433 message authentication code) value using:
1434 (+) one of the algorithms supported by the peripheral
1435 (+) Key selection
1436 (++) Long key : HMAC key is longer than the block size
1437 (++) Short key : HMAC key is shorter or equal to the block size
1438
1439 [..] To calculate the HMAC for a single buffer, user can resort to one of three processing
1440 functions available .
1441 (+) Polling mode : HAL_HASH_HMAC_Start()
1442 (+) Interrupt mode : HAL_HASH_HMAC_Start_IT()
1443 (+) DMA mode : HAL_HASH_HMAC_Start_DMA()
1444
1445 [..] In case of multi-buffer HMAC processing (a single digest is computed while
1446 several buffers are fed to the Peripheral), the user can resort to successive calls
1447 to :
1448 (+) Polling mode : HAL_HASH_HMAC_Accumulate() and wrap-up the digest computation by a call
1449 to HAL_HASH_HMAC_AccumulateLast()
1450 (+) Interrupt mode : HAL_HASH_HMAC_Accumulate_IT() and wrap-up the digest computation by a call
1451 to HAL_HASH_HMAC_AccumulateLast_IT()
1452 (+) DMA mode : HAL_HASH_HMAC_Start_DMA(),MDMAT bit must be set through __HAL_HASH_SET_MDMAT() macro,
1453 before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT()
1454 macro then wrap-up the HMAC processing in feeding the last input buffer through the
1455 same API HAL_HASH_HMAC_Start_DMA()
1456
1457 @endverbatim
1458 * @{
1459 */
1460
1461 /**
1462 * @brief HMAC in polling mode, HASH peripheral processes Key then pInBuffer then reads the computed digest.
1463 * @param hhash HASH handle.
1464 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1465 * @param Size length of the input buffer in bytes.
1466 * @param pOutBuffer pointer to the computed digest.
1467 * @param Timeout specify timeout value
1468 * @retval HAL status
1469 */
HAL_HASH_HMAC_Start(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer,uint32_t Timeout)1470 HAL_StatusTypeDef HAL_HASH_HMAC_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1471 uint8_t *const pOutBuffer, uint32_t Timeout)
1472 {
1473 uint32_t blocksize; /* Block size in bytes */
1474
1475 /* Check the hash handle allocation */
1476 if (hhash == NULL)
1477 {
1478 return HAL_ERROR;
1479 }
1480
1481 /* Check if peripheral is ready to start process */
1482 if (hhash->State == HAL_HASH_STATE_READY)
1483 {
1484
1485 /* Process Locked */
1486 __HAL_LOCK(hhash);
1487
1488 /* Change the HASH state */
1489 hhash->State = HAL_HASH_STATE_BUSY;
1490
1491 /* Reset HASH Phase */
1492 hhash->Phase = HAL_HASH_PHASE_READY;
1493
1494 /* Reset HashInCount and Initialize Size, pHashKeyBuffPtr, pHashInBuffPtr and pHashOutBuffPtr parameters */
1495 hhash->pHashInBuffPtr = pInBuffer;
1496 hhash->pHashOutBuffPtr = pOutBuffer;
1497 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
1498 hhash->HashInCount = 0U;
1499 hhash->Size = Size;
1500
1501 /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting bits */
1502 if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
1503 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
1504 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
1505 {
1506 blocksize = 64U;
1507 }
1508 else
1509 {
1510 blocksize = 128U;
1511 }
1512 if (hhash->Init.KeySize > blocksize)
1513 {
1514 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1515 HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
1516 }
1517 else
1518 {
1519
1520 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1521 HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1522 }
1523
1524 /* Configure the number of valid bits in last word of the Key */
1525 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1526
1527
1528 /* Set the phase */
1529 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1530 /* Write Key */
1531 HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
1532
1533 /* Start the Key padding then the Digest calculation */
1534 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1535
1536 /* Wait for BUSY flag to be cleared */
1537 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1538 {
1539 return HAL_ERROR;
1540 }
1541
1542 /* Configure the number of valid bits in last word of the message */
1543 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
1544
1545 /* Write message */
1546 HASH_WriteData(hhash, pInBuffer, Size);
1547
1548 /* Start the message padding then the Digest calculation */
1549 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1550
1551 /* Wait for BUSY flag to be cleared */
1552 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1553 {
1554 return HAL_ERROR;
1555 }
1556 /* Configure the number of valid bits in last word of the Key */
1557 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1558
1559 /* Write Key */
1560 HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
1561
1562 /* Start the Key padding then the Digest calculation */
1563 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1564
1565 /* Wait for digest calculation completion status(DCIS) flag to be set */
1566 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
1567 {
1568 return HAL_ERROR;
1569 }
1570
1571 /* Read the message digest */
1572 HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash));
1573
1574 /* Change the HASH state */
1575 hhash->State = HAL_HASH_STATE_READY;
1576
1577 /* Change the HASH phase */
1578 hhash->Phase = HAL_HASH_PHASE_READY;
1579
1580 /* Process Unlocked */
1581 __HAL_UNLOCK(hhash);
1582
1583 /* Return function status */
1584 return HAL_OK;
1585
1586 }
1587 else
1588 {
1589 return HAL_BUSY;
1590 }
1591 }
1592
1593 /**
1594 * @brief HMAC accumulate mode, HASH peripheral processes Key then several input buffers.
1595 * @note Consecutive calls to HAL_HASH_HMAC_Accumulate() can be used to feed
1596 * several input buffers back-to-back to the Peripheral that will yield a single
1597 * HASH signature once all buffers have been entered. Wrap-up of input
1598 * buffers feeding and retrieval of digest is done by a call to
1599 * HAL_HASH_HMAC_AccumulateLast()
1600 * @param hhash HASH handle.
1601 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1602 * @param Size length of the input buffer in bytes and a multiple of 4
1603 * @param Timeout specify timeout value
1604 * @retval HAL status
1605 */
HAL_HASH_HMAC_Accumulate(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint32_t Timeout)1606 HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1607 uint32_t Timeout)
1608 {
1609 uint32_t blocksize; /* Block size in bytes */
1610
1611 /* Check the hash handle allocation and buffer length multiple of 4 */
1612 if ((hhash == NULL) || ((Size % 4U) != 0U))
1613 {
1614 return HAL_ERROR;
1615 }
1616
1617 /* Check if peripheral is ready to start process */
1618 if (hhash->State == HAL_HASH_STATE_READY)
1619 {
1620 /* Process Locked */
1621 __HAL_LOCK(hhash);
1622
1623 /* Change the HASH state */
1624 hhash->State = HAL_HASH_STATE_BUSY;
1625
1626 /* Initialize Size, pHashInBuffPtr and pHashKeyBuffPtr parameters */
1627 hhash->pHashInBuffPtr = pInBuffer;
1628 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
1629 hhash->Size = Size;
1630
1631 if (hhash->Phase == HAL_HASH_PHASE_READY)
1632 {
1633 /* Reset HashInCount parameter */
1634 hhash->HashInCount = 0U;
1635 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
1636 /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */
1637 if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
1638 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
1639 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
1640 {
1641 blocksize = 64U;
1642 }
1643 else
1644 {
1645 blocksize = 128U;
1646 }
1647 if (hhash->Init.KeySize > blocksize)
1648 {
1649 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1650 HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
1651 }
1652 else
1653 {
1654
1655 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1656 HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1657 }
1658 /* Set phase process */
1659 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1660
1661 /* Configure the number of valid bits in last word of the Key */
1662 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1663
1664 /* Write Key */
1665 HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
1666
1667 /* Start the Key padding then the Digest calculation */
1668 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1669
1670 /* Wait for BUSY flag to be cleared */
1671 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1672 {
1673 return HAL_ERROR;
1674 }
1675 }
1676
1677 /* Change the number of valid bits in last word of the message */
1678 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U);
1679
1680 /* Write message */
1681 HASH_WriteData(hhash, pInBuffer, Size);
1682
1683 /* Change the HASH state */
1684 hhash->State = HAL_HASH_STATE_READY;
1685
1686 /* Process Unlocked */
1687 __HAL_UNLOCK(hhash);
1688
1689 /* Return function status */
1690 return HAL_OK;
1691
1692 }
1693 else
1694 {
1695 return HAL_BUSY;
1696 }
1697 }
1698 /**
1699 * @brief End computation of a single HMAC signature after several calls to HAL_HASH_HMAC_Accumulate() API.
1700 * @note Digest is available in pOutBuffer
1701 * @param hhash HASH handle.
1702 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1703 * @param Size length of the input buffer in bytes.
1704 * @param pOutBuffer pointer to the computed digest.
1705 * @param Timeout specify timeout value
1706 * @retval HAL status
1707 */
HAL_HASH_HMAC_AccumulateLast(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer,uint32_t Timeout)1708 HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1709 uint8_t *const pOutBuffer, uint32_t Timeout)
1710 {
1711 /* Check the hash handle allocation */
1712 if (hhash == NULL)
1713 {
1714 return HAL_ERROR;
1715 }
1716
1717 /* Check if peripheral is ready to start process */
1718 if (hhash->State == HAL_HASH_STATE_READY)
1719 {
1720
1721 /* Process Locked */
1722 __HAL_LOCK(hhash);
1723
1724 /* Change the HASH state */
1725 hhash->State = HAL_HASH_STATE_BUSY;
1726
1727 /* Initialize Size, pHashInBuffPtr, pHashKeyBuffPtr and pHashOutBuffPtr parameters */
1728 hhash->pHashInBuffPtr = pInBuffer;
1729 hhash->pHashOutBuffPtr = pOutBuffer;
1730 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
1731 hhash->Size = Size;
1732
1733 if (hhash->Phase != HAL_HASH_PHASE_PROCESS)
1734 {
1735 return HAL_ERROR;
1736 }
1737 else
1738 {
1739 /* Configure the number of valid bits in last word of the message */
1740 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U));
1741
1742 /* Write message */
1743 HASH_WriteData(hhash, pInBuffer, Size);
1744
1745 /* Start the message padding then the Digest calculation */
1746 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1747
1748 /* Wait for BUSY flag to be cleared */
1749 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
1750 {
1751 return HAL_ERROR;
1752 }
1753 /* Configure the number of valid bits in last word of the Key */
1754 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1755
1756 /* Write Key */
1757 HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
1758
1759 /* Start the Key padding then the Digest calculation */
1760 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
1761
1762 /* Wait for digest calculation completion status(DCIS) flag to be set */
1763 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
1764 {
1765 return HAL_ERROR;
1766 }
1767
1768 /* Read the message digest */
1769 HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash));
1770 }
1771
1772 /* Change the HASH state */
1773 hhash->State = HAL_HASH_STATE_READY;
1774
1775 /* Reset HASH state machine */
1776 hhash->Phase = HAL_HASH_PHASE_READY;
1777
1778 /* Process Unlocked */
1779 __HAL_UNLOCK(hhash);
1780
1781 /* Return function status */
1782 return HAL_OK;
1783 }
1784 else
1785 {
1786 return HAL_BUSY;
1787 }
1788 }
1789
1790 /**
1791 * @brief HMAC in interrupt mode, HASH peripheral process Key then pInBuffer then read the computed digest.
1792 * @param hhash HASH handle.
1793 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1794 * @param Size length of the input buffer in bytes.
1795 * @param pOutBuffer pointer to the computed digest.
1796 * @retval HAL status
1797 */
HAL_HASH_HMAC_Start_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)1798 HAL_StatusTypeDef HAL_HASH_HMAC_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1799 uint8_t *const pOutBuffer)
1800 {
1801 HAL_StatusTypeDef status;
1802 uint32_t blocksize; /* Block size in bytes */
1803
1804 /* Check the hash handle allocation */
1805 if (hhash == NULL)
1806 {
1807 return HAL_ERROR;
1808 }
1809
1810 /* Check if peripheral is ready to start process */
1811 if (hhash->State == HAL_HASH_STATE_READY)
1812 {
1813 /* Process Locked */
1814 __HAL_LOCK(hhash);
1815
1816 /* Change the HASH state */
1817 hhash->State = HAL_HASH_STATE_BUSY;
1818
1819 /* Reset HASH Phase */
1820 hhash->Phase = HAL_HASH_PHASE_READY;
1821
1822 /* Reset HashInCount and Initialize Size, pHashKeyBuffPtr, pHashInBuffPtr and pHashOutBuffPtr parameters */
1823 hhash->pHashInBuffPtr = pInBuffer;
1824 hhash->pHashOutBuffPtr = pOutBuffer;
1825 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
1826 hhash->HashInCount = 0U;
1827 hhash->Size = Size;
1828
1829 /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting bits */
1830 if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
1831 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
1832 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
1833 {
1834 blocksize = 64U;
1835 }
1836 else
1837 {
1838 blocksize = 128U;
1839 }
1840 if (hhash->Init.KeySize > blocksize)
1841 {
1842 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1843 HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
1844 }
1845 else
1846 {
1847
1848 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1849 HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1850 }
1851
1852 /* Configure the number of valid bits in last word of the Key */
1853 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1854
1855 /* Set the phase */
1856 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1857 }
1858 else if (hhash->State == HAL_HASH_STATE_SUSPENDED)
1859 {
1860 /* Process Locked */
1861 __HAL_LOCK(hhash);
1862 /* Change the HASH state */
1863 hhash->State = HAL_HASH_STATE_BUSY;
1864 }
1865 else
1866 {
1867 return HAL_BUSY;
1868 }
1869
1870 /* Enable the specified HASH interrupt*/
1871 __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
1872
1873 status = HASH_WriteData_IT(hhash);
1874
1875 /* Return function status */
1876 return status;
1877 }
1878
1879 /**
1880 * @brief HMAC accumulate in interrupt mode, HASH peripheral processes Key then several input buffers.
1881 * @note Consecutive calls to HAL_HASH_HMAC_Accumulate_IT() can be used to feed
1882 * several input buffers back-to-back to the Peripheral that will yield a single
1883 * HASH signature once all buffers have been entered. Wrap-up of input
1884 * buffers feeding and retrieval of digest is done by a call to
1885 * HAL_HASH_HMAC_AccumulateLast_IT()
1886 * @param hhash HASH handle.
1887 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1888 * @param Size length of the input buffer in bytes and a multiple of 4.
1889 * @retval HAL status
1890 */
HAL_HASH_HMAC_Accumulate_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size)1891 HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1892 {
1893 HAL_StatusTypeDef status;
1894 uint32_t blocksize; /* Block size in bytes */
1895
1896 /* Check the hash handle allocation and buffer length multiple of 4 */
1897 if ((hhash == NULL) || ((Size % 4U) != 0U))
1898 {
1899 return HAL_ERROR;
1900 }
1901
1902 /* Check if peripheral is ready to start process */
1903 if (hhash->State == HAL_HASH_STATE_READY)
1904 {
1905 /* Process Locked */
1906 __HAL_LOCK(hhash);
1907
1908 /* Change the HASH state */
1909 hhash->State = HAL_HASH_STATE_BUSY;
1910
1911 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1912 hhash->pHashInBuffPtr = pInBuffer;
1913 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
1914 hhash->HashInCount = 0U;
1915 hhash->Size = Size;
1916 /* Set multi buffers accumulation flag */
1917 hhash->Accumulation = 1U;
1918
1919 if (hhash->Phase == HAL_HASH_PHASE_READY)
1920 {
1921 /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */
1922 if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
1923 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
1924 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
1925 {
1926 blocksize = 64U;
1927 }
1928 else
1929 {
1930 blocksize = 128U;
1931 }
1932 if (hhash->Init.KeySize > blocksize)
1933 {
1934 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1935 HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
1936 }
1937 else
1938 {
1939
1940 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
1941 HASH_ALGOMODE_HMAC | HASH_CR_INIT);
1942 }
1943
1944 /* Configure the number of valid bits in last word of the Key */
1945 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
1946
1947 /* Set the phase */
1948 hhash->Phase = HAL_HASH_PHASE_PROCESS;
1949 }
1950 /* Enable the specified HASH interrupt*/
1951 __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
1952
1953 status = HASH_WriteData_IT(hhash);
1954 }
1955 else
1956 {
1957 status = HAL_BUSY;
1958 }
1959 /* Return function status */
1960 return status;
1961 }
1962 /**
1963 * @brief End computation of a single HMAC signature in interrupt mode, after
1964 * several calls to HAL_HASH_HMAC_Accumulate() API.
1965 * @note Digest is available in pOutBuffer
1966 * @param hhash HASH handle.
1967 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
1968 * @param Size length of the input buffer in bytes.
1969 * @param pOutBuffer pointer to the computed digest.
1970 * @retval HAL status
1971 */
HAL_HASH_HMAC_AccumulateLast_IT(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)1972 HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer,
1973 uint32_t Size, uint8_t *const pOutBuffer)
1974 {
1975 HAL_StatusTypeDef status;
1976
1977 /* Check the hash handle allocation */
1978 if (hhash == NULL)
1979 {
1980 return HAL_ERROR;
1981 }
1982
1983 /* Check if peripheral is ready to start process*/
1984 if (hhash->State == HAL_HASH_STATE_READY)
1985 {
1986 /* Process Locked */
1987 __HAL_LOCK(hhash);
1988
1989 /* Change the HASH state */
1990 hhash->State = HAL_HASH_STATE_BUSY;
1991
1992 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
1993 hhash->pHashInBuffPtr = pInBuffer;
1994 hhash->pHashOutBuffPtr = pOutBuffer;
1995 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
1996 hhash->HashInCount = 0U;
1997 hhash->Size = Size;
1998 /* Set multi buffers accumulation flag */
1999 hhash->Accumulation = 0U;
2000 /* Enable the specified HASH interrupt*/
2001 __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2002
2003 status = HASH_WriteData_IT(hhash);
2004 }
2005 else
2006 {
2007 status = HAL_BUSY;
2008 }
2009 /* Return function status */
2010 return status;
2011 }
2012
2013 /**
2014 * @brief HMAC in DMA mode,HASH peripheral processes Key then pInBuffer in DMA mode
2015 * then read the computed digest.
2016 * @note Multi-buffer HMAC processing is possible, consecutive calls to HAL_HASH_HMAC_Start_DMA
2017 * (MDMAT bit must be set) can be used to feed several input buffers
2018 * back-to-back to the Peripheral that will yield a single
2019 * HASH signature once all buffers have been entered. Wrap-up of input
2020 * buffers feeding and retrieval of digest is done by a call to
2021 * HAL_HASH_HMAC_Start_DMA (MDMAT bit must be reset).
2022 * @param hhash HASH handle.
2023 * @param pInBuffer pointer to the input buffer (buffer to be hashed).
2024 * @param Size length of the input buffer in bytes.
2025 * @param pOutBuffer pointer to the computed digest.
2026 * @retval HAL status
2027 */
HAL_HASH_HMAC_Start_DMA(HASH_HandleTypeDef * hhash,const uint8_t * const pInBuffer,uint32_t Size,uint8_t * const pOutBuffer)2028 HAL_StatusTypeDef HAL_HASH_HMAC_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
2029 uint8_t *const pOutBuffer)
2030 {
2031 HAL_StatusTypeDef status;
2032 uint32_t count;
2033 uint32_t blocksize; /* Block size in bytes */
2034
2035 /* Check the hash handle allocation */
2036 if (hhash == NULL)
2037 {
2038 return HAL_ERROR;
2039 }
2040
2041 /* Check if peripheral is ready to start process*/
2042 if (hhash->State == HAL_HASH_STATE_READY)
2043 {
2044 /* Process Locked */
2045 __HAL_LOCK(hhash);
2046
2047 /* Change the HASH state */
2048 hhash->State = HAL_HASH_STATE_BUSY;
2049
2050 /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */
2051 hhash->pHashInBuffPtr = pInBuffer;
2052 hhash->pHashOutBuffPtr = pOutBuffer;
2053 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
2054 hhash->HashInCount = 0U;
2055 hhash->Size = Size;
2056
2057 /* Set the phase */
2058 if (hhash->Phase == HAL_HASH_PHASE_READY)
2059 {
2060 /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */
2061 if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) ||
2062 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) ||
2063 (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256))
2064 {
2065 blocksize = 64U;
2066 }
2067 else
2068 {
2069 blocksize = 128U;
2070 }
2071 if (hhash->Init.KeySize > blocksize)
2072 {
2073 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
2074 HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT);
2075 }
2076 else
2077 {
2078
2079 MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT,
2080 HASH_ALGOMODE_HMAC | HASH_CR_INIT);
2081 }
2082
2083 /* Set the phase */
2084 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
2085
2086 /* Configure the number of valid bits in last word of the Key */
2087 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
2088
2089 /* Write Key */
2090 HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
2091
2092 /* Start the Key padding then the Digest calculation */
2093 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2094
2095 /* Wait for DCIS flag to be set */
2096 count = HASH_TIMEOUTVALUE;
2097 do
2098 {
2099 count--;
2100 if (count == 0U)
2101 {
2102 /* Change state */
2103 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2104 hhash->State = HAL_HASH_STATE_READY;
2105 __HAL_UNLOCK(hhash);
2106 return HAL_ERROR;
2107 }
2108 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_BUSY));
2109 }
2110
2111 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2;
2112 if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U)
2113 {
2114 /* Configure the number of valid bits in last word of the message */
2115 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Size) % 4U));
2116 }
2117 else
2118 {
2119 /* Configure the number of valid bits in last word of the message */
2120 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U);
2121 }
2122 }
2123 else if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2124 {
2125 /* Process Locked */
2126 __HAL_LOCK(hhash);
2127 /* Change the HASH state */
2128 hhash->State = HAL_HASH_STATE_BUSY;
2129
2130 /*only part not yet hashed to compute */
2131 hhash->Size = hhash->HashInCount;
2132 }
2133
2134 else
2135 {
2136 /* Return busy status */
2137 return HAL_BUSY;
2138 }
2139
2140 /* Set the HASH DMA transfer complete callback */
2141 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
2142 /* Set the DMA error callback */
2143 hhash->hdmain->XferErrorCallback = HASH_DMAError;
2144
2145 if ((hhash->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2146 {
2147 if ((hhash->hdmain->LinkedListQueue != NULL) && (hhash->hdmain->LinkedListQueue->Head != NULL))
2148 {
2149 /* Enable the DMA channel */
2150 hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET]\
2151 = ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : ((hhash->Size)));
2152 hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET]\
2153 = (uint32_t)(hhash->pHashInBuffPtr); /* Set DMA source address */
2154 hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET]\
2155 = (uint32_t)&hhash->Instance->DIN; /* Set DMA destination address */
2156
2157 status = HAL_DMAEx_List_Start_IT(hhash->hdmain);
2158 }
2159 else
2160 {
2161 /* Return error status */
2162 status = HAL_ERROR;
2163 }
2164 }
2165 else
2166 {
2167 status = HAL_DMA_Start_IT(hhash->hdmain, (uint32_t)(hhash->pHashInBuffPtr), (uint32_t)&hhash->Instance->DIN, \
2168 ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : \
2169 ((hhash->Size))));
2170 }
2171 if (status != HAL_OK)
2172 {
2173 /* DMA error code field */
2174 hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
2175
2176 /* Return error */
2177 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
2178 /*Call registered error callback*/
2179 hhash->ErrorCallback(hhash);
2180 #else
2181 /*Call legacy weak error callback*/
2182 HAL_HASH_ErrorCallback(hhash);
2183 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2184 }
2185 else
2186 {
2187 /* Enable DMA requests */
2188 SET_BIT(hhash->Instance->CR, HASH_CR_DMAE);
2189 }
2190
2191 /* Return function status */
2192 return status;
2193 }
2194
2195
2196 /**
2197 * @}
2198 */
2199
2200 /** @defgroup HASH_Exported_Functions_Group4 HASH IRQ handler management
2201 * @brief HASH IRQ handler.
2202 *
2203 @verbatim
2204 ==============================================================================
2205 ##### HASH IRQ handler management #####
2206 ==============================================================================
2207 [..] This section provides HASH IRQ handler and callback functions.
2208 (+) HAL_HASH_IRQHandler HASH interrupt request
2209 (+) HAL_HASH_InCpltCallback input data transfer complete callback
2210 (+) HAL_HASH_DgstCpltCallback digest computation complete callback
2211 (+) HAL_HASH_ErrorCallback HASH error callback
2212 (+) HAL_HASH_GetState return the HASH state
2213 (+) HAL_HASH_GetError return the HASH error code
2214 @endverbatim
2215 * @{
2216 */
2217
2218 /**
2219 * @brief Handle HASH interrupt request.
2220 * @param hhash HASH handle.
2221 * @note HAL_HASH_IRQHandler() handles interrupts in HMAC processing as well.
2222 * @retval None
2223 */
HAL_HASH_IRQHandler(HASH_HandleTypeDef * hhash)2224 void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
2225 {
2226 HAL_StatusTypeDef status;
2227 uint32_t itsource = hhash->Instance->IMR;
2228 uint32_t itflag = hhash->Instance->SR;
2229
2230 /* If digest is ready */
2231 if ((itflag & HASH_FLAG_DCIS) == HASH_FLAG_DCIS)
2232 {
2233 /* Read the digest */
2234 HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash));
2235
2236 /* Disable Interrupts */
2237 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2238 /* Change the HASH state */
2239 hhash->State = HAL_HASH_STATE_READY;
2240 /* Reset HASH state machine */
2241 hhash->Phase = HAL_HASH_PHASE_READY;
2242 /* Process Unlocked */
2243 __HAL_UNLOCK(hhash);
2244 /* Call digest computation complete call back */
2245 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2246 hhash->DgstCpltCallback(hhash);
2247 #else
2248 HAL_HASH_DgstCpltCallback(hhash);
2249 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2250
2251 }
2252 /* If Peripheral ready to accept new data */
2253 if ((itflag & HASH_FLAG_DINIS) == HASH_FLAG_DINIS)
2254 {
2255 if ((itsource & HASH_IT_DINI) == HASH_IT_DINI)
2256 {
2257 status = HASH_WriteData_IT(hhash);
2258 if (status != HAL_OK)
2259 {
2260 /* Call error callback */
2261 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2262 hhash->ErrorCallback(hhash);
2263 #else
2264 HAL_HASH_ErrorCallback(hhash);
2265 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2266 }
2267 }
2268 }
2269 }
2270
2271 /**
2272 * @brief Input data transfer complete call back.
2273 * @note HAL_HASH_InCpltCallback() is called when the complete input message
2274 * has been fed to the Peripheral. This API is invoked only when input data are
2275 * entered under interruption or through DMA.
2276 * @note In case of HASH or HMAC multi-buffer DMA feeding case (MDMAT bit set),
2277 * HAL_HASH_InCpltCallback() is called at the end of each buffer feeding
2278 * to the Peripheral.
2279 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
2280 * the configuration information for HASH module.
2281 * @retval None
2282 */
HAL_HASH_InCpltCallback(HASH_HandleTypeDef * hhash)2283 __weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
2284 {
2285 /* Prevent unused argument(s) compilation warning */
2286 UNUSED(hhash);
2287
2288 /* NOTE : This function should not be modified; when the callback is needed,
2289 HAL_HASH_InCpltCallback() can be implemented in the user file.
2290 */
2291 }
2292
2293 /**
2294 * @brief Digest computation complete call back.
2295 * @note HAL_HASH_DgstCpltCallback() is used under interruption, is not
2296 * relevant with DMA.
2297 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
2298 * the configuration information for HASH module.
2299 * @retval None
2300 */
HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef * hhash)2301 __weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
2302 {
2303 /* Prevent unused argument(s) compilation warning */
2304 UNUSED(hhash);
2305
2306 /* NOTE : This function should not be modified; when the callback is needed,
2307 HAL_HASH_DgstCpltCallback() can be implemented in the user file.
2308 */
2309 }
2310
2311 /**
2312 * @brief HASH error callback.
2313 * @note Code user can resort to hhash->Status (HAL_ERROR, HAL_TIMEOUT,...)
2314 * to retrieve the error type.
2315 * @param hhash pointer to a HASH_HandleTypeDef structure that contains
2316 * the configuration information for HASH module.
2317 * @retval None
2318 */
HAL_HASH_ErrorCallback(HASH_HandleTypeDef * hhash)2319 __weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
2320 {
2321 /* Prevent unused argument(s) compilation warning */
2322 UNUSED(hhash);
2323
2324 /* NOTE : This function should not be modified; when the callback is needed,
2325 HAL_HASH_ErrorCallback() can be implemented in the user file.
2326 */
2327 }
2328
2329 /**
2330 * @brief Return the HASH handle state.
2331 * @note The API yields the current state of the handle (BUSY, READY,...).
2332 * @param hhash HASH handle.
2333 * @retval HAL HASH state
2334 */
HAL_HASH_GetState(HASH_HandleTypeDef * hhash)2335 HAL_HASH_StateTypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
2336 {
2337 return hhash->State;
2338 }
2339
2340 /**
2341 * @brief Return the HASH handle error code.
2342 * @param hhash pointer to a HASH_HandleTypeDef structure.
2343 * @retval HASH Error Code
2344 */
HAL_HASH_GetError(HASH_HandleTypeDef * hhash)2345 uint32_t HAL_HASH_GetError(HASH_HandleTypeDef *hhash)
2346 {
2347 /* Return HASH Error Code */
2348 return hhash->ErrorCode;
2349 }
2350 /**
2351 * @}
2352 */
2353
2354 /**
2355 * @}
2356 */
2357
2358 /* Private functions ---------------------------------------------------------*/
2359 /** @addtogroup HASH_Private_Functions
2360 * @{
2361 */
2362
2363 /**
2364 * @brief DMA HASH Input Data transfer completion callback.
2365 * @param hdma DMA handle.
2366 * @retval None
2367 */
HASH_DMAXferCplt(DMA_HandleTypeDef * hdma)2368 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
2369 {
2370 HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2371 uint32_t count;
2372
2373 if (READ_BIT(hhash->Instance->CR, HASH_CR_MODE) == 0U)
2374 {
2375 if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U)
2376 {
2377 /* Disable the DMA transfer */
2378 CLEAR_BIT(hhash->Instance->CR, HASH_CR_DMAE);
2379
2380
2381 /* Wait for DCIS flag to be set */
2382 count = HASH_TIMEOUTVALUE;
2383 do
2384 {
2385 count--;
2386 if (count == 0U)
2387 {
2388 /* Change state */
2389 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2390 hhash->State = HAL_HASH_STATE_READY;
2391 __HAL_UNLOCK(hhash);
2392 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2393 hhash->ErrorCallback(hhash);
2394 #else
2395 HAL_HASH_ErrorCallback(hhash);
2396 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2397 }
2398 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS));
2399 /* Call Input data transfer complete call back */
2400 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2401 hhash->InCpltCallback(hhash);
2402 #else
2403 HAL_HASH_InCpltCallback(hhash);
2404 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2405
2406 /* Read the message digest */
2407 HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash));
2408
2409 /* Change the HASH state to ready */
2410 hhash->State = HAL_HASH_STATE_READY;
2411
2412 /* Reset HASH state machine */
2413 hhash->Phase = HAL_HASH_PHASE_READY;
2414
2415 /* Process UnLock */
2416 __HAL_UNLOCK(hhash);
2417
2418 /* Call digest complete call back */
2419 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2420 hhash->DgstCpltCallback(hhash);
2421 #else
2422 HAL_HASH_DgstCpltCallback(hhash);
2423 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2424 }
2425 else
2426 {
2427 hhash->State = HAL_HASH_STATE_READY;
2428 __HAL_UNLOCK(hhash);
2429 }
2430 }
2431 else /*HMAC DMA*/
2432 {
2433 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
2434 {
2435 if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U)
2436 {
2437 /* Set the phase */
2438 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3;
2439 /* Configure the number of valid bits in last word of the Key */
2440 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
2441 /* Write Key */
2442 HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize);
2443
2444 /* Start the Key padding then the Digest calculation */
2445 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2446
2447 /* Wait for DCIS flag to be set */
2448 count = HASH_TIMEOUTVALUE;
2449 do
2450 {
2451 count--;
2452 if (count == 0U)
2453 {
2454 /* Disable the DMA transfer */
2455 CLEAR_BIT(hhash->Instance->CR, HASH_CR_DMAE);
2456
2457 /* Change state */
2458 hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
2459 hhash->State = HAL_HASH_STATE_READY;
2460 __HAL_UNLOCK(hhash);
2461 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2462 hhash->ErrorCallback(hhash);
2463 #else
2464 HAL_HASH_ErrorCallback(hhash);
2465 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2466 }
2467 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS));
2468
2469 /* Read the message digest */
2470 HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash));
2471
2472 /* Change the HASH state to ready */
2473 hhash->State = HAL_HASH_STATE_READY;
2474
2475 /* Reset HASH state machine */
2476 hhash->Phase = HAL_HASH_PHASE_READY;
2477
2478 /* Process UnLock */
2479 __HAL_UNLOCK(hhash);
2480
2481 /* Call digest complete call back */
2482 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2483 hhash->DgstCpltCallback(hhash);
2484 #else
2485 HAL_HASH_DgstCpltCallback(hhash);
2486 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2487
2488 }
2489 else
2490 {
2491 hhash->State = HAL_HASH_STATE_READY;
2492 __HAL_UNLOCK(hhash);
2493 hhash->Accumulation = 1;
2494 }
2495 }
2496 }
2497 }
2498
2499 /**
2500 * @brief DMA HASH communication error callback.
2501 * @param hdma DMA handle.
2502 * @retval None
2503 */
HASH_DMAError(DMA_HandleTypeDef * hdma)2504 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
2505 {
2506 HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2507
2508 hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
2509 /* Set HASH state to ready to prevent any blocking issue in user code
2510 present in HAL_HASH_ErrorCallback() */
2511 hhash->State = HAL_HASH_STATE_READY;
2512
2513 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2514 hhash->ErrorCallback(hhash);
2515 #else
2516 HAL_HASH_ErrorCallback(hhash);
2517 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2518 }
2519
2520 /**
2521 * @brief Feed the input buffer to the HASH peripheral in polling.
2522 * @param hhash HASH handle.
2523 * @param pInBuffer pointer to input buffer.
2524 * @param Size the size of input buffer in bytes.
2525 * @retval HAL status
2526 */
HASH_WriteData(HASH_HandleTypeDef * hhash,const uint8_t * pInBuffer,uint32_t Size)2527 static void HASH_WriteData(HASH_HandleTypeDef *hhash, const uint8_t *pInBuffer, uint32_t Size)
2528 {
2529 uint32_t buffercounter;
2530 __IO uint32_t inputaddr = (uint32_t) pInBuffer;
2531
2532
2533 for (buffercounter = 0U; buffercounter < Size ; buffercounter += 4U)
2534 {
2535 /* Write input data 4 bytes at a time */
2536 hhash->Instance->DIN = *(uint32_t *)inputaddr;
2537 inputaddr += 4U;
2538 hhash->HashInCount += 4U;
2539 }
2540 }
2541
2542 /**
2543 * @brief Feed the input buffer to the HASH peripheral in interruption mode.
2544 * @param hhash HASH handle.
2545 * @retval HAL status
2546 */
HASH_WriteData_IT(HASH_HandleTypeDef * hhash)2547 static HAL_StatusTypeDef HASH_WriteData_IT(HASH_HandleTypeDef *hhash)
2548 {
2549 uint32_t buffercounter;
2550 uint32_t count;
2551 __IO uint32_t keyaddr = (uint32_t)(hhash->pHashKeyBuffPtr);
2552 __IO uint32_t inputaddr = (uint32_t)(hhash->pHashInBuffPtr);
2553 uint32_t nbbytePartialHash = (((hhash->Instance->SR) >> 16U) * 4U); /* Nb byte to enter in HASH fifo to trig
2554 a partial HASH computation*/
2555
2556 if (hhash->State == HAL_HASH_STATE_BUSY)
2557 {
2558 if ((hhash->Instance->CR & HASH_CR_MODE) == 0U)
2559 {
2560 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
2561 /* If suspension flag has been raised, suspend processing */
2562 if (hhash->SuspendRequest == HAL_HASH_SUSPEND)
2563 {
2564 /* reset SuspendRequest */
2565 hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
2566 /* Disable Computation Complete Flag and Errors Interrupts */
2567 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2568 /* Change the HASH state */
2569 hhash->State = HAL_HASH_STATE_SUSPENDED;
2570 __HAL_UNLOCK(hhash);
2571 }
2572 else
2573 {
2574 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
2575
2576 if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Size))
2577 {
2578 for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U)
2579 {
2580 /* Write input data 4 bytes at a time */
2581 hhash->Instance->DIN = *(uint32_t *)inputaddr;
2582 inputaddr += 4U;
2583 hhash->HashInCount += 4U;
2584 hhash->pHashInBuffPtr += 4U;
2585 }
2586 /* Wait for HASH_IT_DINI flag to be set */
2587 count = HASH_TIMEOUTVALUE;
2588 do
2589 {
2590 count--;
2591 if (count == 0U)
2592 {
2593 /* Disable Interrupts */
2594 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2595
2596 /* Change state */
2597 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2598 hhash->State = HAL_HASH_STATE_READY;
2599 __HAL_UNLOCK(hhash);
2600 return HAL_ERROR;
2601 }
2602 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS));
2603 }
2604 else
2605 {
2606 while ((hhash->HashInCount) < hhash->Size)
2607 {
2608 /* Write input data 4 bytes at a time */
2609 hhash->Instance->DIN = *(uint32_t *)inputaddr;
2610 inputaddr += 4U;
2611 hhash->HashInCount += 4U;
2612 hhash->pHashInBuffPtr += 4U;
2613 }
2614 /* Call Input transfer complete callback */
2615 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
2616 /*Call registered Input complete callback*/
2617 hhash->InCpltCallback(hhash);
2618 #else
2619 /*Call legacy weak Input complete callback*/
2620 HAL_HASH_InCpltCallback(hhash);
2621 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2622 if (hhash->Accumulation == 0U)
2623 {
2624 if (__HAL_HASH_GET_IT_SOURCE(hhash, HASH_IT_DINI))
2625 {
2626 /* Start the message padding then the Digest calculation */
2627 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2628
2629 /* Wait for HASH_FLAG_DCIS flag to be set */
2630 count = HASH_TIMEOUTVALUE;
2631 do
2632 {
2633 count--;
2634 if (count == 0U)
2635 {
2636 /* Disable Interrupts */
2637 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2638
2639 /* Change state */
2640 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2641 hhash->State = HAL_HASH_STATE_READY;
2642 __HAL_UNLOCK(hhash);
2643 return HAL_ERROR;
2644 }
2645 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS));
2646 }
2647 }
2648 else
2649 {
2650 /* Reset multi buffers accumulation flag */
2651 hhash->Accumulation = 0U;
2652 /* Disable Interrupts */
2653 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI);
2654 }
2655 }
2656 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
2657 }
2658 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
2659 }
2660 else /*HMAC */
2661 {
2662 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2) /* loading input*/
2663 {
2664 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
2665 /* If suspension flag has been raised, suspend processing */
2666 if (hhash->SuspendRequest == HAL_HASH_SUSPEND)
2667 {
2668 /* reset SuspendRequest */
2669 hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
2670 /* Disable Computation Complete Flag and Errors Interrupts */
2671 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2672 /* Change the HASH state */
2673 hhash->State = HAL_HASH_STATE_SUSPENDED;
2674 __HAL_UNLOCK(hhash);
2675 }
2676 else
2677 {
2678 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
2679 if (hhash->Accumulation == 1U)
2680 {
2681 /* Configure the number of valid bits in last word of the message */
2682 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U);
2683 }
2684 else
2685 {
2686 /* Configure the number of valid bits in last word of the message */
2687 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (hhash->Size % 4U));
2688 }
2689 if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Size))
2690 {
2691 for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U)
2692 {
2693 /* Write input data 4 bytes at a time */
2694 hhash->Instance->DIN = *(uint32_t *)inputaddr;
2695 inputaddr += 4U;
2696 hhash->HashInCount += 4U;
2697 hhash->pHashInBuffPtr += 4U;
2698 }
2699 /* Wait for HASH_IT_DINI flag to be set */
2700 count = HASH_TIMEOUTVALUE;
2701 do
2702 {
2703 count--;
2704 if (count == 0U)
2705 {
2706 /* Disable Interrupts */
2707 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2708
2709 /* Change state */
2710 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2711 hhash->State = HAL_HASH_STATE_READY;
2712 __HAL_UNLOCK(hhash);
2713 return HAL_ERROR;
2714 }
2715 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS));
2716 }
2717 else
2718 {
2719 while ((hhash->HashInCount) < hhash->Size)
2720 {
2721 /* Write input data 4 bytes at a time */
2722 hhash->Instance->DIN = *(uint32_t *)inputaddr;
2723 inputaddr += 4U;
2724 hhash->HashInCount += 4U;
2725 hhash->pHashInBuffPtr += 4U;
2726 }
2727 /* Call Input transfer complete callback */
2728 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
2729 /*Call registered Input complete callback*/
2730 hhash->InCpltCallback(hhash);
2731 #else
2732 /*Call legacy weak Input complete callback*/
2733 HAL_HASH_InCpltCallback(hhash);
2734 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2735
2736 if (hhash->Accumulation == 0U)
2737 {
2738 if (__HAL_HASH_GET_IT_SOURCE(hhash, HASH_IT_DINI))
2739 {
2740 /* Start the message padding then the Digest calculation */
2741 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2742
2743 /* Wait for HASH_FLAG_BUSY flag to be set */
2744 count = HASH_TIMEOUTVALUE;
2745 do
2746 {
2747 count--;
2748 if (count == 0U)
2749 {
2750 /* Disable Interrupts */
2751 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2752
2753 /* Change state */
2754 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2755 hhash->State = HAL_HASH_STATE_READY;
2756 __HAL_UNLOCK(hhash);
2757 return HAL_ERROR;
2758 }
2759 } while (HAL_IS_BIT_SET(hhash->Instance->SR, HASH_FLAG_BUSY));
2760
2761 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3;
2762 hhash->HashInCount = 0U;
2763 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
2764 }
2765 }
2766
2767 else
2768 {
2769 /* Disable Interrupts */
2770 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2771 hhash->State = HAL_HASH_STATE_READY;
2772 __HAL_UNLOCK(hhash);
2773 return HAL_OK;
2774 }
2775 }
2776 #if (USE_HAL_HASH_SUSPEND_RESUME == 1U)
2777 }
2778 #endif /* USE_HAL_HASH_SUSPEND_RESUME */
2779 }
2780
2781 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)/* loading Key*/
2782 {
2783
2784 /* Configure the number of valid bits in last word of the Key */
2785 MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U));
2786
2787 if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Init.KeySize))
2788 {
2789 for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U)
2790 {
2791 /* Write input data 4 bytes at a time */
2792 hhash->Instance->DIN = *(uint32_t *)keyaddr;
2793 keyaddr += 4U;
2794 hhash->HashInCount += 4U;
2795 hhash->pHashKeyBuffPtr += 4U;
2796 }
2797 /* Wait for HASH_IT_DINI flag to be set */
2798 count = HASH_TIMEOUTVALUE;
2799 do
2800 {
2801 count--;
2802 if (count == 0U)
2803 {
2804 /* Disable Interrupts */
2805 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2806
2807 /* Change state */
2808 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2809 hhash->State = HAL_HASH_STATE_READY;
2810 __HAL_UNLOCK(hhash);
2811 return HAL_ERROR;
2812 }
2813 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS));
2814 }
2815 else
2816 {
2817 while ((hhash->HashInCount) < (hhash->Init.KeySize))
2818 {
2819 /* Write input data 4 bytes at a time */
2820 hhash->Instance->DIN = *(uint32_t *)keyaddr;
2821 keyaddr += 4U;
2822 hhash->HashInCount += 4U;
2823 }
2824 /* Start the message padding then the Digest calculation */
2825 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2826
2827 /* Wait for HASH_FLAG_DCIS flag to be set */
2828 count = HASH_TIMEOUTVALUE;
2829 do
2830 {
2831 count--;
2832 if (count == 0U)
2833 {
2834 /* Disable Interrupts */
2835 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2836
2837 /* Change state */
2838 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2839 hhash->State = HAL_HASH_STATE_READY;
2840 __HAL_UNLOCK(hhash);
2841 return HAL_ERROR;
2842 }
2843 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS));
2844 }
2845 }
2846 else /*first step , loading key*/
2847 {
2848
2849 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
2850
2851 if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Init.KeySize))
2852 {
2853 for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U)
2854 {
2855 /* Write input data 4 bytes at a time */
2856 hhash->Instance->DIN = *(uint32_t *)keyaddr;
2857 keyaddr += 4U;
2858 hhash->HashInCount += 4U;
2859 hhash->pHashKeyBuffPtr += 4U;
2860 }
2861 /* Wait for HASH_IT_DINI flag to be set */
2862 count = HASH_TIMEOUTVALUE;
2863 do
2864 {
2865 count--;
2866 if (count == 0U)
2867 {
2868 /* Disable Interrupts */
2869 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2870
2871 /* Change state */
2872 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2873 hhash->State = HAL_HASH_STATE_READY;
2874 __HAL_UNLOCK(hhash);
2875 return HAL_ERROR;
2876 }
2877 } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS));
2878 }
2879 else
2880 {
2881 while ((hhash->HashInCount) < (hhash->Init.KeySize))
2882 {
2883 /* Write input data 4 bytes at a time */
2884 hhash->Instance->DIN = *(uint32_t *)keyaddr;
2885 keyaddr += 4U;
2886 hhash->HashInCount += 4U;
2887 hhash->pHashKeyBuffPtr += 4U;
2888 }
2889 /* Start the message padding then the Digest calculation */
2890 SET_BIT(hhash->Instance->STR, HASH_STR_DCAL);
2891
2892 /* Wait for HASH_FLAG_BUSY flag to be set */
2893 count = HASH_TIMEOUTVALUE;
2894 do
2895 {
2896 count--;
2897 if (count == 0U)
2898 {
2899 /* Disable Interrupts */
2900 __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI);
2901
2902 /* Change state */
2903 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
2904 hhash->State = HAL_HASH_STATE_READY;
2905 __HAL_UNLOCK(hhash);
2906 return HAL_ERROR;
2907 }
2908 } while (HAL_IS_BIT_SET(hhash->Instance->SR, HASH_FLAG_BUSY));
2909 /*change Phase to step 2*/
2910 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2;
2911 hhash->HashInCount = 0U;
2912 }
2913 }
2914 }
2915 }
2916 else if ((hhash->State == HAL_HASH_STATE_SUSPENDED))
2917 {
2918 return HAL_OK;
2919 }
2920 else
2921 {
2922 /* Busy error code field */
2923 hhash->ErrorCode |= HAL_HASH_ERROR_BUSY;
2924 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U)
2925 /*Call registered error callback*/
2926 hhash->ErrorCallback(hhash);
2927 #else
2928 /*Call legacy weak error callback*/
2929 HAL_HASH_ErrorCallback(hhash);
2930 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2931 }
2932
2933 return HAL_OK;
2934 }
2935
2936 /**
2937 * @brief Retrieve the message digest.
2938 * @param hhash HASH handle
2939 * @param pMsgDigest pointer to the computed digest.
2940 * @param Size message digest size in bytes.
2941 * @retval None
2942 */
HASH_GetDigest(HASH_HandleTypeDef * hhash,uint8_t * pMsgDigest,uint8_t Size)2943 static void HASH_GetDigest(HASH_HandleTypeDef *hhash, uint8_t *pMsgDigest, uint8_t Size)
2944 {
2945 uint32_t msgdigest = (uint32_t)pMsgDigest;
2946
2947 switch (Size)
2948 {
2949 case 20: /* SHA1 */
2950 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
2951 msgdigest += 4U;
2952 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
2953 msgdigest += 4U;
2954 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
2955 msgdigest += 4U;
2956 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
2957 msgdigest += 4U;
2958 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
2959 break;
2960
2961 case 28: /* SHA224 */
2962 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
2963 msgdigest += 4U;
2964 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
2965 msgdigest += 4U;
2966 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
2967 msgdigest += 4U;
2968 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
2969 msgdigest += 4U;
2970 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
2971 msgdigest += 4U;
2972 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
2973 msgdigest += 4U;
2974 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
2975
2976 break;
2977 case 32: /* SHA256 */
2978 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
2979 msgdigest += 4U;
2980 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
2981 msgdigest += 4U;
2982 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
2983 msgdigest += 4U;
2984 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
2985 msgdigest += 4U;
2986 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
2987 msgdigest += 4U;
2988 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
2989 msgdigest += 4U;
2990 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
2991 msgdigest += 4U;
2992 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
2993 break;
2994 #if defined(HASH_ALGOSELECTION_SHA512)
2995 case 48: /* SHA384 */
2996 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
2997 msgdigest += 4U;
2998 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
2999 msgdigest += 4U;
3000 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
3001 msgdigest += 4U;
3002 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
3003 msgdigest += 4U;
3004 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
3005 msgdigest += 4U;
3006 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
3007 msgdigest += 4U;
3008 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
3009 msgdigest += 4U;
3010 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
3011 msgdigest += 4U;
3012 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[8]);
3013 msgdigest += 4U;
3014 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[9]);
3015 msgdigest += 4U;
3016 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[10]);
3017 msgdigest += 4U;
3018 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[11]);
3019 break;
3020
3021 case 64: /* SHA 512 */
3022 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]);
3023 msgdigest += 4U;
3024 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]);
3025 msgdigest += 4U;
3026 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]);
3027 msgdigest += 4U;
3028 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]);
3029 msgdigest += 4U;
3030 *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]);
3031 msgdigest += 4U;
3032 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
3033 msgdigest += 4U;
3034 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
3035 msgdigest += 4U;
3036 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
3037 msgdigest += 4U;
3038 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[8]);
3039 msgdigest += 4U;
3040 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[9]);
3041 msgdigest += 4U;
3042 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[10]);
3043 msgdigest += 4U;
3044 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[11]);
3045 msgdigest += 4U;
3046 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[12]);
3047 msgdigest += 4U;
3048 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[13]);
3049 msgdigest += 4U;
3050 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[14]);
3051 msgdigest += 4U;
3052 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[15]);
3053
3054 break;
3055 #endif /* defined(HASH_ALGOSELECTION_SHA512)*/
3056 default:
3057 break;
3058 }
3059 }
3060
3061 /**
3062 * @brief Handle HASH processing Timeout.
3063 * @param hhash HASH handle.
3064 * @param Flag specifies the HASH flag to check.
3065 * @param Status the Flag status (SET or RESET).
3066 * @param Timeout Timeout duration.
3067 * @retval HAL status
3068 */
HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef * hhash,uint32_t Flag,FlagStatus Status,uint32_t Timeout)3069 static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status,
3070 uint32_t Timeout)
3071 {
3072 uint32_t tickstart = HAL_GetTick();
3073
3074 /* Wait until flag is set */
3075 if (Status == RESET)
3076 {
3077 while (__HAL_HASH_GET_FLAG(hhash, Flag) == RESET)
3078 {
3079 /* Check for the Timeout */
3080 if (Timeout != HAL_MAX_DELAY)
3081 {
3082 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3083 {
3084 /* Set State to Ready to be able to restart later on */
3085 hhash->State = HAL_HASH_STATE_READY;
3086 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
3087 /* Process Unlocked */
3088 __HAL_UNLOCK(hhash);
3089 return HAL_ERROR;
3090 }
3091 }
3092 }
3093 }
3094 else
3095 {
3096 while (__HAL_HASH_GET_FLAG(hhash, Flag) != RESET)
3097 {
3098 /* Check for the Timeout */
3099 if (Timeout != HAL_MAX_DELAY)
3100 {
3101 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3102 {
3103 /* Set State to Ready to be able to restart later on */
3104 hhash->State = HAL_HASH_STATE_READY;
3105 hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT;
3106 /* Process Unlocked */
3107 __HAL_UNLOCK(hhash);
3108
3109 return HAL_ERROR;
3110 }
3111 }
3112 }
3113 }
3114 return HAL_OK;
3115 }
3116
3117 /**
3118 * @}
3119 */
3120
3121
3122 #endif /* HAL_HASH_MODULE_ENABLED */
3123
3124 #endif /* HASH*/
3125 /**
3126 * @}
3127 */
3128
3129 /**
3130 * @}
3131 */
3132