从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)