乍一看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)