[HAL][HASH] Read the last remaining bytes (3 or 2 or 1) of the data in a temporary variable (taking into account swap mode) and enter this variable into the HASH->DIN when the data is not a multiple of 4 bytes
diff --git a/Src/stm32l5xx_hal_hash.c b/Src/stm32l5xx_hal_hash.c
index 2e274b0..5c28a8e 100644
--- a/Src/stm32l5xx_hal_hash.c
+++ b/Src/stm32l5xx_hal_hash.c
@@ -123,7 +123,7 @@
(#) HAL in interruption mode (interruptions driven)
(##)Due to HASH peripheral hardware design, the peripheral interruption is triggered every 64 bytes.
- This is why, for driver implementation simplicity’s sake, user is requested to enter a message the
+ This is why, for driver implementation simplicity s sake, user is requested to enter a message the
length of which is a multiple of 4 bytes.
(##) When the message length (in bytes) is not a multiple of words, a specific field exists in HASH_STR
@@ -1825,8 +1825,9 @@
{
uint32_t buffercounter;
__IO uint32_t inputaddr = (uint32_t) pInBuffer;
+ uint32_t tmp;
- for (buffercounter = 0U; buffercounter < Size; buffercounter += 4U)
+ for (buffercounter = 0U; buffercounter < Size / 4U; buffercounter++)
{
/* Write input data 4 bytes at a time */
HASH->DIN = *(uint32_t *)inputaddr;
@@ -1834,8 +1835,16 @@
/* If the suspension flag has been raised and if the processing is not about
to end, suspend processing */
- if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter + 4U) < Size))
+ if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter * 4 + 4U) < Size))
{
+ /* wait for flag BUSY not set before Wait for DINIS = 1*/
+ if (buffercounter * 4 >= 64U)
+ {
+ if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
/* Wait for DINIS = 1, which occurs when 16 32-bit locations are free
in the input buffer */
if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
@@ -1850,14 +1859,14 @@
/* Save current reading and writing locations of Input and Output buffers */
hhash->pHashInBuffPtr = (uint8_t *)inputaddr;
/* Save the number of bytes that remain to be processed at this point */
- hhash->HashInCount = Size - (buffercounter + 4U);
+ hhash->HashInCount = Size - (buffercounter * 4 + 4U);
}
else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3))
{
/* Save current reading and writing locations of Input and Output buffers */
hhash->pHashKeyBuffPtr = (uint8_t *)inputaddr;
/* Save the number of bytes that remain to be processed at this point */
- hhash->HashKeyCount = Size - (buffercounter + 4U);
+ hhash->HashKeyCount = Size - (buffercounter * 4 + 4U);
}
else
{
@@ -1876,6 +1885,52 @@
} /* for(buffercounter = 0; buffercounter < Size; buffercounter+=4) */
/* At this point, all the data have been entered to the Peripheral: exit */
+
+ if (Size % 4U != 0U)
+ {
+ if (hhash->Init.DataType == HASH_DATATYPE_16B)
+ {
+ /* Write remaining input data */
+
+ if (Size % 4U <= 2)
+ {
+ HASH->DIN = (uint32_t) * (uint16_t *)inputaddr;
+ }
+ if (Size % 4U == 3)
+ {
+ HASH->DIN = *(uint32_t *)inputaddr;
+ }
+
+ }
+ else if ((hhash->Init.DataType == HASH_DATATYPE_8B)
+ || (hhash->Init.DataType == HASH_DATATYPE_1B)) /* byte swap or bit swap or */
+ {
+ /* Write remaining input data */
+ if (Size % 4U == 1)
+ {
+ HASH->DIN = (uint32_t) * (uint8_t *)inputaddr;
+ }
+ if (Size % 4U == 2)
+ {
+ HASH->DIN = (uint32_t) * (uint16_t *)inputaddr;
+ }
+ if (Size % 4U == 3)
+ {
+ tmp = *(uint8_t *)inputaddr;
+ tmp |= *(uint8_t *)(inputaddr + 1U) << 8U ;
+ tmp |= *(uint8_t *)(inputaddr + 2U) << 16U;
+ HASH->DIN = tmp;
+ }
+
+ }
+ else
+ {
+ HASH->DIN = *(uint32_t *)inputaddr;
+ }
+ /*hhash->HashInCount += 4U;*/
+ }
+
+
return HAL_OK;
}
@@ -2963,11 +3018,11 @@
HAL_StatusTypeDef status ;
HAL_HASH_StateTypeDef State_tmp = hhash->State;
-
+
/* Make sure the input buffer size (in bytes) is a multiple of 4 when MDMAT bit is set
(case of multi-buffer HASH processing) */
assert_param(IS_HASH_DMA_MULTIBUFFER_SIZE(Size));
-
+
/* If State is ready or suspended, start or resume polling-based HASH processing */
if ((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED))
{
@@ -3446,7 +3501,7 @@
/* Enable the DMA In DMA channel */
status = HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, \
(((inputSize % 4U) != 0U) ? ((inputSize + (4U - (inputSize % 4U))) / 4U) \
- : (inputSize / 4U)));
+ : (inputSize / 4U)));
/* Enable DMA requests */
SET_BIT(HASH->CR, HASH_CR_DMAE);