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