前一篇我们体验了AES算法,这一篇继续安全相关加速器的HASH-384. 还是按照硬件和软件对比的方式来体验。
HASH-384原理见https://eips.ethereum.org/assets/eip-2680/sha256-384-512.pdf
三.软件算法
参考https://github.com/th-blitz/Hash-Algorithms/blob/main/sha384.c
添加驱动文件
stm32h5xx_hal_hash.c
stm32h5xx_hal_conf.h中取消注释
/*#define HAL_HASH_MODULE_ENABLED */
初始化
HASH_HandleTypeDef hhash;
__HAL_RCC_HASH_CLK_ENABLE();
hhash.Instance = HASH;
hhash.Init.DataType = HASH_BYTE_SWAP;
hhash.Init.Algorithm = HASH_ALGOSELECTION_SHA384;
if (HAL_HASH_Init(&hhash) != HAL_OK)
{
/* 错误 */
}
取消初始化
__HAL_RCC_HASH_FORCE_RESET();
__HAL_RCC_HASH_RELEASE_RESET();
__HAL_RCC_HASH_CLK_DISABLE();
计算
if (HAL_HASH_Start(&hhash, (uint8_t *)Input, INPUT_TAB_SIZE, aDigest, 0xFF) != HAL_OK)
{
/* 错误 */
}
shell_func.c中申明实现函数
static void sw_hash384_func(uint8_t* param);
static void hw_hash384_func(uint8_t* param);
新增两行命令用于计算
{ (uint8_t*)"sw_hash384", sw_hash384_func, (uint8_t*)"sw_hash384 input testtimes"},
{ (uint8_t*)"hw_hash384", hw_hash384_func, (uint8_t*)"sw_hash384 input testtimes"},
实现如下
HASH_HandleTypeDef hhash;
int hw_hash384(uint8_t* input, uint8_t* output, uint32_t len)
{
__HAL_RCC_HASH_CLK_ENABLE();
hhash.Instance = HASH;
hhash.Init.DataType = HASH_BYTE_SWAP;
hhash.Init.Algorithm = HASH_ALGOSELECTION_SHA384;
if (HAL_HASH_Init(&hhash) != HAL_OK)
{
return -1;
}
if (HAL_HASH_Start(&hhash, input, len, output, 0xFF) != HAL_OK)
{
__HAL_RCC_HASH_FORCE_RESET();
__HAL_RCC_HASH_RELEASE_RESET();
__HAL_RCC_HASH_CLK_DISABLE();
return -1;
}
__HAL_RCC_HASH_FORCE_RESET();
__HAL_RCC_HASH_RELEASE_RESET();
__HAL_RCC_HASH_CLK_DISABLE();
return 0;
}
int sw_hash384(uint8_t* input, uint8_t* output, uint32_t len)
{
sha384_core(input, len, (uint64_t*)output);
return 0;
}
static void sw_hash384_func(uint8_t* param)
{
uint32_t inlen;
uint32_t test_times;
if(sscanf((const char*)param,"%*s %s %d",(char*)(&(s_input[0])),&test_times) == 2)
{
inlen = str2hex_buf(s_input,strlen((char*)s_input));
ULONG sw_start_time = tx_time_get();
for(uint32_t i=0; i<test_times;i++)
{
sw_hash384(s_input,s_output,inlen);
}
ULONG sw_used_time = tx_time_get()-sw_start_time;
xprintf("sw %d\r\n",sw_used_time);
uint8_t* p = (uint8_t*)s_output;
for(int i=0; i<48; i++)
{
xprintf("%02x",p);
}
xprintf("\r\n");
}
}
static void hw_hash384_func(uint8_t* param)
{
uint32_t inlen;
uint32_t test_times;
if(sscanf((const char*)param,"%*s %s %d",(char*)(&(s_input[0])),&test_times) == 2)
{
inlen = str2hex_buf(s_input,strlen((char*)s_input));
ULONG hw_start_time = tx_time_get();
for(uint32_t i=0; i<test_times;i++)
{
hw_hash384(s_input,s_output,inlen);
}
ULONG hw_used_time = tx_time_get()-hw_start_time;
xprintf("hw %d\r\n",hw_used_time);
uint8_t* p = (uint8_t*)s_output;
for(int i=0; i<48; i++)
{
xprintf("%02x",p);
}
xprintf("\r\n");
}
}
测试如下
hw_hash384 01020304050607080900 10000
sw_hash384 01020304050607080900 10000
定义了大数组,栈要大点
uint64_t buffer[80];
硬件计算和在线计算工具计算出来的完全一样
在线计算工具计算
https://www.lddgo.net/encrypt/hash
以上测试了HASH加速计算,使用硬件加速计算运算很快,接口也很简单。