这部分属于最迷惑的部分,框架层套用了设备框架,但实现一个都没对接,虽然对上层没啥区别,但是在框架层就感觉很奇怪了。
源码分析
源码路径
components/drivers/hwcrypto/hwcrypto.c
对接驱动接口
注册入口
#ifdef RT_USING_DEVICE_OPS const static struct rt_device_ops hwcrypto_ops = { RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL }; #endif rt_err_t rt_hwcrypto_register(struct rt_hwcrypto_device *device, const char *name) { rt_err_t err; RT_ASSERT(device != RT_NULL); RT_ASSERT(name != RT_NULL); RT_ASSERT(device->ops != RT_NULL); RT_ASSERT(device->ops->create != RT_NULL); RT_ASSERT(device->ops->destroy != RT_NULL); RT_ASSERT(device->ops->copy != RT_NULL); RT_ASSERT(device->ops->reset != RT_NULL); rt_memset(&device->parent, 0, sizeof(struct rt_device)); #ifdef RT_USING_DEVICE_OPS device->parent.ops = &hwcrypto_ops; #else device->parent.init = RT_NULL; device->parent.open = RT_NULL; device->parent.close = RT_NULL; device->parent.read = RT_NULL; device->parent.write = RT_NULL; device->parent.control = RT_NULL; #endif device->parent.user_data = RT_NULL; device->parent.type = RT_Device_Class_Security; /* Register device */ err = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR); return err; }
这地方是我最疑惑的点,注册了设备,但对应设备的标准接口一个都没做,仅仅是自定义了一套新的接口,create,destory,copy和reset,按照之前其他设备框架的实现的做法,其实这些接口都能通过init,open,close,read,write,control实现,但不知为何直接跳过了这一层,不向上层暴露统一的操作接口。
对接上层入口
寻找默认的加密设备
// 如果没有就寻找,找到后就返回指针 struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void) { static struct rt_hwcrypto_device *hwcrypto_dev; if (hwcrypto_dev) { return hwcrypto_dev; } hwcrypto_dev = (struct rt_hwcrypto_device *)rt_device_find(RT_HWCRYPTO_DEFAULT_NAME); return hwcrypto_dev; }
可能rtt认为芯片虽然支持多种硬件加密,但还是需要指定一个默认的加密方式吧,除了这,实在想不出这个接口还有什么作用。
获取加密设备的唯一ID号
rt_uint64_t rt_hwcrypto_id(struct rt_hwcrypto_device *device) { if (device) {id return device->id; } return 0; }
同寻找默认的加密设备一样,不太清楚此接口的作用,而且从此文件看,这个id号并未初始化,可能是实际硬件模块初始化的。
创建加密设备
#define HWCRYPTO_MAIN_TYPE_MASK (0xffffUL << 16) #define HWCRYPTO_SUB_TYPE_MASK (0xffUL << 8) typedef enum { HWCRYPTO_TYPE_NULL = 0x00000000, /* Main Type */ /* symmetric Type */ HWCRYPTO_TYPE_HEAD = __LINE__, 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 */ /* 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 */ /* Other Type */ HWCRYPTO_TYPE_RNG = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< RNG */ HWCRYPTO_TYPE_CRC = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< CRC */ HWCRYPTO_TYPE_BIGNUM = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< BIGNUM */ /* 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 << 8), HWCRYPTO_TYPE_AES_CTR = HWCRYPTO_TYPE_AES | (0x04 << 8), HWCRYPTO_TYPE_AES_OFB = HWCRYPTO_TYPE_AES | (0x05 << 8), /* DES Subtype */ HWCRYPTO_TYPE_DES_ECB = HWCRYPTO_TYPE_DES | (0x01 << 8), HWCRYPTO_TYPE_DES_CBC = HWCRYPTO_TYPE_DES | (0x02 << 8), /* 3DES Subtype */ HWCRYPTO_TYPE_3DES_ECB = HWCRYPTO_TYPE_3DES | (0x01 << 8), HWCRYPTO_TYPE_3DES_CBC = HWCRYPTO_TYPE_3DES | (0x02 << 8), /* 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), } hwcrypto_type; rt_err_t rt_hwcrypto_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type) { if (ctx) { if ((ctx->type & HWCRYPTO_MAIN_TYPE_MASK) == (type & HWCRYPTO_MAIN_TYPE_MASK)) { // 同一种设备,仅仅是子加密设备不一致,直接更新类型即可 ctx->type = type; return RT_EOK; } else if (ctx->type == HWCRYPTO_TYPE_NULL) { // 当前设备没有初始化过,直接提供类型 ctx->type = type; return RT_EOK; } else { // 当前设备已经初始化,但是要改变的加密方式与当前使用的加密方式不一致,直接返回错误 return -RT_ERROR; } } return -RT_EINVAL; } rt_err_t rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx *ctx, struct rt_hwcrypto_device *device, hwcrypto_type type) { rt_err_t err; // 此处有瑕疵,如果设置类型报错,其实是需要直接返回的,但是这里没有这么做。 rt_hwcrypto_set_type(ctx, type); ctx->device = device; // 直接创建设备 err = ctx->device->ops->create(ctx); if (err != RT_EOK) { return err; } return RT_EOK; } struct rt_hwcrypto_ctx *rt_hwcrypto_ctx_create(struct rt_hwcrypto_device *device, hwcrypto_type type, rt_uint32_t obj_size) { struct rt_hwcrypto_ctx *ctx; rt_err_t err; // 资源初始化 if (device == RT_NULL || obj_size < sizeof(struct rt_hwcrypto_ctx)) { return RT_NULL; } ctx = rt_malloc(obj_size); if (ctx == RT_NULL) { return ctx; } rt_memset(ctx, 0, obj_size); // 实际初始化硬件部分 err = rt_hwcrypto_ctx_init(ctx, device, type); if (err != RT_EOK) { rt_free(ctx); ctx = RT_NULL; } return ctx; }
复制加密上下文
rt_err_t rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src) { if (des == RT_NULL || src == RT_NULL) { return -RT_EINVAL; } if (des->device != src->device || (des->type & HWCRYPTO_MAIN_TYPE_MASK) != (src->type & HWCRYPTO_MAIN_TYPE_MASK)) { return -RT_EINVAL; } // 若是同一类加密设备,则允许复制上下文,此时更新设备的密文并调用底层的复制实现 des->type = src->type; return src->device->ops->copy(des, src); }
销毁加密设备
void rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx *ctx) { if (ctx == RT_NULL) { return; } if (ctx->device->ops->destroy) { ctx->device->ops->destroy(ctx); } rt_free(ctx); }
销毁部分没啥内容,就是调用实际加密设备的销毁接口并释放掉设备所占用的空间。
复位加密设备
void rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx *ctx) { if (ctx && ctx->device->ops->reset) { ctx->device->ops->reset(ctx); } }
同样的,复位接口也仅仅是调用了实际加密设备的复位实现,但是感觉此处的判断有些多余,因为在注册时,没有reset实现会无法注册。
总结
至此,我们可以发现,硬件加密设备的关键对象为 struct rt_hwcrypto_device *device,此设备在注册时,必须包含以下实现create,destroy,copy,reset四个关键实现,而此结构体的其他信息,则需要看下一级的对应硬件的加密实现部分才清楚了。