这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 软件与操作系统 » rtthread硬件加密-5hash加密分析

共2条 1/1 1 跳转至

rtthread硬件加密-5hash加密分析

高工
2025-03-18 01:50:19   被打赏 10 分(兑奖)     打赏

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





关键词: 硬件     加密     hash     rtthread    

院士
2025-03-21 09:50:37     打赏
2楼

这几个算法还是属于散队计算使用,主要应用于加密。

不过,他们特别之处在于不能解密


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]