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