目录
CRYPTO 设备
加解密(Encryption/Decryption)是一种文件、消息加密、解密技术。这种技术随着物联网快速发展,用户的正常工作中对数据的加解密需求有着强烈的需求。
为保证物联网设备的信息安全,软件层面引入了 TLS 安全传输层协议,同时硬件芯片上也逐渐添加安全相关的加解密模块,甚至出现了专为安全设计的安全芯片。芯片上的硬件安全模块相比纯软件实现的安全算法,拥有更快的运算速度,更小的资源占用。但大多数物联网设备上仍在使用纯软件的安全算法。其中最重要的一个原因,就是硬件接口不一,种类繁杂,软件对接起来比较困难。
因此 RT-Thread 推出了 hwcrypto 硬件加解密驱动框架,并对接了常见的安全传输套件。只要硬件支持加解密模块,就能直接使用基于硬件加解密的安全传输套件,传输速度提升数倍。
CRYPTO 简介
框架简介
hwcrypto 是一个硬件加解密设备驱动框架。主要由硬件加解密驱动抽象层以及各种加解密 API 接口两部分构成。对于上层应用,可对接安全套件或直接使用,使用方式十分灵活。对于驱动,需要对接的接口少,功能单一,驱动开发简单快捷。下图是 Crypto 框架层次图:
主要特性如下:
- 设计轻薄,运行高效
硬件加解密驱动的最重要的一个功能就是接口转换,实现接口统一,方便上层应用使用硬件加解密。所以它被设计的十分轻薄。有着极低资源占用,ROM < 0.8K / RAM < 0.2K。
加解密在运行速度上,也有着很高的要求。所以频繁调用的代码,细致考虑,把运行过程的步骤降到最少,让性能损失降到最小,如同直接操作硬件寄存器一般迅速。
- 考虑周全,使用简单
在 API 设计上,从简单易用,功能齐全两个维度出发。首先是用户直接使用硬件加解密API,要求上手简单, 使用容易。为此前期针对众多软件接口进行了评估。亲身使用测试,最终定义出一套功能齐全,接口简单的 API。
满足用户的使用需求的同时,在安全传输套件的对接上,也做了许多考虑。专门为安全传输套件增加了API。最终这套API用户使用或是对接安全传输套件,都能游刃有余。
- 完全兼容,通用性强
驱动对接的接口设计上,也精心设计。前期对多家硬件厂商的加解密外设根据功能进行分类,进行分析整理,提取出一套功能单一,参数全面的驱动接口。该驱动接口可完全适配常规 MCU 加解密外设。现目前已在多个平台上做验证,例如联盛德 W60X 系列,STM32 系列等。
功能简介
硬件加解密框架目前已经支持 AES/DES/3DES/RC4/SHA1/SHA2/MD5/CRC/RNG/BIGNUM 等加解密相关的接口。
将上述加解密算法按照不同的类型分成如下几个大类,每一类都有丰富的 API 可供使用。目前已经支持的类型如下:
- hash: 散列算法
- symmetric: 对称加解密算法
- gcm: GMAC 消息认证码
- crc: CRC 冗余校验
- rng: 随机数发生器
- bignum: 大数运算
hash 算法
hash 算法是把任意长度的输入通过散列算法变换成固定长度的输出,是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。
访问 hash 算法设备
应用程序通过 RT-Thread 提供的 hash 算法设备管理接口来访问 hash 算法设备硬件,相关接口如下所示:
函数 | 描述 |
---|---|
rt_hwcrypto_hash_create() | 创建 hash 上下文 |
rt_hwcrypto_hash_destroy() | 释放上下文 |
rt_hwcrypto_hash_finish() | 计算最终 hash 值 |
rt_hwcrypto_hash_update() | 处理一包数据 |
rt_hwcrypto_hash_cpy() | 复制上下文 |
rt_hwcrypto_hash_reset() | 重置上下文 |
rt_hwcrypto_hash_set_type() | 设置 hash 算法类型 |
创建 hash 上下文
应用程序根据 hash 设备的句柄,创建 hash 上下文,如下所示:
struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device,
hwcrypto_type type);
参数 | 描述 |
---|---|
device | 加解密设备句柄 |
type | hash 算法类型 |
返回 | —— |
NULL | 失败 |
其他 | 设备对象 |
hash 算法常用类型及子类型如下
/* HASH Type */
HWCRYPTO_TYPE_MD5 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< MD5 */
HWCRYPTO_TYPE_SHA1 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< SHA1 */
HWCRYPTO_TYPE_SHA2 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< SHA2 */
/* SHA2 Subtype */
HWCRYPTO_TYPE_SHA224 = HWCRYPTO_TYPE_SHA2 | (0x01 << 8),
HWCRYPTO_TYPE_SHA256 = HWCRYPTO_TYPE_SHA2 | (0x02 << 8),
HWCRYPTO_TYPE_SHA384 = HWCRYPTO_TYPE_SHA2 | (0x03 << 8),
HWCRYPTO_TYPE_SHA512 = HWCRYPTO_TYPE_SHA2 | (0x04 << 8),
如果创建 MD5 类型的 hash 算法,使用示例如下
struct rt_hwcrypto_ctx *ctx;
ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_MD5);
- rt_hwcrypto_dev_default()函数原型为
struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void)
,返回默认的硬件加解密设备句柄。
释放上下文
应用程序根据 hash 的上下文,删除该上下文,并且释放资源,如下所示:
void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx);
参数 | 描述 |
---|---|
ctx | 上下文 |
返回 | —— |
计算最终 hash 值
应用程序根据 hash 的上下文,可以输出最后的 hash 值,如下所示:
rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length);
参数 | 描述 |
---|---|
ctx | 上下文 |
output | 输出数据 |
length | 数据长度 |
返回 | —— |
RT_EOK | 计算成功 |
其他 | 失败 |
计算一包数据
应用程序根据 hash 的上下文,输入一包数据,计算 hash 值,如下所示:
rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length);
参数 | 描述 |
---|---|
ctx | 上下文 |
input | 输入数据 |
length | 输入数据长度 |
返回 | —— |
RT_EOK | 计算成功 |
其他 | 失败 |
使用实例如下:
int main(void)
{
rt_uint8_t buf_in[32];
int i;
struct rt_hwcrypto_ctx *ctx;
/* 填充测试数据 */
for (i = 0; i < sizeof(buf_in); i++)
{
buf_in[i] = (rt_uint8_t)i;
}
/* 创建一个 SHA1/MD5 类型的上下文 */
ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), type);
/* 将输入数据进行 hash 运算 */
rt_hwcrypto_hash_update(ctx, in, 32);
/* 获得运算结果 */
rt_hwcrypto_hash_finish(ctx, out, 32);
/* 删除上下文,释放资源 */
rt_hwcrypto_hash_destroy(ctx);
}
复制上下文
应用程序根据源 hash 的上下文,复制到目标 hash 的上下文中,如下所示:
rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
参数 | 描述 |
---|---|
des | 目标上下文 |
src | 源上下文 |
返回 | —— |
RT_EOK | 计算成功 |
其他 | 失败 |
重置上下文
应用程序根据 hash 的上下文,重置 hash 上下文文本,如下所示:
void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx);
参数 | 描述 |
---|---|
ctx | 上下文 |
返回 | —— |
- 没有释放上下文之前,只有重置后才可以计算下一包数据
设置 hash 算法类型
应用程序根据 hash 的上下文,设置 hash 算法类型,如下所示:
rt_err_t rt_hwcrypto_hash_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
参数 | 描述 |
---|---|
ctx | 上下文 |
type | hash 算法类型 |
返回 | —— |
RT_EOK | 计算成功 |
其他 | 失败 |
- 常用 hash 算法类型,参考创建 hash 上下文中类型介绍
- 设置类型仅在数据运算之前有效,运算中途更改类型,将导致运算结果错误
对称加解密算法
对称加解密指加密和解密使用相同密钥的加密算法,所以也称这种加密算法为秘密密钥算法或单密钥算法。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信的安全性至关重要。
访问对称加解密设备
应用程序通过 RT-Thread 提供的 symmetric 设备管理接口来访问 symmetric 算法设备硬件,相关接口如下所示:
函数 | 描述 |
---|---|
rt_hwcrypto_symmetric_create() | 创建对称加解密上下文 |
rt_hwcrypto_symmetric_destroy() | 释放上下文 |
rt_hwcrypto_symmetric_crypt() | 加解密操作 |
rt_hwcrypto_symmetric_setkey() | 设置加解密密钥 |
rt_hwcrypto_symmetric_getkey() | 获取加解密密钥 |
rt_hwcrypto_symmetric_setiv() | 设置对称加解密初始化向量 |
rt_hwcrypto_symmetric_getiv() | 获取对称加解密初始化向量 |
rt_hwcrypto_symmetric_set_ivoff() | 设置对称加解密初始化向量偏移值 |
rt_hwcrypto_symmetric_get_ivoff() | 获取对称加解密初始化向量偏移值 |
rt_hwcrypto_symmetric_cpy() | 复制上下文 |
rt_hwcrypto_symmetric_reset() | 重置上下文 |
rt_hwcrypto_symmetric_set_type() | 设置加解密类型 |
创建对称加解密上下文
应用程序根据对称加解密设备的句柄,创建对称加解密上下文,如下所示:
struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device, hwcrypto_type type);
参数 | 描述 |
---|---|
device | 加解密设备句柄 |
type | 对称加解密算法类型 |
返回 | —— |
NULL | 失败 |
其他 | 设备对象 |
对称加解密算法常用类型及子类型如下
/* symmetric Type */
HWCRYPTO_TYPE_AES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< AES */
HWCRYPTO_TYPE_DES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< DES */
HWCRYPTO_TYPE_3DES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< 3DES */
HWCRYPTO_TYPE_RC4 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< RC4 */
HWCRYPTO_TYPE_GCM = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< GCM */
/* AES Subtype */
HWCRYPTO_TYPE_AES_ECB = HWCRYPTO_TYPE_AES | (0x01 << 8),
HWCRYPTO_TYPE_AES_CBC = HWCRYPTO_TYPE_AES | (0x02 << 8),
HWCRYPTO_TYPE_AES_CFB = HWCRYPTO_TYPE_AES | (0x03 <<