STM32F4xx_HAL_Driver  1.8.3
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 -----------------------------------------------*/
273 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma);
274 static void HASH_DMAError(DMA_HandleTypeDef *hdma);
275 static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
276 static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status,
277  uint32_t Timeout);
278 static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size);
279 static HAL_StatusTypeDef HASH_IT(HASH_HandleTypeDef *hhash);
280 static uint32_t HASH_Write_Block_Data(HASH_HandleTypeDef *hhash);
281 static HAL_StatusTypeDef HMAC_Processing(HASH_HandleTypeDef *hhash, uint32_t Timeout);
328 HAL_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 
408 HAL_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 
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)
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  {
578  hhash->InCpltCallback = pCallback;
579  break;
580 
582  hhash->DgstCpltCallback = pCallback;
583  break;
584 
585  case HAL_HASH_ERROR_CB_ID :
586  hhash->ErrorCallback = pCallback;
587  break;
588 
590  hhash->MspInitCallback = pCallback;
591  break;
592 
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  {
610  hhash->MspInitCallback = pCallback;
611  break;
612 
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 
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  {
663  hhash->InCpltCallback = HAL_HASH_InCpltCallback; /* Legacy weak (surcharged) input completion callback */
664  break;
665 
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 
676  hhash->MspInitCallback = HAL_HASH_MspInit; /* Legacy weak (surcharged) Msp Init */
677  break;
678 
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  {
696  hhash->MspInitCallback = HAL_HASH_MspInit; /* Legacy weak (surcharged) Msp Init */
697  break;
698 
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 
769 HAL_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 
795 HAL_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 
810 HAL_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 
827 HAL_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 
853 HAL_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 
868 HAL_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 
916 HAL_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 
940 HAL_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 
954 HAL_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 
970 HAL_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 
995 HAL_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 
1009 HAL_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
1033  HAL_HASH_ErrorCallback(hhash);
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 
1082 HAL_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 
1097 HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
1098 {
1099  return HASH_Finish(hhash, pOutBuffer, Timeout);
1100 }
1101 
1112 HAL_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 
1128 HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
1129 {
1130  return HASH_Finish(hhash, pOutBuffer, Timeout);
1131 }
1132 
1169 HAL_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 
1188 HAL_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 
1230 HAL_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 
1248 HAL_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 
1302 HAL_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 
1327 HAL_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 
1387 HAL_StatusTypeDef HAL_HASH_GetStatus(HASH_HandleTypeDef *hhash)
1388 {
1389  return hhash->Status;
1390 }
1391 
1405 void 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 
1451 void 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) */
1472  __HAL_HASH_INIT();
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 */
1497  hhash->SuspendRequest = HAL_HASH_SUSPEND;
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 */
1533  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
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 */
1544  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, RESET, HASH_TIMEOUTVALUE) != HAL_OK)
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 */
1563  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
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 */
1618  hhash->State = HAL_HASH_STATE_SUSPENDED;
1619 
1620  return HAL_OK;
1621 
1622  }
1623 }
1624 
1631 {
1632  /* Return HASH Error Code */
1633  return hhash->ErrorCode;
1634 }
1655 static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
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
1679  HAL_HASH_InCpltCallback(hhash);
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
1703  HAL_HASH_InCpltCallback(hhash);
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 */
1725  __HAL_HASH_SET_MDMAT();
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
1742  HAL_HASH_InCpltCallback(hhash);
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 */
1765  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
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 
1799 static void HASH_DMAError(DMA_HandleTypeDef *hdma)
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
1814  HAL_HASH_ErrorCallback(hhash);
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 
1833 static 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  {
1852  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
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 */
1859  if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
1860  {
1861  /* Reset SuspendRequest */
1862  hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
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 */
1889  hhash->State = HAL_HASH_STATE_SUSPENDED;
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 
1952 static 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 
2030 static 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 
2093 static HAL_StatusTypeDef HASH_IT(HASH_HandleTypeDef *hhash)
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 */
2101  __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
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 */
2122  if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
2123  {
2124  /* Read the digest */
2125  HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH());
2126 
2127  /* Disable Interrupts */
2128  __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
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 */
2144  if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
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 */
2152  __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
2153 
2154  /* Reset SuspendRequest */
2155  hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
2156 
2157  /* Change the HASH state */
2158  hhash->State = HAL_HASH_STATE_SUSPENDED;
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 */
2165  if (HASH_Write_Block_Data(hhash) == HASH_DIGEST_CALCULATION_STARTED)
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
2172  HAL_HASH_InCpltCallback(hhash);
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 */
2178  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
2179  {
2180  /* Disable Interrupts */
2181  __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
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 */
2196  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
2197  {
2198  /* Disable Interrupts */
2199  __HAL_HASH_DISABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
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 
2234 static uint32_t HASH_Write_Block_Data(HASH_HandleTypeDef *hhash)
2235 {
2236  uint32_t inputaddr;
2237  uint32_t buffercounter;
2238  uint32_t inputcounter;
2239  uint32_t ret = HASH_DIGEST_CALCULATION_NOT_STARTED;
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 */
2290  __HAL_HASH_DISABLE_IT(HASH_IT_DINI);
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
2312  HAL_HASH_InCpltCallback(hhash);
2313 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2314  }
2315  else
2316  {
2317  /* Start the Digest calculation */
2318  __HAL_HASH_START_DIGEST();
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. */
2323  ret = HASH_DIGEST_CALCULATION_STARTED;
2324  }
2325  /* Reset buffer counter */
2326  hhash->HashInCount = 0;
2327  }
2328 
2329  /* Return whether or digest calculation has started */
2330  return ret;
2331 }
2332 
2339 static HAL_StatusTypeDef HMAC_Processing(HASH_HandleTypeDef *hhash, uint32_t Timeout)
2340 {
2341  /* Ensure first that Phase is correct */
2342  if ((hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_1) && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_2)
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 */
2360  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
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. */
2380  __HAL_HASH_START_DIGEST();
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 */
2389  hhash->Phase = HAL_HASH_PHASE_HMAC_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 */
2402  __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize);
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. */
2422  __HAL_HASH_START_DIGEST();
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 */
2431  hhash->Phase = HAL_HASH_PHASE_HMAC_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 */
2449  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
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. */
2469  __HAL_HASH_START_DIGEST();
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 */
2478  HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH());
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 
2507 HAL_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 */
2538  __HAL_HASH_SET_NBVALIDBITS(Size);
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 */
2546  hhash->Phase = HAL_HASH_PHASE_PROCESS;
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 */
2569  __HAL_HASH_SET_NBVALIDBITS(Size);
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 */
2598  __HAL_HASH_START_DIGEST();
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 
2644 HAL_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 */
2700  hhash->Phase = HAL_HASH_PHASE_PROCESS;
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 
2747 HAL_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 */
2796  hhash->Phase = HAL_HASH_PHASE_PROCESS;
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 */
2843  __HAL_HASH_ENABLE_IT(HASH_IT_DINI);
2844 
2845  /* Return function status */
2846  return HAL_OK;
2847 
2848  }
2849  else
2850  {
2851  return HAL_BUSY;
2852  }
2853 
2854 }
2855 
2856 
2857 
2869 HAL_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 */
2904  __HAL_HASH_SET_NBVALIDBITS(SizeVar);
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 */
2924  hhash->Phase = HAL_HASH_PHASE_PROCESS;
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 */
2948  __HAL_HASH_START_DIGEST();
2949  /* Process Unlock */
2950  __HAL_UNLOCK(hhash);
2951 
2952  /* Enable Interrupts */
2953  __HAL_HASH_ENABLE_IT(HASH_IT_DCI);
2954 
2955  /* Return function status */
2956  return HAL_OK;
2957  }
2958  else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
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 */
2966  __HAL_HASH_SET_NBVALIDBITS(SizeVar);
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. */
2977  __HAL_HASH_SET_NBVALIDBITS(SizeVar);
2978  HASH->DIN = *(uint32_t *)inputaddr;
2979 
2980  /* Start the Digest calculation */
2981  hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2982  __HAL_HASH_START_DIGEST();
2983  /* Process Unlock */
2984  __HAL_UNLOCK(hhash);
2985 
2986  /* Enable Interrupts */
2987  __HAL_HASH_ENABLE_IT(HASH_IT_DCI);
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 */
2999  __HAL_HASH_ENABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
3000 
3001  /* Return function status */
3002  return HAL_OK;
3003  }
3004  else
3005  {
3006  return HAL_BUSY;
3007  }
3008 
3009 }
3010 
3011 
3027 HAL_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) */
3037  assert_param(IS_HASH_DMA_MULTIBUFFER_SIZE(Size));
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 */
3073  hhash->Phase = HAL_HASH_PHASE_PROCESS;
3074  }
3075 
3076  /* Configure the Number of valid bits in last word of the message */
3077  __HAL_HASH_SET_NBVALIDBITS(Size);
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 */
3102  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
3103  /* Set the DMA error callback */
3104  hhash->hdmain->XferErrorCallback = HASH_DMAError;
3105 
3106  /* Store number of words already pushed to manage proper DMA processing suspension */
3107  hhash->NbWordsAlreadyPushed = HASH_NBW_PUSHED();
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 
3143 HAL_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 
3204 HAL_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 */
3241  hhash->Phase = HAL_HASH_PHASE_HMAC_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 
3282 HAL_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 */
3336  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
3337 
3338  /* Set the phase to Step 1 */
3339  hhash->Phase = HAL_HASH_PHASE_HMAC_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 */
3364  __HAL_HASH_ENABLE_IT(HASH_IT_DINI | HASH_IT_DCI);
3365 
3366  /* Return function status */
3367  return HAL_OK;
3368  }
3369  else
3370  {
3371  return HAL_BUSY;
3372  }
3373 
3374 }
3375 
3376 
3377 
3393 HAL_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) */
3401  assert_param(IS_HMAC_DMA_MULTIBUFFER_SIZE(hhash, Size));
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 */
3467  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
3468 
3469  /* Set the phase to Step 1 */
3470  hhash->Phase = HAL_HASH_PHASE_HMAC_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)
3493  __HAL_HASH_RESET_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 */
3523  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
3524  /* Set the DMA error callback */
3525  hhash->hdmain->XferErrorCallback = HASH_DMAError;
3526 
3527  /* Store number of words already pushed to manage proper DMA processing suspension */
3528  hhash->NbWordsAlreadyPushed = HASH_NBW_PUSHED();
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.
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.
HAL_StatusTypeDef HAL_HASH_RegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID, pHASH_CallbackTypeDef pCallback)
Register a User HASH Callback To be used instead of the weak (surcharged) predefined callback.
void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
Input data transfer complete call back.
HAL_StatusTypeDef HAL_HASH_UnRegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID)
Unregister a HASH Callback HASH Callback is redirected to the weak (surcharged) predefined callback.
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.
void(* pHASH_CallbackTypeDef)(HASH_HandleTypeDef *hhash)
HAL HASH Callback pointer definition.
HAL_HASH_CallbackIDTypeDef
HAL HASH common Callback ID enumeration definition.
struct __HASH_HandleTypeDef else typedef struct endif HASH_HandleTypeDef
HASH Handle Structure definition.
HAL_HASH_StateTypeDef
HAL State structures definition.
@ HAL_HASH_MSPINIT_CB_ID
@ HAL_HASH_INPUTCPLT_CB_ID
@ HAL_HASH_MSPDEINIT_CB_ID
@ HAL_HASH_ERROR_CB_ID
@ HAL_HASH_DGSTCPLT_CB_ID
@ 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
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.
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.
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 ...
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 ...
This file contains all the functions prototypes for the HAL module driver.
DMA handle Structure definition.