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