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

共2条 1/1 1 跳转至

rtthread硬件加密--2crc加密分析

工程师
2025-03-06 00:36:14   被打赏 10 分(兑奖)     打赏

       加密框架代码看完了,下一步便是看基于加密框架的下一级,实际硬件加解密的实现框架。这篇集中看crc加密部分(虽然个人感觉使用查表法的crc加密也耗不了多少资源和算力,没必要对这个做硬件加密模块)。

代码分析

源码路径

components\drivers\hwcrypto\hw_crc.c

创建CRC上下文

#define CRC_FLAG_REFIN    (0x1 << 0)
#define CRC_FLAG_REFOUT   (0x1 << 1)

#define HWCRYPTO_CRC8_CFG       \
{                               \
    .last_val = 0x00,           \
    .poly = 0x07,               \
    .width = 8,                 \
    .xorout = 0x00,             \
    .flags = 0,                 \
}

#define HWCRYPTO_CRC16_CFG      \
{                               \
    .last_val = 0x0000,           \
    .poly = 0x8005,               \
    .width = 16,                 \
    .xorout = 0x0000,             \
    .flags = 0,                 \
}

#define HWCRYPTO_CRC32_CFG   \
{                           \
    .last_val = 0x00000000, \
    .poly = 0x04C11DB7,              \
    .width = 32,             \
    .xorout = 0x00000000,            \
    .flags = 0,             \
}

#define HWCRYPTO_CRC_CCITT_CFG   \
{                           \
    .last_val = 0x0000,          \
    .poly = 0x1021,              \
    .width = 16,             \
    .xorout = 0x0000,            \
    .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
}

#define HWCRYPTO_CRC_DNP_CFG   \
{                           \
    .last_val = 0x0000,          \
    .poly = 0x3D65,              \
    .width = 16,             \
    .xorout = 0xffff,            \
    .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
}

typedef enum
{
    HWCRYPTO_CRC_CUSTOM,        /**< Custom CRC mode */
    HWCRYPTO_CRC_CRC8,          /**< poly : 0x07 */
    HWCRYPTO_CRC_CRC16,         /**< poly : 0x8005 */
    HWCRYPTO_CRC_CRC32,         /**< poly : 0x04C11DB7 */
    HWCRYPTO_CRC_CCITT,         /**< poly : 0x1021 */
    HWCRYPTO_CRC_DNP,           /**< poly : 0x3D65 */
} hwcrypto_crc_mode;

struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device,
                                               hwcrypto_crc_mode mode)
{
    struct hwcrypto_crc *crc_ctx;

    // 调用硬件加密框架的创建crc校验入口
    crc_ctx = (struct hwcrypto_crc *)rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_CRC, sizeof(struct hwcrypto_crc));
    if (crc_ctx == RT_NULL)
    {
        return RT_NULL;
    }

    // 几种典型的CRC校验码赋值,若在这几种典型的之外,则需要在调用此函数后,自行更新crc_cfgcrc_cfg
    switch (mode)
    {
    case HWCRYPTO_CRC_CRC8:
    {
        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC8_CFG;
        crc_ctx->crc_cfg = temp;
        break;
    }
    case HWCRYPTO_CRC_CRC16:
    {
        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC16_CFG;
        crc_ctx->crc_cfg = temp;
        break;
    }
    case HWCRYPTO_CRC_CRC32:
    {
        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC32_CFG;
        crc_ctx->crc_cfg = temp;
        break;
    }
    case HWCRYPTO_CRC_CCITT:
    {
        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_CCITT_CFG;
        crc_ctx->crc_cfg = temp;
        break;
    }
    case HWCRYPTO_CRC_DNP:
    {
        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_DNP_CFG;
        crc_ctx->crc_cfg = temp;
        break;
    }
    default:
        break;
    }

    return &crc_ctx->parent;
}

更新CRC校验码算子

       当rt_hwcrypto_crc_create函数传入的模式是HWCRYPTO_CRC_CUSTOM时,需要自行配置校验码算子,具体实现如下:

struct hwcrypto_crc_cfg
{
    rt_uint32_t last_val;       /**< Last CRC value cache */
    rt_uint32_t poly;           /**< CRC polynomial */
    rt_uint16_t width;          /**< CRC value width */
    rt_uint32_t xorout;         /**< Result XOR Value */
    rt_uint16_t flags;          /**< Input or output data reverse. CRC_FLAG_REFIN or CRC_FLAG_REFOUT */
};

void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx,
                                   struct hwcrypto_crc_cfg *cfg)
{
    if (cfg)
    {
        ((struct hwcrypto_crc *)ctx)->crc_cfg = *cfg;
    }
}

CRC计算实现

struct hwcrypto_crc_ops
{
    rt_uint32_t (*update)(struct hwcrypto_crc *ctx,
                          const rt_uint8_t *in, rt_size_t length);  /**< Perform a CRC calculation. return CRC value */
};

struct hwcrypto_crc
{
    struct rt_hwcrypto_ctx parent;          /**< Inherited from the standard device */
    struct hwcrypto_crc_cfg crc_cfg;        /**< CRC configure */
    const struct hwcrypto_crc_ops *ops;     /**< !! Hardware initializes this value when creating context !! */
};

rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx,
                                             const rt_uint8_t *input,
                                             rt_size_t length)
{
    struct hwcrypto_crc *crc_ctx = (struct hwcrypto_crc *)ctx;
    if (ctx && crc_ctx->ops->update)
    {
        return crc_ctx->ops->update(crc_ctx, input, length);
    }
    return 0;
}

      计算实现里有个很巧妙的点,传入参数是结构体的第一个参数的指针,在使用时转换成实际所需的结构体格式,这种操作在linux上经常看见。但是实现入口update让人很疑惑,因为找遍框架代码,并没有找到这个update函数的赋值入口,也就是说,这个update就像凭空出现的一样,不过细看ops的注释,会发现ops有个很重要的注释,提示ops必须在create时指定,也就是说,在驱动层的create函数里,需要进一步指定ops实现,以便计算crc校验码。

销毁CRC校验上下文

       实现对应的是创建的入口。

void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx)
{
    rt_hwcrypto_ctx_destroy(ctx);
}

总结

    至此,CRC硬件加密框架基本上梳理清楚,大致写法如下(其中销毁和克隆接口并未做类型判断,只要是不太确定其他加密方法是否有其他需要复位的内容):

#include <rtconfig.h>

#if defined(RT_USING_HWCRYPTO)
#include <rtdevice.h>
#include <rtdbg.h>
#include <board.h>

#if defined(BSP_USING_CRC)
#include "drv_crc.h"
#endif


#if defined(BSP_USING_CRC)
rt_uint32_t crc_update(struct hwcrypto_crc *ctx,
                          const rt_uint8_t *in, rt_size_t length)
{
    // TODO:CRC计算实现
    return length;
}

static const struct hwcrypto_crc_ops crc_ops =
{
    .update = crc_update,
};
#endif

static rt_err_t hwcrypto_create(struct rt_hwcrypto_ctx *ctx)
{
    rt_err_t res = RT_EOK;

    switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
    {
#if defined(BSP_USING_CRC)
    case HWCRYPTO_TYPE_CRC:
    {
        ctx->contex = RT_NULL;
        //Setup CRC operation
        ((struct hwcrypto_crc *)ctx)->ops = &crc_ops;
        break;
    }
#endif /* BSP_USING_CRC */

    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 & HWCRYPTO_MAIN_TYPE_MASK)
    {
#if defined(BSP_USING_CRC)
    case HWCRYPTO_TYPE_CRC:
    {
        // TODO:复位CRC实现
        break;
    }
#endif /* BSP_USING_CRC */

    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)



关键词: rtthread     加密     分析     crc    

院士
2025-03-06 16:23:46     打赏
2楼

硬件算法就是省空间。

我们在做bootrom的时候,空间小成本就低。

性能上面,我看过一篇帖子说是查表法和硬件计算的时间差不多。


共2条 1/1 1 跳转至

回复

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