加密框架代码看完了,下一步便是看基于加密框架的下一级,实际硬件加解密的实现框架。这篇集中看crc加密部分(虽然个人感觉使用查表法的crc加密也耗不了多少资源和算力,没必要对这个做硬件加密模块)。
代码分析
源码路径
components\drivers\hwcrypto\hw_crc.c
创建CRC上下文
#define CRC_FLAG_REFIN (0x1 << 0)
#define CRC_FLAG_REFOUT (0x1 << 1)
#define HWCRYPTO_CRC8_CFG \
{ \
.last_val = 0x00, \
.poly = 0x07, \
.width = 8, \
.xorout = 0x00, \
.flags = 0, \
}
#define HWCRYPTO_CRC16_CFG \
{ \
.last_val = 0x0000, \
.poly = 0x8005, \
.width = 16, \
.xorout = 0x0000, \
.flags = 0, \
}
#define HWCRYPTO_CRC32_CFG \
{ \
.last_val = 0x00000000, \
.poly = 0x04C11DB7, \
.width = 32, \
.xorout = 0x00000000, \
.flags = 0, \
}
#define HWCRYPTO_CRC_CCITT_CFG \
{ \
.last_val = 0x0000, \
.poly = 0x1021, \
.width = 16, \
.xorout = 0x0000, \
.flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
}
#define HWCRYPTO_CRC_DNP_CFG \
{ \
.last_val = 0x0000, \
.poly = 0x3D65, \
.width = 16, \
.xorout = 0xffff, \
.flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
}
typedef enum
{
HWCRYPTO_CRC_CUSTOM, /**< Custom CRC mode */
HWCRYPTO_CRC_CRC8, /**< poly : 0x07 */
HWCRYPTO_CRC_CRC16, /**< poly : 0x8005 */
HWCRYPTO_CRC_CRC32, /**< poly : 0x04C11DB7 */
HWCRYPTO_CRC_CCITT, /**< poly : 0x1021 */
HWCRYPTO_CRC_DNP, /**< poly : 0x3D65 */
} hwcrypto_crc_mode;
struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device,
hwcrypto_crc_mode mode)
{
struct hwcrypto_crc *crc_ctx;
// 调用硬件加密框架的创建crc校验入口
crc_ctx = (struct hwcrypto_crc *)rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_CRC, sizeof(struct hwcrypto_crc));
if (crc_ctx == RT_NULL)
{
return RT_NULL;
}
// 几种典型的CRC校验码赋值,若在这几种典型的之外,则需要在调用此函数后,自行更新crc_cfgcrc_cfg
switch (mode)
{
case HWCRYPTO_CRC_CRC8:
{
struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC8_CFG;
crc_ctx->crc_cfg = temp;
break;
}
case HWCRYPTO_CRC_CRC16:
{
struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC16_CFG;
crc_ctx->crc_cfg = temp;
break;
}
case HWCRYPTO_CRC_CRC32:
{
struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC32_CFG;
crc_ctx->crc_cfg = temp;
break;
}
case HWCRYPTO_CRC_CCITT:
{
struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_CCITT_CFG;
crc_ctx->crc_cfg = temp;
break;
}
case HWCRYPTO_CRC_DNP:
{
struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_DNP_CFG;
crc_ctx->crc_cfg = temp;
break;
}
default:
break;
}
return &crc_ctx->parent;
}更新CRC校验码算子
当rt_hwcrypto_crc_create函数传入的模式是HWCRYPTO_CRC_CUSTOM时,需要自行配置校验码算子,具体实现如下:
struct hwcrypto_crc_cfg
{
rt_uint32_t last_val; /**< Last CRC value cache */
rt_uint32_t poly; /**< CRC polynomial */
rt_uint16_t width; /**< CRC value width */
rt_uint32_t xorout; /**< Result XOR Value */
rt_uint16_t flags; /**< Input or output data reverse. CRC_FLAG_REFIN or CRC_FLAG_REFOUT */
};
void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx,
struct hwcrypto_crc_cfg *cfg)
{
if (cfg)
{
((struct hwcrypto_crc *)ctx)->crc_cfg = *cfg;
}
}CRC计算实现
struct hwcrypto_crc_ops
{
rt_uint32_t (*update)(struct hwcrypto_crc *ctx,
const rt_uint8_t *in, rt_size_t length); /**< Perform a CRC calculation. return CRC value */
};
struct hwcrypto_crc
{
struct rt_hwcrypto_ctx parent; /**< Inherited from the standard device */
struct hwcrypto_crc_cfg crc_cfg; /**< CRC configure */
const struct hwcrypto_crc_ops *ops; /**< !! Hardware initializes this value when creating context !! */
};
rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx,
const rt_uint8_t *input,
rt_size_t length)
{
struct hwcrypto_crc *crc_ctx = (struct hwcrypto_crc *)ctx;
if (ctx && crc_ctx->ops->update)
{
return crc_ctx->ops->update(crc_ctx, input, length);
}
return 0;
}计算实现里有个很巧妙的点,传入参数是结构体的第一个参数的指针,在使用时转换成实际所需的结构体格式,这种操作在linux上经常看见。但是实现入口update让人很疑惑,因为找遍框架代码,并没有找到这个update函数的赋值入口,也就是说,这个update就像凭空出现的一样,不过细看ops的注释,会发现ops有个很重要的注释,提示ops必须在create时指定,也就是说,在驱动层的create函数里,需要进一步指定ops实现,以便计算crc校验码。
销毁CRC校验上下文
实现对应的是创建的入口。
void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx)
{
rt_hwcrypto_ctx_destroy(ctx);
}总结
至此,CRC硬件加密框架基本上梳理清楚,大致写法如下(其中销毁和克隆接口并未做类型判断,只要是不太确定其他加密方法是否有其他需要复位的内容):
#include <rtconfig.h>
#if defined(RT_USING_HWCRYPTO)
#include <rtdevice.h>
#include <rtdbg.h>
#include <board.h>
#if defined(BSP_USING_CRC)
#include "drv_crc.h"
#endif
#if defined(BSP_USING_CRC)
rt_uint32_t crc_update(struct hwcrypto_crc *ctx,
const rt_uint8_t *in, rt_size_t length)
{
// TODO:CRC计算实现
return length;
}
static const struct hwcrypto_crc_ops crc_ops =
{
.update = crc_update,
};
#endif
static rt_err_t hwcrypto_create(struct rt_hwcrypto_ctx *ctx)
{
rt_err_t res = RT_EOK;
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
{
ctx->contex = RT_NULL;
//Setup CRC operation
((struct hwcrypto_crc *)ctx)->ops = &crc_ops;
break;
}
#endif /* BSP_USING_CRC */
default:
res = -RT_ERROR;
break;
}
return res;
}
static void hwcrypto_destroy(struct rt_hwcrypto_ctx *ctx)
{
if (ctx->contex)
rt_free(ctx->contex);
}
static rt_err_t hwcrypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
{
rt_err_t res = RT_EOK;
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(struct rt_hwcrypto_ctx));
}
else
return -RT_EINVAL;
return res;
}
static void hwcrypto_reset(struct rt_hwcrypto_ctx *ctx)
{
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
{
// TODO:复位CRC实现
break;
}
#endif /* BSP_USING_CRC */
default:
res = -RT_ERROR;
break;
}
return;
}
static const struct rt_hwcrypto_ops hwcrypto_ops =
{
.create = hwcrypto_create,
.destroy = hwcrypto_destroy,
.copy = hwcrypto_clone,
.reset = hwcrypto_reset,
};
int hwcrypto_device_init(void)
{
static struct rt_hwcrypto_device hwcrypto_dev;
hwcrypto_dev.ops = &hwcrypto_ops;
hwcrypto_dev.id = 0;
hwcrypto_dev.user_data = &hwcrypto_dev;
// 硬件资源初始化
// 注册加密设备
if (rt_hwcrypto_register(&hwcrypto_dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
{
return -1;
}
return 0;
}
INIT_DEVICE_EXPORT(hwcrypto_device_init);
#endif //#if defined(RT_USING_HWCRYPTO)
我要赚赏金
