Hash
The HASH engine is a computational accelerator for hash sequence algorithms. Users can select different hash algorithms to calculate hash values for specific data in memory. The HASH engine is faster than software algorithms and more flexible in configuration. Users can also implement multi-threaded HASH computation through custom initial vectors. The HASH engine supports the following algorithms:
SHA1
SHA224
SHA256
SM3
Using Hash HAL Driver
Hash supports both polling and interrupt modes, which can call different HASH interfaces.
Example of Hash HAL polling with block processing:
// Output result stored in g_temp, length is 20 bytes for SHA1, 32 bytes for other algorithms.
uint8_t g_temp[32];
// Each block must be a multiple of 64, except the last block.
// Input array is g_hash_input, length is len, using SHA1 algorithm
#define SPLIT_THRESHOLD 64
for (i=0;i<len;i+=SPLIT_THRESHOLD) {
if (i==0)
// First block
HAL_HASH_init(NULL, HASH_ALGO_SHA1, 0);
else
// Continue previous calculation, load previous run result
HAL_HASH_init((uint32_t*)g_temp, HASH_ALGO_SHA1, i);
if (i+SPLIT_THRESHOLD<len) {
LOG_I("AES run %d\n", i);
status = HAL_HASH_run(&(g_hash_input[i]), SPLIT_THRESHOLD, 0);
}
else {
// Last block
LOG_I("AES run continue %d\n", i);
status = HAL_HASH_run(&(g_hash_input[i]), len-i, 1);
}
if (HAL_OK != status) // Decryption sync
{
LOG_E("AES run (sync mode) error\n");
uassert_true(status == HAL_OK);
}
HAL_HASH_result(g_temp);
}
// Result stored in g_temp
Example of Hash HAL using interrupt, completed in one pass:
// Input array is g_hash_input, length is len, using SHA256 algorithm
// Output result stored in g_temp, length is 20 bytes for SHA1, 32 bytes for other algorithms.
uint8_t g_temp[32];
// AES and HASH share one interrupt
void AES_IRQHandler(void)
{
rt_interrupt_enter();
// Check Hash completion interrupt source
if (hwp_aes_acc->IRQ & HASH_DONE_STAT)
{
HAL_HASH_IRQHandler();
// Hash completion signal
rt_sem_release(g_aes_sem);
}
rt_interrupt_leave();
}
....
// HASH module initialization
HAL_HASH_init(NULL, HASH_ALGO_SHA256, 0);
// Enable interrupt
NVIC_EnableIRQ(AES_IRQn);
HAL_NVIC_SetPriority(AES_IRQn, 5, 0);
status = HAL_HASH_run_IT(g_hash_input, len, 1);
if (HAL_OK != status) // Encryption Asyn
{
LOG_E("AES run (async mode) error\n");
uassert_true(status == HAL_OK);
}
// Wait for Hash completion signal
rt_sem_take(g_aes_sem, RT_TICK_PER_SECOND);
// Output Hash to g_temp, length depends on different Hash algorithms.
HAL_HASH_result(g_temp);
...