加密框架代码看完了,下一步便是看基于加密框架的下一级,实际硬件加解密的实现框架。这篇集中看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)