STM32L4xx_HAL_Driver  1.14.0
HASH Private Functions

Functions

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. More...
 
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. More...
 
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. More...
 
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 mode. More...
 
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 Peripheral. More...
 
HAL_StatusTypeDef HASH_Finish (HASH_HandleTypeDef *hhash, uint8_t *pOutBuffer, uint32_t Timeout)
 Return the computed digest. More...
 
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. More...
 
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 interruption mode. More...
 
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 and the input buffer to the Peripheral. More...
 
static void HASH_DMAXferCplt (DMA_HandleTypeDef *hdma)
 DMA HASH Input Data transfer completion callback. More...
 
static void HASH_DMAError (DMA_HandleTypeDef *hdma)
 DMA HASH communication error callback. More...
 
static void HASH_GetDigest (uint8_t *pMsgDigest, uint8_t Size)
 Retrieve the message digest. More...
 
static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout (HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
 Handle HASH processing Timeout. More...
 
static HAL_StatusTypeDef HASH_WriteData (HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
 Feed the input buffer to the HASH Peripheral. More...
 
static HAL_StatusTypeDef HASH_IT (HASH_HandleTypeDef *hhash)
 HASH processing in interruption mode. More...
 
static uint32_t HASH_Write_Block_Data (HASH_HandleTypeDef *hhash)
 Write a block of data in HASH Peripheral in interruption mode. More...
 
static HAL_StatusTypeDef HMAC_Processing (HASH_HandleTypeDef *hhash, uint32_t Timeout)
 HMAC processing in polling mode. More...
 

Detailed Description

Function Documentation

◆ HASH_Accumulate()

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.

Note
Field hhash->Phase of HASH handle is tested to check whether or not the Peripheral has already been initialized.
The input buffer size (in bytes) must be a multiple of 4 otherwise, the HASH digest computation is corrupted.
Parameters
hhashHASH handle.
pInBufferpointer to the input buffer (buffer to be hashed).
Sizelength of the input buffer in bytes, must be a multiple of 4.
AlgorithmHASH algorithm.
Return values
HALstatus

Definition at line 2474 of file stm32l4xx_hal_hash.c.

2475 {
2476  uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */
2477  uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */
2478  HAL_HASH_StateTypeDef State_tmp = hhash->State;
2479 
2480  /* Make sure the input buffer size (in bytes) is a multiple of 4 */
2481  if ((Size % 4U) != 0U)
2482  {
2483  return HAL_ERROR;
2484  }
2485 
2486  /* Initiate HASH processing in case of start or resumption */
2487 if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2488  {
2489  /* Check input parameters */
2490  if ((pInBuffer == NULL) || (Size == 0U))
2491  {
2492  hhash->State = HAL_HASH_STATE_READY;
2493  return HAL_ERROR;
2494  }
2495 
2496  /* Process Locked */
2497  __HAL_LOCK(hhash);
2498 
2499  /* If resuming the HASH processing */
2500  if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2501  {
2502  /* Change the HASH state */
2503  hhash->State = HAL_HASH_STATE_BUSY;
2504 
2505  /* Since this is resumption, pInBuffer_tmp and Size_tmp are not set
2506  to the API input parameters but to those saved beforehand by HASH_WriteData()
2507  when the processing was suspended */
2508  pInBuffer_tmp = hhash->pHashInBuffPtr; /* pInBuffer_tmp is set to the input data address */
2509  Size_tmp = hhash->HashInCount; /* Size_tmp contains the input data size in bytes */
2510 
2511  }
2512  else
2513  {
2514  /* Change the HASH state */
2515  hhash->State = HAL_HASH_STATE_BUSY;
2516 
2517  /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2518  input parameters of HASH_WriteData() */
2519  pInBuffer_tmp = pInBuffer; /* pInBuffer_tmp is set to the input data address */
2520  Size_tmp = Size; /* Size_tmp contains the input data size in bytes */
2521 
2522  /* Check if initialization phase has already be performed */
2523  if(hhash->Phase == HAL_HASH_PHASE_READY)
2524  {
2525  /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2526  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2527  }
2528 
2529  /* Set the phase */
2530  hhash->Phase = HAL_HASH_PHASE_PROCESS;
2531 
2532  }
2533 
2534  /* Write input buffer in Data register */
2535  hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp);
2536  if (hhash->Status != HAL_OK)
2537  {
2538  return hhash->Status;
2539  }
2540 
2541  /* If the process has not been suspended, move the state to Ready */
2542  if (hhash->State != HAL_HASH_STATE_SUSPENDED)
2543  {
2544  /* Change the HASH state */
2545  hhash->State = HAL_HASH_STATE_READY;
2546  }
2547 
2548  /* Process Unlocked */
2549  __HAL_UNLOCK(hhash);
2550 
2551  /* Return function status */
2552  return HAL_OK;
2553 
2554  }
2555  else
2556  {
2557  return HAL_BUSY;
2558  }
2559 
2560 
2561 }
__HAL_UNLOCK(hrtc)
__HAL_LOCK(hrtc)
return HAL_OK
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
Feed the input buffer to the HASH Peripheral.
HAL_HASH_StateTypeDef
HAL State structures definition.

◆ HASH_Accumulate_IT()

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.

Note
Field hhash->Phase of HASH handle is tested to check whether or not the Peripheral has already been initialized.
The input buffer size (in bytes) must be a multiple of 4 otherwise, the HASH digest computation is corrupted.
Parameters
hhashHASH handle.
pInBufferpointer to the input buffer (buffer to be hashed).
Sizelength of the input buffer in bytes, must be a multiple of 4.
AlgorithmHASH algorithm.
Return values
HALstatus

Definition at line 2577 of file stm32l4xx_hal_hash.c.

2578 {
2579  HAL_HASH_StateTypeDef State_tmp = hhash->State;
2580  __IO uint32_t inputaddr = (uint32_t) pInBuffer;
2581  uint32_t SizeVar = Size;
2582 
2583  /* Make sure the input buffer size (in bytes) is a multiple of 4 */
2584  if ((Size % 4U) != 0U)
2585  {
2586  return HAL_ERROR;
2587  }
2588 
2589  /* Initiate HASH processing in case of start or resumption */
2590  if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2591  {
2592  /* Check input parameters */
2593  if ((pInBuffer == NULL) || (Size == 0U))
2594  {
2595  hhash->State = HAL_HASH_STATE_READY;
2596  return HAL_ERROR;
2597  }
2598 
2599  /* Process Locked */
2600  __HAL_LOCK(hhash);
2601 
2602  /* If resuming the HASH processing */
2603  if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2604  {
2605  /* Change the HASH state */
2606  hhash->State = HAL_HASH_STATE_BUSY;
2607  }
2608  else
2609  {
2610  /* Change the HASH state */
2611  hhash->State = HAL_HASH_STATE_BUSY;
2612 
2613  /* Check if initialization phase has already be performed */
2614  if(hhash->Phase == HAL_HASH_PHASE_READY)
2615  {
2616  /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2617  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2618  hhash->HashITCounter = 1;
2619  }
2620  else
2621  {
2622  hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */
2623  }
2624 
2625  /* Set the phase */
2626  hhash->Phase = HAL_HASH_PHASE_PROCESS;
2627 
2628  /* If DINIS is equal to 0 (for example if an incomplete block has been previously
2629  fed to the Peripheral), the DINIE interruption won't be triggered when DINIE is set.
2630  Therefore, first words are manually entered until DINIS raises, or until there
2631  is not more data to enter. */
2632  while((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 0U))
2633  {
2634 
2635  /* Write input data 4 bytes at a time */
2636  HASH->DIN = *(uint32_t*)inputaddr;
2637  inputaddr+=4U;
2638  SizeVar-=4U;
2639  }
2640 
2641  /* If DINIS is still not set or if all the data have been fed, stop here */
2642  if ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) || (SizeVar == 0U))
2643  {
2644  /* Change the HASH state */
2645  hhash->State = HAL_HASH_STATE_READY;
2646 
2647  /* Process Unlock */
2648  __HAL_UNLOCK(hhash);
2649 
2650  /* Return function status */
2651  return HAL_OK;
2652  }
2653 
2654  /* otherwise, carry on in interrupt-mode */
2655  hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data
2656  to be fed to the Peripheral */
2657  hhash->pHashInBuffPtr = (uint8_t *)inputaddr; /* Points at data which will be fed to the Peripheral at
2658  the next interruption */
2659  /* In case of suspension, hhash->HashInCount and hhash->pHashInBuffPtr contain
2660  the information describing where the HASH process is stopped.
2661  These variables are used later on to resume the HASH processing at the
2662  correct location. */
2663 
2664  }
2665 
2666  /* Set multi buffers accumulation flag */
2667  hhash->Accumulation = 1U;
2668 
2669  /* Process Unlock */
2670  __HAL_UNLOCK(hhash);
2671 
2672  /* Enable Data Input interrupt */
2673  __HAL_HASH_ENABLE_IT(HASH_IT_DINI);
2674 
2675  /* Return function status */
2676  return HAL_OK;
2677 
2678  }
2679  else
2680  {
2681  return HAL_BUSY;
2682  }
2683 
2684 }
__HAL_UNLOCK(hrtc)
__HAL_LOCK(hrtc)
return HAL_OK
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
HAL_HASH_StateTypeDef
HAL State structures definition.

◆ HASH_DMAError()

static void HASH_DMAError ( DMA_HandleTypeDef hdma)
static

DMA HASH communication error callback.

Parameters
hdmaDMA handle.
Note
HASH_DMAError() callback invokes HAL_HASH_ErrorCallback() that can contain user code to manage the error.
Return values
None

Definition at line 1701 of file stm32l4xx_hal_hash.c.

1702 {
1703  HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1704 
1705  if (hhash->State != HAL_HASH_STATE_SUSPENDED)
1706  {
1707  hhash->ErrorCode |= HAL_HASH_ERROR_DMA;
1708  /* Set HASH state to ready to prevent any blocking issue in user code
1709  present in HAL_HASH_ErrorCallback() */
1710  hhash->State= HAL_HASH_STATE_READY;
1711  /* Set HASH handle status to error */
1712  hhash->Status = HAL_ERROR;
1713 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1714  hhash->ErrorCallback(hhash);
1715 #else
1716  HAL_HASH_ErrorCallback(hhash);
1717 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1718  /* After error handling by code user, reset HASH handle HAL status */
1719  hhash->Status = HAL_OK;
1720 
1721  }
1722 }
struct __HASH_HandleTypeDef else typedef struct endif HASH_HandleTypeDef
HASH Handle Structure definition.
DMA handle Structure definition.
return HAL_OK
void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash)
Error callback.

◆ HASH_DMAXferCplt()

static void HASH_DMAXferCplt ( DMA_HandleTypeDef hdma)
static

DMA HASH Input Data transfer completion callback.

Parameters
hdmaDMA handle.
Note
In case of HMAC processing, HASH_DMAXferCplt() initiates the next DMA transfer for the following HMAC step.
Return values
None

Definition at line 1561 of file stm32l4xx_hal_hash.c.

1562 {
1563  HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1564  uint32_t inputaddr;
1565  uint32_t buffersize;
1566  HAL_StatusTypeDef status ;
1567 
1568  if (hhash->State != HAL_HASH_STATE_SUSPENDED)
1569  {
1570 
1571  /* Disable the DMA transfer */
1572  CLEAR_BIT(HASH->CR, HASH_CR_DMAE);
1573 
1574  if (READ_BIT(HASH->CR, HASH_CR_MODE) == 0U)
1575  {
1576  /* If no HMAC processing, input data transfer is now over */
1577 
1578  /* Change the HASH state to ready */
1579  hhash->State = HAL_HASH_STATE_READY;
1580 
1581  /* Call Input data transfer complete call back */
1582 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1583  hhash->InCpltCallback(hhash);
1584 #else
1585  HAL_HASH_InCpltCallback(hhash);
1586 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1587 
1588  }
1589  else
1590  {
1591  /* HMAC processing: depending on the current HMAC step and whether or
1592  not multi-buffer processing is on-going, the next step is initiated
1593  and MDMAT bit is set. */
1594 
1595 
1596  if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)
1597  {
1598  /* This is the end of HMAC processing */
1599 
1600  /* Change the HASH state to ready */
1601  hhash->State = HAL_HASH_STATE_READY;
1602 
1603  /* Call Input data transfer complete call back
1604  (note that the last DMA transfer was that of the key
1605  for the outer HASH operation). */
1606 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1607  hhash->InCpltCallback(hhash);
1608 #else
1609  HAL_HASH_InCpltCallback(hhash);
1610 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1611 
1612  return;
1613  }
1614  else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
1615  {
1616  inputaddr = (uint32_t)hhash->pHashMsgBuffPtr; /* DMA transfer start address */
1617  buffersize = hhash->HashBuffSize; /* DMA transfer size (in bytes) */
1618  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; /* Move phase from Step 1 to Step 2 */
1619 
1620  /* In case of suspension request, save the new starting parameters */
1621  hhash->HashInCount = hhash->HashBuffSize; /* Initial DMA transfer size (in bytes) */
1622  hhash->pHashInBuffPtr = hhash->pHashMsgBuffPtr ; /* DMA transfer start address */
1623 
1624  hhash->NbWordsAlreadyPushed = 0U; /* Reset number of words already pushed */
1625  /* Check whether or not digest calculation must be disabled (in case of multi-buffer HMAC processing) */
1626  if (hhash->DigestCalculationDisable != RESET)
1627  {
1628  /* Digest calculation is disabled: Step 2 must start with MDMAT bit set,
1629  no digest calculation will be triggered at the end of the input buffer feeding to the Peripheral */
1630  __HAL_HASH_SET_MDMAT();
1631  }
1632  }
1633  else /*case (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)*/
1634  {
1635  if (hhash->DigestCalculationDisable != RESET)
1636  {
1637  /* No automatic move to Step 3 as a new message buffer will be fed to the Peripheral
1638  (case of multi-buffer HMAC processing):
1639  DCAL must not be set.
1640  Phase remains in Step 2, MDMAT remains set at this point.
1641  Change the HASH state to ready and call Input data transfer complete call back. */
1642  hhash->State = HAL_HASH_STATE_READY;
1643 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1644  hhash->InCpltCallback(hhash);
1645 #else
1646  HAL_HASH_InCpltCallback(hhash);
1647 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1648  return ;
1649  }
1650  else
1651  {
1652  /* Digest calculation is not disabled (case of single buffer input or last buffer
1653  of multi-buffer HMAC processing) */
1654  inputaddr = (uint32_t)hhash->Init.pKey; /* DMA transfer start address */
1655  buffersize = hhash->Init.KeySize; /* DMA transfer size (in bytes) */
1656  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; /* Move phase from Step 2 to Step 3 */
1657  /* In case of suspension request, save the new starting parameters */
1658  hhash->HashInCount = hhash->Init.KeySize; /* Initial size for second DMA transfer (input data) */
1659  hhash->pHashInBuffPtr = hhash->Init.pKey ; /* address passed to DMA, now entering data message */
1660 
1661  hhash->NbWordsAlreadyPushed = 0U; /* Reset number of words already pushed */
1662  }
1663  }
1664 
1665  /* Configure the Number of valid bits in last word of the message */
1666  __HAL_HASH_SET_NBVALIDBITS(buffersize);
1667 
1668  /* Set the HASH DMA transfert completion call back */
1669  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
1670 
1671  /* Enable the DMA In DMA Stream */
1672  status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (((buffersize %4U)!=0U) ? ((buffersize+(4U-(buffersize %4U)))/4U):(buffersize/4U)));
1673 
1674  /* Enable DMA requests */
1675  SET_BIT(HASH->CR, HASH_CR_DMAE);
1676 
1677  /* Return function status */
1678  if (status != HAL_OK)
1679  {
1680  /* Update DAC state machine to error */
1681  hhash->State = HAL_HASH_STATE_ERROR;
1682  }
1683  else
1684  {
1685  /* Change DAC state */
1686  hhash->State = HAL_HASH_STATE_READY;
1687  }
1688  }
1689  }
1690 
1691  return;
1692 }
struct __HASH_HandleTypeDef else typedef struct endif HASH_HandleTypeDef
HASH Handle Structure definition.
static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
DMA HASH Input Data transfer completion callback.
return(brrresult)
DMA handle Structure definition.
if(lpuartdiv >=LPUART_BRR_MIN_VALUE)
void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
Input data transfer complete call back.
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.
CLEAR_BIT(hrtc->Instance->CR, RTC_CR_WUTE)
return HAL_OK

◆ HASH_Finish()

HAL_StatusTypeDef HASH_Finish ( HASH_HandleTypeDef hhash,
uint8_t *  pOutBuffer,
uint32_t  Timeout 
)

Return the computed digest.

Note
The API waits for DCIS to be set then reads the computed digest.
Parameters
hhashHASH handle.
pOutBufferpointer to the computed digest.
TimeoutTimeout value.
Return values
HALstatus

Definition at line 2969 of file stm32l4xx_hal_hash.c.

2970 {
2971 
2972  if(hhash->State == HAL_HASH_STATE_READY)
2973  {
2974  /* Check parameter */
2975  if (pOutBuffer == NULL)
2976  {
2977  return HAL_ERROR;
2978  }
2979 
2980  /* Process Locked */
2981  __HAL_LOCK(hhash);
2982 
2983  /* Change the HASH state to busy */
2984  hhash->State = HAL_HASH_STATE_BUSY;
2985 
2986  /* Wait for DCIS flag to be set */
2987  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
2988  {
2989  return HAL_TIMEOUT;
2990  }
2991 
2992  /* Read the message digest */
2993  HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH());
2994 
2995  /* Change the HASH state to ready */
2996  hhash->State = HAL_HASH_STATE_READY;
2997 
2998  /* Process UnLock */
2999  __HAL_UNLOCK(hhash);
3000 
3001  /* Return function status */
3002  return HAL_OK;
3003 
3004  }
3005  else
3006  {
3007  return HAL_BUSY;
3008  }
3009 
3010 }
static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
Handle HASH processing Timeout.
__HAL_UNLOCK(hrtc)
__HAL_LOCK(hrtc)
return HAL_OK
static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
Retrieve the message digest.

◆ HASH_GetDigest()

static void HASH_GetDigest ( uint8_t *  pMsgDigest,
uint8_t  Size 
)
static

Retrieve the message digest.

Parameters
pMsgDigestpointer to the computed digest.
Sizemessage digest size in bytes.
Return values
None

Definition at line 1799 of file stm32l4xx_hal_hash.c.

1800 {
1801  uint32_t msgdigest = (uint32_t)pMsgDigest;
1802 
1803  switch(Size)
1804  {
1805  /* Read the message digest */
1806  case 16: /* MD5 */
1807  *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1808  msgdigest+=4U;
1809  *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1810  msgdigest+=4U;
1811  *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1812  msgdigest+=4U;
1813  *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1814  break;
1815  case 20: /* SHA1 */
1816  *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1817  msgdigest+=4U;
1818  *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1819  msgdigest+=4U;
1820  *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1821  msgdigest+=4U;
1822  *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1823  msgdigest+=4U;
1824  *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1825  break;
1826  case 28: /* SHA224 */
1827  *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1828  msgdigest+=4U;
1829  *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1830  msgdigest+=4U;
1831  *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1832  msgdigest+=4U;
1833  *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1834  msgdigest+=4U;
1835  *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1836  msgdigest+=4U;
1837  *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1838  msgdigest+=4U;
1839  *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1840  break;
1841  case 32: /* SHA256 */
1842  *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]);
1843  msgdigest+=4U;
1844  *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]);
1845  msgdigest+=4U;
1846  *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]);
1847  msgdigest+=4U;
1848  *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]);
1849  msgdigest+=4U;
1850  *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]);
1851  msgdigest+=4U;
1852  *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]);
1853  msgdigest+=4U;
1854  *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]);
1855  msgdigest+=4U;
1856  *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]);
1857  break;
1858  default:
1859  break;
1860  }
1861 }

◆ HASH_IT()

static HAL_StatusTypeDef HASH_IT ( HASH_HandleTypeDef hhash)
static

HASH processing in interruption mode.

Parameters
hhashHASH handle.
Note
HASH_IT() regularly reads hhash->SuspendRequest to check whether or not the HASH processing must be suspended. If this is the case, the processing is suspended when possible and the Peripheral feeding point reached at suspension time is stored in the handle for resumption later on.
Return values
HALstatus

Definition at line 1935 of file stm32l4xx_hal_hash.c.

1936 {
1937  if (hhash->State == HAL_HASH_STATE_BUSY)
1938  {
1939  /* ITCounter must not be equal to 0 at this point. Report an error if this is the case. */
1940  if(hhash->HashITCounter == 0U)
1941  {
1942  /* Disable Interrupts */
1943  __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI);
1944  /* HASH state set back to Ready to prevent any issue in user code
1945  present in HAL_HASH_ErrorCallback() */
1946  hhash->State = HAL_HASH_STATE_READY;
1947  return HAL_ERROR;
1948  }
1949  else if (hhash->HashITCounter == 1U)
1950  {
1951  /* This is the first call to HASH_IT, the first input data are about to be
1952  entered in the Peripheral. A specific processing is carried out at this point to
1953  start-up the processing. */
1954  hhash->HashITCounter = 2U;
1955  }
1956  else
1957  {
1958  /* Cruise speed reached, HashITCounter remains equal to 3 until the end of
1959  the HASH processing or the end of the current step for HMAC processing. */
1960  hhash->HashITCounter = 3U;
1961  }
1962 
1963  /* If digest is ready */
1964  if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
1965  {
1966  /* Read the digest */
1967  HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH());
1968 
1969  /* Disable Interrupts */
1970  __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI);
1971  /* Change the HASH state */
1972  hhash->State = HAL_HASH_STATE_READY;
1973  /* Call digest computation complete call back */
1974 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
1975  hhash->DgstCpltCallback(hhash);
1976 #else
1978 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
1979 
1980  return HAL_OK;
1981  }
1982 
1983  /* If Peripheral ready to accept new data */
1984  if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
1985  {
1986 
1987  /* If the suspension flag has been raised and if the processing is not about
1988  to end, suspend processing */
1989  if ( (hhash->HashInCount != 0U) && (hhash->SuspendRequest == HAL_HASH_SUSPEND))
1990  {
1991  /* Disable Interrupts */
1992  __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI);
1993 
1994  /* Reset SuspendRequest */
1995  hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
1996 
1997  /* Change the HASH state */
1998  hhash->State = HAL_HASH_STATE_SUSPENDED;
1999 
2000  return HAL_OK;
2001  }
2002 
2003  /* Enter input data in the Peripheral thru HASH_Write_Block_Data() call and
2004  check whether the digest calculation has been triggered */
2005  if (HASH_Write_Block_Data(hhash) == HASH_DIGEST_CALCULATION_STARTED)
2006  {
2007  /* Call Input data transfer complete call back
2008  (called at the end of each step for HMAC) */
2009 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2010  hhash->InCpltCallback(hhash);
2011 #else
2012  HAL_HASH_InCpltCallback(hhash);
2013 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2014 
2015  if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
2016  {
2017  /* Wait until Peripheral is not busy anymore */
2018  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
2019  {
2020  /* Disable Interrupts */
2021  __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI);
2022  return HAL_TIMEOUT;
2023  }
2024  /* Initialization start for HMAC STEP 2 */
2025  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; /* Move phase from Step 1 to Step 2 */
2026  __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); /* Set NBLW for the input message */
2027  hhash->HashInCount = hhash->HashBuffSize; /* Set the input data size (in bytes) */
2028  hhash->pHashInBuffPtr = hhash->pHashMsgBuffPtr; /* Set the input data address */
2029  hhash->HashITCounter = 1; /* Set ITCounter to 1 to indicate the start of a new phase */
2030  __HAL_HASH_ENABLE_IT(HASH_IT_DINI); /* Enable IT (was disabled in HASH_Write_Block_Data) */
2031  }
2032  else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
2033  {
2034  /* Wait until Peripheral is not busy anymore */
2035  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
2036  {
2037  /* Disable Interrupts */
2038  __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI);
2039  return HAL_TIMEOUT;
2040  }
2041  /* Initialization start for HMAC STEP 3 */
2042  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; /* Move phase from Step 2 to Step 3 */
2043  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); /* Set NBLW for the key */
2044  hhash->HashInCount = hhash->Init.KeySize; /* Set the key size (in bytes) */
2045  hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */
2046  hhash->HashITCounter = 1; /* Set ITCounter to 1 to indicate the start of a new phase */
2047  __HAL_HASH_ENABLE_IT(HASH_IT_DINI); /* Enable IT (was disabled in HASH_Write_Block_Data) */
2048  }
2049  else
2050  {
2051  /* Nothing to do */
2052  }
2053  } /* if (HASH_Write_Block_Data(hhash) == HASH_DIGEST_CALCULATION_STARTED) */
2054  } /* if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))*/
2055 
2056  /* Return function status */
2057  return HAL_OK;
2058  }
2059  else
2060  {
2061  return HAL_BUSY;
2062  }
2063 }
void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
Input data transfer complete call back.
static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
Handle HASH processing Timeout.
void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash)
Digest computation complete call back.
return HAL_OK
static uint32_t HASH_Write_Block_Data(HASH_HandleTypeDef *hhash)
Write a block of data in HASH Peripheral in interruption mode.
static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
Retrieve the message digest.

◆ HASH_Start()

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.

Note
Digest is available in pOutBuffer.
Parameters
hhashHASH handle.
pInBufferpointer to the input buffer (buffer to be hashed).
Sizelength of the input buffer in bytes.
pOutBufferpointer to the computed digest.
TimeoutTimeout value.
AlgorithmHASH algorithm.
Return values
HALstatus

Definition at line 2341 of file stm32l4xx_hal_hash.c.

2342 {
2343  uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */
2344  uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */
2345  HAL_HASH_StateTypeDef State_tmp = hhash->State;
2346 
2347 
2348  /* Initiate HASH processing in case of start or resumption */
2349 if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2350  {
2351  /* Check input parameters */
2352  if ((pInBuffer == NULL) || (Size == 0U) || (pOutBuffer == NULL))
2353  {
2354  hhash->State = HAL_HASH_STATE_READY;
2355  return HAL_ERROR;
2356  }
2357 
2358  /* Process Locked */
2359  __HAL_LOCK(hhash);
2360 
2361  /* Check if initialization phase has not been already performed */
2362  if(hhash->Phase == HAL_HASH_PHASE_READY)
2363  {
2364  /* Change the HASH state */
2365  hhash->State = HAL_HASH_STATE_BUSY;
2366 
2367  /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2368  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2369 
2370  /* Configure the number of valid bits in last word of the message */
2371  __HAL_HASH_SET_NBVALIDBITS(Size);
2372 
2373  /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2374  input parameters of HASH_WriteData() */
2375  pInBuffer_tmp = pInBuffer; /* pInBuffer_tmp is set to the input data address */
2376  Size_tmp = Size; /* Size_tmp contains the input data size in bytes */
2377 
2378  /* Set the phase */
2379  hhash->Phase = HAL_HASH_PHASE_PROCESS;
2380  }
2381  else if (hhash->Phase == HAL_HASH_PHASE_PROCESS)
2382  {
2383  /* if the Peripheral has already been initialized, two cases are possible */
2384 
2385  /* Process resumption time ... */
2386  if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2387  {
2388  /* Since this is resumption, pInBuffer_tmp and Size_tmp are not set
2389  to the API input parameters but to those saved beforehand by HASH_WriteData()
2390  when the processing was suspended */
2391  pInBuffer_tmp = hhash->pHashInBuffPtr;
2392  Size_tmp = hhash->HashInCount;
2393  }
2394  /* ... or multi-buffer HASH processing end */
2395  else
2396  {
2397  /* pInBuffer_tmp and Size_tmp are initialized to be used afterwards as
2398  input parameters of HASH_WriteData() */
2399  pInBuffer_tmp = pInBuffer;
2400  Size_tmp = Size;
2401  /* Configure the number of valid bits in last word of the message */
2402  __HAL_HASH_SET_NBVALIDBITS(Size);
2403  }
2404  /* Change the HASH state */
2405  hhash->State = HAL_HASH_STATE_BUSY;
2406  }
2407  else
2408  {
2409  /* Phase error */
2410  hhash->State = HAL_HASH_STATE_READY;
2411 
2412  /* Process Unlocked */
2413  __HAL_UNLOCK(hhash);
2414 
2415  /* Return function status */
2416  return HAL_ERROR;
2417  }
2418 
2419 
2420  /* Write input buffer in Data register */
2421  hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp);
2422  if (hhash->Status != HAL_OK)
2423  {
2424  return hhash->Status;
2425  }
2426 
2427  /* If the process has not been suspended, carry on to digest calculation */
2428  if (hhash->State != HAL_HASH_STATE_SUSPENDED)
2429  {
2430  /* Start the Digest calculation */
2431  __HAL_HASH_START_DIGEST();
2432 
2433  /* Wait for DCIS flag to be set */
2434  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
2435  {
2436  return HAL_TIMEOUT;
2437  }
2438 
2439  /* Read the message digest */
2440  HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH());
2441 
2442  /* Change the HASH state */
2443  hhash->State = HAL_HASH_STATE_READY;
2444 
2445  }
2446 
2447  /* Process Unlocked */
2448  __HAL_UNLOCK(hhash);
2449 
2450  /* Return function status */
2451  return HAL_OK;
2452 
2453  }
2454  else
2455  {
2456  return HAL_BUSY;
2457  }
2458 }
static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
Handle HASH processing Timeout.
__HAL_UNLOCK(hrtc)
__HAL_LOCK(hrtc)
return HAL_OK
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
Retrieve the message digest.
static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
Feed the input buffer to the HASH Peripheral.
HAL_HASH_StateTypeDef
HAL State structures definition.

◆ HASH_Start_DMA()

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 Peripheral.

Note
If MDMAT bit is set before calling this function (multi-buffer HASH processing case), the input buffer size (in bytes) must be a multiple of 4 otherwise, the HASH digest computation is corrupted. For the processing of the last buffer of the thread, MDMAT bit must be reset and the buffer length (in bytes) doesn't have to be a multiple of 4.
Parameters
hhashHASH handle.
pInBufferpointer to the input buffer (buffer to be hashed).
Sizelength of the input buffer in bytes.
AlgorithmHASH algorithm.
Return values
HALstatus

Definition at line 2855 of file stm32l4xx_hal_hash.c.

2856 {
2857  uint32_t inputaddr;
2858  uint32_t inputSize;
2859  HAL_StatusTypeDef status ;
2860  HAL_HASH_StateTypeDef State_tmp = hhash->State;
2861 
2862 #if defined (HASH_CR_MDMAT)
2863  /* Make sure the input buffer size (in bytes) is a multiple of 4 when MDMAT bit is set
2864  (case of multi-buffer HASH processing) */
2865  assert_param(IS_HASH_DMA_MULTIBUFFER_SIZE(Size));
2866 #endif /* MDMA defined*/
2867  /* If State is ready or suspended, start or resume polling-based HASH processing */
2868 if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2869  {
2870  /* Check input parameters */
2871  if ( (pInBuffer == NULL ) || (Size == 0U) ||
2872  /* Check phase coherency. Phase must be
2873  either READY (fresh start)
2874  or PROCESS (multi-buffer HASH management) */
2875  ((hhash->Phase != HAL_HASH_PHASE_READY) && (!(IS_HASH_PROCESSING(hhash)))))
2876  {
2877  hhash->State = HAL_HASH_STATE_READY;
2878  return HAL_ERROR;
2879  }
2880 
2881 
2882  /* Process Locked */
2883  __HAL_LOCK(hhash);
2884 
2885  /* If not a resumption case */
2886  if (hhash->State == HAL_HASH_STATE_READY)
2887  {
2888  /* Change the HASH state */
2889  hhash->State = HAL_HASH_STATE_BUSY;
2890 
2891  /* Check if initialization phase has already been performed.
2892  If Phase is already set to HAL_HASH_PHASE_PROCESS, this means the
2893  API is processing a new input data message in case of multi-buffer HASH
2894  computation. */
2895  if(hhash->Phase == HAL_HASH_PHASE_READY)
2896  {
2897  /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2898  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2899 
2900  /* Set the phase */
2901  hhash->Phase = HAL_HASH_PHASE_PROCESS;
2902  }
2903 
2904  /* Configure the Number of valid bits in last word of the message */
2905  __HAL_HASH_SET_NBVALIDBITS(Size);
2906 
2907  inputaddr = (uint32_t)pInBuffer; /* DMA transfer start address */
2908  inputSize = Size; /* DMA transfer size (in bytes) */
2909 
2910  /* In case of suspension request, save the starting parameters */
2911  hhash->pHashInBuffPtr = pInBuffer; /* DMA transfer start address */
2912  hhash->HashInCount = Size; /* DMA transfer size (in bytes) */
2913 
2914  }
2915  /* If resumption case */
2916  else
2917  {
2918  /* Change the HASH state */
2919  hhash->State = HAL_HASH_STATE_BUSY;
2920 
2921  /* Resumption case, inputaddr and inputSize are not set to the API input parameters
2922  but to those saved beforehand by HAL_HASH_DMAFeed_ProcessSuspend() when the
2923  processing was suspended */
2924  inputaddr = (uint32_t)hhash->pHashInBuffPtr; /* DMA transfer start address */
2925  inputSize = hhash->HashInCount; /* DMA transfer size (in bytes) */
2926 
2927  }
2928 
2929  /* Set the HASH DMA transfert complete callback */
2930  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
2931  /* Set the DMA error callback */
2932  hhash->hdmain->XferErrorCallback = HASH_DMAError;
2933 
2934  /* Store number of words already pushed to manage proper DMA processing suspension */
2935  hhash->NbWordsAlreadyPushed = HASH_NBW_PUSHED();
2936 
2937  /* Enable the DMA In DMA Stream */
2938  status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (((inputSize %4U)!=0U) ? ((inputSize+(4U-(inputSize %4U)))/4U):(inputSize/4U)));
2939 
2940  /* Enable DMA requests */
2941  SET_BIT(HASH->CR, HASH_CR_DMAE);
2942 
2943  /* Process Unlock */
2944  __HAL_UNLOCK(hhash);
2945 
2946  /* Return function status */
2947  if (status != HAL_OK)
2948  {
2949  /* Update HASH state machine to error */
2950  hhash->State = HAL_HASH_STATE_ERROR;
2951  }
2952 
2953  return status;
2954  }
2955  else
2956  {
2957  return HAL_BUSY;
2958  }
2959 }
static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
DMA HASH Input Data transfer completion callback.
static void HASH_DMAError(DMA_HandleTypeDef *hdma)
DMA HASH communication error callback.
__HAL_UNLOCK(hrtc)
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.
__HAL_LOCK(hrtc)
return HAL_OK
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
HAL_HASH_StateTypeDef
HAL State structures definition.
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))

◆ HASH_Start_IT()

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 mode.

Note
Digest is available in pOutBuffer.
Parameters
hhashHASH handle.
pInBufferpointer to the input buffer (buffer to be hashed).
Sizelength of the input buffer in bytes.
pOutBufferpointer to the computed digest.
AlgorithmHASH algorithm.
Return values
HALstatus

Definition at line 2699 of file stm32l4xx_hal_hash.c.

2700 {
2701  HAL_HASH_StateTypeDef State_tmp = hhash->State;
2702  __IO uint32_t inputaddr = (uint32_t) pInBuffer;
2703  uint32_t polling_step = 0U;
2704  uint32_t initialization_skipped = 0U;
2705  uint32_t SizeVar = Size;
2706 
2707  /* If State is ready or suspended, start or resume IT-based HASH processing */
2708 if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
2709  {
2710  /* Check input parameters */
2711  if ((pInBuffer == NULL) || (Size == 0U) || (pOutBuffer == NULL))
2712  {
2713  hhash->State = HAL_HASH_STATE_READY;
2714  return HAL_ERROR;
2715  }
2716 
2717  /* Process Locked */
2718  __HAL_LOCK(hhash);
2719 
2720  /* Change the HASH state */
2721  hhash->State = HAL_HASH_STATE_BUSY;
2722 
2723  /* Initialize IT counter */
2724  hhash->HashITCounter = 1;
2725 
2726  /* Check if initialization phase has already be performed */
2727  if(hhash->Phase == HAL_HASH_PHASE_READY)
2728  {
2729  /* Select the HASH algorithm, clear HMAC mode and long key selection bit, reset the HASH processor core */
2730  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT);
2731 
2732  /* Configure the number of valid bits in last word of the message */
2733  __HAL_HASH_SET_NBVALIDBITS(SizeVar);
2734 
2735 
2736  hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data
2737  to be fed to the Peripheral */
2738  hhash->pHashInBuffPtr = pInBuffer; /* Points at data which will be fed to the Peripheral at
2739  the next interruption */
2740  /* In case of suspension, hhash->HashInCount and hhash->pHashInBuffPtr contain
2741  the information describing where the HASH process is stopped.
2742  These variables are used later on to resume the HASH processing at the
2743  correct location. */
2744 
2745  hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2746  }
2747  else
2748  {
2749  initialization_skipped = 1; /* info user later on in case of multi-buffer */
2750  }
2751 
2752  /* Set the phase */
2753  hhash->Phase = HAL_HASH_PHASE_PROCESS;
2754 
2755  /* If DINIS is equal to 0 (for example if an incomplete block has been previously
2756  fed to the Peripheral), the DINIE interruption won't be triggered when DINIE is set.
2757  Therefore, first words are manually entered until DINIS raises. */
2758  while((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 3U))
2759  {
2760  polling_step = 1U; /* note that some words are entered before enabling the interrupt */
2761 
2762  /* Write input data 4 bytes at a time */
2763  HASH->DIN = *(uint32_t*)inputaddr;
2764  inputaddr+=4U;
2765  SizeVar-=4U;
2766  }
2767 
2768  if (polling_step == 1U)
2769  {
2770  if (SizeVar == 0U)
2771  {
2772  /* If all the data have been entered at this point, it only remains to
2773  read the digest */
2774  hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2775 
2776  /* Start the Digest calculation */
2777  __HAL_HASH_START_DIGEST();
2778  /* Process Unlock */
2779  __HAL_UNLOCK(hhash);
2780 
2781  /* Enable Interrupts */
2782  __HAL_HASH_ENABLE_IT(HASH_IT_DCI);
2783 
2784  /* Return function status */
2785  return HAL_OK;
2786  }
2787  else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
2788  {
2789  /* It remains data to enter and the Peripheral is ready to trigger DINIE,
2790  carry on as usual.
2791  Update HashInCount and pHashInBuffPtr accordingly. */
2792  hhash->HashInCount = SizeVar;
2793  hhash->pHashInBuffPtr = (uint8_t *)inputaddr;
2794  __HAL_HASH_SET_NBVALIDBITS(SizeVar); /* Update the configuration of the number of valid bits in last word of the message */
2795  hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2796  if (initialization_skipped == 1U)
2797  {
2798  hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */
2799  }
2800  }
2801  else
2802  {
2803  /* DINIS is not set but it remains a few data to enter (not enough for a full word).
2804  Manually enter the last bytes before enabling DCIE. */
2805  __HAL_HASH_SET_NBVALIDBITS(SizeVar);
2806  HASH->DIN = *(uint32_t*)inputaddr;
2807 
2808  /* Start the Digest calculation */
2809  hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */
2810  __HAL_HASH_START_DIGEST();
2811  /* Process Unlock */
2812  __HAL_UNLOCK(hhash);
2813 
2814  /* Enable Interrupts */
2815  __HAL_HASH_ENABLE_IT(HASH_IT_DCI);
2816 
2817  /* Return function status */
2818  return HAL_OK;
2819  }
2820  } /* if (polling_step == 1) */
2821 
2822 
2823  /* Process Unlock */
2824  __HAL_UNLOCK(hhash);
2825 
2826  /* Enable Interrupts */
2827  __HAL_HASH_ENABLE_IT(HASH_IT_DINI|HASH_IT_DCI);
2828 
2829  /* Return function status */
2830  return HAL_OK;
2831  }
2832  else
2833  {
2834  return HAL_BUSY;
2835  }
2836 
2837 }
__HAL_UNLOCK(hrtc)
__HAL_LOCK(hrtc)
return HAL_OK
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
HAL_HASH_StateTypeDef
HAL State structures definition.

◆ HASH_WaitOnFlagUntilTimeout()

static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout ( HASH_HandleTypeDef hhash,
uint32_t  Flag,
FlagStatus  Status,
uint32_t  Timeout 
)
static

Handle HASH processing Timeout.

Parameters
hhashHASH handle.
Flagspecifies the HASH flag to check.
Statusthe Flag status (SET or RESET).
TimeoutTimeout duration.
Return values
HALstatus

Definition at line 1873 of file stm32l4xx_hal_hash.c.

1874 {
1875  uint32_t tickstart = HAL_GetTick();
1876 
1877  /* Wait until flag is set */
1878  if(Status == RESET)
1879  {
1880  while(__HAL_HASH_GET_FLAG(Flag) == RESET)
1881  {
1882  /* Check for the Timeout */
1883  if(Timeout != HAL_MAX_DELAY)
1884  {
1885  if(((HAL_GetTick()-tickstart) > Timeout) || (Timeout == 0U))
1886  {
1887  /* Set State to Ready to be able to restart later on */
1888  hhash->State = HAL_HASH_STATE_READY;
1889  /* Store time out issue in handle status */
1890  hhash->Status = HAL_TIMEOUT;
1891 
1892  /* Process Unlocked */
1893  __HAL_UNLOCK(hhash);
1894 
1895  return HAL_TIMEOUT;
1896  }
1897  }
1898  }
1899  }
1900  else
1901  {
1902  while(__HAL_HASH_GET_FLAG(Flag) != RESET)
1903  {
1904  /* Check for the Timeout */
1905  if(Timeout != HAL_MAX_DELAY)
1906  {
1907  if(((HAL_GetTick()-tickstart) > Timeout) || (Timeout == 0U))
1908  {
1909  /* Set State to Ready to be able to restart later on */
1910  hhash->State = HAL_HASH_STATE_READY;
1911  /* Store time out issue in handle status */
1912  hhash->Status = HAL_TIMEOUT;
1913 
1914  /* Process Unlocked */
1915  __HAL_UNLOCK(hhash);
1916 
1917  return HAL_TIMEOUT;
1918  }
1919  }
1920  }
1921  }
1922  return HAL_OK;
1923 }
uint32_t HAL_GetTick(void)
Provide a tick value in millisecond.
__HAL_UNLOCK(hrtc)
return HAL_OK

◆ HASH_Write_Block_Data()

static uint32_t HASH_Write_Block_Data ( HASH_HandleTypeDef hhash)
static

Write a block of data in HASH Peripheral in interruption mode.

Parameters
hhashHASH handle.
Note
HASH_Write_Block_Data() is called under interruption by HASH_IT().
Return values
HALstatus

Definition at line 2072 of file stm32l4xx_hal_hash.c.

2073 {
2074  uint32_t inputaddr;
2075  uint32_t buffercounter;
2076  uint32_t inputcounter;
2077  uint32_t ret = HASH_DIGEST_CALCULATION_NOT_STARTED;
2078 
2079  /* If there are more than 64 bytes remaining to be entered */
2080  if(hhash->HashInCount > 64U)
2081  {
2082  inputaddr = (uint32_t)hhash->pHashInBuffPtr;
2083  /* Write the Input block in the Data IN register
2084  (16 32-bit words, or 64 bytes are entered) */
2085  for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
2086  {
2087  HASH->DIN = *(uint32_t*)inputaddr;
2088  inputaddr+=4U;
2089  }
2090  /* If this is the start of input data entering, an additional word
2091  must be entered to start up the HASH processing */
2092  if(hhash->HashITCounter == 2U)
2093  {
2094  HASH->DIN = *(uint32_t*)inputaddr;
2095  if(hhash->HashInCount >= 68U)
2096  {
2097  /* There are still data waiting to be entered in the Peripheral.
2098  Decrement buffer counter and set pointer to the proper
2099  memory location for the next data entering round. */
2100  hhash->HashInCount -= 68U;
2101  hhash->pHashInBuffPtr+= 68U;
2102  }
2103  else
2104  {
2105  /* All the input buffer has been fed to the HW. */
2106  hhash->HashInCount = 0U;
2107  }
2108  }
2109  else
2110  {
2111  /* 64 bytes have been entered and there are still some remaining:
2112  Decrement buffer counter and set pointer to the proper
2113  memory location for the next data entering round.*/
2114  hhash->HashInCount -= 64U;
2115  hhash->pHashInBuffPtr+= 64U;
2116  }
2117  }
2118  else
2119  {
2120  /* 64 or less bytes remain to be entered. This is the last
2121  data entering round. */
2122 
2123  /* Get the buffer address */
2124  inputaddr = (uint32_t)hhash->pHashInBuffPtr;
2125  /* Get the buffer counter */
2126  inputcounter = hhash->HashInCount;
2127  /* Disable Interrupts */
2128  __HAL_HASH_DISABLE_IT(HASH_IT_DINI);
2129 
2130  /* Write the Input block in the Data IN register */
2131  for(buffercounter = 0U; buffercounter < ((inputcounter+3U)/4U); buffercounter++)
2132  {
2133  HASH->DIN = *(uint32_t*)inputaddr;
2134  inputaddr+=4U;
2135  }
2136 
2137  if (hhash->Accumulation == 1U)
2138  {
2139  /* Field accumulation is set, API only feeds data to the Peripheral and under interruption.
2140  The digest computation will be started when the last buffer data are entered. */
2141 
2142  /* Reset multi buffers accumulation flag */
2143  hhash->Accumulation = 0U;
2144  /* Change the HASH state */
2145  hhash->State = HAL_HASH_STATE_READY;
2146  /* Call Input data transfer complete call back */
2147 #if (USE_HAL_HASH_REGISTER_CALLBACKS == 1)
2148  hhash->InCpltCallback(hhash);
2149 #else
2150  HAL_HASH_InCpltCallback(hhash);
2151 #endif /* USE_HAL_HASH_REGISTER_CALLBACKS */
2152  }
2153  else
2154  {
2155  /* Start the Digest calculation */
2156  __HAL_HASH_START_DIGEST();
2157  /* Return indication that digest calculation has started:
2158  this return value triggers the call to Input data transfer
2159  complete call back as well as the proper transition from
2160  one step to another in HMAC mode. */
2161  ret = HASH_DIGEST_CALCULATION_STARTED;
2162  }
2163  /* Reset buffer counter */
2164  hhash->HashInCount = 0;
2165  }
2166 
2167  /* Return whether or digest calculation has started */
2168  return ret;
2169 }
void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash)
Input data transfer complete call back.

◆ HASH_WriteData()

static HAL_StatusTypeDef HASH_WriteData ( HASH_HandleTypeDef hhash,
uint8_t *  pInBuffer,
uint32_t  Size 
)
static

Feed the input buffer to the HASH Peripheral.

Parameters
hhashHASH handle.
pInBufferpointer to input buffer.
Sizethe size of input buffer in bytes.
Note
HASH_WriteData() regularly reads hhash->SuspendRequest to check whether or not the HASH processing must be suspended. If this is the case, the processing is suspended when possible and the Peripheral feeding point reached at suspension time is stored in the handle for resumption later on.
Return values
HALstatus

Definition at line 1735 of file stm32l4xx_hal_hash.c.

1736 {
1737  uint32_t buffercounter;
1738  __IO uint32_t inputaddr = (uint32_t) pInBuffer;
1739 
1740  for(buffercounter = 0U; buffercounter < Size; buffercounter+=4U)
1741  {
1742  /* Write input data 4 bytes at a time */
1743  HASH->DIN = *(uint32_t*)inputaddr;
1744  inputaddr+=4U;
1745 
1746  /* If the suspension flag has been raised and if the processing is not about
1747  to end, suspend processing */
1748  if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4U) < Size))
1749  {
1750  /* Wait for DINIS = 1, which occurs when 16 32-bit locations are free
1751  in the input buffer */
1752  if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
1753  {
1754  /* Reset SuspendRequest */
1755  hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE;
1756 
1757  /* Depending whether the key or the input data were fed to the Peripheral, the feeding point
1758  reached at suspension time is not saved in the same handle fields */
1759  if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2))
1760  {
1761  /* Save current reading and writing locations of Input and Output buffers */
1762  hhash->pHashInBuffPtr = (uint8_t *)inputaddr;
1763  /* Save the number of bytes that remain to be processed at this point */
1764  hhash->HashInCount = Size - (buffercounter + 4U);
1765  }
1766  else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3))
1767  {
1768  /* Save current reading and writing locations of Input and Output buffers */
1769  hhash->pHashKeyBuffPtr = (uint8_t *)inputaddr;
1770  /* Save the number of bytes that remain to be processed at this point */
1771  hhash->HashKeyCount = Size - (buffercounter + 4U);
1772  }
1773  else
1774  {
1775  /* Unexpected phase: unlock process and report error */
1776  hhash->State = HAL_HASH_STATE_READY;
1777  __HAL_UNLOCK(hhash);
1778  return HAL_ERROR;
1779  }
1780 
1781  /* Set the HASH state to Suspended and exit to stop entering data */
1782  hhash->State = HAL_HASH_STATE_SUSPENDED;
1783 
1784  return HAL_OK;
1785  } /* if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) */
1786  } /* if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4) < Size)) */
1787  } /* for(buffercounter = 0; buffercounter < Size; buffercounter+=4) */
1788 
1789  /* At this point, all the data have been entered to the Peripheral: exit */
1790  return HAL_OK;
1791 }
__HAL_UNLOCK(hrtc)
return HAL_OK

◆ HMAC_Processing()

static HAL_StatusTypeDef HMAC_Processing ( HASH_HandleTypeDef hhash,
uint32_t  Timeout 
)
static

HMAC processing in polling mode.

Parameters
hhashHASH handle.
TimeoutTimeout value.
Return values
HALstatus

Definition at line 2177 of file stm32l4xx_hal_hash.c.

2178 {
2179  /* Ensure first that Phase is correct */
2180  if ((hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_1) && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_2) && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_3))
2181  {
2182  /* Change the HASH state */
2183  hhash->State = HAL_HASH_STATE_READY;
2184 
2185  /* Process Unlock */
2186  __HAL_UNLOCK(hhash);
2187 
2188  /* Return function status */
2189  return HAL_ERROR;
2190  }
2191 
2192  /* HMAC Step 1 processing */
2193  if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1)
2194  {
2195  /************************** STEP 1 ******************************************/
2196  /* Configure the Number of valid bits in last word of the message */
2197  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
2198 
2199  /* Write input buffer in Data register */
2200  hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount);
2201  if (hhash->Status != HAL_OK)
2202  {
2203  return hhash->Status;
2204  }
2205 
2206  /* Check whether or not key entering process has been suspended */
2207  if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2208  {
2209  /* Process Unlocked */
2210  __HAL_UNLOCK(hhash);
2211 
2212  /* Stop right there and return function status */
2213  return HAL_OK;
2214  }
2215 
2216  /* No processing suspension at this point: set DCAL bit. */
2217  __HAL_HASH_START_DIGEST();
2218 
2219  /* Wait for BUSY flag to be cleared */
2220  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
2221  {
2222  return HAL_TIMEOUT;
2223  }
2224 
2225  /* Move from Step 1 to Step 2 */
2226  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2;
2227 
2228  }
2229 
2230  /* HMAC Step 2 processing.
2231  After phase check, HMAC_Processing() may
2232  - directly start up from this point in resumption case
2233  if the same Step 2 processing was suspended previously
2234  - or fall through from the Step 1 processing carried out hereabove */
2235  if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
2236  {
2237  /************************** STEP 2 ******************************************/
2238  /* Configure the Number of valid bits in last word of the message */
2239  __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize);
2240 
2241  /* Write input buffer in Data register */
2242  hhash->Status = HASH_WriteData(hhash, hhash->pHashInBuffPtr, hhash->HashInCount);
2243  if (hhash->Status != HAL_OK)
2244  {
2245  return hhash->Status;
2246  }
2247 
2248  /* Check whether or not data entering process has been suspended */
2249  if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2250  {
2251  /* Process Unlocked */
2252  __HAL_UNLOCK(hhash);
2253 
2254  /* Stop right there and return function status */
2255  return HAL_OK;
2256  }
2257 
2258  /* No processing suspension at this point: set DCAL bit. */
2259  __HAL_HASH_START_DIGEST();
2260 
2261  /* Wait for BUSY flag to be cleared */
2262  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK)
2263  {
2264  return HAL_TIMEOUT;
2265  }
2266 
2267  /* Move from Step 2 to Step 3 */
2268  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3;
2269  /* In case Step 1 phase was suspended then resumed,
2270  set again Key input buffers and size before moving to
2271  next step */
2272  hhash->pHashKeyBuffPtr = hhash->Init.pKey;
2273  hhash->HashKeyCount = hhash->Init.KeySize;
2274  }
2275 
2276 
2277  /* HMAC Step 3 processing.
2278  After phase check, HMAC_Processing() may
2279  - directly start up from this point in resumption case
2280  if the same Step 3 processing was suspended previously
2281  - or fall through from the Step 2 processing carried out hereabove */
2282  if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)
2283  {
2284  /************************** STEP 3 ******************************************/
2285  /* Configure the Number of valid bits in last word of the message */
2286  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
2287 
2288  /* Write input buffer in Data register */
2289  hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount);
2290  if (hhash->Status != HAL_OK)
2291  {
2292  return hhash->Status;
2293  }
2294 
2295  /* Check whether or not key entering process has been suspended */
2296  if (hhash->State == HAL_HASH_STATE_SUSPENDED)
2297  {
2298  /* Process Unlocked */
2299  __HAL_UNLOCK(hhash);
2300 
2301  /* Stop right there and return function status */
2302  return HAL_OK;
2303  }
2304 
2305  /* No processing suspension at this point: start the Digest calculation. */
2306  __HAL_HASH_START_DIGEST();
2307 
2308  /* Wait for DCIS flag to be set */
2309  if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK)
2310  {
2311  return HAL_TIMEOUT;
2312  }
2313 
2314  /* Read the message digest */
2315  HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH());
2316  }
2317 
2318  /* Change the HASH state */
2319  hhash->State = HAL_HASH_STATE_READY;
2320 
2321  /* Process Unlock */
2322  __HAL_UNLOCK(hhash);
2323 
2324  /* Return function status */
2325  return HAL_OK;
2326 }
static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
Handle HASH processing Timeout.
__HAL_UNLOCK(hrtc)
return HAL_OK
static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
Retrieve the message digest.
static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
Feed the input buffer to the HASH Peripheral.

◆ HMAC_Start()

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.

Note
Digest is available in pOutBuffer.
Same key is used for the inner and the outer hash functions; pointer to key and key size are respectively stored in hhash->Init.pKey and hhash->Init.KeySize.
Parameters
hhashHASH handle.
pInBufferpointer to the input buffer (buffer to be hashed).
Sizelength of the input buffer in bytes.
pOutBufferpointer to the computed digest.
TimeoutTimeout value.
AlgorithmHASH algorithm.
Return values
HALstatus

Definition at line 3027 of file stm32l4xx_hal_hash.c.

3028 {
3029  HAL_HASH_StateTypeDef State_tmp = hhash->State;
3030 
3031  /* If State is ready or suspended, start or resume polling-based HASH processing */
3032 if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3033  {
3034  /* Check input parameters */
3035  if ((pInBuffer == NULL) || (Size == 0U) || (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U) || (pOutBuffer == NULL))
3036  {
3037  hhash->State = HAL_HASH_STATE_READY;
3038  return HAL_ERROR;
3039  }
3040 
3041  /* Process Locked */
3042  __HAL_LOCK(hhash);
3043 
3044  /* Change the HASH state */
3045  hhash->State = HAL_HASH_STATE_BUSY;
3046 
3047  /* Check if initialization phase has already be performed */
3048  if(hhash->Phase == HAL_HASH_PHASE_READY)
3049  {
3050  /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
3051  if(hhash->Init.KeySize > 64U)
3052  {
3053  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3054  }
3055  else
3056  {
3057  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3058  }
3059  /* Set the phase to Step 1 */
3060  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
3061  /* Resort to hhash internal fields to feed the Peripheral.
3062  Parameters will be updated in case of suspension to contain the proper
3063  information at resumption time. */
3064  hhash->pHashOutBuffPtr = pOutBuffer; /* Output digest address */
3065  hhash->pHashInBuffPtr = pInBuffer; /* Input data address, HMAC_Processing input parameter for Step 2 */
3066  hhash->HashInCount = Size; /* Input data size, HMAC_Processing input parameter for Step 2 */
3067  hhash->HashBuffSize = Size; /* Store the input buffer size for the whole HMAC process */
3068  hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address, HMAC_Processing input parameter for Step 1 and Step 3 */
3069  hhash->HashKeyCount = hhash->Init.KeySize; /* Key size, HMAC_Processing input parameter for Step 1 and Step 3 */
3070  }
3071 
3072  /* Carry out HMAC processing */
3073  return HMAC_Processing(hhash, Timeout);
3074 
3075  }
3076  else
3077  {
3078  return HAL_BUSY;
3079  }
3080 }
__HAL_LOCK(hrtc)
static HAL_StatusTypeDef HMAC_Processing(HASH_HandleTypeDef *hhash, uint32_t Timeout)
HMAC processing in polling mode.
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
HAL_HASH_StateTypeDef
HAL State structures definition.

◆ HMAC_Start_DMA()

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 and the input buffer to the Peripheral.

Note
Same key is used for the inner and the outer hash functions; pointer to key and key size are respectively stored in hhash->Init.pKey and hhash->Init.KeySize.
In case of multi-buffer HMAC processing, the input buffer size (in bytes) must be a multiple of 4 otherwise, the HASH digest computation is corrupted. Only the length of the last buffer of the thread doesn't have to be a multiple of 4.
Parameters
hhashHASH handle.
pInBufferpointer to the input buffer (buffer to be hashed).
Sizelength of the input buffer in bytes.
AlgorithmHASH algorithm.
Return values
HALstatus

Definition at line 3204 of file stm32l4xx_hal_hash.c.

3205 {
3206  uint32_t inputaddr;
3207  uint32_t inputSize;
3208  HAL_StatusTypeDef status ;
3209  HAL_HASH_StateTypeDef State_tmp = hhash->State;
3210  /* Make sure the input buffer size (in bytes) is a multiple of 4 when digest calculation
3211  is disabled (multi-buffer HMAC processing, MDMAT bit to be set) */
3212  assert_param(IS_HMAC_DMA_MULTIBUFFER_SIZE(hhash, Size));
3213  /* If State is ready or suspended, start or resume DMA-based HASH processing */
3214 if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3215  {
3216  /* Check input parameters */
3217  if ((pInBuffer == NULL ) || (Size == 0U) || (hhash->Init.pKey == NULL ) || (hhash->Init.KeySize == 0U) ||
3218  /* Check phase coherency. Phase must be
3219  either READY (fresh start)
3220  or one of HMAC PROCESS steps (multi-buffer HASH management) */
3221  ((hhash->Phase != HAL_HASH_PHASE_READY) && (!(IS_HMAC_PROCESSING(hhash)))))
3222  {
3223  hhash->State = HAL_HASH_STATE_READY;
3224  return HAL_ERROR;
3225  }
3226 
3227 
3228  /* Process Locked */
3229  __HAL_LOCK(hhash);
3230 
3231  /* If not a case of resumption after suspension */
3232  if (hhash->State == HAL_HASH_STATE_READY)
3233  {
3234  /* Check whether or not initialization phase has already be performed */
3235  if(hhash->Phase == HAL_HASH_PHASE_READY)
3236  {
3237  /* Change the HASH state */
3238  hhash->State = HAL_HASH_STATE_BUSY;
3239  /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits.
3240  At the same time, ensure MDMAT bit is cleared. */
3241  if(hhash->Init.KeySize > 64U)
3242  {
3243  MODIFY_REG(HASH->CR, HASH_CR_MDMAT|HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3244  }
3245  else
3246  {
3247  MODIFY_REG(HASH->CR, HASH_CR_MDMAT|HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3248  }
3249  /* Store input aparameters in handle fields to manage steps transition
3250  or possible HMAC suspension/resumption */
3251  hhash->HashInCount = hhash->Init.KeySize; /* Initial size for first DMA transfer (key size) */
3252  hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address */
3253  hhash->pHashInBuffPtr = hhash->Init.pKey ; /* First address passed to DMA (key address at Step 1) */
3254  hhash->pHashMsgBuffPtr = pInBuffer; /* Input data address */
3255  hhash->HashBuffSize = Size; /* input data size (in bytes) */
3256 
3257  /* Set DMA input parameters */
3258  inputaddr = (uint32_t)(hhash->Init.pKey); /* Address passed to DMA (start by entering Key message) */
3259  inputSize = hhash->Init.KeySize; /* Size for first DMA transfer (in bytes) */
3260 
3261  /* Configure the number of valid bits in last word of the key */
3262  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
3263 
3264  /* Set the phase to Step 1 */
3265  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
3266 
3267  }
3268  else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
3269  {
3270  /* Process a new input data message in case of multi-buffer HMAC processing
3271  (this is not a resumption case) */
3272 
3273  /* Change the HASH state */
3274  hhash->State = HAL_HASH_STATE_BUSY;
3275 
3276  /* Save input parameters to be able to manage possible suspension/resumption */
3277  hhash->HashInCount = Size; /* Input message address */
3278  hhash->pHashInBuffPtr = pInBuffer; /* Input message size in bytes */
3279 
3280  /* Set DMA input parameters */
3281  inputaddr = (uint32_t)pInBuffer; /* Input message address */
3282  inputSize = Size; /* Input message size in bytes */
3283 
3284  if (hhash->DigestCalculationDisable == RESET)
3285  {
3286  /* This means this is the last buffer of the multi-buffer sequence: DCAL needs to be set. */
3287  __HAL_HASH_RESET_MDMAT();
3288  __HAL_HASH_SET_NBVALIDBITS(inputSize);
3289  }
3290  }
3291  else
3292  {
3293  /* Phase not aligned with handle READY state */
3294  __HAL_UNLOCK(hhash);
3295  /* Return function status */
3296  return HAL_ERROR;
3297  }
3298  }
3299  else
3300  {
3301  /* Resumption case (phase may be Step 1, 2 or 3) */
3302 
3303  /* Change the HASH state */
3304  hhash->State = HAL_HASH_STATE_BUSY;
3305 
3306  /* Set DMA input parameters at resumption location;
3307  inputaddr and inputSize are not set to the API input parameters
3308  but to those saved beforehand by HAL_HASH_DMAFeed_ProcessSuspend() when the
3309  processing was suspended. */
3310  inputaddr = (uint32_t)(hhash->pHashInBuffPtr); /* Input message address */
3311  inputSize = hhash->HashInCount; /* Input message size in bytes */
3312  }
3313 
3314 
3315  /* Set the HASH DMA transfert complete callback */
3316  hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt;
3317  /* Set the DMA error callback */
3318  hhash->hdmain->XferErrorCallback = HASH_DMAError;
3319 
3320  /* Store number of words already pushed to manage proper DMA processing suspension */
3321  hhash->NbWordsAlreadyPushed = HASH_NBW_PUSHED();
3322 
3323  /* Enable the DMA In DMA Stream */
3324  status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (((inputSize %4U)!=0U) ? ((inputSize+(4U-(inputSize %4U)))/4U):(inputSize/4U)));
3325  /* Enable DMA requests */
3326  SET_BIT(HASH->CR, HASH_CR_DMAE);
3327 
3328  /* Process Unlocked */
3329  __HAL_UNLOCK(hhash);
3330 
3331  /* Return function status */
3332  if (status != HAL_OK)
3333  {
3334  /* Update HASH state machine to error */
3335  hhash->State = HAL_HASH_STATE_ERROR;
3336  }
3337 
3338  /* Return function status */
3339  return status;
3340  }
3341  else
3342  {
3343  return HAL_BUSY;
3344  }
3345 }
static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma)
DMA HASH Input Data transfer completion callback.
static void HASH_DMAError(DMA_HandleTypeDef *hdma)
DMA HASH communication error callback.
__HAL_UNLOCK(hrtc)
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.
__HAL_LOCK(hrtc)
return HAL_OK
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
HAL_HASH_StateTypeDef
HAL State structures definition.
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))

◆ HMAC_Start_IT()

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 interruption mode.

Note
Digest is available in pOutBuffer.
Same key is used for the inner and the outer hash functions; pointer to key and key size are respectively stored in hhash->Init.pKey and hhash->Init.KeySize.
Parameters
hhashHASH handle.
pInBufferpointer to the input buffer (buffer to be hashed).
Sizelength of the input buffer in bytes.
pOutBufferpointer to the computed digest.
AlgorithmHASH algorithm.
Return values
HALstatus

Definition at line 3097 of file stm32l4xx_hal_hash.c.

3098 {
3099  HAL_HASH_StateTypeDef State_tmp = hhash->State;
3100 
3101  /* If State is ready or suspended, start or resume IT-based HASH processing */
3102 if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
3103  {
3104  /* Check input parameters */
3105  if ((pInBuffer == NULL) || (Size == 0U) || (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U) || (pOutBuffer == NULL))
3106  {
3107  hhash->State = HAL_HASH_STATE_READY;
3108  return HAL_ERROR;
3109  }
3110 
3111  /* Process Locked */
3112  __HAL_LOCK(hhash);
3113 
3114  /* Change the HASH state */
3115  hhash->State = HAL_HASH_STATE_BUSY;
3116 
3117  /* Initialize IT counter */
3118  hhash->HashITCounter = 1;
3119 
3120  /* Check if initialization phase has already be performed */
3121  if (hhash->Phase == HAL_HASH_PHASE_READY)
3122  {
3123  /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */
3124  if(hhash->Init.KeySize > 64U)
3125  {
3126  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
3127  }
3128  else
3129  {
3130  MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
3131  }
3132 
3133  /* Resort to hhash internal fields hhash->pHashInBuffPtr and hhash->HashInCount
3134  to feed the Peripheral whatever the HMAC step.
3135  Lines below are set to start HMAC Step 1 processing where key is entered first. */
3136  hhash->HashInCount = hhash->Init.KeySize; /* Key size */
3137  hhash->pHashInBuffPtr = hhash->Init.pKey ; /* Key address */
3138 
3139  /* Store input and output parameters in handle fields to manage steps transition
3140  or possible HMAC suspension/resumption */
3141  hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address */
3142  hhash->pHashMsgBuffPtr = pInBuffer; /* Input message address */
3143  hhash->HashBuffSize = Size; /* Input message size (in bytes) */
3144  hhash->pHashOutBuffPtr = pOutBuffer; /* Output digest address */
3145 
3146  /* Configure the number of valid bits in last word of the key */
3147  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);
3148 
3149  /* Set the phase to Step 1 */
3150  hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1;
3151  }
3152  else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3))
3153  {
3154  /* Restart IT-based HASH processing after Step 1 or Step 3 suspension */
3155 
3156  }
3157  else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)
3158  {
3159  /* Restart IT-based HASH processing after Step 2 suspension */
3160 
3161  }
3162  else
3163  {
3164  /* Error report as phase incorrect */
3165  /* Process Unlock */
3166  __HAL_UNLOCK(hhash);
3167  hhash->State = HAL_HASH_STATE_READY;
3168  return HAL_ERROR;
3169  }
3170 
3171  /* Process Unlock */
3172  __HAL_UNLOCK(hhash);
3173 
3174  /* Enable Interrupts */
3175  __HAL_HASH_ENABLE_IT(HASH_IT_DINI|HASH_IT_DCI);
3176 
3177  /* Return function status */
3178  return HAL_OK;
3179  }
3180  else
3181  {
3182  return HAL_BUSY;
3183  }
3184 
3185 }
__HAL_UNLOCK(hrtc)
__HAL_LOCK(hrtc)
return HAL_OK
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
HAL_HASH_StateTypeDef
HAL State structures definition.