stm32h7xx_hal_driver icon indicating copy to clipboard operation
stm32h7xx_hal_driver copied to clipboard

HASH_Start_IT fails when called with buffer size < 4 while in HAL_HASH_PHASE_PROCESS phase

Open mariuszste opened this issue 1 year ago • 4 comments

Describe the set-up

  • STM32H757I-EVAL
  • arm-none-eabi-gcc (Arch Repository) 14.1.0 + CMake

Describe the bug HASH_Start_IT silently fails when called with Size < 4 while in HAL_HASH_PHASE_PROCESS phase. The interrupt handler is never called, no error returned

How To Reproduce

  1. Indicate the global behavior of your application project Hashing data of arbitrary length

  2. The modules that you suspect to be the cause of the problem (Driver, BSP, MW ...) stm32h7xx_hal_hash.c HASH_Start_IT

  3. The use case that generates the problem I'm reading and hashing data in chunks, the last chunk can be any size. Let's say the chunk size is 64 bytes and I want to hash 66 bytes of data. That is 64 + 2

  4. How we can reproduce the problem

this should give a general idea of what I'm trying to do.

HASH_HandleTypeDef hhash;
/////////
void example() {
    HAL_HASH_DeInit(&hhash);
    hhash.Init.DataType = HASH_DATATYPE_8B;
    HAL_HASH_Init(&hhash);
    
    tx_semaphore_create(&sync, "HASH sync", 0);
    
    uint8_t buf[64];
    uint8_t out[32];
    memset(buf, 0, sizeof(buf));
    
    // chunk 1
    // This will switch the phase to HAL_HASH_PHASE_PROCESS, removing it will make the next call succeed
    HASH_Accumulate_IT(&hhash, buf, 64, HASH_ALGOSELECTION_SHA256);
    tx_semaphore_get(&sync, TX_WAIT_FOREVER);
    
    // chunk 2 - last
    // can also be 
    HASH_Start_IT(&hhash, buf, 2, out, HASH_ALGOSELECTION_SHA256);
    tx_semaphore_get(&sync, TX_WAIT_FOREVER); // this will hang because `HASH_RNG_IRQHandler` will never be called
}
/////////
void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash) {
    tx_semaphore_put(&sync);
}

void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash) {
    tx_semaphore_put(&sync);
}

Additional context polling_step will never be 1 if Size is < 4 so the entire if (polling_step == 1U) {} block is skipped and since hhash->Phase is not HAL_HASH_PHASE_READY there is basically no code left in the function. Something here is seriously wrong.

I assume this is a supported use case based on the comments from HAL_HASHEx_SHA256_Accmlt_IT and HAL_HASHEx_SHA256_Accmlt_End_IT since they are just aliases for HASH_Accumulate_IT and HASH_Start_IT respectively.

As far as I can tell this works just fine with the blocking variants, as well as DMA, only the interrupt variant is broken.

Screenshots N/A

mariuszste avatar Jun 17 '24 17:06 mariuszste