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