STM32F4xx HAL Documentation
Hardware Abstraction Layer for STM32F4 familiy
Loading...
Searching...
No Matches
stm32f4xx_hal_hash.c
Go to the documentation of this file.
1
208/* Includes ------------------------------------------------------------------*/
209#include "stm32f4xx_hal.h"
210
211
215#if defined (HASH)
216
222#ifdef HAL_HASH_MODULE_ENABLED
223
224/* Private typedef -----------------------------------------------------------*/
225/* Private define ------------------------------------------------------------*/
233#define HASH_DIGEST_CALCULATION_NOT_STARTED ((uint32_t)0x00000000U)
234#define HASH_DIGEST_CALCULATION_STARTED ((uint32_t)0x00000001U)
242#define HASH_NUMBER_OF_CSR_REGISTERS 54U
250#define HASH_TIMEOUTVALUE 1000U
258#define HASH_DMA_SUSPENSION_WORDS_LIMIT 20U
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(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, uint8_t *pInBuffer, uint32_t Size);
280static uint32_t HASH_Write_Block_Data(HASH_HandleTypeDef *hhash);
281static HAL_StatusTypeDef HMAC_Processing(HASH_HandleTypeDef *hhash, uint32_t Timeout);
329{
330 /* Check the hash handle allocation */
331 if (hhash == NULL)
332 {
333 return HAL_ERROR;
334 }
335
336 /* Check the parameters */
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 */
381 /* Reset suspension request flag */
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 */
389#endif /* HASH_CR_MDMAT */
390 /* Reset HASH handle status */
391 hhash->Status = HAL_OK;
392
393 /* Set the HASH state to Ready */
395
396 /* Initialise the error code */
398
399 /* Return function status */
400 return HAL_OK;
401}
402
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 */
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 */
448
449 /* Initialise the error code */
451
452 /* Reset multi buffers accumulation flag */
453 hhash->Accumulation = 0U;
454
455 /* Return function status */
456 return HAL_OK;
457}
458
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
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
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
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
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
769HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer,
770 uint32_t Timeout)
771{
772 return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_MD5);
773}
774
795HAL_StatusTypeDef HAL_HASH_MD5_Accmlt(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
796{
797 return HASH_Accumulate(hhash, pInBuffer, Size, HASH_ALGOSELECTION_MD5);
798}
799
810HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_End(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size,
811 uint8_t *pOutBuffer, uint32_t Timeout)
812{
813 return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_MD5);
814}
815
827HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer,
828 uint32_t Timeout)
829{
830 return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA1);
831}
832
853HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
854{
855 return HASH_Accumulate(hhash, pInBuffer, Size, HASH_ALGOSELECTION_SHA1);
856}
857
868HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_End(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size,
869 uint8_t *pOutBuffer, uint32_t Timeout)
870{
871 return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA1);
872}
873
916HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size,
917 uint8_t *pOutBuffer)
918{
919 return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_MD5);
920}
921
940HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
941{
942 return HASH_Accumulate_IT(hhash, pInBuffer, Size, HASH_ALGOSELECTION_MD5);
943}
944
954HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_End_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size,
955 uint8_t *pOutBuffer)
956{
957 return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_MD5);
958}
959
970HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size,
971 uint8_t *pOutBuffer)
972{
973 return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_SHA1);
974}
975
976
995HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
996{
997 return HASH_Accumulate_IT(hhash, pInBuffer, Size, HASH_ALGOSELECTION_SHA1);
998}
999
1009HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_End_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size,
1010 uint8_t *pOutBuffer)
1011{
1012 return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_SHA1);
1013}
1014
1025{
1026 hhash->Status = HASH_IT(hhash);
1027 if (hhash->Status != HAL_OK)
1028 {
1029 hhash->ErrorCode |= HAL_HASH_ERROR_IT;
1030#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1031 hhash->ErrorCallback(hhash);
1032#else
1034#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1035 /* After error handling by code user, reset HASH handle HAL status */
1036 hhash->Status = HAL_OK;
1037 }
1038}
1039
1082HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1083{
1084 return HASH_Start_DMA(hhash, pInBuffer, Size, HASH_ALGOSELECTION_MD5);
1085}
1086
1097HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
1098{
1099 return HASH_Finish(hhash, pOutBuffer, Timeout);
1100}
1101
1112HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1113{
1114 return HASH_Start_DMA(hhash, pInBuffer, Size, HASH_ALGOSELECTION_SHA1);
1115}
1116
1117
1128HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
1129{
1130 return HASH_Finish(hhash, pOutBuffer, Timeout);
1131}
1132
1169HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer,
1170 uint32_t Timeout)
1171{
1172 return HMAC_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_MD5);
1173}
1174
1188HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer,
1189 uint32_t Timeout)
1190{
1191 return HMAC_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA1);
1192}
1193
1230HAL_StatusTypeDef HAL_HMAC_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size,
1231 uint8_t *pOutBuffer)
1232{
1233 return HMAC_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_MD5);
1234}
1235
1248HAL_StatusTypeDef HAL_HMAC_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size,
1249 uint8_t *pOutBuffer)
1250{
1251 return HMAC_Start_IT(hhash, pInBuffer, Size, pOutBuffer, HASH_ALGOSELECTION_SHA1);
1252}
1253
1302HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1303{
1304 return HMAC_Start_DMA(hhash, pInBuffer, Size, HASH_ALGOSELECTION_MD5);
1305}
1306
1307
1327HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1328{
1329 return HMAC_Start_DMA(hhash, pInBuffer, Size, HASH_ALGOSELECTION_SHA1);
1330}
1331
1375{
1376 return hhash->State;
1377}
1378
1379
1388{
1389 return hhash->Status;
1390}
1391
1405void HAL_HASH_ContextSaving(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer)
1406{
1407 uint32_t mem_ptr = (uint32_t)pMemBuffer;
1408 uint32_t csr_ptr = (uint32_t)HASH->CSR;
1409 uint32_t i;
1410
1411 /* Prevent unused argument(s) compilation warning */
1412 UNUSED(hhash);
1413
1414 /* Save IMR register content */
1415 *(uint32_t *)(mem_ptr) = READ_BIT(HASH->IMR, HASH_IT_DINI | HASH_IT_DCI);
1416 mem_ptr += 4U;
1417 /* Save STR register content */
1418 *(uint32_t *)(mem_ptr) = READ_BIT(HASH->STR, HASH_STR_NBLW);
1419 mem_ptr += 4U;
1420 /* Save CR register content */
1421#if defined(HASH_CR_MDMAT)
1422 *(uint32_t *)(mem_ptr) = READ_BIT(HASH->CR, HASH_CR_DMAE | HASH_CR_DATATYPE | HASH_CR_MODE | HASH_CR_ALGO |
1423 HASH_CR_LKEY | HASH_CR_MDMAT);
1424#else
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);
1427#endif /* HASH_CR_MDMAT*/
1428 mem_ptr += 4U;
1429 /* By default, save all CSRs registers */
1430 for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--)
1431 {
1432 *(uint32_t *)(mem_ptr) = *(uint32_t *)(csr_ptr);
1433 mem_ptr += 4U;
1434 csr_ptr += 4U;
1435 }
1436}
1437
1438
1451void HAL_HASH_ContextRestoring(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer)
1452{
1453 uint32_t mem_ptr = (uint32_t)pMemBuffer;
1454 uint32_t csr_ptr = (uint32_t)HASH->CSR;
1455 uint32_t i;
1456
1457 /* Prevent unused argument(s) compilation warning */
1458 UNUSED(hhash);
1459
1460 /* Restore IMR register content */
1461 WRITE_REG(HASH->IMR, (*(uint32_t *)(mem_ptr)));
1462 mem_ptr += 4U;
1463 /* Restore STR register content */
1464 WRITE_REG(HASH->STR, (*(uint32_t *)(mem_ptr)));
1465 mem_ptr += 4U;
1466 /* Restore CR register content */
1467 WRITE_REG(HASH->CR, (*(uint32_t *)(mem_ptr)));
1468 mem_ptr += 4U;
1469
1470 /* Reset the HASH processor before restoring the Context
1471 Swap Registers (CSR) */
1473
1474 /* By default, restore all CSR registers */
1475 for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--)
1476 {
1477 WRITE_REG((*(uint32_t *)(csr_ptr)), (*(uint32_t *)(mem_ptr)));
1478 mem_ptr += 4U;
1479 csr_ptr += 4U;
1480 }
1481}
1482
1483
1495{
1496 /* Set Handle Suspend Request field */
1498}
1499
1510{
1511 uint32_t tmp_remaining_DMATransferSize_inWords;
1512 uint32_t tmp_initial_DMATransferSize_inWords;
1513 uint32_t tmp_words_already_pushed;
1514
1515 if (hhash->State == HAL_HASH_STATE_READY)
1516 {
1517 return HAL_ERROR;
1518 }
1519 else
1520 {
1521
1522 /* Make sure there is enough time to suspend the processing */
1523 tmp_remaining_DMATransferSize_inWords = ((DMA_Stream_TypeDef *)hhash->hdmain->Instance)->NDTR;
1524
1525 if (tmp_remaining_DMATransferSize_inWords <= HASH_DMA_SUSPENSION_WORDS_LIMIT)
1526 {
1527 /* No suspension attempted since almost to the end of the transferred data. */
1528 /* Best option for user code is to wrap up low priority message hashing */
1529 return HAL_ERROR;
1530 }
1531
1532 /* Wait for BUSY flag to be reset */
1534 {
1535 return HAL_TIMEOUT;
1536 }
1537
1538 if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS) != RESET)
1539 {
1540 return HAL_ERROR;
1541 }
1542
1543 /* Wait for BUSY flag to be set */
1545 {
1546 return HAL_TIMEOUT;
1547 }
1548 /* Disable DMA channel */
1549 /* Note that the Abort function will
1550 - Clear the transfer error flags
1551 - Unlock
1552 - Set the State
1553 */
1554 if (HAL_DMA_Abort(hhash->hdmain) != HAL_OK)
1555 {
1556 return HAL_ERROR;
1557 }
1558
1559 /* Clear DMAE bit */
1560 CLEAR_BIT(HASH->CR, HASH_CR_DMAE);
1561
1562 /* Wait for BUSY flag to be reset */
1564 {
1565 return HAL_TIMEOUT;
1566 }
1567
1568 if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS) != RESET)
1569 {
1570 return HAL_ERROR;
1571 }
1572
1573 /* At this point, DMA interface is disabled and no transfer is on-going */
1574 /* Retrieve from the DMA handle how many words remain to be written */
1575 tmp_remaining_DMATransferSize_inWords = ((DMA_Stream_TypeDef *)hhash->hdmain->Instance)->NDTR;
1576
1577 if (tmp_remaining_DMATransferSize_inWords == 0U)
1578 {
1579 /* All the DMA transfer is actually done. Suspension occurred at the very end
1580 of the transfer. Either the digest computation is about to start (HASH case)
1581 or processing is about to move from one step to another (HMAC case).
1582 In both cases, the processing can't be suspended at this point. It is
1583 safer to
1584 - retrieve the low priority block digest before starting the high
1585 priority block processing (HASH case)
1586 - re-attempt a new suspension (HMAC case)
1587 */
1588 return HAL_ERROR;
1589 }
1590 else
1591 {
1592
1593 /* Compute how many words were supposed to be transferred by DMA */
1594 tmp_initial_DMATransferSize_inWords = (((hhash->HashInCount % 4U) != 0U) ? \
1595 ((hhash->HashInCount + 3U) / 4U) : (hhash->HashInCount / 4U));
1596
1597 /* If discrepancy between the number of words reported by DMA Peripheral and
1598 the numbers of words entered as reported by HASH Peripheral, correct it */
1599 /* tmp_words_already_pushed reflects the number of words that were already pushed before
1600 the start of DMA transfer (multi-buffer processing case) */
1601 tmp_words_already_pushed = hhash->NbWordsAlreadyPushed;
1602 if (((tmp_words_already_pushed + tmp_initial_DMATransferSize_inWords - \
1603 tmp_remaining_DMATransferSize_inWords) % 16U) != HASH_NBW_PUSHED())
1604 {
1605 tmp_remaining_DMATransferSize_inWords--; /* one less word to be transferred again */
1606 }
1607
1608 /* Accordingly, update the input pointer that points at the next word to be
1609 transferred to the Peripheral by DMA */
1610 hhash->pHashInBuffPtr += 4U * (tmp_initial_DMATransferSize_inWords - tmp_remaining_DMATransferSize_inWords) ;
1611
1612 /* And store in HashInCount the remaining size to transfer (in bytes) */
1613 hhash->HashInCount = 4U * tmp_remaining_DMATransferSize_inWords;
1614
1615 }
1616
1617 /* Set State as suspended */
1619
1620 return HAL_OK;
1621
1622 }
1623}
1624
1631{
1632 /* Return HASH Error Code */
1633 return hhash->ErrorCode;
1634}
1656{
1657 HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1658 uint32_t inputaddr;
1659 uint32_t buffersize;
1660 HAL_StatusTypeDef status;
1661
1662 if (hhash->State != HAL_HASH_STATE_SUSPENDED)
1663 {
1664
1665 /* Disable the DMA transfer */
1666 CLEAR_BIT(HASH->CR, HASH_CR_DMAE);
1667
1668 if (READ_BIT(HASH->CR, HASH_CR_MODE) == 0U)
1669 {
1670 /* If no HMAC processing, input data transfer is now over */
1671
1672 /* Change the HASH state to ready */
1673 hhash->State = HAL_HASH_STATE_READY;
1674
1675 /* Call Input data transfer complete call back */
1676#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1677 hhash->InCpltCallback(hhash);
1678#else
1680#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1681
1682 }
1683 else
1684 {
1685 /* HMAC processing: depending on the current HMAC step and whether or
1686 not multi-buffer processing is on-going, the next step is initiated
1687 and MDMAT bit is set. */
1688
1689
1690 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)
1691 {
1692 /* This is the end of HMAC processing */
1693
1694 /* Change the HASH state to ready */
1695 hhash->State = HAL_HASH_STATE_READY;
1696
1697 /* Call Input data transfer complete call back
1698 (note that the last DMA transfer was that of the key
1699 for the outer HASH operation). */
1700#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1701 hhash->InCpltCallback(hhash);
1702#else
1704#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1705
1706 return;
1707 }
1708 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
1709 {
1710 inputaddr = (uint32_t)hhash->pHashMsgBuffPtr; /* DMA transfer start address */
1711 buffersize = hhash->HashBuffSize; /* DMA transfer size (in bytes) */
1712 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; /* Move phase from Step 1 to Step 2 */
1713
1714 /* In case of suspension request, save the new starting parameters */
1715 hhash->HashInCount = hhash->HashBuffSize; /* Initial DMA transfer size (in bytes) */
1716 hhash->pHashInBuffPtr = hhash->pHashMsgBuffPtr ; /* DMA transfer start address */
1717
1718 hhash->NbWordsAlreadyPushed = 0U; /* Reset number of words already pushed */
1719#if defined(HASH_CR_MDMAT)
1720 /* Check whether or not digest calculation must be disabled (in case of multi-buffer HMAC processing) */
1721 if (hhash->DigestCalculationDisable != RESET)
1722 {
1723 /* Digest calculation is disabled: Step 2 must start with MDMAT bit set,
1724 no digest calculation will be triggered at the end of the input buffer feeding to the Peripheral */
1726 }
1727#endif /* HASH_CR_MDMAT*/
1728 }
1729 else /*case (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)*/
1730 {
1731 if (hhash->DigestCalculationDisable != RESET)
1732 {
1733 /* No automatic move to Step 3 as a new message buffer will be fed to the Peripheral
1734 (case of multi-buffer HMAC processing):
1735 DCAL must not be set.
1736 Phase remains in Step 2, MDMAT remains set at this point.
1737 Change the HASH state to ready and call Input data transfer complete call back. */
1738 hhash->State = HAL_HASH_STATE_READY;
1739#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1740 hhash->InCpltCallback(hhash);
1741#else
1743#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1744 return ;
1745 }
1746 else
1747 {
1748 /* Digest calculation is not disabled (case of single buffer input or last buffer
1749 of multi-buffer HMAC processing) */
1750 inputaddr = (uint32_t)hhash->Init.pKey; /* DMA transfer start address */
1751 buffersize = hhash->Init.KeySize; /* DMA transfer size (in bytes) */
1752 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; /* Move phase from Step 2 to Step 3 */
1753 /* In case of suspension request, save the new starting parameters */
1754 hhash->HashInCount = hhash->Init.KeySize; /* Initial size for second DMA transfer (input data) */
1755 hhash->pHashInBuffPtr = hhash->Init.pKey ; /* address passed to DMA, now entering data message */
1756
1757 hhash->NbWordsAlreadyPushed = 0U; /* Reset number of words already pushed */
1758 }
1759 }
1760
1761 /* Configure the Number of valid bits in last word of the message */
1762 __HAL_HASH_SET_NBVALIDBITS(buffersize);
1763
1764 /* Set the HASH DMA transfer completion call back */
1766
1767 /* Enable the DMA In DMA stream */
1768 status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, \
1769 (((buffersize % 4U) != 0U) ? ((buffersize + (4U - (buffersize % 4U))) / 4U) : \
1770 (buffersize / 4U)));
1771
1772 /* Enable DMA requests */
1773 SET_BIT(HASH->CR, HASH_CR_DMAE);
1774
1775 /* Return function status */
1776 if (status != HAL_OK)
1777 {
1778 /* Update HASH state machine to error */
1779 hhash->State = HAL_HASH_STATE_ERROR;
1780 }
1781 else
1782 {
1783 /* Change HASH state */
1784 hhash->State = HAL_HASH_STATE_BUSY;
1785 }
1786 }
1787 }
1788
1789 return;
1790}
1791
1800{
1801 HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1802
1803 if (hhash->State != HAL_HASH_STATE_SUSPENDED)
1804 {
1805 hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
1806 /* Set HASH state to ready to prevent any blocking issue in user code
1807 present in HAL_HASH_ErrorCallback() */
1808 hhash->State = HAL_HASH_STATE_READY;
1809 /* Set HASH handle status to error */
1810 hhash->Status = HAL_ERROR;
1811#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1812 hhash->ErrorCallback(hhash);
1813#else
1815#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1816 /* After error handling by code user, reset HASH handle HAL status */
1817 hhash->Status = HAL_OK;
1818
1819 }
1820}
1821
1833static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
1834{
1835 uint32_t buffercounter;
1836 __IO uint32_t inputaddr = (uint32_t) pInBuffer;
1837 uint32_t tmp;
1838
1839 for (buffercounter = 0U; buffercounter < Size / 4U; buffercounter++)
1840 {
1841 /* Write input data 4 bytes at a time */
1842 HASH->DIN = *(uint32_t *)inputaddr;
1843 inputaddr += 4U;
1844
1845 /* If the suspension flag has been raised and if the processing is not about
1846 to end, suspend processing */
1847 if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter * 4 + 4U) < Size))
1848 {
1849 /* wait for flag BUSY not set before Wait for DINIS = 1*/
1850 if (buffercounter * 4 >= 64U)
1851 {
1853 {
1854 return HAL_TIMEOUT;
1855 }
1856 }
1857 /* Wait for DINIS = 1, which occurs when 16 32-bit locations are free
1858 in the input buffer */
1860 {
1861 /* Reset SuspendRequest */
1863
1864 /* Depending whether the key or the input data were fed to the Peripheral, the feeding point
1865 reached at suspension time is not saved in the same handle fields */
1866 if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2))
1867 {
1868 /* Save current reading and writing locations of Input and Output buffers */
1869 hhash->pHashInBuffPtr = (uint8_t *)inputaddr;
1870 /* Save the number of bytes that remain to be processed at this point */
1871 hhash->HashInCount = Size - (buffercounter * 4 + 4U);
1872 }
1873 else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3))
1874 {
1875 /* Save current reading and writing locations of Input and Output buffers */
1876 hhash->pHashKeyBuffPtr = (uint8_t *)inputaddr;
1877 /* Save the number of bytes that remain to be processed at this point */
1878 hhash->HashKeyCount = Size - (buffercounter * 4 + 4U);
1879 }
1880 else
1881 {
1882 /* Unexpected phase: unlock process and report error */
1883 hhash->State = HAL_HASH_STATE_READY;
1884 __HAL_UNLOCK(hhash);
1885 return HAL_ERROR;
1886 }
1887
1888 /* Set the HASH state to Suspended and exit to stop entering data */
1890
1891 return HAL_OK;
1892 } /* if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) */
1893 } /* if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4) < Size)) */
1894 } /* for(buffercounter = 0; buffercounter < Size; buffercounter+=4) */
1895
1896 /* At this point, all the data have been entered to the Peripheral: exit */
1897
1898 if (Size % 4U != 0U)
1899 {
1900 if (hhash->Init.DataType == HASH_DATATYPE_16B)
1901 {
1902 /* Write remaining input data */
1903
1904 if (Size % 4U <= 2)
1905 {
1906 HASH->DIN = (uint32_t) * (uint16_t *)inputaddr;
1907 }
1908 if (Size % 4U == 3)
1909 {
1910 HASH->DIN = *(uint32_t *)inputaddr;
1911 }
1912
1913 }
1914 else if ((hhash->Init.DataType == HASH_DATATYPE_8B)
1915 || (hhash->Init.DataType == HASH_DATATYPE_1B)) /* byte swap or bit swap or */
1916 {
1917 /* Write remaining input data */
1918 if (Size % 4U == 1)
1919 {
1920 HASH->DIN = (uint32_t) * (uint8_t *)inputaddr;
1921 }
1922 if (Size % 4U == 2)
1923 {
1924 HASH->DIN = (uint32_t) * (uint16_t *)inputaddr;
1925 }
1926 if (Size % 4U == 3)
1927 {
1928 tmp = *(uint8_t *)inputaddr;
1929 tmp |= *(uint8_t *)(inputaddr + 1U) << 8U ;
1930 tmp |= *(uint8_t *)(inputaddr + 2U) << 16U;
1931 HASH->DIN = tmp;
1932 }
1933
1934 }
1935 else
1936 {
1937 HASH->DIN = *(uint32_t *)inputaddr;
1938 }
1939 /*hhash->HashInCount += 4U;*/
1940 }
1941
1942
1943 return HAL_OK;
1944}
1945
1952static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
1953{
1954 uint32_t msgdigest = (uint32_t)pMsgDigest;
1955
1956 switch (Size)
1957 {
1958 /* Read the message digest */
1959 case 16: /* MD5 */
1960 *(uint32_t *)(msgdigest) = __REV(HASH->HR[0]);
1961 msgdigest += 4U;
1962 *(uint32_t *)(msgdigest) = __REV(HASH->HR[1]);
1963 msgdigest += 4U;
1964 *(uint32_t *)(msgdigest) = __REV(HASH->HR[2]);
1965 msgdigest += 4U;
1966 *(uint32_t *)(msgdigest) = __REV(HASH->HR[3]);
1967 break;
1968 case 20: /* SHA1 */
1969 *(uint32_t *)(msgdigest) = __REV(HASH->HR[0]);
1970 msgdigest += 4U;
1971 *(uint32_t *)(msgdigest) = __REV(HASH->HR[1]);
1972 msgdigest += 4U;
1973 *(uint32_t *)(msgdigest) = __REV(HASH->HR[2]);
1974 msgdigest += 4U;
1975 *(uint32_t *)(msgdigest) = __REV(HASH->HR[3]);
1976 msgdigest += 4U;
1977 *(uint32_t *)(msgdigest) = __REV(HASH->HR[4]);
1978 break;
1979 case 28: /* SHA224 */
1980 *(uint32_t *)(msgdigest) = __REV(HASH->HR[0]);
1981 msgdigest += 4U;
1982 *(uint32_t *)(msgdigest) = __REV(HASH->HR[1]);
1983 msgdigest += 4U;
1984 *(uint32_t *)(msgdigest) = __REV(HASH->HR[2]);
1985 msgdigest += 4U;
1986 *(uint32_t *)(msgdigest) = __REV(HASH->HR[3]);
1987 msgdigest += 4U;
1988 *(uint32_t *)(msgdigest) = __REV(HASH->HR[4]);
1989#if defined(HASH_CR_MDMAT)
1990 msgdigest += 4U;
1991 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1992 msgdigest += 4U;
1993 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1994#endif /* HASH_CR_MDMAT*/
1995 break;
1996 case 32: /* SHA256 */
1997 *(uint32_t *)(msgdigest) = __REV(HASH->HR[0]);
1998 msgdigest += 4U;
1999 *(uint32_t *)(msgdigest) = __REV(HASH->HR[1]);
2000 msgdigest += 4U;
2001 *(uint32_t *)(msgdigest) = __REV(HASH->HR[2]);
2002 msgdigest += 4U;
2003 *(uint32_t *)(msgdigest) = __REV(HASH->HR[3]);
2004 msgdigest += 4U;
2005 *(uint32_t *)(msgdigest) = __REV(HASH->HR[4]);
2006#if defined(HASH_CR_MDMAT)
2007 msgdigest += 4U;
2008 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
2009 msgdigest += 4U;
2010 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
2011 msgdigest += 4U;
2012 *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
2013#endif /* HASH_CR_MDMAT*/
2014 break;
2015 default:
2016 break;
2017 }
2018}
2019
2020
2021
2030static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status,
2031 uint32_t Timeout)
2032{
2033 uint32_t tickstart = HAL_GetTick();
2034
2035 /* Wait until flag is set */
2036 if (Status == RESET)
2037 {
2038 while (__HAL_HASH_GET_FLAG(Flag) == RESET)
2039 {
2040 /* Check for the Timeout */
2041 if (Timeout != HAL_MAX_DELAY)
2042 {
2043 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2044 {
2045 /* Set State to Ready to be able to restart later on */
2046 hhash->State = HAL_HASH_STATE_READY;
2047 /* Store time out issue in handle status */
2048 hhash->Status = HAL_TIMEOUT;
2049
2050 /* Process Unlocked */
2051 __HAL_UNLOCK(hhash);
2052
2053 return HAL_TIMEOUT;
2054 }
2055 }
2056 }
2057 }
2058 else
2059 {
2060 while (__HAL_HASH_GET_FLAG(Flag) != RESET)
2061 {
2062 /* Check for the Timeout */
2063 if (Timeout != HAL_MAX_DELAY)
2064 {
2065 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2066 {
2067 /* Set State to Ready to be able to restart later on */
2068 hhash->State = HAL_HASH_STATE_READY;
2069 /* Store time out issue in handle status */
2070 hhash->Status = HAL_TIMEOUT;
2071
2072 /* Process Unlocked */
2073 __HAL_UNLOCK(hhash);
2074
2075 return HAL_TIMEOUT;
2076 }
2077 }
2078 }
2079 }
2080 return HAL_OK;
2081}
2082
2083
2094{
2095 if (hhash->State == HAL_HASH_STATE_BUSY)
2096 {
2097 /* ITCounter must not be equal to 0 at this point. Report an error if this is the case. */
2098 if (hhash->HashITCounter == 0U)
2099 {
2100 /* Disable Interrupts */
2102 /* HASH state set back to Ready to prevent any issue in user code
2103 present in HAL_HASH_ErrorCallback() */
2104 hhash->State = HAL_HASH_STATE_READY;
2105 return HAL_ERROR;
2106 }
2107 else if (hhash->HashITCounter == 1U)
2108 {
2109 /* This is the first call to HASH_IT, the first input data are about to be
2110 entered in the Peripheral. A specific processing is carried out at this point to
2111 start-up the processing. */
2112 hhash->HashITCounter = 2U;
2113 }
2114 else
2115 {
2116 /* Cruise speed reached, HashITCounter remains equal to 3 until the end of
2117 the HASH processing or the end of the current step for HMAC processing. */
2118 hhash->HashITCounter = 3U;
2119 }
2120
2121 /* If digest is ready */
2123 {
2124 /* Read the digest */
2126
2127 /* Disable Interrupts */
2129 /* Change the HASH state */
2130 hhash->State = HAL_HASH_STATE_READY;
2131 /* Reset HASH state machine */
2132 hhash->Phase = HAL_HASH_PHASE_READY;
2133 /* Call digest computation complete call back */
2134#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2135 hhash->DgstCpltCallback(hhash);
2136#else
2138#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2139
2140 return HAL_OK;
2141 }
2142
2143 /* If Peripheral ready to accept new data */
2145 {
2146
2147 /* If the suspension flag has been raised and if the processing is not about
2148 to end, suspend processing */
2149 if ((hhash->HashInCount != 0U) && (hhash->SuspendRequest == HAL_HASH_SUSPEND))
2150 {
2151 /* Disable Interrupts */
2153
2154 /* Reset SuspendRequest */
2156
2157 /* Change the HASH state */
2159
2160 return HAL_OK;
2161 }
2162
2163 /* Enter input data in the Peripheral through HASH_Write_Block_Data() call and
2164 check whether the digest calculation has been triggered */
2166 {
2167 /* Call Input data transfer complete call back
2168 (called at the end of each step for HMAC) */
2169#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2170 hhash->InCpltCallback(hhash);
2171#else
2173#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2174
2175 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
2176 {
2177 /* Wait until Peripheral is not busy anymore */
2179 {
2180 /* Disable Interrupts */
2182 return HAL_TIMEOUT;
2183 }
2184 /* Initialization start for HMAC STEP 2 */
2185 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; /* Move phase from Step 1 to Step 2 */
2186 __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); /* Set NBLW for the input message */
2187 hhash->HashInCount = hhash->HashBuffSize; /* Set the input data size (in bytes) */
2188 hhash->pHashInBuffPtr = hhash->pHashMsgBuffPtr; /* Set the input data address */
2189 hhash->HashITCounter = 1; /* Set ITCounter to 1 to indicate the start
2190 of a new phase */
2191 __HAL_HASH_ENABLE_IT(HASH_IT_DINI); /* Enable IT (was disabled in HASH_Write_Block_Data) */
2192 }
2193 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
2194 {
2195 /* Wait until Peripheral is not busy anymore */
2197 {
2198 /* Disable Interrupts */
2200 return HAL_TIMEOUT;
2201 }
2202 /* Initialization start for HMAC STEP 3 */
2203 hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; /* Move phase from Step 2 to Step 3 */
2204 __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); /* Set NBLW for the key */
2205 hhash->HashInCount = hhash->Init.KeySize; /* Set the key size (in bytes) */
2206 hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */
2207 hhash->HashITCounter = 1; /* Set ITCounter to 1 to indicate the start
2208 of a new phase */
2209 __HAL_HASH_ENABLE_IT(HASH_IT_DINI); /* Enable IT (was disabled in HASH_Write_Block_Data) */
2210 }
2211 else
2212 {
2213 /* Nothing to do */
2214 }
2215 } /* if (HASH_Write_Block_Data(hhash) == HASH_DIGEST_CALCULATION_STARTED) */
2216 } /* if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))*/
2217
2218 /* Return function status */
2219 return HAL_OK;
2220 }
2221 else
2222 {
2223 return HAL_BUSY;
2224 }
2225}
2226
2227
2235{
2236 uint32_t inputaddr;
2237 uint32_t buffercounter;
2238 uint32_t inputcounter;
2240
2241 /* If there are more than 64 bytes remaining to be entered */
2242 if (hhash->HashInCount > 64U)
2243 {
2244 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
2245 /* Write the Input block in the Data IN register
2246 (16 32-bit words, or 64 bytes are entered) */
2247 for (buffercounter = 0U; buffercounter < 64U; buffercounter += 4U)
2248 {
2249 HASH->DIN = *(uint32_t *)inputaddr;
2250 inputaddr += 4U;
2251 }
2252 /* If this is the start of input data entering, an additional word
2253 must be entered to start up the HASH processing */
2254 if (hhash->HashITCounter == 2U)
2255 {
2256 HASH->DIN = *(uint32_t *)inputaddr;
2257 if (hhash->HashInCount >= 68U)
2258 {
2259 /* There are still data waiting to be entered in the Peripheral.
2260 Decrement buffer counter and set pointer to the proper
2261 memory location for the next data entering round. */
2262 hhash->HashInCount -= 68U;
2263 hhash->pHashInBuffPtr += 68U;
2264 }
2265 else
2266 {
2267 /* All the input buffer has been fed to the HW. */
2268 hhash->HashInCount = 0U;
2269 }
2270 }
2271 else
2272 {
2273 /* 64 bytes have been entered and there are still some remaining:
2274 Decrement buffer counter and set pointer to the proper
2275 memory location for the next data entering round.*/
2276 hhash->HashInCount -= 64U;
2277 hhash->pHashInBuffPtr += 64U;
2278 }
2279 }
2280 else
2281 {
2282 /* 64 or less bytes remain to be entered. This is the last
2283 data entering round. */
2284
2285 /* Get the buffer address */
2286 inputaddr = (uint32_t)hhash->pHashInBuffPtr;
2287 /* Get the buffer counter */
2288 inputcounter = hhash->HashInCount;
2289 /* Disable Interrupts */
2291
2292 /* Write the Input block in the Data IN register */
2293 for (buffercounter = 0U; buffercounter < ((inputcounter + 3U) / 4U); buffercounter++)
2294 {
2295 HASH->DIN = *(uint32_t *)inputaddr;
2296 inputaddr += 4U;
2297 }
2298
2299 if (hhash->Accumulation == 1U)
2300 {
2301 /* Field accumulation is set, API only feeds data to the Peripheral and under interruption.
2302 The digest computation will be started when the last buffer data are entered. */
2303
2304 /* Reset multi buffers accumulation flag */
2305 hhash->Accumulation = 0U;
2306 /* Change the HASH state */
2307 hhash->State = HAL_HASH_STATE_READY;
2308 /* Call Input data transfer complete call back */
2309#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2310 hhash->InCpltCallback(hhash);
2311#else
2313#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2314 }
2315 else
2316 {
2317 /* Start the Digest calculation */
2319 /* Return indication that digest calculation has started:
2320 this return value triggers the call to Input data transfer
2321 complete call back as well as the proper transition from
2322 one step to another in HMAC mode. */
2324 }
2325 /* Reset buffer counter */
2326 hhash->HashInCount = 0;
2327 }
2328
2329 /* Return whether or digest calculation has started */
2330 return ret;
2331}
2332
2340{
2341 /* Ensure first that Phase is correct */
2343 && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_3))
2344 {
2345 /* Change the HASH state */
2346 hhash->State = HAL_HASH_STATE_READY;
2347
2348 /* Process Unlock */
2349 __HAL_UNLOCK(hhash);
2350
2351 /* Return function status */
2352 return HAL_ERROR;
2353 }
2354
2355 /* HMAC Step 1 processing */
2356 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
2357 {
2358 /************************** STEP 1 ******************************************/
2359 /* Configure the Number of valid bits in last word of the message */
2361
2362 /* Write input buffer in Data register */
2363 hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount);
2364 if (hhash->Status != HAL_OK)
2365 {
2366 return hhash->Status;
2367 }
2368
2369 /* Check whether or not key entering process has been suspended */
2370 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2371 {
2372 /* Process Unlocked */
2373 __HAL_UNLOCK(hhash);
2374
2375 /* Stop right there and return function status */
2376 return HAL_OK;
2377 }
2378
2379 /* No processing suspension at this point: set DCAL bit. */
2381
2382 /* Wait for BUSY flag to be cleared */
2383 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
2384 {
2385 return HAL_TIMEOUT;
2386 }
2387
2388 /* Move from Step 1 to Step 2 */
2390
2391 }
2392
2393 /* HMAC Step 2 processing.
2394 After phase check, HMAC_Processing() may
2395 - directly start up from this point in resumption case
2396 if the same Step 2 processing was suspended previously
2397 - or fall through from the Step 1 processing carried out hereabove */
2398 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
2399 {
2400 /************************** STEP 2 ******************************************/
2401 /* Configure the Number of valid bits in last word of the message */
2403
2404 /* Write input buffer in Data register */
2405 hhash->Status = HASH_WriteData(hhash, hhash->pHashInBuffPtr, hhash->HashInCount);
2406 if (hhash->Status != HAL_OK)
2407 {
2408 return hhash->Status;
2409 }
2410
2411 /* Check whether or not data entering process has been suspended */
2412 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2413 {
2414 /* Process Unlocked */
2415 __HAL_UNLOCK(hhash);
2416
2417 /* Stop right there and return function status */
2418 return HAL_OK;
2419 }
2420
2421 /* No processing suspension at this point: set DCAL bit. */
2423
2424 /* Wait for BUSY flag to be cleared */
2425 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
2426 {
2427 return HAL_TIMEOUT;
2428 }
2429
2430 /* Move from Step 2 to Step 3 */
2432 /* In case Step 1 phase was suspended then resumed,
2433 set again Key input buffers and size before moving to
2434 next step */
2435 hhash->pHashKeyBuffPtr = hhash->Init.pKey;
2436 hhash->HashKeyCount = hhash->Init.KeySize;
2437 }
2438
2439
2440 /* HMAC Step 3 processing.
2441 After phase check, HMAC_Processing() may
2442 - directly start up from this point in resumption case
2443 if the same Step 3 processing was suspended previously
2444 - or fall through from the Step 2 processing carried out hereabove */
2445 if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)
2446 {
2447 /************************** STEP 3 ******************************************/
2448 /* Configure the Number of valid bits in last word of the message */
2450
2451 /* Write input buffer in Data register */
2452 hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount);
2453 if (hhash->Status != HAL_OK)
2454 {
2455 return hhash->Status;
2456 }
2457
2458 /* Check whether or not key entering process has been suspended */
2459 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2460 {
2461 /* Process Unlocked */
2462 __HAL_UNLOCK(hhash);
2463
2464 /* Stop right there and return function status */
2465 return HAL_OK;
2466 }
2467
2468 /* No processing suspension at this point: start the Digest calculation. */
2470
2471 /* Wait for DCIS flag to be set */
2472 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
2473 {
2474 return HAL_TIMEOUT;
2475 }
2476
2477 /* Read the message digest */
2479
2480 /* Reset HASH state machine */
2481 hhash->Phase = HAL_HASH_PHASE_READY;
2482 }
2483
2484 /* Change the HASH state */
2485 hhash->State = HAL_HASH_STATE_READY;
2486
2487 /* Process Unlock */
2488 __HAL_UNLOCK(hhash);
2489
2490 /* Return function status */
2491 return HAL_OK;
2492}
2493
2494
2507HAL_StatusTypeDef HASH_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer,
2508 uint32_t Timeout, uint32_t Algorithm)
2509{
2510 uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */
2511 uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */
2512 HAL_HASH_StateTypeDef State_tmp = hhash->State;
2513
2514
2515 /* Initiate HASH processing in case of start or resumption */
2516 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2517 {
2518 /* Check input parameters */
2519 if ((pInBuffer == NULL) || (pOutBuffer == NULL))
2520 {
2521 hhash->State = HAL_HASH_STATE_READY;
2522 return HAL_ERROR;
2523 }
2524
2525 /* Process Locked */
2526 __HAL_LOCK(hhash);
2527
2528 /* Check if initialization phase has not been already performed */
2529 if (hhash->Phase == HAL_HASH_PHASE_READY)
2530 {
2531 /* Change the HASH state */
2532 hhash->State = HAL_HASH_STATE_BUSY;
2533
2534 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2535 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2536
2537 /* Configure the number of valid bits in last word of the message */
2539
2540 /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2541 input parameters of HASH_WriteData() */
2542 pInBuffer_tmp = pInBuffer; /* pInBuffer_tmp is set to the input data address */
2543 Size_tmp = Size; /* Size_tmp contains the input data size in bytes */
2544
2545 /* Set the phase */
2547 }
2548 else if (hhash->Phase == HAL_HASH_PHASE_PROCESS)
2549 {
2550 /* if the Peripheral has already been initialized, two cases are possible */
2551
2552 /* Process resumption time ... */
2553 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2554 {
2555 /* Since this is resumption, pInBuffer_tmp and Size_tmp are not set
2556 to the API input parameters but to those saved beforehand by HASH_WriteData()
2557 when the processing was suspended */
2558 pInBuffer_tmp = hhash->pHashInBuffPtr;
2559 Size_tmp = hhash->HashInCount;
2560 }
2561 /* ... or multi-buffer HASH processing end */
2562 else
2563 {
2564 /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2565 input parameters of HASH_WriteData() */
2566 pInBuffer_tmp = pInBuffer;
2567 Size_tmp = Size;
2568 /* Configure the number of valid bits in last word of the message */
2570 }
2571 /* Change the HASH state */
2572 hhash->State = HAL_HASH_STATE_BUSY;
2573 }
2574 else
2575 {
2576 /* Phase error */
2577 hhash->State = HAL_HASH_STATE_READY;
2578
2579 /* Process Unlocked */
2580 __HAL_UNLOCK(hhash);
2581
2582 /* Return function status */
2583 return HAL_ERROR;
2584 }
2585
2586
2587 /* Write input buffer in Data register */
2588 hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp);
2589 if (hhash->Status != HAL_OK)
2590 {
2591 return hhash->Status;
2592 }
2593
2594 /* If the process has not been suspended, carry on to digest calculation */
2595 if (hhash->State != HAL_HASH_STATE_SUSPENDED)
2596 {
2597 /* Start the Digest calculation */
2599
2600 /* Wait for DCIS flag to be set */
2601 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
2602 {
2603 return HAL_TIMEOUT;
2604 }
2605
2606 /* Read the message digest */
2607 HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH());
2608
2609 /* Change the HASH state */
2610 hhash->State = HAL_HASH_STATE_READY;
2611
2612 /* Reset HASH state machine */
2613 hhash->Phase = HAL_HASH_PHASE_READY;
2614
2615 }
2616
2617 /* Process Unlocked */
2618 __HAL_UNLOCK(hhash);
2619
2620 /* Return function status */
2621 return HAL_OK;
2622
2623 }
2624 else
2625 {
2626 return HAL_BUSY;
2627 }
2628}
2629
2630
2644HAL_StatusTypeDef HASH_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
2645{
2646 uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */
2647 uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */
2648 HAL_HASH_StateTypeDef State_tmp = hhash->State;
2649
2650 /* Make sure the input buffer size (in bytes) is a multiple of 4 */
2651 if ((Size % 4U) != 0U)
2652 {
2653 return HAL_ERROR;
2654 }
2655
2656 /* Initiate HASH processing in case of start or resumption */
2657 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2658 {
2659 /* Check input parameters */
2660 if ((pInBuffer == NULL) || (Size == 0U))
2661 {
2662 hhash->State = HAL_HASH_STATE_READY;
2663 return HAL_ERROR;
2664 }
2665
2666 /* Process Locked */
2667 __HAL_LOCK(hhash);
2668
2669 /* If resuming the HASH processing */
2670 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2671 {
2672 /* Change the HASH state */
2673 hhash->State = HAL_HASH_STATE_BUSY;
2674
2675 /* Since this is resumption, pInBuffer_tmp and Size_tmp are not set
2676 to the API input parameters but to those saved beforehand by HASH_WriteData()
2677 when the processing was suspended */
2678 pInBuffer_tmp = hhash->pHashInBuffPtr; /* pInBuffer_tmp is set to the input data address */
2679 Size_tmp = hhash->HashInCount; /* Size_tmp contains the input data size in bytes */
2680
2681 }
2682 else
2683 {
2684 /* Change the HASH state */
2685 hhash->State = HAL_HASH_STATE_BUSY;
2686
2687 /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2688 input parameters of HASH_WriteData() */
2689 pInBuffer_tmp = pInBuffer; /* pInBuffer_tmp is set to the input data address */
2690 Size_tmp = Size; /* Size_tmp contains the input data size in bytes */
2691
2692 /* Check if initialization phase has already be performed */
2693 if (hhash->Phase == HAL_HASH_PHASE_READY)
2694 {
2695 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2696 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2697 }
2698
2699 /* Set the phase */
2701
2702 }
2703
2704 /* Write input buffer in Data register */
2705 hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp);
2706 if (hhash->Status != HAL_OK)
2707 {
2708 return hhash->Status;
2709 }
2710
2711 /* If the process has not been suspended, move the state to Ready */
2712 if (hhash->State != HAL_HASH_STATE_SUSPENDED)
2713 {
2714 /* Change the HASH state */
2715 hhash->State = HAL_HASH_STATE_READY;
2716 }
2717
2718 /* Process Unlocked */
2719 __HAL_UNLOCK(hhash);
2720
2721 /* Return function status */
2722 return HAL_OK;
2723
2724 }
2725 else
2726 {
2727 return HAL_BUSY;
2728 }
2729
2730
2731}
2732
2733
2747HAL_StatusTypeDef HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
2748{
2749 HAL_HASH_StateTypeDef State_tmp = hhash->State;
2750 __IO uint32_t inputaddr = (uint32_t) pInBuffer;
2751 uint32_t SizeVar = Size;
2752
2753 /* Make sure the input buffer size (in bytes) is a multiple of 4 */
2754 if ((Size % 4U) != 0U)
2755 {
2756 return HAL_ERROR;
2757 }
2758
2759 /* Initiate HASH processing in case of start or resumption */
2760 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2761 {
2762 /* Check input parameters */
2763 if ((pInBuffer == NULL) || (Size == 0U))
2764 {
2765 hhash->State = HAL_HASH_STATE_READY;
2766 return HAL_ERROR;
2767 }
2768
2769 /* Process Locked */
2770 __HAL_LOCK(hhash);
2771
2772 /* If resuming the HASH processing */
2773 if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2774 {
2775 /* Change the HASH state */
2776 hhash->State = HAL_HASH_STATE_BUSY;
2777 }
2778 else
2779 {
2780 /* Change the HASH state */
2781 hhash->State = HAL_HASH_STATE_BUSY;
2782
2783 /* Check if initialization phase has already be performed */
2784 if (hhash->Phase == HAL_HASH_PHASE_READY)
2785 {
2786 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2787 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2788 hhash->HashITCounter = 1;
2789 }
2790 else
2791 {
2792 hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */
2793 }
2794
2795 /* Set the phase */
2797
2798 /* If DINIS is equal to 0 (for example if an incomplete block has been previously
2799 fed to the Peripheral), the DINIE interruption won't be triggered when DINIE is set.
2800 Therefore, first words are manually entered until DINIS raises, or until there
2801 is not more data to enter. */
2802 while ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 0U))
2803 {
2804
2805 /* Write input data 4 bytes at a time */
2806 HASH->DIN = *(uint32_t *)inputaddr;
2807 inputaddr += 4U;
2808 SizeVar -= 4U;
2809 }
2810
2811 /* If DINIS is still not set or if all the data have been fed, stop here */
2812 if ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) || (SizeVar == 0U))
2813 {
2814 /* Change the HASH state */
2815 hhash->State = HAL_HASH_STATE_READY;
2816
2817 /* Process Unlock */
2818 __HAL_UNLOCK(hhash);
2819
2820 /* Return function status */
2821 return HAL_OK;
2822 }
2823
2824 /* otherwise, carry on in interrupt-mode */
2825 hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data
2826 to be fed to the Peripheral */
2827 hhash->pHashInBuffPtr = (uint8_t *)inputaddr; /* Points at data which will be fed to the Peripheral at
2828 the next interruption */
2829 /* In case of suspension, hhash->HashInCount and hhash->pHashInBuffPtr contain
2830 the information describing where the HASH process is stopped.
2831 These variables are used later on to resume the HASH processing at the
2832 correct location. */
2833
2834 }
2835
2836 /* Set multi buffers accumulation flag */
2837 hhash->Accumulation = 1U;
2838
2839 /* Process Unlock */
2840 __HAL_UNLOCK(hhash);
2841
2842 /* Enable Data Input interrupt */
2844
2845 /* Return function status */
2846 return HAL_OK;
2847
2848 }
2849 else
2850 {
2851 return HAL_BUSY;
2852 }
2853
2854}
2855
2856
2857
2869HAL_StatusTypeDef HASH_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer,
2870 uint32_t Algorithm)
2871{
2872 HAL_HASH_StateTypeDef State_tmp = hhash->State;
2873 __IO uint32_t inputaddr = (uint32_t) pInBuffer;
2874 uint32_t polling_step = 0U;
2875 uint32_t initialization_skipped = 0U;
2876 uint32_t SizeVar = Size;
2877
2878 /* If State is ready or suspended, start or resume IT-based HASH processing */
2879 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2880 {
2881 /* Check input parameters */
2882 if ((pInBuffer == NULL) || (Size == 0U) || (pOutBuffer == NULL))
2883 {
2884 hhash->State = HAL_HASH_STATE_READY;
2885 return HAL_ERROR;
2886 }
2887
2888 /* Process Locked */
2889 __HAL_LOCK(hhash);
2890
2891 /* Change the HASH state */
2892 hhash->State = HAL_HASH_STATE_BUSY;
2893
2894 /* Initialize IT counter */
2895 hhash->HashITCounter = 1;
2896
2897 /* Check if initialization phase has already be performed */
2898 if (hhash->Phase == HAL_HASH_PHASE_READY)
2899 {
2900 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2901 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2902
2903 /* Configure the number of valid bits in last word of the message */
2905
2906
2907 hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data
2908 to be fed to the Peripheral */
2909 hhash->pHashInBuffPtr = pInBuffer; /* Points at data which will be fed to the Peripheral at
2910 the next interruption */
2911 /* In case of suspension, hhash->HashInCount and hhash->pHashInBuffPtr contain
2912 the information describing where the HASH process is stopped.
2913 These variables are used later on to resume the HASH processing at the
2914 correct location. */
2915
2916 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2917 }
2918 else
2919 {
2920 initialization_skipped = 1; /* info user later on in case of multi-buffer */
2921 }
2922
2923 /* Set the phase */
2925
2926 /* If DINIS is equal to 0 (for example if an incomplete block has been previously
2927 fed to the Peripheral), the DINIE interruption won't be triggered when DINIE is set.
2928 Therefore, first words are manually entered until DINIS raises. */
2929 while ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 3U))
2930 {
2931 polling_step = 1U; /* note that some words are entered before enabling the interrupt */
2932
2933 /* Write input data 4 bytes at a time */
2934 HASH->DIN = *(uint32_t *)inputaddr;
2935 inputaddr += 4U;
2936 SizeVar -= 4U;
2937 }
2938
2939 if (polling_step == 1U)
2940 {
2941 if (SizeVar == 0U)
2942 {
2943 /* If all the data have been entered at this point, it only remains to
2944 read the digest */
2945 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2946
2947 /* Start the Digest calculation */
2949 /* Process Unlock */
2950 __HAL_UNLOCK(hhash);
2951
2952 /* Enable Interrupts */
2954
2955 /* Return function status */
2956 return HAL_OK;
2957 }
2959 {
2960 /* It remains data to enter and the Peripheral is ready to trigger DINIE,
2961 carry on as usual.
2962 Update HashInCount and pHashInBuffPtr accordingly. */
2963 hhash->HashInCount = SizeVar;
2964 hhash->pHashInBuffPtr = (uint8_t *)inputaddr;
2965 /* Update the configuration of the number of valid bits in last word of the message */
2967 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2968 if (initialization_skipped == 1U)
2969 {
2970 hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */
2971 }
2972 }
2973 else
2974 {
2975 /* DINIS is not set but it remains a few data to enter (not enough for a full word).
2976 Manually enter the last bytes before enabling DCIE. */
2978 HASH->DIN = *(uint32_t *)inputaddr;
2979
2980 /* Start the Digest calculation */
2981 hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2983 /* Process Unlock */
2984 __HAL_UNLOCK(hhash);
2985
2986 /* Enable Interrupts */
2988
2989 /* Return function status */
2990 return HAL_OK;
2991 }
2992 } /* if (polling_step == 1) */
2993
2994
2995 /* Process Unlock */
2996 __HAL_UNLOCK(hhash);
2997
2998 /* Enable Interrupts */
3000
3001 /* Return function status */
3002 return HAL_OK;
3003 }
3004 else
3005 {
3006 return HAL_BUSY;
3007 }
3008
3009}
3010
3011
3027HAL_StatusTypeDef HASH_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
3028{
3029 uint32_t inputaddr;
3030 uint32_t inputSize;
3031 HAL_StatusTypeDef status ;
3032 HAL_HASH_StateTypeDef State_tmp = hhash->State;
3033
3034 #if defined (HASH_CR_MDMAT)
3035 /* Make sure the input buffer size (in bytes) is a multiple of 4 when MDMAT bit is set
3036 (case of multi-buffer HASH processing) */
3038 #endif /* MDMA defined*/
3039 /* If State is ready or suspended, start or resume polling-based HASH processing */
3040 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3041 {
3042 /* Check input parameters */
3043 if ((pInBuffer == NULL) || (Size == 0U) ||
3044 /* Check phase coherency. Phase must be
3045 either READY (fresh start)
3046 or PROCESS (multi-buffer HASH management) */
3047 ((hhash->Phase != HAL_HASH_PHASE_READY) && (!(IS_HASH_PROCESSING(hhash)))))
3048 {
3049 hhash->State = HAL_HASH_STATE_READY;
3050 return HAL_ERROR;
3051 }
3052
3053
3054 /* Process Locked */
3055 __HAL_LOCK(hhash);
3056
3057 /* If not a resumption case */
3058 if (hhash->State == HAL_HASH_STATE_READY)
3059 {
3060 /* Change the HASH state */
3061 hhash->State = HAL_HASH_STATE_BUSY;
3062
3063 /* Check if initialization phase has already been performed.
3064 If Phase is already set to HAL_HASH_PHASE_PROCESS, this means the
3065 API is processing a new input data message in case of multi-buffer HASH
3066 computation. */
3067 if (hhash->Phase == HAL_HASH_PHASE_READY)
3068 {
3069 /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
3070 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT, Algorithm | HASH_CR_INIT);
3071
3072 /* Set the phase */
3074 }
3075
3076 /* Configure the Number of valid bits in last word of the message */
3078
3079 inputaddr = (uint32_t)pInBuffer; /* DMA transfer start address */
3080 inputSize = Size; /* DMA transfer size (in bytes) */
3081
3082 /* In case of suspension request, save the starting parameters */
3083 hhash->pHashInBuffPtr = pInBuffer; /* DMA transfer start address */
3084 hhash->HashInCount = Size; /* DMA transfer size (in bytes) */
3085
3086 }
3087 /* If resumption case */
3088 else
3089 {
3090 /* Change the HASH state */
3091 hhash->State = HAL_HASH_STATE_BUSY;
3092
3093 /* Resumption case, inputaddr and inputSize are not set to the API input parameters
3094 but to those saved beforehand by HAL_HASH_DMAFeed_ProcessSuspend() when the
3095 processing was suspended */
3096 inputaddr = (uint32_t)hhash->pHashInBuffPtr; /* DMA transfer start address */
3097 inputSize = hhash->HashInCount; /* DMA transfer size (in bytes) */
3098
3099 }
3100
3101 /* Set the HASH DMA transfer complete callback */
3103 /* Set the DMA error callback */
3105
3106 /* Store number of words already pushed to manage proper DMA processing suspension */
3108
3109 /* Enable the DMA In DMA stream */
3110 status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, \
3111 (((inputSize % 4U) != 0U) ? ((inputSize + (4U - (inputSize % 4U))) / 4U) : \
3112 (inputSize / 4U)));
3113
3114 /* Enable DMA requests */
3115 SET_BIT(HASH->CR, HASH_CR_DMAE);
3116
3117 /* Process Unlock */
3118 __HAL_UNLOCK(hhash);
3119
3120 /* Return function status */
3121 if (status != HAL_OK)
3122 {
3123 /* Update HASH state machine to error */
3124 hhash->State = HAL_HASH_STATE_ERROR;
3125 }
3126
3127 return status;
3128 }
3129 else
3130 {
3131 return HAL_BUSY;
3132 }
3133}
3134
3143HAL_StatusTypeDef HASH_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
3144{
3145
3146 if (hhash->State == HAL_HASH_STATE_READY)
3147 {
3148 /* Check parameter */
3149 if (pOutBuffer == NULL)
3150 {
3151 return HAL_ERROR;
3152 }
3153
3154 /* Process Locked */
3155 __HAL_LOCK(hhash);
3156
3157 /* Change the HASH state to busy */
3158 hhash->State = HAL_HASH_STATE_BUSY;
3159
3160 /* Wait for DCIS flag to be set */
3161 if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
3162 {
3163 return HAL_TIMEOUT;
3164 }
3165
3166 /* Read the message digest */
3167 HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH());
3168
3169 /* Change the HASH state to ready */
3170 hhash->State = HAL_HASH_STATE_READY;
3171
3172 /* Reset HASH state machine */
3173 hhash->Phase = HAL_HASH_PHASE_READY;
3174
3175 /* Process UnLock */
3176 __HAL_UNLOCK(hhash);
3177
3178 /* Return function status */
3179 return HAL_OK;
3180
3181 }
3182 else
3183 {
3184 return HAL_BUSY;
3185 }
3186
3187}
3188
3189
3204HAL_StatusTypeDef HMAC_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer,
3205 uint32_t Timeout, uint32_t Algorithm)
3206{
3207 HAL_HASH_StateTypeDef State_tmp = hhash->State;
3208
3209 /* If State is ready or suspended, start or resume polling-based HASH processing */
3210 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3211 {
3212 /* Check input parameters */
3213 if ((pInBuffer == NULL) || (Size == 0U) || (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U)
3214 || (pOutBuffer == NULL))
3215 {
3216 hhash->State = HAL_HASH_STATE_READY;
3217 return HAL_ERROR;
3218 }
3219
3220 /* Process Locked */
3221 __HAL_LOCK(hhash);
3222
3223 /* Change the HASH state */
3224 hhash->State = HAL_HASH_STATE_BUSY;
3225
3226 /* Check if initialization phase has already be performed */
3227 if (hhash->Phase == HAL_HASH_PHASE_READY)
3228 {
3229 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
3230 if (hhash->Init.KeySize > 64U)
3231 {
3232 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3233 Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3234 }
3235 else
3236 {
3237 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3238 Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3239 }
3240 /* Set the phase to Step 1 */
3242 /* Resort to hhash internal fields to feed the Peripheral.
3243 Parameters will be updated in case of suspension to contain the proper
3244 information at resumption time. */
3245 hhash->pHashOutBuffPtr = pOutBuffer; /* Output digest address */
3246 hhash->pHashInBuffPtr = pInBuffer; /* Input data address, HMAC_Processing input
3247 parameter for Step 2 */
3248 hhash->HashInCount = Size; /* Input data size, HMAC_Processing input
3249 parameter for Step 2 */
3250 hhash->HashBuffSize = Size; /* Store the input buffer size for the whole HMAC process*/
3251 hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address, HMAC_Processing input parameter for Step
3252 1 and Step 3 */
3253 hhash->HashKeyCount = hhash->Init.KeySize; /* Key size, HMAC_Processing input parameter for Step 1
3254 and Step 3 */
3255 }
3256
3257 /* Carry out HMAC processing */
3258 return HMAC_Processing(hhash, Timeout);
3259
3260 }
3261 else
3262 {
3263 return HAL_BUSY;
3264 }
3265}
3266
3267
3268
3282HAL_StatusTypeDef HMAC_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer,
3283 uint32_t Algorithm)
3284{
3285 HAL_HASH_StateTypeDef State_tmp = hhash->State;
3286
3287 /* If State is ready or suspended, start or resume IT-based HASH processing */
3288 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3289 {
3290 /* Check input parameters */
3291 if ((pInBuffer == NULL) || (Size == 0U) || (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U)
3292 || (pOutBuffer == NULL))
3293 {
3294 hhash->State = HAL_HASH_STATE_READY;
3295 return HAL_ERROR;
3296 }
3297
3298 /* Process Locked */
3299 __HAL_LOCK(hhash);
3300
3301 /* Change the HASH state */
3302 hhash->State = HAL_HASH_STATE_BUSY;
3303
3304 /* Initialize IT counter */
3305 hhash->HashITCounter = 1;
3306
3307 /* Check if initialization phase has already be performed */
3308 if (hhash->Phase == HAL_HASH_PHASE_READY)
3309 {
3310 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
3311 if (hhash->Init.KeySize > 64U)
3312 {
3313 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3314 Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3315 }
3316 else
3317 {
3318 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3319 Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3320 }
3321
3322 /* Resort to hhash internal fields hhash->pHashInBuffPtr and hhash->HashInCount
3323 to feed the Peripheral whatever the HMAC step.
3324 Lines below are set to start HMAC Step 1 processing where key is entered first. */
3325 hhash->HashInCount = hhash->Init.KeySize; /* Key size */
3326 hhash->pHashInBuffPtr = hhash->Init.pKey ; /* Key address */
3327
3328 /* Store input and output parameters in handle fields to manage steps transition
3329 or possible HMAC suspension/resumption */
3330 hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address */
3331 hhash->pHashMsgBuffPtr = pInBuffer; /* Input message address */
3332 hhash->HashBuffSize = Size; /* Input message size (in bytes) */
3333 hhash->pHashOutBuffPtr = pOutBuffer; /* Output digest address */
3334
3335 /* Configure the number of valid bits in last word of the key */
3337
3338 /* Set the phase to Step 1 */
3340 }
3341 else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3))
3342 {
3343 /* Restart IT-based HASH processing after Step 1 or Step 3 suspension */
3344
3345 }
3346 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
3347 {
3348 /* Restart IT-based HASH processing after Step 2 suspension */
3349
3350 }
3351 else
3352 {
3353 /* Error report as phase incorrect */
3354 /* Process Unlock */
3355 __HAL_UNLOCK(hhash);
3356 hhash->State = HAL_HASH_STATE_READY;
3357 return HAL_ERROR;
3358 }
3359
3360 /* Process Unlock */
3361 __HAL_UNLOCK(hhash);
3362
3363 /* Enable Interrupts */
3365
3366 /* Return function status */
3367 return HAL_OK;
3368 }
3369 else
3370 {
3371 return HAL_BUSY;
3372 }
3373
3374}
3375
3376
3377
3393HAL_StatusTypeDef HMAC_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
3394{
3395 uint32_t inputaddr;
3396 uint32_t inputSize;
3397 HAL_StatusTypeDef status ;
3398 HAL_HASH_StateTypeDef State_tmp = hhash->State;
3399 /* Make sure the input buffer size (in bytes) is a multiple of 4 when digest calculation
3400 is disabled (multi-buffer HMAC processing, MDMAT bit to be set) */
3402 /* If State is ready or suspended, start or resume DMA-based HASH processing */
3403 if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3404 {
3405 /* Check input parameters */
3406 if ((pInBuffer == NULL) || (Size == 0U) || (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U) ||
3407 /* Check phase coherency. Phase must be
3408 either READY (fresh start)
3409 or one of HMAC PROCESS steps (multi-buffer HASH management) */
3410 ((hhash->Phase != HAL_HASH_PHASE_READY) && (!(IS_HMAC_PROCESSING(hhash)))))
3411 {
3412 hhash->State = HAL_HASH_STATE_READY;
3413 return HAL_ERROR;
3414 }
3415
3416
3417 /* Process Locked */
3418 __HAL_LOCK(hhash);
3419
3420 /* If not a case of resumption after suspension */
3421 if (hhash->State == HAL_HASH_STATE_READY)
3422 {
3423 /* Check whether or not initialization phase has already be performed */
3424 if (hhash->Phase == HAL_HASH_PHASE_READY)
3425 {
3426 /* Change the HASH state */
3427 hhash->State = HAL_HASH_STATE_BUSY;
3428#if defined(HASH_CR_MDMAT)
3429 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits.
3430 At the same time, ensure MDMAT bit is cleared. */
3431 if (hhash->Init.KeySize > 64U)
3432 {
3433 MODIFY_REG(HASH->CR, HASH_CR_MDMAT | HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3434 Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3435 }
3436 else
3437 {
3438 MODIFY_REG(HASH->CR, HASH_CR_MDMAT | HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3439 Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3440 }
3441#else
3442 /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
3443 if (hhash->Init.KeySize > 64U)
3444 {
3445 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3446 Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3447 }
3448 else
3449 {
3450 MODIFY_REG(HASH->CR, HASH_CR_LKEY | HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_INIT,
3451 Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3452 }
3453#endif /* HASH_CR_MDMAT*/
3454 /* Store input aparameters in handle fields to manage steps transition
3455 or possible HMAC suspension/resumption */
3456 hhash->HashInCount = hhash->Init.KeySize; /* Initial size for first DMA transfer (key size) */
3457 hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address */
3458 hhash->pHashInBuffPtr = hhash->Init.pKey ; /* First address passed to DMA (key address at Step 1) */
3459 hhash->pHashMsgBuffPtr = pInBuffer; /* Input data address */
3460 hhash->HashBuffSize = Size; /* input data size (in bytes) */
3461
3462 /* Set DMA input parameters */
3463 inputaddr = (uint32_t)(hhash->Init.pKey); /* Address passed to DMA (start by entering Key message) */
3464 inputSize = hhash->Init.KeySize; /* Size for first DMA transfer (in bytes) */
3465
3466 /* Configure the number of valid bits in last word of the key */
3468
3469 /* Set the phase to Step 1 */
3471
3472 }
3473 else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
3474 {
3475 /* Process a new input data message in case of multi-buffer HMAC processing
3476 (this is not a resumption case) */
3477
3478 /* Change the HASH state */
3479 hhash->State = HAL_HASH_STATE_BUSY;
3480
3481 /* Save input parameters to be able to manage possible suspension/resumption */
3482 hhash->HashInCount = Size; /* Input message address */
3483 hhash->pHashInBuffPtr = pInBuffer; /* Input message size in bytes */
3484
3485 /* Set DMA input parameters */
3486 inputaddr = (uint32_t)pInBuffer; /* Input message address */
3487 inputSize = Size; /* Input message size in bytes */
3488
3489 if (hhash->DigestCalculationDisable == RESET)
3490 {
3491 /* This means this is the last buffer of the multi-buffer sequence: DCAL needs to be set. */
3492#if defined(HASH_CR_MDMAT)
3494#endif /* HASH_CR_MDMAT*/
3495 __HAL_HASH_SET_NBVALIDBITS(inputSize);
3496 }
3497 }
3498 else
3499 {
3500 /* Phase not aligned with handle READY state */
3501 __HAL_UNLOCK(hhash);
3502 /* Return function status */
3503 return HAL_ERROR;
3504 }
3505 }
3506 else
3507 {
3508 /* Resumption case (phase may be Step 1, 2 or 3) */
3509
3510 /* Change the HASH state */
3511 hhash->State = HAL_HASH_STATE_BUSY;
3512
3513 /* Set DMA input parameters at resumption location;
3514 inputaddr and inputSize are not set to the API input parameters
3515 but to those saved beforehand by HAL_HASH_DMAFeed_ProcessSuspend() when the
3516 processing was suspended. */
3517 inputaddr = (uint32_t)(hhash->pHashInBuffPtr); /* Input message address */
3518 inputSize = hhash->HashInCount; /* Input message size in bytes */
3519 }
3520
3521
3522 /* Set the HASH DMA transfer complete callback */
3524 /* Set the DMA error callback */
3526
3527 /* Store number of words already pushed to manage proper DMA processing suspension */
3529
3530 /* Enable the DMA In DMA stream */
3531 status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, \
3532 (((inputSize % 4U) != 0U) ? ((inputSize + (4U - (inputSize % 4U))) / 4U) \
3533 : (inputSize / 4U)));
3534
3535 /* Enable DMA requests */
3536 SET_BIT(HASH->CR, HASH_CR_DMAE);
3537
3538 /* Process Unlocked */
3539 __HAL_UNLOCK(hhash);
3540
3541 /* Return function status */
3542 if (status != HAL_OK)
3543 {
3544 /* Update HASH state machine to error */
3545 hhash->State = HAL_HASH_STATE_ERROR;
3546 }
3547
3548 /* Return function status */
3549 return status;
3550 }
3551 else
3552 {
3553 return HAL_BUSY;
3554 }
3555}
3560#endif /* HAL_HASH_MODULE_ENABLED */
3561
3565#endif /* HASH*/
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer.
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
Start the DMA Transfer with interrupt enabled.
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
#define HASH_ALGOSELECTION_MD5
#define HASH_ALGOSELECTION_SHA1
#define HASH_ALGOMODE_HMAC
#define HASH_DMA_SUSPENSION_WORDS_LIMIT
#define HASH_DATATYPE_8B
#define HASH_DATATYPE_16B
#define HASH_DATATYPE_1B
#define HASH_DIGEST_CALCULATION_STARTED
#define HASH_DIGEST_CALCULATION_NOT_STARTED
#define HAL_HASH_ERROR_NONE
#define HAL_HASH_ERROR_DMA
#define HAL_HASH_ERROR_IT
void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
DeInitialize the HASH MSP.
void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
Digest computation complete call back.
HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash)
DeInitialize the HASH peripheral.
void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
Input data transfer complete call back.
HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash)
Initialize the HASH according to the specified parameters in the HASH_HandleTypeDef and create the as...
void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
Initialize the HASH MSP.
void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
Error callback.
HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Timeout)
Initialize the HASH peripheral in MD5 mode, next process pInBuffer then read the computed digest.
HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_End(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Timeout)
End computation of a single HASH signature after several calls to HAL_HASH_MD5_Accmlt() API.
HAL_StatusTypeDef HAL_HASH_MD5_Accmlt(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
If not already done, initialize the HASH peripheral in MD5 mode then processes pInBuffer.
HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_End(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Timeout)
End computation of a single HASH signature after several calls to HAL_HASH_SHA1_Accmlt() API.
HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Timeout)
Initialize the HASH peripheral in SHA1 mode, next process pInBuffer then read the computed digest.
HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
If not already done, initialize the HASH peripheral in SHA1 mode then processes pInBuffer.
HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer)
Initialize the HASH peripheral in SHA1 mode, next process pInBuffer then read the computed digest in ...
HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_End_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer)
End computation of a single HASH signature after several calls to HAL_HASH_MD5_Accmlt_IT() API.
HAL_StatusTypeDef HAL_HASH_MD5_Accmlt_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
If not already done, initialize the HASH peripheral in MD5 mode then processes pInBuffer in interrupt...
HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_End_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer)
End computation of a single HASH signature after several calls to HAL_HASH_SHA1_Accmlt_IT() API.
HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer)
Initialize the HASH peripheral in MD5 mode, next process pInBuffer then read the computed digest in i...
void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash)
Handle HASH interrupt request.
HAL_StatusTypeDef HAL_HASH_SHA1_Accmlt_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
If not already done, initialize the HASH peripheral in SHA1 mode then processes pInBuffer in interrup...
HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
Return the computed digest in MD5 mode.
HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
Initialize the HASH peripheral in MD5 mode then initiate a DMA transfer to feed the input buffer to t...
HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
Initialize the HASH peripheral in SHA1 mode then initiate a DMA transfer to feed the input buffer to ...
HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
Return the computed digest in SHA1 mode.
HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Timeout)
Initialize the HASH peripheral in HMAC MD5 mode, next process pInBuffer then read the computed digest...
HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Timeout)
Initialize the HASH peripheral in HMAC SHA1 mode, next process pInBuffer then read the computed diges...
HAL_StatusTypeDef HAL_HMAC_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer)
Initialize the HASH peripheral in HMAC SHA1 mode, next process pInBuffer then read the computed diges...
HAL_StatusTypeDef HAL_HMAC_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer)
Initialize the HASH peripheral in HMAC MD5 mode, next process pInBuffer then read the computed digest...
HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
Initialize the HASH peripheral in HMAC MD5 mode then initiate the required DMA transfers to feed the ...
HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
Initialize the HASH peripheral in HMAC SHA1 mode then initiate the required DMA transfers to feed the...
void HAL_HASH_ContextSaving(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer)
Save the HASH context in case of processing suspension.
HAL_HASH_StateTypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash)
Return the HASH handle state.
HAL_StatusTypeDef HAL_HASH_GetStatus(HASH_HandleTypeDef *hhash)
Return the HASH HAL status.
uint32_t HAL_HASH_GetError(HASH_HandleTypeDef *hhash)
Return the HASH handle error code.
void HAL_HASH_ContextRestoring(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer)
Restore the HASH context in case of processing resumption.
void HAL_HASH_SwFeed_ProcessSuspend(HASH_HandleTypeDef *hhash)
Initiate HASH processing suspension when in polling or interruption mode.
HAL_StatusTypeDef HAL_HASH_DMAFeed_ProcessSuspend(HASH_HandleTypeDef *hhash)
Suspend the HASH processing when in DMA mode.
#define __HAL_HASH_SET_MDMAT()
Enable the multi-buffer DMA transfer mode.
#define __HAL_HASH_INIT()
Reset the HASH core.
#define __HAL_HASH_SET_NBVALIDBITS(__SIZE__)
Set the number of valid bits in the last word written in data register DIN.
#define __HAL_HASH_DISABLE_IT(__INTERRUPT__)
Disable the specified HASH interrupt.
#define __HAL_HASH_ENABLE_IT(__INTERRUPT__)
Enable the specified HASH interrupt.
#define __HAL_HASH_GET_FLAG(__FLAG__)
Check whether or not the specified HASH flag is set.
#define __HAL_HASH_RESET_MDMAT()
Disable the multi-buffer DMA transfer mode.
#define __HAL_HASH_START_DIGEST()
Start the digest computation.
HAL_HASH_StateTypeDef
HAL State structures definition.
@ HAL_HASH_PHASE_HMAC_STEP_1
@ HAL_HASH_PHASE_HMAC_STEP_3
@ HAL_HASH_PHASE_READY
@ HAL_HASH_PHASE_PROCESS
@ HAL_HASH_PHASE_HMAC_STEP_2
@ HAL_HASH_SUSPEND
@ HAL_HASH_SUSPEND_NONE
@ HAL_HASH_STATE_BUSY
@ HAL_HASH_STATE_SUSPENDED
@ HAL_HASH_STATE_READY
@ HAL_HASH_STATE_ERROR
@ HAL_HASH_STATE_RESET
#define HASH_HMAC_KEYTYPE_LONGKEY
#define HASH_NUMBER_OF_CSR_REGISTERS
static uint32_t HASH_Write_Block_Data(HASH_HandleTypeDef *hhash)
Write a block of data in HASH Peripheral in interruption mode.
static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
DMA HASH Input Data transfer completion callback.
static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
Handle HASH processing Timeout.
static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
Retrieve the message digest.
static HAL_StatusTypeDef HMAC_Processing(HASH_HandleTypeDef *hhash, uint32_t Timeout)
HMAC processing in polling mode.
HAL_StatusTypeDef HMAC_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Timeout, uint32_t Algorithm)
Initialize the HASH peripheral in HMAC mode, next process pInBuffer then read the computed digest.
static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
Feed the input buffer to the HASH Peripheral.
HAL_StatusTypeDef HASH_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
If not already done, initialize the HASH peripheral then processes pInBuffer.
HAL_StatusTypeDef HASH_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
Initialize the HASH peripheral then initiate a DMA transfer to feed the input buffer to the Periphera...
HAL_StatusTypeDef HASH_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Timeout, uint32_t Algorithm)
Initialize the HASH peripheral, next process pInBuffer then read the computed digest.
static HAL_StatusTypeDef HASH_IT(HASH_HandleTypeDef *hhash)
HASH processing in interruption mode.
HAL_StatusTypeDef HASH_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
Return the computed digest.
HAL_StatusTypeDef HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
If not already done, initialize the HASH peripheral then processes pInBuffer in interruption mode.
HAL_StatusTypeDef HASH_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Algorithm)
Initialize the HASH peripheral, next process pInBuffer then read the computed digest in interruption ...
static void HASH_DMAError(DMA_HandleTypeDef *hdma)
DMA HASH communication error callback.
HAL_StatusTypeDef HMAC_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm)
Initialize the HASH peripheral in HMAC mode then initiate the required DMA transfers to feed the key ...
HAL_StatusTypeDef HMAC_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t *pOutBuffer, uint32_t Algorithm)
Initialize the HASH peripheral in HMAC mode, next process pInBuffer then read the computed digest in ...
#define IS_HMAC_DMA_MULTIBUFFER_SIZE(__HANDLE__, __SIZE__)
Ensure that input data buffer size is valid for multi-buffer HMAC processing in DMA mode.
#define IS_HASH_PROCESSING(__HANDLE__)
Ensure that handle phase is set to HASH processing.
#define HASH_NBW_PUSHED()
Return number of words already pushed in the FIFO.
#define IS_HMAC_PROCESSING(__HANDLE__)
Ensure that handle phase is set to HMAC processing.
#define HASH_DIGEST_LENGTH()
Return digest length in bytes.
#define IS_HASH_DMA_MULTIBUFFER_SIZE(__SIZE__)
Ensure that input data buffer size is valid for multi-buffer HASH processing in DMA mode.
#define IS_HASH_DATATYPE(__DATATYPE__)
Ensure that HASH input data type is valid.
#define HASH_TIMEOUTVALUE
#define HASH_FLAG_DCIS
#define HASH_FLAG_DINIS
#define HASH_FLAG_BUSY
#define HASH_IT_DINI
#define HASH_IT_DCI
#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 UNUSED(X)
#define __HAL_UNLOCK(__HANDLE__)
#define HAL_MAX_DELAY
@ HAL_UNLOCKED
#define __HAL_LOCK(__HANDLE__)
HASH Handle Structure definition.
HAL_StatusTypeDef Status
__IO uint32_t NbWordsAlreadyPushed
HAL_HASH_PhaseTypeDef Phase
__IO HAL_HASH_StateTypeDef State
HASH_InitTypeDef Init
FlagStatus DigestCalculationDisable
__IO uint32_t HashITCounter
DMA_HandleTypeDef * hdmain
HAL_HASH_SuspendTypeDef SuspendRequest
DMA handle Structure definition.
void(* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma)
DMA_Stream_TypeDef * Instance