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

共1条 1/1 1 跳转至

rtthread硬件加密-3bignum加密分析

高工
2025-03-09 19:13:55     打赏

       乍一看bignum加密,感觉很陌生,但是通过查询资料发现,这个加密是RSA,ECC加密的基础部分,也就是说,这部分并不是直接面对用户的部分,在他之上,还有更复杂的面对用户层面的加密算法。

源码解读

源码路径

components\drivers\hwcrypto\hw_bignum.c
components\drivers\hwcrypto\hw_bignum.h

数据结构

struct hw_bignum_mpi
{ // bignum操作的对象
    int sign;                   /**< integer sign. -1 or 1 */
                                // 虽然备注这么写的,但是看实际功能是: 1 为已初始化,0为无数据 
    rt_size_t total;            /**< buffer总大小 */
    rt_uint8_t *p;              /**< 指向buffer的指针 */
};

struct hwcrypto_bignum_ops
{
    rt_err_t (*add)(struct hwcrypto_bignum *bignum_ctx,
                    struct hw_bignum_mpi *x,
                    const struct hw_bignum_mpi *a,
                    const struct hw_bignum_mpi *b);             /**< x = a + b */
    rt_err_t (*sub)(struct hwcrypto_bignum *bignum_ctx,
                    struct hw_bignum_mpi *x,
                    const struct hw_bignum_mpi *a,
                    const struct hw_bignum_mpi *b);             /**< x = a - b */
    rt_err_t (*mul)(struct hwcrypto_bignum *bignum_ctx,
                    struct hw_bignum_mpi *x,
                    const struct hw_bignum_mpi *a,
                    const struct hw_bignum_mpi *b);             /**< x = a * b */
    rt_err_t (*mulmod)(struct hwcrypto_bignum *bignum_ctx,
                       struct hw_bignum_mpi *x,
                       const struct hw_bignum_mpi *a,
                       const struct hw_bignum_mpi *b,
                       const struct hw_bignum_mpi *c);          /**< x = a * b (mod c) */
    rt_err_t (*exptmod)(struct hwcrypto_bignum *bignum_ctx,
                        struct hw_bignum_mpi *x,
                        const struct hw_bignum_mpi *a,
                        const struct hw_bignum_mpi *b,
                        const struct hw_bignum_mpi *c);         /**< x = a ^ b (mod c) */
};

struct hwcrypto_bignum
{
    struct rt_hwcrypto_ctx parent;              /**< 对接的硬件加密框架信息 */
    const struct hwcrypto_bignum_ops *ops;      /**< 创建对象时需要提供的结构体 */
};

创建硬件加密上下文

static struct rt_hwcrypto_ctx *bignum_default;

rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device)
{
    if (bignum_default)
    {    // 如果注册过,则销毁,但结合hwcrypto_bignum_dev_is_init实现会发现,此部分压根不会跑到,因此不需要关注
        rt_hwcrypto_ctx_destroy(bignum_default);
        bignum_default = RT_NULL;
    }
    if (device == RT_NULL)
    {   // 同上,此部分无法跑到
        return RT_EOK;
    }
    // 实际创建bugnum加密设备的操作入口
    bignum_default = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_BIGNUM, sizeof(struct hwcrypto_bignum));
    if (bignum_default == RT_NULL)
    {
        return -RT_ERROR;
    }
    return RT_EOK;
}

struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void)
{ // 如果能找到设备,则返回设备,若找不到,则返回RT_NULLRT_NULL
    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;
}

rt_inline rt_err_t hwcrypto_bignum_dev_is_init(void)
{
    struct rt_hwcrypto_device *dev;

    if (bignum_default)
    { // 如果之前已经注册过设备,则返回注册过
        return RT_EOK;
    }

    dev = rt_hwcrypto_dev_default();
    if (dev == RT_NULL)
    { // 如果硬件加密部分无该加密设备,则返回错误信息
        return -RT_ERROR;
    }
    // 创建bignum加密设备
    return rt_hwcrypto_bignum_default(dev);
}

初始化bignum对象

void rt_hwcrypto_bignum_init(struct hw_bignum_mpi *n)
{ // 初始化成默认值,倒是没什么可深入分析的
    if(n == RT_NULL)
        return;

    n->sign = 1;
    n->total = 0;
    n->p = RT_NULL;
}

销毁bignum对象

void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n)
{// 和初始化相反,不过这对n->p的处理,
 // 明显存在漏洞:
 // 1. 并未判断此指针的有效性
 // 2. 既然都要释放此区域了,全部置为0xFF的操作感觉也没啥必要了
    if (n)
    {
        rt_memset(n->p, 0xFF, n->total);
        rt_free(n->p);
        n->sign = 0;
        n->total = 0;
        n->p = RT_NULL;
    }
}

获取bignum对象维护的数据长度

int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n)
{
    int tmp_len, total;

    if (n == RT_NULL || n->p == RT_NULL)
    {
        return 0;
    }

    // 计算未用部分长度
    tmp_len = 0;
    total = n->total;
    while ((total > 0) && (n->p[total - 1] == 0))
    {
        tmp_len++;
        total--;
    }

    // 返回已用部分长度
    return n->total - tmp_len;
}

输出bigunum数据

int rt_hwcrypto_bignum_export_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
{
    int cp_len, i, j;

    if (n == RT_NULL || buf == RT_NULL)
    {
        return 0;
    }
    rt_memset(buf, 0, len);
    cp_len = (int)n->total > len ? len : (int)n->total;
    for(i = cp_len, j = 0; i > 0; i--, j++)
    {
        buf[i - 1] = n->p[j];
    }

    return cp_len;
}

输入bigunum数据

int rt_hwcrypto_bignum_import_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
{
    int cp_len, i, j;
    void *temp_p;

    if (n == RT_NULL || buf == RT_NULL)
    {
        return 0;
    }
    if ((int)n->total < len)
    {
        temp_p = rt_malloc(len);
        if (temp_p == RT_NULL)
        {
            return 0;
        }
        rt_free(n->p);
        n->p = temp_p;
        n->total = len;
    }

    n->sign = 1;
    rt_memset(n->p, 0, n->total);
    cp_len = (int)n->total > len ? len : n->total;

    for(i = cp_len, j = 0; i > 0; i--, j++)
    {
        n->p[j] = buf[i - 1];
    }

    return cp_len;
}

实际干活的部分

      会发现这部分实现逻辑都是一致的,都是先判断bignum加密是否初始化,如果初始化,则调用驱动提供的加速实现进行加速计算。

bignum加

rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *x,
                                const struct hw_bignum_mpi *a,
                                const struct hw_bignum_mpi *b)
{// 实现的功能为ab相加后输出至x
    struct hwcrypto_bignum *bignum_ctx;

    if (hwcrypto_bignum_dev_is_init() != RT_EOK)
    {
        return -RT_ERROR;
    }
    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
    if (bignum_ctx->ops->add)
    {
        return bignum_ctx->ops->add(bignum_ctx, x, a, b);
    }
    return -RT_ERROR;
}

bignum减

rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *x,
                                const struct hw_bignum_mpi *a,
                                const struct hw_bignum_mpi *b)
{// 实现的功能为ab相减后输出至x
    struct hwcrypto_bignum *bignum_ctx;

    if (hwcrypto_bignum_dev_is_init() != RT_EOK)
    {
        return -RT_ERROR;
    }
    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
    if (bignum_ctx->ops->sub)
    {
        return bignum_ctx->ops->sub(bignum_ctx, x, a, b);
    }
    return -RT_ERROR;
}

bignum乘

rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *x,
                                const struct hw_bignum_mpi *a,
                                const struct hw_bignum_mpi *b)
{ // 实现的功能为ab相乘后输出至x
    struct hwcrypto_bignum *bignum_ctx;

    if (hwcrypto_bignum_dev_is_init() != RT_EOK)
    {
        return -RT_ERROR;
    }
    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
    if (bignum_ctx->ops->mul)
    {
        return bignum_ctx->ops->mul(bignum_ctx, x, a, b);
    }
    return -RT_ERROR;
}

bignum 乘后求余

rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *x,
                                   const struct hw_bignum_mpi *a,
                                   const struct hw_bignum_mpi *b,
                                   const struct hw_bignum_mpi *c)
{ //实现的功能为a乘b后对c求余,输出至x
    struct hwcrypto_bignum *bignum_ctx;

    if (hwcrypto_bignum_dev_is_init() != RT_EOK)
    {
        return -RT_ERROR;
    }
    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
    if (bignum_ctx->ops->mulmod)
    {
        return bignum_ctx->ops->mulmod(bignum_ctx, x, a, b, c);
    }
    return -RT_ERROR;
}

bignum 幂运算求余

rt_err_t rt_hwcrypto_bignum_exptmod(struct hw_bignum_mpi *x,
                                    const struct hw_bignum_mpi *a,
                                    const struct hw_bignum_mpi *b,
                                    const struct hw_bignum_mpi *c)
{//实现的功能为a的b次幂后对c求余,输出至x
    struct hwcrypto_bignum *bignum_ctx;

    if (hwcrypto_bignum_dev_is_init() != RT_EOK)
    {
        return -RT_ERROR;
    }
    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
    if (bignum_ctx->ops->exptmod)
    {
        return bignum_ctx->ops->exptmod(bignum_ctx, x, a, b, c);
    }
    return -RT_ERROR;
}

总结

    看完整个代码后,其实个人认为这部分并不能算是加密,他的实际功能仅仅是大数据运算加速封装接口。单片机大多是冯诺依曼结构的,只能串行的执行命令。在大数据简单处理时,这种操作就显得非常耗时,而如果有一个硬件设备可以一次加载多个数据,同时计算,无疑是十分节省时间的。

       而看完这部分,对应的驱动实现部分可以按如下实现:

#include <rtconfig.h>

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

#if defined(BSP_USING_BIGNUM)
rt_err_t bignum_addbignum_add(struct hwcrypto_bignum *bignum_ctx,
                    struct hw_bignum_mpi *x,
                    const struct hw_bignum_mpi *a,
                    const struct hw_bignum_mpi *b) {
    // TODO: Add function
    return RT_EOK;                 
}

rt_err_t bignum_addbignum_sub(struct hwcrypto_bignum *bignum_ctx,
                    struct hw_bignum_mpi *x,
                    const struct hw_bignum_mpi *a,
                    const struct hw_bignum_mpi *b) {
    // TODO: Add function
    return RT_EOK;                 
}

rt_err_t bignum_addbignum_mul(struct hwcrypto_bignum *bignum_ctx,
                    struct hw_bignum_mpi *x,
                    const struct hw_bignum_mpi *a,
                    const struct hw_bignum_mpi *b) {
    // TODO: Add function
    return RT_EOK;                 
}

rt_err_t bignum_addbignum_mulmod(struct hwcrypto_bignum *bignum_ctx,
                       struct hw_bignum_mpi *x,
                       const struct hw_bignum_mpi *a,
                       const struct hw_bignum_mpi *b,
                       const struct hw_bignum_mpi *c) {
    // TODO: Add function
    return RT_EOK;                 
}

rt_err_t bignum_addbignum_exptmod(struct hwcrypto_bignum *bignum_ctx,
                       struct hw_bignum_mpi *x,
                       const struct hw_bignum_mpi *a,
                       const struct hw_bignum_mpi *b,
                       const struct hw_bignum_mpi *c) {
    // TODO: Add function
    return RT_EOK;                 
}

static const struct hwcrypto_bignum_ops bignum_ops =
{
    .add = bignum_addbignum_add,
    .sub = bignum_addbignum_sub,
    .mul = bignum_addbignum_mul,
    .mulmod = bignum_addbignum_mulmod,
    .exptmod = bignum_addbignum_exptmod,
};
#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_BIGNUM)
    case HWCRYPTO_TYPE_BIGNUM:
    {
        ctx->contex = RT_NULL;
        //Setup bignum operation
        ((struct hwcrypto_bignum_ops *)ctx)->ops = &bignum_ops;
        break;
    }
#endif /* BSP_USING_BIGNUM */

    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_BIGNUM)
    case HWCRYPTO_TYPE_BIGNUM:
    {
        // TODO: Bignum reset
        break;
    }
#endif /* BSP_USING_BIGNUM */

    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     硬件     加密     bignum     hwc    

共1条 1/1 1 跳转至

回复

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