STM32F4xx HAL Driver master
STM32CubeF4 HAL / LL Drivers API Reference
Loading...
Searching...
No Matches
stm32f4xx_hal_hash.c
Go to the documentation of this file.
1
207
208/* Includes ------------------------------------------------------------------*/
209#include "stm32f4xx_hal.h"
210
211
215#if defined (HASH)
216
221
222#ifdef HAL_HASH_MODULE_ENABLED
223
224/* Private typedef -----------------------------------------------------------*/
225/* Private define ------------------------------------------------------------*/
229
233#define HASH_DIGEST_CALCULATION_NOT_STARTED ((uint32_t)0x00000000U)
234#define HASH_DIGEST_CALCULATION_STARTED ((uint32_t)0x00000001U)
238
242#define HASH_NUMBER_OF_CSR_REGISTERS 54U
246
250#define HASH_TIMEOUTVALUE 1000U
254
258#define HASH_DMA_SUSPENSION_WORDS_LIMIT 20U
262
266
267/* Private macro -------------------------------------------------------------*/
268/* Private variables ---------------------------------------------------------*/
269/* Private function prototypes -----------------------------------------------*/
273static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
274static void HASH_DMAError(DMA_HandleTypeDef *hdma);
275static void HASH_GetDigest(const uint8_t *pMsgDigest, uint8_t Size);
276static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status,
277 uint32_t Timeout);
278static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size);
279static HAL_StatusTypeDef HASH_IT(HASH_HandleTypeDef *hhash);
280static uint32_t HASH_Write_Block_Data(HASH_HandleTypeDef *hhash);
281static HAL_StatusTypeDef HMAC_Processing(HASH_HandleTypeDef *hhash, uint32_t Timeout);
285
289
315
328HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
329{
330 /* Check the hash handle allocation */
331 if (hhash == NULL)
332 {
333 return HAL_ERROR;
334 }
335
336 /* Check the parameters */
337 assert_param(IS_HASH_DATATYPE(hhash->Init.DataType));
338
339#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
340 if (hhash->State == HAL_HASH_STATE_RESET)
341 {
342 /* Allocate lock resource and initialize it */
343 hhash->Lock = HAL_UNLOCKED;
344
345 /* Reset Callback pointers in HAL_HASH_STATE_RESET only */
346 hhash->InCpltCallback = HAL_HASH_InCpltCallback; /* Legacy weak (surcharged) input completion callback */
347 hhash->DgstCpltCallback = HAL_HASH_DgstCpltCallback; /* Legacy weak (surcharged) digest computation
348 completion callback */
349 hhash->ErrorCallback = HAL_HASH_ErrorCallback; /* Legacy weak (surcharged) error callback */
350 if (hhash->MspInitCallback == NULL)
351 {
352 hhash->MspInitCallback = HAL_HASH_MspInit;
353 }
354
355 /* Init the low level hardware */
356 hhash->MspInitCallback(hhash);
357 }
358#else
359 if (hhash->State == HAL_HASH_STATE_RESET)
360 {
361 /* Allocate lock resource and initialize it */
362 hhash->Lock = HAL_UNLOCKED;
363
364 /* Init the low level hardware */
365 HAL_HASH_MspInit(hhash);
366 }
367#endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */
368
369 /* Change the HASH state */
370 hhash->State = HAL_HASH_STATE_BUSY;
371
372 /* Reset HashInCount, HashITCounter, HashBuffSize and NbWordsAlreadyPushed */
373 hhash->HashInCount = 0;
374 hhash->HashBuffSize = 0;
375 hhash->HashITCounter = 0;
376 hhash->NbWordsAlreadyPushed = 0;
377 /* Reset digest calculation bridle (MDMAT bit control) */
378 hhash->DigestCalculationDisable = RESET;
379 /* Set phase to READY */
380 hhash->Phase = HAL_HASH_PHASE_READY;
381 /* Reset suspension request flag */
382 hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
383
384 /* Set the data type bit */
385 MODIFY_REG(HASH->CR, HASH_CR_DATATYPE, hhash->Init.DataType);
386#if defined(HASH_CR_MDMAT)
387 /* Reset MDMAT bit */
388 __HAL_HASH_RESET_MDMAT();
389#endif /* HASH_CR_MDMAT */
390 /* Reset HASH handle status */
391 hhash->Status = HAL_OK;
392
393 /* Set the HASH state to Ready */
394 hhash->State = HAL_HASH_STATE_READY;
395
396 /* Initialise the error code */
397 hhash->ErrorCode = HAL_HASH_ERROR_NONE;
398
399 /* Return function status */
400 return HAL_OK;
401}
402
408HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
409{
410 /* Check the HASH handle allocation */
411 if (hhash == NULL)
412 {
413 return HAL_ERROR;
414 }
415
416 /* Change the HASH state */
417 hhash->State = HAL_HASH_STATE_BUSY;
418
419 /* Set the default HASH phase */
420 hhash->Phase = HAL_HASH_PHASE_READY;
421
422 /* Reset HashInCount, HashITCounter and HashBuffSize */
423 hhash->HashInCount = 0;
424 hhash->HashBuffSize = 0;
425 hhash->HashITCounter = 0;
426 /* Reset digest calculation bridle (MDMAT bit control) */
427 hhash->DigestCalculationDisable = RESET;
428
429#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
430 if (hhash->MspDeInitCallback == NULL)
431 {
432 hhash->MspDeInitCallback = HAL_HASH_MspDeInit;
433 }
434
435 /* DeInit the low level hardware */
436 hhash->MspDeInitCallback(hhash);
437#else
438 /* DeInit the low level hardware: CLOCK, NVIC */
439 HAL_HASH_MspDeInit(hhash);
440#endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */
441
442
443 /* Reset HASH handle status */
444 hhash->Status = HAL_OK;
445
446 /* Set the HASH state to Ready */
447 hhash->State = HAL_HASH_STATE_RESET;
448
449 /* Initialise the error code */
450 hhash->ErrorCode = HAL_HASH_ERROR_NONE;
451
452 /* Reset multi buffers accumulation flag */
453 hhash->Accumulation = 0U;
454
455 /* Return function status */
456 return HAL_OK;
457}
458
464__weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
465{
466 /* Prevent unused argument(s) compilation warning */
467 UNUSED(hhash);
468
469 /* NOTE : This function should not be modified; when the callback is needed,
470 HAL_HASH_MspInit() can be implemented in the user file.
471 */
472}
473
479__weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
480{
481 /* Prevent unused argument(s) compilation warning */
482 UNUSED(hhash);
483
484 /* NOTE : This function should not be modified; when the callback is needed,
485 HAL_HASH_MspDeInit() can be implemented in the user file.
486 */
487}
488
500__weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
501{
502 /* Prevent unused argument(s) compilation warning */
503 UNUSED(hhash);
504
505 /* NOTE : This function should not be modified; when the callback is needed,
506 HAL_HASH_InCpltCallback() can be implemented in the user file.
507 */
508}
509
517__weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
518{
519 /* Prevent unused argument(s) compilation warning */
520 UNUSED(hhash);
521
522 /* NOTE : This function should not be modified; when the callback is needed,
523 HAL_HASH_DgstCpltCallback() can be implemented in the user file.
524 */
525}
526
534__weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
535{
536 /* Prevent unused argument(s) compilation warning */
537 UNUSED(hhash);
538
539 /* NOTE : This function should not be modified; when the callback is needed,
540 HAL_HASH_ErrorCallback() can be implemented in the user file.
541 */
542}
543
544#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
559HAL_StatusTypeDef HAL_HASH_RegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID,
560 pHASH_CallbackTypeDef pCallback)
561{
562 HAL_StatusTypeDef status = HAL_OK;
563
564 if (pCallback == NULL)
565 {
566 /* Update the error code */
567 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
568 return HAL_ERROR;
569 }
570 /* Process locked */
571 __HAL_LOCK(hhash);
572
573 if (HAL_HASH_STATE_READY == hhash->State)
574 {
575 switch (CallbackID)
576 {
577 case HAL_HASH_INPUTCPLT_CB_ID :
578 hhash->InCpltCallback = pCallback;
579 break;
580
581 case HAL_HASH_DGSTCPLT_CB_ID :
582 hhash->DgstCpltCallback = pCallback;
583 break;
584
585 case HAL_HASH_ERROR_CB_ID :
586 hhash->ErrorCallback = pCallback;
587 break;
588
589 case HAL_HASH_MSPINIT_CB_ID :
590 hhash->MspInitCallback = pCallback;
591 break;
592
593 case HAL_HASH_MSPDEINIT_CB_ID :
594 hhash->MspDeInitCallback = pCallback;
595 break;
596
597 default :
598 /* Update the error code */
599 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
600 /* update return status */
601 status = HAL_ERROR;
602 break;
603 }
604 }
605 else if (HAL_HASH_STATE_RESET == hhash->State)
606 {
607 switch (CallbackID)
608 {
609 case HAL_HASH_MSPINIT_CB_ID :
610 hhash->MspInitCallback = pCallback;
611 break;
612
613 case HAL_HASH_MSPDEINIT_CB_ID :
614 hhash->MspDeInitCallback = pCallback;
615 break;
616
617 default :
618 /* Update the error code */
619 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
620 /* update return status */
621 status = HAL_ERROR;
622 break;
623 }
624 }
625 else
626 {
627 /* Update the error code */
628 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
629 /* update return status */
630 status = HAL_ERROR;
631 }
632
633 /* Release Lock */
634 __HAL_UNLOCK(hhash);
635 return status;
636}
637
651HAL_StatusTypeDef HAL_HASH_UnRegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID)
652{
653 HAL_StatusTypeDef status = HAL_OK;
654
655 /* Process locked */
656 __HAL_LOCK(hhash);
657
658 if (HAL_HASH_STATE_READY == hhash->State)
659 {
660 switch (CallbackID)
661 {
662 case HAL_HASH_INPUTCPLT_CB_ID :
663 hhash->InCpltCallback = HAL_HASH_InCpltCallback; /* Legacy weak (surcharged) input completion callback */
664 break;
665
666 case HAL_HASH_DGSTCPLT_CB_ID :
667 hhash->DgstCpltCallback = HAL_HASH_DgstCpltCallback; /* Legacy weak (surcharged) digest computation
668 completion callback */
669 break;
670
671 case HAL_HASH_ERROR_CB_ID :
672 hhash->ErrorCallback = HAL_HASH_ErrorCallback; /* Legacy weak (surcharged) error callback */
673 break;
674
675 case HAL_HASH_MSPINIT_CB_ID :
676 hhash->MspInitCallback = HAL_HASH_MspInit; /* Legacy weak (surcharged) Msp Init */
677 break;
678
679 case HAL_HASH_MSPDEINIT_CB_ID :
680 hhash->MspDeInitCallback = HAL_HASH_MspDeInit; /* Legacy weak (surcharged) Msp DeInit */
681 break;
682
683 default :
684 /* Update the error code */
685 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
686 /* update return status */
687 status = HAL_ERROR;
688 break;
689 }
690 }
691 else if (HAL_HASH_STATE_RESET == hhash->State)
692 {
693 switch (CallbackID)
694 {
695 case HAL_HASH_MSPINIT_CB_ID :
696 hhash->MspInitCallback = HAL_HASH_MspInit; /* Legacy weak (surcharged) Msp Init */
697 break;
698
699 case HAL_HASH_MSPDEINIT_CB_ID :
700 hhash->MspDeInitCallback = HAL_HASH_MspDeInit; /* Legacy weak (surcharged) Msp DeInit */
701 break;
702
703 default :
704 /* Update the error code */
705 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
706 /* update return status */
707 status = HAL_ERROR;
708 break;
709 }
710 }
711 else
712 {
713 /* Update the error code */
714 hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK;
715 /* update return status */
716 status = HAL_ERROR;
717 }
718
719 /* Release Lock */
720 __HAL_UNLOCK(hhash);
721 return status;
722}
723#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
724
728
757
769HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
770 uint8_t *pOutBuffer,
771 uint32_t Timeout)
772{
773 return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_MD5);
774}
775
796HAL_StatusTypeDef HAL_HASH_MD5_Accmlt(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
797{
798 return HASH_Accumulate(hhash, pInBuffer, Size, HASH_ALGOSELECTION_MD5);
799}
800
811HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_End(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
812 uint8_t *pOutBuffer, uint32_t Timeout)
813{
814 return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_MD5);
815}
816
828HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
829 uint8_t *pOutBuffer,
830 uint32_t Timeout)
831{
832 return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA1);
833}
834
855HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
856{
857 return HASH_Accumulate(hhash, pInBuffer, Size, HASH_ALGOSELECTION_SHA1);
858}
859
870HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_End(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
871 uint8_t *pOutBuffer, uint32_t Timeout)
872{
873 return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA1);
874}
875
879
907
918HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
919 uint8_t *pOutBuffer)
920{
921 return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_MD5);
922}
923
942HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
943{
944 return HASH_Accumulate_IT(hhash, pInBuffer, Size, HASH_ALGOSELECTION_MD5);
945}
946
956HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_End_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
957 uint8_t *pOutBuffer)
958{
959 return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_MD5);
960}
961
972HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
973 uint8_t *pOutBuffer)
974{
975 return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_SHA1);
976}
977
978
997HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
998{
999 return HASH_Accumulate_IT(hhash, pInBuffer, Size, HASH_ALGOSELECTION_SHA1);
1000}
1001
1011HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_End_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1012 uint8_t *pOutBuffer)
1013{
1014 return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_SHA1);
1015}
1016
1026void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
1027{
1028 hhash->Status = HASH_IT(hhash);
1029 if (hhash->Status != HAL_OK)
1030 {
1031 hhash->ErrorCode |= HAL_HASH_ERROR_IT;
1032#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1033 hhash->ErrorCallback(hhash);
1034#else
1035 HAL_HASH_ErrorCallback(hhash);
1036#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1037 /* After error handling by code user, reset HASH handle HAL status */
1038 hhash->Status = HAL_OK;
1039 }
1040}
1041
1045
1073
1084HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1085{
1086 return HASH_Start_DMA(hhash, pInBuffer, Size, HASH_ALGOSELECTION_MD5);
1087}
1088
1099HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
1100{
1101 return HASH_Finish(hhash, pOutBuffer, Timeout);
1102}
1103
1114HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1115{
1116 return HASH_Start_DMA(hhash, pInBuffer, Size, HASH_ALGOSELECTION_SHA1);
1117}
1118
1119
1130HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
1131{
1132 return HASH_Finish(hhash, pOutBuffer, Timeout);
1133}
1134
1138
1157
1171HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1172 uint8_t *pOutBuffer,
1173 uint32_t Timeout)
1174{
1175 return HMAC_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_MD5);
1176}
1177
1191HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1192 uint8_t *pOutBuffer,
1193 uint32_t Timeout)
1194{
1195 return HMAC_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA1);
1196}
1197
1201
1202
1220
1221
1234HAL_StatusTypeDef HAL_HMAC_MD5_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1235 uint8_t *pOutBuffer)
1236{
1237 return HMAC_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_MD5);
1238}
1239
1252HAL_StatusTypeDef HAL_HMAC_SHA1_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
1253 uint8_t *pOutBuffer)
1254{
1255 return HMAC_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_SHA1);
1256}
1257
1261
1262
1284
1285
1305HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1306{
1307 return HMAC_Start_DMA(hhash, pInBuffer, Size, HASH_ALGOSELECTION_MD5);
1308}
1309
1310
1330HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1331{
1332 return HMAC_Start_DMA(hhash, pInBuffer, Size, HASH_ALGOSELECTION_SHA1);
1333}
1334
1338
1370
1377HAL_HASH_StateTypeDef HAL_HASH_GetState(const HASH_HandleTypeDef *hhash)
1378{
1379 return hhash->State;
1380}
1381
1382
1390HAL_StatusTypeDef HAL_HASH_GetStatus(const HASH_HandleTypeDef *hhash)
1391{
1392 return hhash->Status;
1393}
1394
1408void HAL_HASH_ContextSaving(const HASH_HandleTypeDef *hhash, const uint8_t *pMemBuffer)
1409{
1410 uint32_t mem_ptr = (uint32_t)pMemBuffer;
1411 uint32_t csr_ptr = (uint32_t)HASH->CSR;
1412 uint32_t i;
1413
1414 /* Prevent unused argument(s) compilation warning */
1415 UNUSED(hhash);
1416
1417 /* Save IMR register content */
1418 *(uint32_t *)(mem_ptr) = READ_BIT(HASH->IMR, HASH_IT_DINI | HASH_IT_DCI);
1419 mem_ptr += 4U;
1420 /* Save STR register content */
1421 *(uint32_t *)(mem_ptr) = READ_BIT(HASH->STR, HASH_STR_NBLW);
1422 mem_ptr += 4U;
1423 /* Save CR register content */
1424#if defined(HASH_CR_MDMAT)
1425 *(uint32_t *)(mem_ptr) = READ_BIT(HASH->CR, HASH_CR_DMAE | HASH_CR_DATATYPE | HASH_CR_MODE | HASH_CR_ALGO |
1426 HASH_CR_LKEY | HASH_CR_MDMAT);
1427#else
1428 *(uint32_t *)(mem_ptr) = READ_BIT(HASH->CR, HASH_CR_DMAE | HASH_CR_DATATYPE | HASH_CR_MODE | HASH_CR_ALGO |
1429 HASH_CR_LKEY);
1430#endif /* HASH_CR_MDMAT*/
1431 mem_ptr += 4U;
1432 /* By default, save all CSRs registers */
1433 for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--)
1434 {
1435 *(uint32_t *)(mem_ptr) = *(uint32_t *)(csr_ptr);
1436 mem_ptr += 4U;
1437 csr_ptr += 4U;
1438 }
1439}
1440
1441
1454void HAL_HASH_ContextRestoring(HASH_HandleTypeDef *hhash, const uint8_t *pMemBuffer)
1455{
1456 uint32_t mem_ptr = (uint32_t)pMemBuffer;
1457 uint32_t csr_ptr = (uint32_t)HASH->CSR;
1458 uint32_t i;
1459
1460 /* Prevent unused argument(s) compilation warning */
1461 UNUSED(hhash);
1462
1463 /* Restore IMR register content */
1464 WRITE_REG(HASH->IMR, (*(uint32_t *)(mem_ptr)));
1465 mem_ptr += 4U;
1466 /* Restore STR register content */
1467 WRITE_REG(HASH->STR, (*(uint32_t *)(mem_ptr)));
1468 mem_ptr += 4U;
1469 /* Restore CR register content */
1470 WRITE_REG(HASH->CR, (*(uint32_t *)(mem_ptr)));
1471 mem_ptr += 4U;
1472
1473 /* Reset the HASH processor before restoring the Context
1474 Swap Registers (CSR) */
1475 __HAL_HASH_INIT();
1476
1477 /* By default, restore all CSR registers */
1478 for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--)
1479 {
1480 WRITE_REG((*(uint32_t *)(csr_ptr)), (*(uint32_t *)(mem_ptr)));
1481 mem_ptr += 4U;
1482 csr_ptr += 4U;
1483 }
1484}
1485
1486
1497void HAL_HASH_SwFeed_ProcessSuspend(HASH_HandleTypeDef *hhash)
1498{
1499 /* Set Handle Suspend Request field */
1500 hhash->SuspendRequest = HAL_HASH_SUSPEND;
1501}
1502
1512HAL_StatusTypeDef HAL_HASH_DMAFeed_ProcessSuspend(HASH_HandleTypeDef *hhash)
1513{
1514 uint32_t tmp_remaining_DMATransferSize_inWords;
1515 uint32_t tmp_initial_DMATransferSize_inWords;
1516 uint32_t tmp_words_already_pushed;
1517
1518 if (hhash->State == HAL_HASH_STATE_READY)
1519 {
1520 return HAL_ERROR;
1521 }
1522 else
1523 {
1524
1525 /* Make sure there is enough time to suspend the processing */
1526 tmp_remaining_DMATransferSize_inWords = ((DMA_Stream_TypeDef *)hhash->hdmain->Instance)->NDTR;
1527
1528 if (tmp_remaining_DMATransferSize_inWords <= HASH_DMA_SUSPENSION_WORDS_LIMIT)
1529 {
1530 /* No suspension attempted since almost to the end of the transferred data. */
1531 /* Best option for user code is to wrap up low priority message hashing */
1532 return HAL_ERROR;
1533 }
1534
1535 /* Wait for BUSY flag to be reset */
1536 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
1537 {
1538 return HAL_TIMEOUT;
1539 }
1540
1541 if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS) != RESET)
1542 {
1543 return HAL_ERROR;
1544 }
1545
1546 /* Wait for BUSY flag to be set */
1547 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, RESET, HASH_TIMEOUTVALUE) != HAL_OK)
1548 {
1549 return HAL_TIMEOUT;
1550 }
1551 /* Disable DMA channel */
1552 /* Note that the Abort function will
1553 - Clear the transfer error flags
1554 - Unlock
1555 - Set the State
1556 */
1557 if (HAL_DMA_Abort(hhash->hdmain) != HAL_OK)
1558 {
1559 return HAL_ERROR;
1560 }
1561
1562 /* Clear DMAE bit */
1563 CLEAR_BIT(HASH->CR, HASH_CR_DMAE);
1564
1565 /* Wait for BUSY flag to be reset */
1566 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
1567 {
1568 return HAL_TIMEOUT;
1569 }
1570
1571 if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS) != RESET)
1572 {
1573 return HAL_ERROR;
1574 }
1575
1576 /* At this point, DMA interface is disabled and no transfer is on-going */
1577 /* Retrieve from the DMA handle how many words remain to be written */
1578 tmp_remaining_DMATransferSize_inWords = ((DMA_Stream_TypeDef *)hhash->hdmain->Instance)->NDTR;
1579
1580 if (tmp_remaining_DMATransferSize_inWords == 0U)
1581 {
1582 /* All the DMA transfer is actually done. Suspension occurred at the very end
1583 of the transfer. Either the digest computation is about to start (HASH case)
1584 or processing is about to move from one step to another (HMAC case).
1585 In both cases, the processing can't be suspended at this point. It is
1586 safer to
1587 - retrieve the low priority block digest before starting the high
1588 priority block processing (HASH case)
1589 - re-attempt a new suspension (HMAC case)
1590 */
1591 return HAL_ERROR;
1592 }
1593 else
1594 {
1595
1596 /* Compute how many words were supposed to be transferred by DMA */
1597 tmp_initial_DMATransferSize_inWords = (((hhash->HashInCount % 4U) != 0U) ? \
1598 ((hhash->HashInCount + 3U) / 4U) : (hhash->HashInCount / 4U));
1599
1600 /* If discrepancy between the number of words reported by DMA Peripheral and
1601 the numbers of words entered as reported by HASH Peripheral, correct it */
1602 /* tmp_words_already_pushed reflects the number of words that were already pushed before
1603 the start of DMA transfer (multi-buffer processing case) */
1604 tmp_words_already_pushed = hhash->NbWordsAlreadyPushed;
1605 if (((tmp_words_already_pushed + tmp_initial_DMATransferSize_inWords - \
1606 tmp_remaining_DMATransferSize_inWords) % 16U) != HASH_NBW_PUSHED())
1607 {
1608 tmp_remaining_DMATransferSize_inWords--; /* one less word to be transferred again */
1609 }
1610
1611 /* Accordingly, update the input pointer that points at the next word to be
1612 transferred to the Peripheral by DMA */
1613 hhash->pHashInBuffPtr += 4U * (tmp_initial_DMATransferSize_inWords - tmp_remaining_DMATransferSize_inWords) ;
1614
1615 /* And store in HashInCount the remaining size to transfer (in bytes) */
1616 hhash->HashInCount = 4U * tmp_remaining_DMATransferSize_inWords;
1617
1618 }
1619
1620 /* Set State as suspended */
1621 hhash->State = HAL_HASH_STATE_SUSPENDED;
1622
1623 return HAL_OK;
1624
1625 }
1626}
1627
1633uint32_t HAL_HASH_GetError(const HASH_HandleTypeDef *hhash)
1634{
1635 /* Return HASH Error Code */
1636 return hhash->ErrorCode;
1637}
1641
1642
1646
1650
1658static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
1659{
1660 HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1661 uint32_t inputaddr;
1662 uint32_t buffersize;
1663 HAL_StatusTypeDef status;
1664
1665 if (hhash->State != HAL_HASH_STATE_SUSPENDED)
1666 {
1667
1668 /* Disable the DMA transfer */
1669 CLEAR_BIT(HASH->CR, HASH_CR_DMAE);
1670
1671 if (READ_BIT(HASH->CR, HASH_CR_MODE) == 0U)
1672 {
1673 /* If no HMAC processing, input data transfer is now over */
1674
1675 /* Change the HASH state to ready */
1676 hhash->State = HAL_HASH_STATE_READY;
1677
1678 /* Call Input data transfer complete call back */
1679#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1680 hhash->InCpltCallback(hhash);
1681#else
1682 HAL_HASH_InCpltCallback(hhash);
1683#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1684
1685 }
1686 else
1687 {
1688 /* HMAC processing: depending on the current HMAC step and whether or
1689 not multi-buffer processing is on-going, the next step is initiated
1690 and MDMAT bit is set. */
1691
1692
1693 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)
1694 {
1695 /* This is the end of HMAC processing */
1696
1697 /* Change the HASH state to ready */
1698 hhash->State = HAL_HASH_STATE_READY;
1699
1700 /* Call Input data transfer complete call back
1701 (note that the last DMA transfer was that of the key
1702 for the outer HASH operation). */
1703#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1704 hhash->InCpltCallback(hhash);
1705#else
1706 HAL_HASH_InCpltCallback(hhash);
1707#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1708
1709 return;
1710 }
1711 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
1712 {
1713 inputaddr = (uint32_t)hhash->pHashMsgBuffPtr; /* DMA transfer start address */
1714 buffersize = hhash->HashBuffSize; /* DMA transfer size (in bytes) */
1715 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; /* Move phase from Step 1 to Step 2 */
1716
1717 /* In case of suspension request, save the new starting parameters */
1718 hhash->HashInCount = hhash->HashBuffSize; /* Initial DMA transfer size (in bytes) */
1719 hhash->pHashInBuffPtr = hhash->pHashMsgBuffPtr ; /* DMA transfer start address */
1720
1721 hhash->NbWordsAlreadyPushed = 0U; /* Reset number of words already pushed */
1722#if defined(HASH_CR_MDMAT)
1723 /* Check whether or not digest calculation must be disabled (in case of multi-buffer HMAC processing) */
1724 if (hhash->DigestCalculationDisable != RESET)
1725 {
1726 /* Digest calculation is disabled: Step 2 must start with MDMAT bit set,
1727 no digest calculation will be triggered at the end of the input buffer feeding to the Peripheral */
1728 __HAL_HASH_SET_MDMAT();
1729 }
1730#endif /* HASH_CR_MDMAT*/
1731 }
1732 else /*case (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)*/
1733 {
1734 if (hhash->DigestCalculationDisable != RESET)
1735 {
1736 /* No automatic move to Step 3 as a new message buffer will be fed to the Peripheral
1737 (case of multi-buffer HMAC processing):
1738 DCAL must not be set.
1739 Phase remains in Step 2, MDMAT remains set at this point.
1740 Change the HASH state to ready and call Input data transfer complete call back. */
1741 hhash->State = HAL_HASH_STATE_READY;
1742#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1743 hhash->InCpltCallback(hhash);
1744#else
1745 HAL_HASH_InCpltCallback(hhash);
1746#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1747 return ;
1748 }
1749 else
1750 {
1751 /* Digest calculation is not disabled (case of single buffer input or last buffer
1752 of multi-buffer HMAC processing) */
1753 inputaddr = (uint32_t)hhash->Init.pKey; /* DMA transfer start address */
1754 buffersize = hhash->Init.KeySize; /* DMA transfer size (in bytes) */
1755 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; /* Move phase from Step 2 to Step 3 */
1756 /* In case of suspension request, save the new starting parameters */
1757 hhash->HashInCount = hhash->Init.KeySize; /* Initial size for second DMA transfer (input data) */
1758 hhash->pHashInBuffPtr = hhash->Init.pKey ; /* address passed to DMA, now entering data message */
1759
1760 hhash->NbWordsAlreadyPushed = 0U; /* Reset number of words already pushed */
1761 }
1762 }
1763
1764 /* Configure the Number of valid bits in last word of the message */
1765 __HAL_HASH_SET_NBVALIDBITS(buffersize);
1766
1767 /* Set the HASH DMA transfer completion call back */
1768 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1769
1770 /* Enable the DMA In DMA stream */
1771 status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, \
1772 (((buffersize % 4U) != 0U) ? ((buffersize + (4U - (buffersize % 4U))) / 4U) : \
1773 (buffersize / 4U)));
1774
1775 /* Enable DMA requests */
1776 SET_BIT(HASH->CR, HASH_CR_DMAE);
1777
1778 /* Return function status */
1779 if (status != HAL_OK)
1780 {
1781 /* Update HASH state machine to error */
1782 hhash->State = HAL_HASH_STATE_ERROR;
1783 }
1784 else
1785 {
1786 /* Change HASH state */
1787 hhash->State = HAL_HASH_STATE_BUSY;
1788 }
1789 }
1790 }
1791
1792 return;
1793}
1794
1802static void HASH_DMAError(DMA_HandleTypeDef *hdma)
1803{
1804 HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1805
1806 if (hhash->State != HAL_HASH_STATE_SUSPENDED)
1807 {
1808 hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
1809 /* Set HASH state to ready to prevent any blocking issue in user code
1810 present in HAL_HASH_ErrorCallback() */
1811 hhash->State = HAL_HASH_STATE_READY;
1812 /* Set HASH handle status to error */
1813 hhash->Status = HAL_ERROR;
1814#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1815 hhash->ErrorCallback(hhash);
1816#else
1817 HAL_HASH_ErrorCallback(hhash);
1818#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1819 /* After error handling by code user, reset HASH handle HAL status */
1820 hhash->Status = HAL_OK;
1821
1822 }
1823}
1824
1836static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size)
1837{
1838 uint32_t buffercounter;
1839 __IO uint32_t inputaddr = (uint32_t) pInBuffer;
1840 uint32_t tmp;
1841
1842 for (buffercounter = 0U; buffercounter < (Size / 4U); buffercounter++)
1843 {
1844 /* Write input data 4 bytes at a time */
1845 HASH->DIN = *(uint32_t *)inputaddr;
1846 inputaddr += 4U;
1847
1848 /* If the suspension flag has been raised and if the processing is not about
1849 to end, suspend processing */
1850 if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && (((buffercounter * 4U) + 4U) < Size))
1851 {
1852 /* wait for flag BUSY not set before Wait for DINIS = 1*/
1853 if ((buffercounter * 4U) >= 64U)
1854 {
1855 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
1856 {
1857 return HAL_TIMEOUT;
1858 }
1859 }
1860 /* Wait for DINIS = 1, which occurs when 16 32-bit locations are free
1861 in the input buffer */
1862 if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
1863 {
1864 /* Reset SuspendRequest */
1865 hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
1866
1867 /* Depending whether the key or the input data were fed to the Peripheral, the feeding point
1868 reached at suspension time is not saved in the same handle fields */
1869 if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2))
1870 {
1871 /* Save current reading and writing locations of Input and Output buffers */
1872 hhash->pHashInBuffPtr = (uint8_t *)inputaddr;
1873 /* Save the number of bytes that remain to be processed at this point */
1874 hhash->HashInCount = Size - ((buffercounter * 4U) + 4U);
1875 }
1876 else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3))
1877 {
1878 /* Save current reading and writing locations of Input and Output buffers */
1879 hhash->pHashKeyBuffPtr = (uint8_t *)inputaddr;
1880 /* Save the number of bytes that remain to be processed at this point */
1881 hhash->HashKeyCount = Size - ((buffercounter * 4U) + 4U);
1882 }
1883 else
1884 {
1885 /* Unexpected phase: unlock process and report error */
1886 hhash->State = HAL_HASH_STATE_READY;
1887 __HAL_UNLOCK(hhash);
1888 return HAL_ERROR;
1889 }
1890
1891 /* Set the HASH state to Suspended and exit to stop entering data */
1892 hhash->State = HAL_HASH_STATE_SUSPENDED;
1893
1894 return HAL_OK;
1895 } /* if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) */
1896 } /* if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4) < Size)) */
1897 } /* for(buffercounter = 0; buffercounter < Size; buffercounter+=4) */
1898
1899 /* At this point, all the data have been entered to the Peripheral: exit */
1900
1901 if ((Size % 4U) != 0U)
1902 {
1903 if (hhash->Init.DataType == HASH_DATATYPE_16B)
1904 {
1905 /* Write remaining input data */
1906
1907 if ((Size % 4U) <= 2U)
1908 {
1909 HASH->DIN = (uint32_t) * (uint16_t *)inputaddr;
1910 }
1911 if ((Size % 4U) == 3U)
1912 {
1913 HASH->DIN = *(uint32_t *)inputaddr;
1914 }
1915
1916 }
1917 else if ((hhash->Init.DataType == HASH_DATATYPE_8B)
1918 || (hhash->Init.DataType == HASH_DATATYPE_1B)) /* byte swap or bit swap or */
1919 {
1920 /* Write remaining input data */
1921 if ((Size % 4U) == 1U)
1922 {
1923 HASH->DIN = (uint32_t) * (uint8_t *)inputaddr;
1924 }
1925 if ((Size % 4U) == 2U)
1926 {
1927 HASH->DIN = (uint32_t) * (uint16_t *)inputaddr;
1928 }
1929 if ((Size % 4U) == 3U)
1930 {
1931 tmp = *(uint8_t *)inputaddr;
1932 tmp |= (uint32_t) * (uint8_t *)(inputaddr + 1U) << 8U;
1933 tmp |= (uint32_t) * (uint8_t *)(inputaddr + 2U) << 16U;
1934 HASH->DIN = tmp;
1935 }
1936
1937 }
1938 else
1939 {
1940 HASH->DIN = *(uint32_t *)inputaddr;
1941 }
1942 }
1943
1944
1945 return HAL_OK;
1946}
1947
1954static void HASH_GetDigest(const uint8_t *pMsgDigest, uint8_t Size)
1955{
1956 uint32_t msgdigest = (uint32_t)pMsgDigest;
1957
1958 switch (Size)
1959 {
1960 /* Read the message digest */
1961 case 16: /* MD5 */
1962 *(uint32_t *)(msgdigest) = __REV(HASH->HR[0]);
1963 msgdigest += 4U;
1964 *(uint32_t *)(msgdigest) = __REV(HASH->HR[1]);
1965 msgdigest += 4U;
1966 *(uint32_t *)(msgdigest) = __REV(HASH->HR[2]);
1967 msgdigest += 4U;
1968 *(uint32_t *)(msgdigest) = __REV(HASH->HR[3]);
1969 break;
1970 case 20: /* SHA1 */
1971 *(uint32_t *)(msgdigest) = __REV(HASH->HR[0]);
1972 msgdigest += 4U;
1973 *(uint32_t *)(msgdigest) = __REV(HASH->HR[1]);
1974 msgdigest += 4U;
1975 *(uint32_t *)(msgdigest) = __REV(HASH->HR[2]);
1976 msgdigest += 4U;
1977 *(uint32_t *)(msgdigest) = __REV(HASH->HR[3]);
1978 msgdigest += 4U;
1979 *(uint32_t *)(msgdigest) = __REV(HASH->HR[4]);
1980 break;
1981 case 28: /* SHA224 */
1982 *(uint32_t *)(msgdigest) = __REV(HASH->HR[0]);
1983 msgdigest += 4U;
1984 *(uint32_t *)(msgdigest) = __REV(HASH->HR[1]);
1985 msgdigest += 4U;
1986 *(uint32_t *)(msgdigest) = __REV(HASH->HR[2]);
1987 msgdigest += 4U;
1988 *(uint32_t *)(msgdigest) = __REV(HASH->HR[3]);
1989 msgdigest += 4U;
1990 *(uint32_t *)(msgdigest) = __REV(HASH->HR[4]);
1991#if defined(HASH_CR_MDMAT)
1992 msgdigest += 4U;
1993 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1994 msgdigest += 4U;
1995 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1996#endif /* HASH_CR_MDMAT*/
1997 break;
1998 case 32: /* SHA256 */
1999 *(uint32_t *)(msgdigest) = __REV(HASH->HR[0]);
2000 msgdigest += 4U;
2001 *(uint32_t *)(msgdigest) = __REV(HASH->HR[1]);
2002 msgdigest += 4U;
2003 *(uint32_t *)(msgdigest) = __REV(HASH->HR[2]);
2004 msgdigest += 4U;
2005 *(uint32_t *)(msgdigest) = __REV(HASH->HR[3]);
2006 msgdigest += 4U;
2007 *(uint32_t *)(msgdigest) = __REV(HASH->HR[4]);
2008#if defined(HASH_CR_MDMAT)
2009 msgdigest += 4U;
2010 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
2011 msgdigest += 4U;
2012 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
2013 msgdigest += 4U;
2014 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
2015#endif /* HASH_CR_MDMAT*/
2016 break;
2017 default:
2018 break;
2019 }
2020}
2021
2022
2031static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status,
2032 uint32_t Timeout)
2033{
2034 uint32_t tickstart = HAL_GetTick();
2035
2036 /* Wait until flag is set */
2037 if (Status == RESET)
2038 {
2039 while (__HAL_HASH_GET_FLAG(Flag) == RESET)
2040 {
2041 /* Check for the Timeout */
2042 if (Timeout != HAL_MAX_DELAY)
2043 {
2044 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2045 {
2046 /* Set State to Ready to be able to restart later on */
2047 hhash->State = HAL_HASH_STATE_READY;
2048 /* Store time out issue in handle status */
2049 hhash->Status = HAL_TIMEOUT;
2050
2051 /* Process Unlocked */
2052 __HAL_UNLOCK(hhash);
2053
2054 return HAL_TIMEOUT;
2055 }
2056 }
2057 }
2058 }
2059 else
2060 {
2061 while (__HAL_HASH_GET_FLAG(Flag) != RESET)
2062 {
2063 /* Check for the Timeout */
2064 if (Timeout != HAL_MAX_DELAY)
2065 {
2066 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2067 {
2068 /* Set State to Ready to be able to restart later on */
2069 hhash->State = HAL_HASH_STATE_READY;
2070 /* Store time out issue in handle status */
2071 hhash->Status = HAL_TIMEOUT;
2072
2073 /* Process Unlocked */
2074 __HAL_UNLOCK(hhash);
2075
2076 return HAL_TIMEOUT;
2077 }
2078 }
2079 }
2080 }
2081 return HAL_OK;
2082}
2083
2084
2094static HAL_StatusTypeDef HASH_IT(HASH_HandleTypeDef *hhash)
2095{
2096 if (hhash->State == HAL_HASH_STATE_BUSY)
2097 {
2098 /* ITCounter must not be equal to 0 at this point. Report an error if this is the case. */
2099 if (hhash->HashITCounter == 0U)
2100 {
2101 /* Disable Interrupts */
2102 __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
2103 /* HASH state set back to Ready to prevent any issue in user code
2104 present in HAL_HASH_ErrorCallback() */
2105 hhash->State = HAL_HASH_STATE_READY;
2106 return HAL_ERROR;
2107 }
2108 else if (hhash->HashITCounter == 1U)
2109 {
2110 /* This is the first call to HASH_IT, the first input data are about to be
2111 entered in the Peripheral. A specific processing is carried out at this point to
2112 start-up the processing. */
2113 hhash->HashITCounter = 2U;
2114 }
2115 else
2116 {
2117 /* Cruise speed reached, HashITCounter remains equal to 3 until the end of
2118 the HASH processing or the end of the current step for HMAC processing. */
2119 hhash->HashITCounter = 3U;
2120 }
2121
2122 /* If digest is ready */
2123 if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
2124 {
2125 /* Read the digest */
2126 HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH());
2127
2128 /* Disable Interrupts */
2129 __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
2130 /* Change the HASH state */
2131 hhash->State = HAL_HASH_STATE_READY;
2132 /* Reset HASH state machine */
2133 hhash->Phase = HAL_HASH_PHASE_READY;
2134 /* Call digest computation complete call back */
2135#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2136 hhash->DgstCpltCallback(hhash);
2137#else
2138 HAL_HASH_DgstCpltCallback(hhash);
2139#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2140
2141 return HAL_OK;
2142 }
2143
2144 /* If Peripheral ready to accept new data */
2145 if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
2146 {
2147
2148 /* If the suspension flag has been raised and if the processing is not about
2149 to end, suspend processing */
2150 if ((hhash->HashInCount != 0U) && (hhash->SuspendRequest == HAL_HASH_SUSPEND))
2151 {
2152 /* Disable Interrupts */
2153 __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
2154
2155 /* Reset SuspendRequest */
2156 hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
2157
2158 /* Change the HASH state */
2159 hhash->State = HAL_HASH_STATE_SUSPENDED;
2160
2161 return HAL_OK;
2162 }
2163
2164 /* Enter input data in the Peripheral through HASH_Write_Block_Data() call and
2165 check whether the digest calculation has been triggered */
2166 if (HASH_Write_Block_Data(hhash) == HASH_DIGEST_CALCULATION_STARTED)
2167 {
2168 /* Call Input data transfer complete call back
2169 (called at the end of each step for HMAC) */
2170#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2171 hhash->InCpltCallback(hhash);
2172#else
2173 HAL_HASH_InCpltCallback(hhash);
2174#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2175
2176 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
2177 {
2178 /* Wait until Peripheral is not busy anymore */
2179 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
2180 {
2181 /* Disable Interrupts */
2182 __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
2183 return HAL_TIMEOUT;
2184 }
2185 /* Initialization start for HMAC STEP 2 */
2186 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; /* Move phase from Step 1 to Step 2 */
2187 __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); /* Set NBLW for the input message */
2188 hhash->HashInCount = hhash->HashBuffSize; /* Set the input data size (in bytes) */
2189 hhash->pHashInBuffPtr = hhash->pHashMsgBuffPtr; /* Set the input data address */
2190 hhash->HashITCounter = 1; /* Set ITCounter to 1 to indicate the start
2191 of a new phase */
2192 __HAL_HASH_ENABLE_IT(HASH_IT_DINI); /* Enable IT (was disabled in HASH_Write_Block_Data) */
2193 }
2194 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
2195 {
2196 /* Wait until Peripheral is not busy anymore */
2197 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
2198 {
2199 /* Disable Interrupts */
2200 __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
2201 return HAL_TIMEOUT;
2202 }
2203 /* Initialization start for HMAC STEP 3 */
2204 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; /* Move phase from Step 2 to Step 3 */
2205 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); /* Set NBLW for the key */
2206 hhash->HashInCount = hhash->Init.KeySize; /* Set the key size (in bytes) */
2207 hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */
2208 hhash->HashITCounter = 1; /* Set ITCounter to 1 to indicate the start
2209 of a new phase */
2210 __HAL_HASH_ENABLE_IT(HASH_IT_DINI); /* Enable IT (was disabled in HASH_Write_Block_Data) */
2211 }
2212 else
2213 {
2214 /* Nothing to do */
2215 }
2216 } /* if (HASH_Write_Block_Data(hhash) == HASH_DIGEST_CALCULATION_STARTED) */
2217 } /* if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))*/
2218
2219 /* Return function status */
2220 return HAL_OK;
2221 }
2222 else
2223 {
2224 return HAL_BUSY;
2225 }
2226}
2227
2228
2235static uint32_t HASH_Write_Block_Data(HASH_HandleTypeDef *hhash)
2236{
2237 uint32_t inputaddr;
2238 uint32_t buffercounter;
2239 uint32_t inputcounter;
2240 uint32_t ret = HASH_DIGEST_CALCULATION_NOT_STARTED;
2241
2242 /* If there are more than 64 bytes remaining to be entered */
2243 if (hhash->HashInCount > 64U)
2244 {
2245 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
2246 /* Write the Input block in the Data IN register
2247 (16 32-bit words, or 64 bytes are entered) */
2248 for (buffercounter = 0U; buffercounter < 64U; buffercounter += 4U)
2249 {
2250 HASH->DIN = *(uint32_t *)inputaddr;
2251 inputaddr += 4U;
2252 }
2253 /* If this is the start of input data entering, an additional word
2254 must be entered to start up the HASH processing */
2255 if (hhash->HashITCounter == 2U)
2256 {
2257 HASH->DIN = *(uint32_t *)inputaddr;
2258 if (hhash->HashInCount >= 68U)
2259 {
2260 /* There are still data waiting to be entered in the Peripheral.
2261 Decrement buffer counter and set pointer to the proper
2262 memory location for the next data entering round. */
2263 hhash->HashInCount -= 68U;
2264 hhash->pHashInBuffPtr += 68U;
2265 }
2266 else
2267 {
2268 /* All the input buffer has been fed to the HW. */
2269 hhash->HashInCount = 0U;
2270 }
2271 }
2272 else
2273 {
2274 /* 64 bytes have been entered and there are still some remaining:
2275 Decrement buffer counter and set pointer to the proper
2276 memory location for the next data entering round.*/
2277 hhash->HashInCount -= 64U;
2278 hhash->pHashInBuffPtr += 64U;
2279 }
2280 }
2281 else
2282 {
2283 /* 64 or less bytes remain to be entered. This is the last
2284 data entering round. */
2285
2286 /* Get the buffer address */
2287 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
2288 /* Get the buffer counter */
2289 inputcounter = hhash->HashInCount;
2290 /* Disable Interrupts */
2291 __HAL_HASH_DISABLE_IT(HASH_IT_DINI);
2292
2293 /* Write the Input block in the Data IN register */
2294 for (buffercounter = 0U; buffercounter < ((inputcounter + 3U) / 4U); buffercounter++)
2295 {
2296 HASH->DIN = *(uint32_t *)inputaddr;
2297 inputaddr += 4U;
2298 }
2299
2300 if (hhash->Accumulation == 1U)
2301 {
2302 /* Field accumulation is set, API only feeds data to the Peripheral and under interruption.
2303 The digest computation will be started when the last buffer data are entered. */
2304
2305 /* Reset multi buffers accumulation flag */
2306 hhash->Accumulation = 0U;
2307 /* Change the HASH state */
2308 hhash->State = HAL_HASH_STATE_READY;
2309 /* Call Input data transfer complete call back */
2310#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2311 hhash->InCpltCallback(hhash);
2312#else
2313 HAL_HASH_InCpltCallback(hhash);
2314#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2315 }
2316 else
2317 {
2318 /* Start the Digest calculation */
2319 __HAL_HASH_START_DIGEST();
2320 /* Return indication that digest calculation has started:
2321 this return value triggers the call to Input data transfer
2322 complete call back as well as the proper transition from
2323 one step to another in HMAC mode. */
2324 ret = HASH_DIGEST_CALCULATION_STARTED;
2325 }
2326 /* Reset buffer counter */
2327 hhash->HashInCount = 0;
2328 }
2329
2330 /* Return whether or digest calculation has started */
2331 return ret;
2332}
2333
2340static HAL_StatusTypeDef HMAC_Processing(HASH_HandleTypeDef *hhash, uint32_t Timeout)
2341{
2342 /* Ensure first that Phase is correct */
2343 if ((hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_1) && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_2)
2344 && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_3))
2345 {
2346 /* Change the HASH state */
2347 hhash->State = HAL_HASH_STATE_READY;
2348
2349 /* Process Unlock */
2350 __HAL_UNLOCK(hhash);
2351
2352 /* Return function status */
2353 return HAL_ERROR;
2354 }
2355
2356 /* HMAC Step 1 processing */
2357 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
2358 {
2359 /************************** STEP 1 ******************************************/
2360 /* Configure the Number of valid bits in last word of the message */
2361 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
2362
2363 /* Write input buffer in Data register */
2364 hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount);
2365 if (hhash->Status != HAL_OK)
2366 {
2367 return hhash->Status;
2368 }
2369
2370 /* Check whether or not key entering process has been suspended */
2371 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2372 {
2373 /* Process Unlocked */
2374 __HAL_UNLOCK(hhash);
2375
2376 /* Stop right there and return function status */
2377 return HAL_OK;
2378 }
2379
2380 /* No processing suspension at this point: set DCAL bit. */
2381 __HAL_HASH_START_DIGEST();
2382
2383 /* Wait for BUSY flag to be cleared */
2384 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
2385 {
2386 return HAL_TIMEOUT;
2387 }
2388
2389 /* Move from Step 1 to Step 2 */
2390 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2;
2391
2392 }
2393
2394 /* HMAC Step 2 processing.
2395 After phase check, HMAC_Processing() may
2396 - directly start up from this point in resumption case
2397 if the same Step 2 processing was suspended previously
2398 - or fall through from the Step 1 processing carried out hereabove */
2399 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
2400 {
2401 /************************** STEP 2 ******************************************/
2402 /* Configure the Number of valid bits in last word of the message */
2403 __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize);
2404
2405 /* Write input buffer in Data register */
2406 hhash->Status = HASH_WriteData(hhash, hhash->pHashInBuffPtr, hhash->HashInCount);
2407 if (hhash->Status != HAL_OK)
2408 {
2409 return hhash->Status;
2410 }
2411
2412 /* Check whether or not data entering process has been suspended */
2413 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2414 {
2415 /* Process Unlocked */
2416 __HAL_UNLOCK(hhash);
2417
2418 /* Stop right there and return function status */
2419 return HAL_OK;
2420 }
2421
2422 /* No processing suspension at this point: set DCAL bit. */
2423 __HAL_HASH_START_DIGEST();
2424
2425 /* Wait for BUSY flag to be cleared */
2426 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
2427 {
2428 return HAL_TIMEOUT;
2429 }
2430
2431 /* Move from Step 2 to Step 3 */
2432 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3;
2433 /* In case Step 1 phase was suspended then resumed,
2434 set again Key input buffers and size before moving to
2435 next step */
2436 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
2437 hhash->HashKeyCount = hhash->Init.KeySize;
2438 }
2439
2440
2441 /* HMAC Step 3 processing.
2442 After phase check, HMAC_Processing() may
2443 - directly start up from this point in resumption case
2444 if the same Step 3 processing was suspended previously
2445 - or fall through from the Step 2 processing carried out hereabove */
2446 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)
2447 {
2448 /************************** STEP 3 ******************************************/
2449 /* Configure the Number of valid bits in last word of the message */
2450 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
2451
2452 /* Write input buffer in Data register */
2453 hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount);
2454 if (hhash->Status != HAL_OK)
2455 {
2456 return hhash->Status;
2457 }
2458
2459 /* Check whether or not key entering process has been suspended */
2460 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2461 {
2462 /* Process Unlocked */
2463 __HAL_UNLOCK(hhash);
2464
2465 /* Stop right there and return function status */
2466 return HAL_OK;
2467 }
2468
2469 /* No processing suspension at this point: start the Digest calculation. */
2470 __HAL_HASH_START_DIGEST();
2471
2472 /* Wait for DCIS flag to be set */
2473 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
2474 {
2475 return HAL_TIMEOUT;
2476 }
2477
2478 /* Read the message digest */
2479 HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH());
2480
2481 /* Reset HASH state machine */
2482 hhash->Phase = HAL_HASH_PHASE_READY;
2483 }
2484
2485 /* Change the HASH state */
2486 hhash->State = HAL_HASH_STATE_READY;
2487
2488 /* Process Unlock */
2489 __HAL_UNLOCK(hhash);
2490
2491 /* Return function status */
2492 return HAL_OK;
2493}
2494
2495
2508HAL_StatusTypeDef HASH_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
2509 uint8_t *pOutBuffer,
2510 uint32_t Timeout, uint32_t Algorithm)
2511{
2512 const uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */
2513 uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */
2514 HAL_HASH_StateTypeDef State_tmp = hhash->State;
2515
2516
2517 /* Initiate HASH processing in case of start or resumption */
2518 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2519 {
2520 /* Check input parameters */
2521 if ((pInBuffer == NULL) || (pOutBuffer == NULL))
2522 {
2523 hhash->State = HAL_HASH_STATE_READY;
2524 return HAL_ERROR;
2525 }
2526
2527 /* Process Locked */
2528 __HAL_LOCK(hhash);
2529
2530 /* Check if initialization phase has not been already performed */
2531 if (hhash->Phase == HAL_HASH_PHASE_READY)
2532 {
2533 /* Change the HASH state */
2534 hhash->State = HAL_HASH_STATE_BUSY;
2535
2536 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2537 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2538
2539 /* Configure the number of valid bits in last word of the message */
2540 __HAL_HASH_SET_NBVALIDBITS(Size);
2541
2542 /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2543 input parameters of HASH_WriteData() */
2544 pInBuffer_tmp = (const uint8_t *)pInBuffer; /* pInBuffer_tmp is set to the input data address */
2545 Size_tmp = Size; /* Size_tmp contains the input data size in bytes */
2546
2547 /* Set the phase */
2548 hhash->Phase = HAL_HASH_PHASE_PROCESS;
2549 }
2550 else if (hhash->Phase == HAL_HASH_PHASE_PROCESS)
2551 {
2552 /* if the Peripheral has already been initialized, two cases are possible */
2553
2554 /* Process resumption time ... */
2555 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2556 {
2557 /* Since this is resumption, pInBuffer_tmp and Size_tmp are not set
2558 to the API input parameters but to those saved beforehand by HASH_WriteData()
2559 when the processing was suspended */
2560 pInBuffer_tmp = (const uint8_t *)hhash->pHashInBuffPtr;
2561 Size_tmp = hhash->HashInCount;
2562 }
2563 /* ... or multi-buffer HASH processing end */
2564 else
2565 {
2566 /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2567 input parameters of HASH_WriteData() */
2568 pInBuffer_tmp = (const uint8_t *)pInBuffer;
2569 Size_tmp = Size;
2570 /* Configure the number of valid bits in last word of the message */
2571 __HAL_HASH_SET_NBVALIDBITS(Size);
2572 }
2573 /* Change the HASH state */
2574 hhash->State = HAL_HASH_STATE_BUSY;
2575 }
2576 else
2577 {
2578 /* Phase error */
2579 hhash->State = HAL_HASH_STATE_READY;
2580
2581 /* Process Unlocked */
2582 __HAL_UNLOCK(hhash);
2583
2584 /* Return function status */
2585 return HAL_ERROR;
2586 }
2587
2588
2589 /* Write input buffer in Data register */
2590 hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp);
2591 if (hhash->Status != HAL_OK)
2592 {
2593 return hhash->Status;
2594 }
2595
2596 /* If the process has not been suspended, carry on to digest calculation */
2597 if (hhash->State != HAL_HASH_STATE_SUSPENDED)
2598 {
2599 /* Start the Digest calculation */
2600 __HAL_HASH_START_DIGEST();
2601
2602 /* Wait for DCIS flag to be set */
2603 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
2604 {
2605 return HAL_TIMEOUT;
2606 }
2607
2608 /* Read the message digest */
2609 HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH());
2610
2611 /* Change the HASH state */
2612 hhash->State = HAL_HASH_STATE_READY;
2613
2614 /* Reset HASH state machine */
2615 hhash->Phase = HAL_HASH_PHASE_READY;
2616
2617 }
2618
2619 /* Process Unlocked */
2620 __HAL_UNLOCK(hhash);
2621
2622 /* Return function status */
2623 return HAL_OK;
2624
2625 }
2626 else
2627 {
2628 return HAL_BUSY;
2629 }
2630}
2631
2632
2646HAL_StatusTypeDef HASH_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
2647 uint32_t Algorithm)
2648{
2649 const uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */
2650 uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */
2651 HAL_HASH_StateTypeDef State_tmp = hhash->State;
2652
2653 /* Make sure the input buffer size (in bytes) is a multiple of 4 */
2654 if ((Size % 4U) != 0U)
2655 {
2656 return HAL_ERROR;
2657 }
2658
2659 /* Initiate HASH processing in case of start or resumption */
2660 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2661 {
2662 /* Check input parameters */
2663 if ((pInBuffer == NULL) || (Size == 0U))
2664 {
2665 hhash->State = HAL_HASH_STATE_READY;
2666 return HAL_ERROR;
2667 }
2668
2669 /* Process Locked */
2670 __HAL_LOCK(hhash);
2671
2672 /* If resuming the HASH processing */
2673 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2674 {
2675 /* Change the HASH state */
2676 hhash->State = HAL_HASH_STATE_BUSY;
2677
2678 /* Since this is resumption, pInBuffer_tmp and Size_tmp are not set
2679 to the API input parameters but to those saved beforehand by HASH_WriteData()
2680 when the processing was suspended */
2681 pInBuffer_tmp = (const uint8_t *)hhash->pHashInBuffPtr; /* pInBuffer_tmp is set to the input data address */
2682 Size_tmp = hhash->HashInCount; /* Size_tmp contains the input data size in bytes */
2683
2684 }
2685 else
2686 {
2687 /* Change the HASH state */
2688 hhash->State = HAL_HASH_STATE_BUSY;
2689
2690 /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2691 input parameters of HASH_WriteData() */
2692 pInBuffer_tmp = (const uint8_t *)pInBuffer; /* pInBuffer_tmp is set to the input data address */
2693 Size_tmp = Size; /* Size_tmp contains the input data size in bytes */
2694
2695 /* Check if initialization phase has already be performed */
2696 if (hhash->Phase == HAL_HASH_PHASE_READY)
2697 {
2698 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2699 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2700 }
2701
2702 /* Set the phase */
2703 hhash->Phase = HAL_HASH_PHASE_PROCESS;
2704
2705 }
2706
2707 /* Write input buffer in Data register */
2708 hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp);
2709 if (hhash->Status != HAL_OK)
2710 {
2711 return hhash->Status;
2712 }
2713
2714 /* If the process has not been suspended, move the state to Ready */
2715 if (hhash->State != HAL_HASH_STATE_SUSPENDED)
2716 {
2717 /* Change the HASH state */
2718 hhash->State = HAL_HASH_STATE_READY;
2719 }
2720
2721 /* Process Unlocked */
2722 __HAL_UNLOCK(hhash);
2723
2724 /* Return function status */
2725 return HAL_OK;
2726
2727 }
2728 else
2729 {
2730 return HAL_BUSY;
2731 }
2732
2733
2734}
2735
2736
2750HAL_StatusTypeDef HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
2751 uint32_t Algorithm)
2752{
2753 HAL_HASH_StateTypeDef State_tmp = hhash->State;
2754 __IO uint32_t inputaddr = (uint32_t) pInBuffer;
2755 uint32_t SizeVar = Size;
2756
2757 /* Make sure the input buffer size (in bytes) is a multiple of 4 */
2758 if ((Size % 4U) != 0U)
2759 {
2760 return HAL_ERROR;
2761 }
2762
2763 /* Initiate HASH processing in case of start or resumption */
2764 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2765 {
2766 /* Check input parameters */
2767 if ((pInBuffer == NULL) || (Size == 0U))
2768 {
2769 hhash->State = HAL_HASH_STATE_READY;
2770 return HAL_ERROR;
2771 }
2772
2773 /* Process Locked */
2774 __HAL_LOCK(hhash);
2775
2776 /* If resuming the HASH processing */
2777 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2778 {
2779 /* Change the HASH state */
2780 hhash->State = HAL_HASH_STATE_BUSY;
2781 }
2782 else
2783 {
2784 /* Change the HASH state */
2785 hhash->State = HAL_HASH_STATE_BUSY;
2786
2787 /* Check if initialization phase has already be performed */
2788 if (hhash->Phase == HAL_HASH_PHASE_READY)
2789 {
2790 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2791 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2792 hhash->HashITCounter = 1;
2793 }
2794 else
2795 {
2796 hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */
2797 }
2798
2799 /* Set the phase */
2800 hhash->Phase = HAL_HASH_PHASE_PROCESS;
2801
2802 /* If DINIS is equal to 0 (for example if an incomplete block has been previously
2803 fed to the Peripheral), the DINIE interruption won't be triggered when DINIE is set.
2804 Therefore, first words are manually entered until DINIS raises, or until there
2805 is not more data to enter. */
2806 while ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 0U))
2807 {
2808
2809 /* Write input data 4 bytes at a time */
2810 HASH->DIN = *(uint32_t *)inputaddr;
2811 inputaddr += 4U;
2812 SizeVar -= 4U;
2813 }
2814
2815 /* If DINIS is still not set or if all the data have been fed, stop here */
2816 if ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) || (SizeVar == 0U))
2817 {
2818 /* Change the HASH state */
2819 hhash->State = HAL_HASH_STATE_READY;
2820
2821 /* Process Unlock */
2822 __HAL_UNLOCK(hhash);
2823
2824 /* Return function status */
2825 return HAL_OK;
2826 }
2827
2828 /* otherwise, carry on in interrupt-mode */
2829 hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data
2830 to be fed to the Peripheral */
2831 hhash->pHashInBuffPtr = (uint8_t *)inputaddr; /* Points at data which will be fed to the Peripheral at
2832 the next interruption */
2833 /* In case of suspension, hhash->HashInCount and hhash->pHashInBuffPtr contain
2834 the information describing where the HASH process is stopped.
2835 These variables are used later on to resume the HASH processing at the
2836 correct location. */
2837
2838 }
2839
2840 /* Set multi buffers accumulation flag */
2841 hhash->Accumulation = 1U;
2842
2843 /* Process Unlock */
2844 __HAL_UNLOCK(hhash);
2845
2846 /* Enable Data Input interrupt */
2847 __HAL_HASH_ENABLE_IT(HASH_IT_DINI);
2848
2849 /* Return function status */
2850 return HAL_OK;
2851
2852 }
2853 else
2854 {
2855 return HAL_BUSY;
2856 }
2857
2858}
2859
2860
2872HAL_StatusTypeDef HASH_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
2873 uint8_t *pOutBuffer,
2874 uint32_t Algorithm)
2875{
2876 HAL_HASH_StateTypeDef State_tmp = hhash->State;
2877 __IO uint32_t inputaddr = (uint32_t) pInBuffer;
2878 uint32_t polling_step = 0U;
2879 uint32_t initialization_skipped = 0U;
2880 uint32_t SizeVar = Size;
2881
2882 /* If State is ready or suspended, start or resume IT-based HASH processing */
2883 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2884 {
2885 /* Check input parameters */
2886 if ((pInBuffer == NULL) || (Size == 0U) || (pOutBuffer == NULL))
2887 {
2888 hhash->State = HAL_HASH_STATE_READY;
2889 return HAL_ERROR;
2890 }
2891
2892 /* Process Locked */
2893 __HAL_LOCK(hhash);
2894
2895 /* Change the HASH state */
2896 hhash->State = HAL_HASH_STATE_BUSY;
2897
2898 /* Initialize IT counter */
2899 hhash->HashITCounter = 1;
2900
2901 /* Check if initialization phase has already be performed */
2902 if (hhash->Phase == HAL_HASH_PHASE_READY)
2903 {
2904 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2905 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2906
2907 /* Configure the number of valid bits in last word of the message */
2908 __HAL_HASH_SET_NBVALIDBITS(SizeVar);
2909
2910
2911 hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data
2912 to be fed to the Peripheral */
2913 hhash->pHashInBuffPtr = pInBuffer; /* Points at data which will be fed to the Peripheral at
2914 the next interruption */
2915 /* In case of suspension, hhash->HashInCount and hhash->pHashInBuffPtr contain
2916 the information describing where the HASH process is stopped.
2917 These variables are used later on to resume the HASH processing at the
2918 correct location. */
2919
2920 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2921 }
2922 else if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) && (SizeVar < 4U))
2923 {
2924 if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
2925 {
2926 /* It remains data to enter and the Peripheral is ready to trigger DINIE,carry on as usual.
2927 Update HashInCount and pHashInBuffPtr accordingly. */
2928 hhash->HashInCount = SizeVar;
2929 hhash->pHashInBuffPtr = (uint8_t *)inputaddr;
2930 /* Update the configuration of the number of valid bits in last word of the message */
2931 __HAL_HASH_SET_NBVALIDBITS(SizeVar);
2932 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2933 }
2934 }
2935 else
2936 {
2937 initialization_skipped = 1; /* info user later on in case of multi-buffer */
2938 }
2939
2940 /* Set the phase */
2941 hhash->Phase = HAL_HASH_PHASE_PROCESS;
2942
2943 /* If DINIS is equal to 0 (for example if an incomplete block has been previously
2944 fed to the Peripheral), the DINIE interruption won't be triggered when DINIE is set.
2945 Therefore, first words are manually entered until DINIS raises. */
2946 while ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 3U))
2947 {
2948 polling_step = 1U; /* note that some words are entered before enabling the interrupt */
2949
2950 /* Write input data 4 bytes at a time */
2951 HASH->DIN = *(uint32_t *)inputaddr;
2952 inputaddr += 4U;
2953 SizeVar -= 4U;
2954 }
2955
2956 if (polling_step == 1U)
2957 {
2958 if (SizeVar == 0U)
2959 {
2960 /* If all the data have been entered at this point, it only remains to
2961 read the digest */
2962 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2963
2964 /* Start the Digest calculation */
2965 __HAL_HASH_START_DIGEST();
2966 /* Process Unlock */
2967 __HAL_UNLOCK(hhash);
2968
2969 /* Enable Interrupts */
2970 __HAL_HASH_ENABLE_IT(HASH_IT_DCI);
2971
2972 /* Return function status */
2973 return HAL_OK;
2974 }
2975 else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
2976 {
2977 /* It remains data to enter and the Peripheral is ready to trigger DINIE,
2978 carry on as usual.
2979 Update HashInCount and pHashInBuffPtr accordingly. */
2980 hhash->HashInCount = SizeVar;
2981 hhash->pHashInBuffPtr = (uint8_t *)inputaddr;
2982 /* Update the configuration of the number of valid bits in last word of the message */
2983 __HAL_HASH_SET_NBVALIDBITS(SizeVar);
2984 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2985 if (initialization_skipped == 1U)
2986 {
2987 hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */
2988 }
2989 }
2990 else
2991 {
2992 /* DINIS is not set but it remains a few data to enter (not enough for a full word).
2993 Manually enter the last bytes before enabling DCIE. */
2994 __HAL_HASH_SET_NBVALIDBITS(SizeVar);
2995 HASH->DIN = *(uint32_t *)inputaddr;
2996
2997 /* Start the Digest calculation */
2998 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2999 __HAL_HASH_START_DIGEST();
3000 /* Process Unlock */
3001 __HAL_UNLOCK(hhash);
3002
3003 /* Enable Interrupts */
3004 __HAL_HASH_ENABLE_IT(HASH_IT_DCI);
3005
3006 /* Return function status */
3007 return HAL_OK;
3008 }
3009 } /* if (polling_step == 1) */
3010
3011
3012 /* Process Unlock */
3013 __HAL_UNLOCK(hhash);
3014
3015 /* Enable Interrupts */
3016 __HAL_HASH_ENABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
3017
3018 /* Return function status */
3019 return HAL_OK;
3020 }
3021 else
3022 {
3023 return HAL_BUSY;
3024 }
3025
3026}
3027
3028
3044HAL_StatusTypeDef HASH_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
3045 uint32_t Algorithm)
3046{
3047 uint32_t inputaddr;
3048 uint32_t inputSize;
3049 HAL_StatusTypeDef status ;
3050 HAL_HASH_StateTypeDef State_tmp = hhash->State;
3051
3052#if defined (HASH_CR_MDMAT)
3053 /* Make sure the input buffer size (in bytes) is a multiple of 4 when MDMAT bit is set
3054 (case of multi-buffer HASH processing) */
3055 assert_param(IS_HASH_DMA_MULTIBUFFER_SIZE(Size));
3056#endif /* MDMA defined*/
3057 /* If State is ready or suspended, start or resume polling-based HASH processing */
3058 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3059 {
3060 /* Check input parameters */
3061 if ((pInBuffer == NULL) || (Size == 0U) ||
3062 /* Check phase coherency. Phase must be
3063 either READY (fresh start)
3064 or PROCESS (multi-buffer HASH management) */
3065 ((hhash->Phase != HAL_HASH_PHASE_READY) && (!(IS_HASH_PROCESSING(hhash)))))
3066 {
3067 hhash->State = HAL_HASH_STATE_READY;
3068 return HAL_ERROR;
3069 }
3070
3071
3072 /* Process Locked */
3073 __HAL_LOCK(hhash);
3074
3075 /* If not a resumption case */
3076 if (hhash->State == HAL_HASH_STATE_READY)
3077 {
3078 /* Change the HASH state */
3079 hhash->State = HAL_HASH_STATE_BUSY;
3080
3081 /* Check if initialization phase has already been performed.
3082 If Phase is already set to HAL_HASH_PHASE_PROCESS, this means the
3083 API is processing a new input data message in case of multi-buffer HASH
3084 computation. */
3085 if (hhash->Phase == HAL_HASH_PHASE_READY)
3086 {
3087 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
3088 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
3089
3090 /* Set the phase */
3091 hhash->Phase = HAL_HASH_PHASE_PROCESS;
3092 }
3093
3094 /* Configure the Number of valid bits in last word of the message */
3095 __HAL_HASH_SET_NBVALIDBITS(Size);
3096
3097 inputaddr = (uint32_t)pInBuffer; /* DMA transfer start address */
3098 inputSize = Size; /* DMA transfer size (in bytes) */
3099
3100 /* In case of suspension request, save the starting parameters */
3101 hhash->pHashInBuffPtr = pInBuffer; /* DMA transfer start address */
3102 hhash->HashInCount = Size; /* DMA transfer size (in bytes) */
3103
3104 }
3105 /* If resumption case */
3106 else
3107 {
3108 /* Change the HASH state */
3109 hhash->State = HAL_HASH_STATE_BUSY;
3110
3111 /* Resumption case, inputaddr and inputSize are not set to the API input parameters
3112 but to those saved beforehand by HAL_HASH_DMAFeed_ProcessSuspend() when the
3113 processing was suspended */
3114 inputaddr = (uint32_t)hhash->pHashInBuffPtr; /* DMA transfer start address */
3115 inputSize = hhash->HashInCount; /* DMA transfer size (in bytes) */
3116
3117 }
3118
3119 /* Set the HASH DMA transfer complete callback */
3120 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
3121 /* Set the DMA error callback */
3122 hhash->hdmain->XferErrorCallback = HASH_DMAError;
3123
3124 /* Store number of words already pushed to manage proper DMA processing suspension */
3125 hhash->NbWordsAlreadyPushed = HASH_NBW_PUSHED();
3126
3127 /* Enable the DMA In DMA stream */
3128 status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, \
3129 (((inputSize % 4U) != 0U) ? ((inputSize + (4U - (inputSize % 4U))) / 4U) : \
3130 (inputSize / 4U)));
3131
3132 /* Enable DMA requests */
3133 SET_BIT(HASH->CR, HASH_CR_DMAE);
3134
3135 /* Process Unlock */
3136 __HAL_UNLOCK(hhash);
3137
3138 /* Return function status */
3139 if (status != HAL_OK)
3140 {
3141 /* Update HASH state machine to error */
3142 hhash->State = HAL_HASH_STATE_ERROR;
3143 }
3144
3145 return status;
3146 }
3147 else
3148 {
3149 return HAL_BUSY;
3150 }
3151}
3152
3161HAL_StatusTypeDef HASH_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
3162{
3163
3164 if (hhash->State == HAL_HASH_STATE_READY)
3165 {
3166 /* Check parameter */
3167 if (pOutBuffer == NULL)
3168 {
3169 return HAL_ERROR;
3170 }
3171
3172 /* Process Locked */
3173 __HAL_LOCK(hhash);
3174
3175 /* Change the HASH state to busy */
3176 hhash->State = HAL_HASH_STATE_BUSY;
3177
3178 /* Wait for DCIS flag to be set */
3179 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
3180 {
3181 return HAL_TIMEOUT;
3182 }
3183
3184 /* Read the message digest */
3185 HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH());
3186
3187 /* Change the HASH state to ready */
3188 hhash->State = HAL_HASH_STATE_READY;
3189
3190 /* Reset HASH state machine */
3191 hhash->Phase = HAL_HASH_PHASE_READY;
3192
3193 /* Process UnLock */
3194 __HAL_UNLOCK(hhash);
3195
3196 /* Return function status */
3197 return HAL_OK;
3198
3199 }
3200 else
3201 {
3202 return HAL_BUSY;
3203 }
3204
3205}
3206
3207
3222HAL_StatusTypeDef HMAC_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
3223 uint8_t *pOutBuffer,
3224 uint32_t Timeout, uint32_t Algorithm)
3225{
3226 HAL_HASH_StateTypeDef State_tmp = hhash->State;
3227
3228 /* If State is ready or suspended, start or resume polling-based HASH processing */
3229 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3230 {
3231 /* Check input parameters */
3232 if ((pInBuffer == NULL) || (Size == 0U) || (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U)
3233 || (pOutBuffer == NULL))
3234 {
3235 hhash->State = HAL_HASH_STATE_READY;
3236 return HAL_ERROR;
3237 }
3238
3239 /* Process Locked */
3240 __HAL_LOCK(hhash);
3241
3242 /* Change the HASH state */
3243 hhash->State = HAL_HASH_STATE_BUSY;
3244
3245 /* Check if initialization phase has already be performed */
3246 if (hhash->Phase == HAL_HASH_PHASE_READY)
3247 {
3248 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
3249 if (hhash->Init.KeySize > 64U)
3250 {
3251 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3252 Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3253 }
3254 else
3255 {
3256 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3257 Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3258 }
3259 /* Set the phase to Step 1 */
3260 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
3261 /* Resort to hhash internal fields to feed the Peripheral.
3262 Parameters will be updated in case of suspension to contain the proper
3263 information at resumption time. */
3264 hhash->pHashOutBuffPtr = pOutBuffer; /* Output digest address */
3265 hhash->pHashInBuffPtr = pInBuffer; /* Input data address, HMAC_Processing input
3266 parameter for Step 2 */
3267 hhash->HashInCount = Size; /* Input data size, HMAC_Processing input
3268 parameter for Step 2 */
3269 hhash->HashBuffSize = Size; /* Store the input buffer size for the whole HMAC process*/
3270 hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address, HMAC_Processing input parameter for Step
3271 1 and Step 3 */
3272 hhash->HashKeyCount = hhash->Init.KeySize; /* Key size, HMAC_Processing input parameter for Step 1
3273 and Step 3 */
3274 }
3275
3276 /* Carry out HMAC processing */
3277 return HMAC_Processing(hhash, Timeout);
3278
3279 }
3280 else
3281 {
3282 return HAL_BUSY;
3283 }
3284}
3285
3286
3300HAL_StatusTypeDef HMAC_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
3301 uint8_t *pOutBuffer,
3302 uint32_t Algorithm)
3303{
3304 HAL_HASH_StateTypeDef State_tmp = hhash->State;
3305
3306 /* If State is ready or suspended, start or resume IT-based HASH processing */
3307 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3308 {
3309 /* Check input parameters */
3310 if ((pInBuffer == NULL) || (Size == 0U) || (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U)
3311 || (pOutBuffer == NULL))
3312 {
3313 hhash->State = HAL_HASH_STATE_READY;
3314 return HAL_ERROR;
3315 }
3316
3317 /* Process Locked */
3318 __HAL_LOCK(hhash);
3319
3320 /* Change the HASH state */
3321 hhash->State = HAL_HASH_STATE_BUSY;
3322
3323 /* Initialize IT counter */
3324 hhash->HashITCounter = 1;
3325
3326 /* Check if initialization phase has already be performed */
3327 if (hhash->Phase == HAL_HASH_PHASE_READY)
3328 {
3329 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
3330 if (hhash->Init.KeySize > 64U)
3331 {
3332 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3333 Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3334 }
3335 else
3336 {
3337 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3338 Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3339 }
3340
3341 /* Resort to hhash internal fields hhash->pHashInBuffPtr and hhash->HashInCount
3342 to feed the Peripheral whatever the HMAC step.
3343 Lines below are set to start HMAC Step 1 processing where key is entered first. */
3344 hhash->HashInCount = hhash->Init.KeySize; /* Key size */
3345 hhash->pHashInBuffPtr = hhash->Init.pKey ; /* Key address */
3346
3347 /* Store input and output parameters in handle fields to manage steps transition
3348 or possible HMAC suspension/resumption */
3349 hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address */
3350 hhash->pHashMsgBuffPtr = pInBuffer; /* Input message address */
3351 hhash->HashBuffSize = Size; /* Input message size (in bytes) */
3352 hhash->pHashOutBuffPtr = pOutBuffer; /* Output digest address */
3353
3354 /* Configure the number of valid bits in last word of the key */
3355 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
3356
3357 /* Set the phase to Step 1 */
3358 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
3359 }
3360 else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3))
3361 {
3362 /* Restart IT-based HASH processing after Step 1 or Step 3 suspension */
3363
3364 }
3365 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
3366 {
3367 /* Restart IT-based HASH processing after Step 2 suspension */
3368
3369 }
3370 else
3371 {
3372 /* Error report as phase incorrect */
3373 /* Process Unlock */
3374 __HAL_UNLOCK(hhash);
3375 hhash->State = HAL_HASH_STATE_READY;
3376 return HAL_ERROR;
3377 }
3378
3379 /* Process Unlock */
3380 __HAL_UNLOCK(hhash);
3381
3382 /* Enable Interrupts */
3383 __HAL_HASH_ENABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
3384
3385 /* Return function status */
3386 return HAL_OK;
3387 }
3388 else
3389 {
3390 return HAL_BUSY;
3391 }
3392
3393}
3394
3395
3411HAL_StatusTypeDef HMAC_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size,
3412 uint32_t Algorithm)
3413{
3414 uint32_t inputaddr;
3415 uint32_t inputSize;
3416 HAL_StatusTypeDef status ;
3417 HAL_HASH_StateTypeDef State_tmp = hhash->State;
3418 /* Make sure the input buffer size (in bytes) is a multiple of 4 when digest calculation
3419 is disabled (multi-buffer HMAC processing, MDMAT bit to be set) */
3420 assert_param(IS_HMAC_DMA_MULTIBUFFER_SIZE(hhash, Size));
3421 /* If State is ready or suspended, start or resume DMA-based HASH processing */
3422 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3423 {
3424 /* Check input parameters */
3425 if ((pInBuffer == NULL) || (Size == 0U) || (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U) ||
3426 /* Check phase coherency. Phase must be
3427 either READY (fresh start)
3428 or one of HMAC PROCESS steps (multi-buffer HASH management) */
3429 ((hhash->Phase != HAL_HASH_PHASE_READY) && (!(IS_HMAC_PROCESSING(hhash)))))
3430 {
3431 hhash->State = HAL_HASH_STATE_READY;
3432 return HAL_ERROR;
3433 }
3434
3435
3436 /* Process Locked */
3437 __HAL_LOCK(hhash);
3438
3439 /* If not a case of resumption after suspension */
3440 if (hhash->State == HAL_HASH_STATE_READY)
3441 {
3442 /* Check whether or not initialization phase has already be performed */
3443 if (hhash->Phase == HAL_HASH_PHASE_READY)
3444 {
3445 /* Change the HASH state */
3446 hhash->State = HAL_HASH_STATE_BUSY;
3447#if defined(HASH_CR_MDMAT)
3448 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits.
3449 At the same time, ensure MDMAT bit is cleared. */
3450 if (hhash->Init.KeySize > 64U)
3451 {
3452 MODIFY_REG(HASH->CR, HASH_CR_MDMAT | HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3453 Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3454 }
3455 else
3456 {
3457 MODIFY_REG(HASH->CR, HASH_CR_MDMAT | HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3458 Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3459 }
3460#else
3461 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
3462 if (hhash->Init.KeySize > 64U)
3463 {
3464 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3465 Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3466 }
3467 else
3468 {
3469 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3470 Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3471 }
3472#endif /* HASH_CR_MDMAT*/
3473 /* Store input aparameters in handle fields to manage steps transition
3474 or possible HMAC suspension/resumption */
3475 hhash->HashInCount = hhash->Init.KeySize; /* Initial size for first DMA transfer (key size) */
3476 hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address */
3477 hhash->pHashInBuffPtr = hhash->Init.pKey ; /* First address passed to DMA (key address at Step 1) */
3478 hhash->pHashMsgBuffPtr = pInBuffer; /* Input data address */
3479 hhash->HashBuffSize = Size; /* input data size (in bytes) */
3480
3481 /* Set DMA input parameters */
3482 inputaddr = (uint32_t)(hhash->Init.pKey); /* Address passed to DMA (start by entering Key message) */
3483 inputSize = hhash->Init.KeySize; /* Size for first DMA transfer (in bytes) */
3484
3485 /* Configure the number of valid bits in last word of the key */
3486 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
3487
3488 /* Set the phase to Step 1 */
3489 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
3490
3491 }
3492 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
3493 {
3494 /* Process a new input data message in case of multi-buffer HMAC processing
3495 (this is not a resumption case) */
3496
3497 /* Change the HASH state */
3498 hhash->State = HAL_HASH_STATE_BUSY;
3499
3500 /* Save input parameters to be able to manage possible suspension/resumption */
3501 hhash->HashInCount = Size; /* Input message address */
3502 hhash->pHashInBuffPtr = pInBuffer; /* Input message size in bytes */
3503
3504 /* Set DMA input parameters */
3505 inputaddr = (uint32_t)pInBuffer; /* Input message address */
3506 inputSize = Size; /* Input message size in bytes */
3507
3508 if (hhash->DigestCalculationDisable == RESET)
3509 {
3510 /* This means this is the last buffer of the multi-buffer sequence: DCAL needs to be set. */
3511#if defined(HASH_CR_MDMAT)
3512 __HAL_HASH_RESET_MDMAT();
3513#endif /* HASH_CR_MDMAT*/
3514 __HAL_HASH_SET_NBVALIDBITS(inputSize);
3515 }
3516 }
3517 else
3518 {
3519 /* Phase not aligned with handle READY state */
3520 __HAL_UNLOCK(hhash);
3521 /* Return function status */
3522 return HAL_ERROR;
3523 }
3524 }
3525 else
3526 {
3527 /* Resumption case (phase may be Step 1, 2 or 3) */
3528
3529 /* Change the HASH state */
3530 hhash->State = HAL_HASH_STATE_BUSY;
3531
3532 /* Set DMA input parameters at resumption location;
3533 inputaddr and inputSize are not set to the API input parameters
3534 but to those saved beforehand by HAL_HASH_DMAFeed_ProcessSuspend() when the
3535 processing was suspended. */
3536 inputaddr = (uint32_t)(hhash->pHashInBuffPtr); /* Input message address */
3537 inputSize = hhash->HashInCount; /* Input message size in bytes */
3538 }
3539
3540
3541 /* Set the HASH DMA transfer complete callback */
3542 hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
3543 /* Set the DMA error callback */
3544 hhash->hdmain->XferErrorCallback = HASH_DMAError;
3545
3546 /* Store number of words already pushed to manage proper DMA processing suspension */
3547 hhash->NbWordsAlreadyPushed = HASH_NBW_PUSHED();
3548
3549 /* Enable the DMA In DMA stream */
3550 status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, \
3551 (((inputSize % 4U) != 0U) ? ((inputSize + (4U - (inputSize % 4U))) / 4U) \
3552 : (inputSize / 4U)));
3553
3554 /* Enable DMA requests */
3555 SET_BIT(HASH->CR, HASH_CR_DMAE);
3556
3557 /* Process Unlocked */
3558 __HAL_UNLOCK(hhash);
3559
3560 /* Return function status */
3561 if (status != HAL_OK)
3562 {
3563 /* Update HASH state machine to error */
3564 hhash->State = HAL_HASH_STATE_ERROR;
3565 }
3566
3567 /* Return function status */
3568 return status;
3569 }
3570 else
3571 {
3572 return HAL_BUSY;
3573 }
3574}
3578
3579#endif /* HAL_HASH_MODULE_ENABLED */
3580
3584#endif /* HASH*/
3588
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
struct __DMA_HandleTypeDef DMA_HandleTypeDef
DMA handle Structure definition.
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
#define assert_param(expr)
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef
HAL Status structures definition.
@ HAL_TIMEOUT
@ HAL_ERROR
@ HAL_OK
@ HAL_BUSY
#define __HAL_UNLOCK(__HANDLE__)
#define HAL_MAX_DELAY
@ HAL_UNLOCKED
#define __HAL_LOCK(__HANDLE__)