内核加密编程接口
本文总结了内核加密子系统的基本编程接口,列出了几个关键数据结构的关联。
- 内核版本:4.19.90
关于内核加密子系统的编程接口介绍,除了内核自带的文档外,能找到的比较详细的参考资料为Boris Brezillon在"Embedded Linux Conference Europe 2017"的报告PPT,关键部分截图如下:
PPT中同时给出了使用案例,如下:
PPT中对内核加密算法的使用总结得很详细。
总的来说,在内核态使用加密算法的过程分为以下几步:
- 分配tranform对象
- 分配request对象
- 设置上下文 如加密密钥/验签公钥,填充数据源
- 完成加密/解密/摘要/验签
- 释放transform,request等对象
以SM3的使用为例,分别对应如下几个步骤:
-
struct crypto_ahash * atfm = crypto_alloc_ahash("sm3-generic",0,0);
-
struct ahash_request *req = ahash_request_alloc(atfm,GFP_KERNEL);
-
struct crypto_wait wait;crypto_init_wait(&wait);
ahash_request_set_callback(req,CRYPTO_TFM_REQ_MAY_BACKLOG,crypto_req_done,&wait);
struct scatterlist sg;sg_init_one(&sg,data,size);
ahash_request_set_crypt(req,&sg,result,size); -
ret=crypto_ahash_digest(req);
-
ahash_request_free(req);
crypto_free_ahash(atfm);
相关数据结构的关联如下所示:
上图粗略描述了静态算法构造transform、构造request的过程:分配空间/初始化函数指针/建立tfm、req和alg之间的关联。
建立关联的过程被各种看似复杂的对象之间的包含/被包含的关系掩盖了简单的实质,之所以实现得这么复杂,是为了未来能灵活地对加密模块进行扩展,阅读这部分代码时我们不要被这种复杂的假象所吓倒。
最终干活的为transform,transform中保存的相关函数指针是在构造transform时从对应的alg实例中拷贝过来的,对应上图中棕色的一部分。