从rtt的加密列表中可以知道,MD5,SHA1和SHA2都属于hash加密,因此这三种加密方式都可以通过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 */
源码解读
代码路径
components\drivers\hwcrypto\hw_hash.c components\drivers\hwcrypto\hw_hash.h
数据结构
struct hwcrypto_hash_ops
{
rt_err_t (*update)(struct hwcrypto_hash *hash_ctx,
const rt_uint8_t *in, rt_size_t length); /**< hash运算入口 */
rt_err_t (*finish)(struct hwcrypto_hash *hash_ctx,
rt_uint8_t *out, rt_size_t length); /**< 计算后的hash值获取入口 */
};
struct hwcrypto_hash
{
struct rt_hwcrypto_ctx parent; /**< 硬件加密框架设备 */
const struct hwcrypto_hash_ops *ops; /**< 注册对象时需提供的操作入口 */
};创建入口
struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device, hwcrypto_type type)
{
struct rt_hwcrypto_ctx *ctx;
ctx = rt_hwcrypto_ctx_create(device, type, sizeof(struct hwcrypto_hash));
return ctx;
}设备加密类型入口
rt_err_t rt_hwcrypto_hash_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
{// 传入参数可以是
// HWCRYPTO_TYPE_MD5,
// HWCRYPTO_TYPE_SHA1,
// HWCRYPTO_TYPE_SHA224,
// HWCRYPTO_TYPE_SHA256,
// HWCRYPTO_TYPE_SHA384。
// HWCRYPTO_TYPE_SHA512
// 中的一个
return rt_hwcrypto_set_type(ctx, type);
}个人理解类型限制应该在hash代码里面实现,而不是继续往下传递,因为驱动层目前看都属于复用方式实现的,如果还存在其他方式加密也需要设置类型,就会出现驱动无法区分的情况。
计算入口
rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length)
{
if (ctx && ((struct hwcrypto_hash *)ctx)->ops->update)
{
return ((struct hwcrypto_hash *)ctx)->ops->update((struct hwcrypto_hash *)ctx, input, length);
}
return -RT_ERROR;
}获取计算结果入口
rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length)
{
if (ctx && ((struct hwcrypto_hash *)ctx)->ops->finish)
{
return ((struct hwcrypto_hash *)ctx)->ops->finish((struct hwcrypto_hash *)ctx, output, length);
}
return -RT_ERROR;
}复制上下文入口
rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
{
return rt_hwcrypto_ctx_cpy(des, src);
}复位入口
void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx)
{
rt_hwcrypto_ctx_reset(ctx);
}销毁入口
void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx)
{
rt_hwcrypto_ctx_destroy(ctx);
}总结
整体来说,hash加密在实现方面相对容易理解,基本上一瞄代码就能看明白是怎么实现的,唯一需要注意的是设置类型时传入的参数。经过以上分析,新增hash加密的驱动适配部分实现框架如下:
#include <rtconfig.h>
#if defined(RT_USING_HWCRYPTO)
#include <rtdevice.h>
#include <rtdbg.h>
#include <board.h>
#if defined(BSP_HWCRYPTO_USING_MD5) || defined(BSP_HWCRYPTO_USING_SHA1) \
|| defined(RT_HWCRYPTO_USING_SHA2_224)|| defined(RT_HWCRYPTO_USING_SHA2_256) \
|| defined(RT_HWCRYPTO_USING_SHA2_384) || defined(RT_HWCRYPTO_USING_SHA2_512)
rt_uint32_t hash_update(struct hwcrypto_hash *hash_ctx,
const rt_uint8_t *in, rt_size_t length)
{
switch (hash_ctx->parent.type)
{
#if defined(BSP_HWCRYPTO_USING_MD5)
case HWCRYPTO_TYPE_MD5:
// TODO: md5 caculate
// lentgh = md5(hash_ctx, in, length);
break;
#endif
#if defined(BSP_HWCRYPTO_USING_SHA1)
case HWCRYPTO_TYPE_SHA1:
// TODO: sha1 caculate
// lentgh = sha1(hash_ctx, in, length);
break;
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_224)
case HWCRYPTO_TYPE_SHA224:
// TODO: sha2_224 caculate
// lentgh = sha2_224(hash_ctx, in, length);
break;
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_256)
case HWCRYPTO_TYPE_SHA256:
// TODO: sha2_256 caculate
// lentgh = sha2_256(hash_ctx, in, length);
break;
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_384)
case HWCRYPTO_TYPE_SHA384:
// TODO: sha2_384 caculate
// lentgh = sha2_384(hash_ctx, in, length);
break;
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_512)
case HWCRYPTO_TYPE_SHA512:
// TODO: sha2_512 caculate
// lentgh = sha2_512(hash_ctx, in, length);
break;
#endif
default:
return 0;
}
return length;
}
rt_uint32_t hash_finish(struct hwcrypto_hash *hash_ctx,
rt_uint8_t *out, rt_size_t length)
{
// TODO:hash导出值实现
switch (hash_ctx->parent.type)
{
#if defined(BSP_HWCRYPTO_USING_MD5)
case HWCRYPTO_TYPE_MD5:
// TODO: Get MD5 result
// length = md5_finish(hash_ctx, out, length);
break;
#endif
#if defined(BSP_HWCRYPTO_USING_SHA1)
case HWCRYPTO_TYPE_SHA1:
// TODO: Get SHA1 result
// length = sha1_finish(hash_ctx, out, length);
break;
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_224)
case HWCRYPTO_TYPE_SHA224:
// TODO: Get SHA2 result
// length = sha2_224_finish(hash_ctx, out, length);
break;
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_256)
case HWCRYPTO_TYPE_SHA256:
// TODO: Get SHA2 result
// length = sha2_256_finish(hash_ctx, out, length);
break;
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_384)
case HWCRYPTO_TYPE_SHA384:
// TODO: Get SHA2 result
// length = sha2_384_finish(hash_ctx, out, length);
break;
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_512)
case HWCRYPTO_TYPE_SHA512:
// TODO: Get SHA2 result
// length = sha2_512_finish(hash_ctx, out, length);
break;
#endif
default:
return 0;
}
return length;
}
static const struct hwcrypto_hash_ops hash_ops=
{
.update = hash_update,
.finish = hash_finish;
};
#endif
static rt_err_t hwcrypto_create(struct rt_hwcrypto_ctx *ctx)
{
rt_err_t res = RT_EOK;
switch (ctx->type)
{
#if defined(BSP_HWCRYPTO_USING_MD5)
case HWCRYPTO_TYPE_MD5:
{
ctx->contex = RT_NULL;
//Setup hash operation
((struct hwcrypto_hash_ops *)ctx)->ops = &hash_ops;
break;
}
#endif
#if defined(BSP_HWCRYPTO_USING_SHA1)
case HWCRYPTO_TYPE_SHA1:
{
ctx->contex = RT_NULL;
//Setup hash operation
((struct hwcrypto_hash_ops *)ctx)->ops = &hash_ops;
break;
}
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_224)
case HWCRYPTO_TYPE_SHA224:
{
ctx->contex = RT_NULL;
//Setup hash operation
((struct hwcrypto_hash_ops *)ctx)->ops = &hash_ops;
break;
}
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_256)
case HWCRYPTO_TYPE_SHA256:
{
ctx->contex = RT_NULL;
//Setup hash operation
((struct hwcrypto_hash_ops *)ctx)->ops = &hash_ops;
break;
}
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_384)
case HWCRYPTO_TYPE_SHA384:
{
ctx->contex = RT_NULL;
//Setup hash operation
((struct hwcrypto_hash_ops *)ctx)->ops = &hash_ops;
break;
}
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_512)
case HWCRYPTO_TYPE_SHA512:
{
ctx->contex = RT_NULL;
//Setup hash operation
((struct hwcrypto_hash_ops *)ctx)->ops = &hash_ops;
break;
}
#endif
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)
{
#if defined(BSP_HWCRYPTO_USING_MD5)
case HWCRYPTO_TYPE_MD5:
{
// TODO: hash reset
break;
}
#endif
#if defined(BSP_HWCRYPTO_USING_SHA1)
case HWCRYPTO_TYPE_SHA1:
{
// TODO: hash reset
break;
}
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_224)
case HWCRYPTO_TYPE_SHA224:
{
// TODO: hash reset
break;
}
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_256)
case HWCRYPTO_TYPE_SHA256:
{
// TODO: hash reset
break;
}
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_384)
case HWCRYPTO_TYPE_SHA384:
{
// TODO: hash reset
break;
}
#endif
#if defined(RT_HWCRYPTO_USING_SHA2_512)
case HWCRYPTO_TYPE_SHA512:
{
// TODO: hash reset
break;
}
#endif
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)
我要赚赏金
