电子说
疑问
前面碰到了一个问题,RT-Thread 支持 MD5,可是 M2354 却不支持,那怎么知道 RT-Thread 的 CRYPTO 设备对 M2354 支持怎样呢?
我看了下文档,没找到,通过查看源码,做了如下表格:
总的来说看就是 RT-thread 支持随机数、哈希、对称加密,
PS:该表格根据文件 rt-threadbspnuvotonlibrariesm2354rtt_portdrv_crypto.c 里面的 static rt_err_t nu_hwcrypto_create(struct rt_hwcrypto_ctx *ctx)) 函数得来
接下来首先使用下 HASH 算法
hash 算法
hash 算法是什么? 我在网上找到这个解释:
哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。
哈希算法最重要的特点就是:
相同的输入一定得到相同的输出;
不同的输入大概率得到不同的输出。
根据这个我的理解是,对于任何(任何长度)数据,不管什么时候计算,通过 hash 算法计算,都一定能得到相同的输出。
常用的 hash 算法有:
目前,在 M2354 跑 RT-Thread 使用 CRYPTO 设备 的话,可以用到的 hash 算法有:
sha1 :使用该算法获得的哈希值为 160 bit
sha2
SHA224:使用该算法获得的哈希值为 224 bit
SHA256:使用该算法获得的哈希值为 256 bit
SHA384:使用该算法获得的哈希值为 384 bit
SHA512:使用该算法获得的哈希值为 512 bit
CRYPTO 设备的 HASH 算法 API
RT-Thread 使用 CRYPTO 设备 对应的 hash 算法 API 有:
根据文档,使用方法为:
使用 rt_hwcrypto_hash_create 创建 hash 上下文
使用 rt_hwcrypto_hash_update 对数据进行 hash 运算
使用 rt_hwcrypto_hash_finish 获得运算结果
最后使用 rt_hwcrypto_hash_destroy 删除上下文,释放资源
通过前面运行文档 CRYPTO 设备 给出的例程,我的实践结果是如果按照该流程,在 NuMaker-M2354 上是无法正常运行的,需要在创建了上下文后调用函数 rt_hwcrypto_hash_reset 才能够正常运行。
如何测试
该文档中 CRYPTO 设备 给出的 hash 例程比较简单,我有没实际使用场景,该如何测试 hash 呢?
我看了下 M2354 官方给出的 BSP (M2354_Series_BSP_CMSIS_V3.00.002)有个 sha1 的例程(目录:M2354_Series_BSP_CMSIS_V3.00.002SampleCodeStdDriverCRYPTO_SHA),这个例程里面有 64 组数据及对应的 hash 值,正好可以拿来测试,我把这个例程移植到 RT-Thread 中的 NuMaker-M2354 BSP 中,
移植好后,编译运行:
程序一开始是跑下来了,计算出来的哈希值也是对的,可是运行到最后一组数据的时候,程序卡死了,通过调试发现也是卡死在 rt-threadbspnuvotonlibrariesm2354rtt_portdrv_crypto.c 里面的 SHABlockUpdate 函数,也是停在了该函数的最后一句 while (!s_SHA_done) {};,一直等待在完成。
通过单步调试查看寄存器,发了了卡住的原因,如下图:
在执行开始计算的时候,CRYPTO_HMAC_DMACNT 寄存器为 0。
M2354 的参考手册中,关于 Hash 的使用中有说道开始计算之前,需要先设置寄存器 CRYPTO_HMAC_DMACNT :
摘自:M2354 Series Technical Reference Manual
然后再单步调试、查看代码,发现可疑点:
把上图中的 >= 改为 > 后,程序可以跑完了:
M2354 Sha1 的性能怎样
怎么测试 Hash 算法的性能呢? 我不知道,我也只是刚接触 CRYPTO,不过,我想起了之前见过的一张 PPT:
这是某个 MCU 的 HASH 算法的统计数据,给出了 SHA2、SHA3 计算每 16KB 所需的时间,最下面 2 行是什么,还不知道,根据这个,做个简化版的,毕竟 MCU 资源有限,我就做个计算 1K Byte 数据所需的时间。
做法是,根据 M2354 官方给出的 BSP (M2354_Series_BSP_CMSIS_V3.00.002)里面的 sha1 例程,我做 10 组 大小 1024 字节的数据,算出计算每组数据所需时间求和再除 10,统计出计算 1024 字节 HASH 所需的时间。
那这数据怎么来呢?
我用 python 做了个简单的小程序,生成 10 组大小为 1024 字节的随机数的数组,并计算 hash 值,保存到一个文件中,代码很简单,才 20 多行,如下:
import numpy as np
import hashlib
def create_item():
first = np.random.randint(20,high = 0xff, size=1024)
str = ""
for item in first:
str += hex(item).replace("0x","")
source = []
for by in first:
source.append(by)
bye = bytes(source)
n = hashlib.sha1()
n.update(bye)
return str,n.hexdigest()
dat = "[L = 20]nn"
for i in range(10):
msg,has = create_item()
dat += "Len = 8192nMsg = " + msg + "nMD = " + has + "nn"
print(has)
print(dat)
file = open("sha_test_vector","w")
file.write(dat)
file.close()
运行结果如下:
在 MCU 部分,我需要个可以统计计算 hash 所需时间的方法,一开始使用系统节拍(使用函数 rt_tick_get() 获取系统节拍)来统计,发现计算出来的时间是 0,精度不够,后来试了下 HWTIMER,可以出时间,应该是可以满足需求的。
我分别做了 SHA1、SHA224、SHA256、SHA384、SHA512 的得出如下数据:
总结
RT-Thread 的 HASH 算法用起来还是挺简单的,文档也是很详细。我在使用过程中碰到 2 个问题:
使用 HASH 算法的时候,在创建 HASH 上下文后需要调用函数 rt_hwcrypto_hash_reset 才能够正常运行,可是这个跟文档有出入,不知道是 M2364 的 BSP 的问题还是 文档的问题
M2354 BSP 中的 rt-threadbspnuvotonlibrariesm2354rtt_portdrv_crypto.c里面的函数 nu_sha_hash_run 这句:
while ((psSHACtx->u32SHATempBufLen + u32DataLen) >= psSHACtx->u32BlockSize)
需要改为:
while ((psSHACtx->u32SHATempBufLen + u32DataLen) > psSHACtx->u32BlockSize)
这个是不是 bug ?
全部0条评论
快来发表一下你的评论吧 !