乍一看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)
我要赚赏金
