这部分属于最迷惑的部分,框架层套用了设备框架,但实现一个都没对接,虽然对上层没啥区别,但是在框架层就感觉很奇怪了。
源码分析
源码路径
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四个关键实现,而此结构体的其他信息,则需要看下一级的对应硬件的加密实现部分才清楚了。
我要赚赏金
