乍一看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)
 
					
				
 
			
			
			
						
			 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

