Linux内核crypto子系统的调用逻辑

  • testmgr.c - crypto/testmgr.c - Linux source code (v5.15.11) - Bootlin
  • 上述代码是内核内部即crypto子系统对外提供密码服务的测试程序
  • 调用流程:crypto API <—> crypto core <—> crypto_register_alg
  • 处于用户态的程序想要调用处于内核态的密码算法,需要使用crypto_register_alg函数提交对应的相关信息,进行注册,将一个内核支持的算法注册到crypto系统里。
  • crypto_alg参考链接如下
    • Linux加密框架crypto crypto_alg|cipher_alg数据结构|AES例子_CHYabc123456hh的博客-CSDN博客
  • crypto_alg 结构
struct crypto_alg {struct list_head cra_list;struct list_head cra_users;u32 cra_flags;unsigned int cra_blocksize;unsigned int cra_ctxsize;unsigned int cra_alignmask;int cra_priority;refcount_t cra_refcnt;char cra_name[CRYPTO_MAX_ALG_NAME];char cra_driver_name[CRYPTO_MAX_ALG_NAME];const struct crypto_type *cra_type;union {struct cipher_alg cipher;struct compress_alg compress;} cra_u;int (*cra_init)(struct crypto_tfm *tfm);void (*cra_exit)(struct crypto_tfm *tfm);void (*cra_destroy)(struct crypto_alg *alg);struct module *cra_module;#ifdef CONFIG_CRYPTO_STATSunion {struct crypto_istat_aead aead;struct crypto_istat_akcipher akcipher;struct crypto_istat_cipher cipher;struct crypto_istat_compress compress;struct crypto_istat_hash hash;struct crypto_istat_rng rng;struct crypto_istat_kpp kpp;} stats;
#endif /* CONFIG_CRYPTO_STATS */} CRYPTO_MINALIGN_ATTR;
  • 执行一个请求的时候,还有维护一组上下文的信息, 这些信息记录在结构体: struct crypto_tfm
  • crypto_tfm类型指针tfm可以理解为指代了一个算法对象
  • 参考链接 Linux内核 crypto文件夹 密码学知识学习_CHYabc123456hh的博客-CSDN博客
  • cra_init是准备上下文的函数,比如,你用一个硬件设备压缩数据,实际的物理操作发生在这个硬件的一个队列上,那么就需要准备这个队列,准备必要的缓存等等。
  • cra_exit 是退出上下文。
  • cra_u里是具体执行算法的函数,比如可以压缩和解压缩的函数。
struct crypto_tfm {u32 crt_flags;int node;void (*exit)(struct crypto_tfm *tfm);struct crypto_alg *__crt_alg;void *__crt_ctx[] CRYPTO_MINALIGN_ATTR;
};
  • crypto_tfm中最后一个元素__crt_ctx是这个上下文的私有数据。
  • 上面的crypto_alg中cra_ctxsize参数就是这个私有数据的__crt_ctx的大小

例子   同步接口

/* 分配一个压缩解压缩的上下文, 可以看到这里的压缩解压缩的上下文完全就是crypto_tfm */
struct crypto_comp = crypto_alloc_comp(driver, type, mask);--> crypto_alloc_base(alg_name, type, mask)/* find algrithm: use alg_name, driver name */--> alg = crypto_alg_mod_lookup(alg_name, type, mask);/* 上下文是依据具体的算法去分配的 */--> tfm = __crypto_alloc_tfm(alg, type, mask);/* 上下文中指定相关的算法 */--> tfm->__crt_alg = alg;--> crypto_init_ops/* 把相应的算法中的压缩解压缩函数传递给上下文 */--> crypto_init_compress_ops(tfm)/* ops is struct compress_tfm */--> ops->cot_compress = crypto_compress;--> tfm->__crt_alg->cra_compress.coa_compress--> ops->cot_decompress = crypto_decompress;/** 在创建上下文的最后调用下,算法里的初始化函数,如果是和一个硬件* 的驱动适配,那么这里就可以执行相应硬件初始化的内容。*/--> if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm)))第二,就是执行压缩的操作:
crypto_comp_compress(tfm, input, ilen, result, &dlen)crypto_comp_decompress(crypto_comp, src, slen, dst, dlen)/* so hardware can do compress here! */--> compress_tfm->cot_compress;第三,就是释放这个压缩的上下文
crypto_free_comp(comp)
  • 从设备驱动的角度讲, 设备驱动只是看到了crypto_alg这个结构。

  • 这个结构里的crypt_tfm 即一个操作执行的上下文是从哪里知道的呢?毕竟crypto_alg这个结构里的.cra_init, .cra_exit, .cra_u里的.coa_compress都需要这个执行上下文。

  • 知道这些内部的数据结构对我们理解外部的API有帮助。现在假设crypto的设备驱动已经有了,那么,其他的内核模块怎么用呢? 其实一开头我们已经讲到crypto/testmgr.c测试程序。

  • 测试的代码里有异步的测试和同步的测试流程,我们这里先看同步的测试:

  • 主要的逻辑就三个函数, 首先需要分配一个压缩的上下文(本文用压缩的例子), 其实它就是crypto_tfm的包装,和cryto_tfm是一样的:    紫色的删去 ,我没找到这个压缩的例子 

struct crypto_comp {struct crypto_tfm base;
};
  • 使用testmgr.c文件中的函数进行分析 

第一步 创建对象  进行准备操作

  • crypto.h - include/linux/crypto.h - Linux source code (v5.15.11) - Bootlin   crypto_alloc_comp
  • 创建对象

  • api.c - crypto/api.c - Linux source code (v5.15.11) - Bootlin crypto_alloc_base
  • 调用 crypto_alg_mod_lookup寻找 用户输入的函数的名字是否是内核支持的算法类型

  •  crypto_alloc_base通过crypro_alg_mod_lookup判断这个算法类型是存在的
  • 才会使用函数__crypto_alloc_tfm为其创建对象

  • api.c - crypto/api.c - Linux source code (v5.15.11) - Bootlin 
  • 使用上层输入的 参数 初始化对象

  • api.c - crypto/api.c - Linux source code (v5.15.11) - Bootlin  crypto_init_ops

  • 调用crypto_type的init 
  • algapi.h - include/crypto/algapi.h - Linux source code (v5.15.11) - Bootlin

第二步 执行具体的函数操作

  •  本例子具体执行的函数操作是crypto_comp_compress和crypto_comp_decompress
  • testmgr.c - crypto/testmgr.c - Linux source code (v5.15.11) - Bootlin

 第三步 释放压缩的上下文

例子 异步接口 

  • testmgr.c - crypto/testmgr.c - Linux source code (v5.15.11) - Bootlin
  •  异步接口和同步接口不一样的是,这里又创建一个acomp_req的上下文, 后续的操作都围绕着这个req结构展开。
  • 可以看到req里面包含了异步接口需要的回调函数
static int test_acomp(struct crypto_acomp *tfm,const struct comp_testvec *ctemplate,const struct comp_testvec *dtemplate,int ctcount, int dtcount)
{const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm));unsigned int i;char *output, *decomp_out;int ret;struct scatterlist src, dst;struct acomp_req *req;struct crypto_wait wait;output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);if (!output)return -ENOMEM;decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL);if (!decomp_out) {kfree(output);return -ENOMEM;}for (i = 0; i < ctcount; i++) {unsigned int dlen = COMP_BUF_SIZE;int ilen = ctemplate[i].inlen;void *input_vec;input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL);if (!input_vec) {ret = -ENOMEM;goto out;}memset(output, 0, dlen);crypto_init_wait(&wait);sg_init_one(&src, input_vec, ilen);sg_init_one(&dst, output, dlen);req = acomp_request_alloc(tfm);if (!req) {pr_err("alg: acomp: request alloc failed for %s\n",algo);kfree(input_vec);ret = -ENOMEM;goto out;}acomp_request_set_params(req, &src, &dst, ilen, dlen);acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,crypto_req_done, &wait);ret = crypto_wait_req(crypto_acomp_compress(req), &wait);if (ret) {pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",i + 1, algo, -ret);kfree(input_vec);acomp_request_free(req);goto out;}ilen = req->dlen;dlen = COMP_BUF_SIZE;sg_init_one(&src, output, ilen);sg_init_one(&dst, decomp_out, dlen);crypto_init_wait(&wait);acomp_request_set_params(req, &src, &dst, ilen, dlen);ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);if (ret) {pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",i + 1, algo, -ret);kfree(input_vec);acomp_request_free(req);goto out;}if (req->dlen != ctemplate[i].inlen) {pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",i + 1, algo, req->dlen);ret = -EINVAL;kfree(input_vec);acomp_request_free(req);goto out;}if (memcmp(input_vec, decomp_out, req->dlen)) {pr_err("alg: acomp: Compression test %d failed for %s\n",i + 1, algo);hexdump(output, req->dlen);ret = -EINVAL;kfree(input_vec);acomp_request_free(req);goto out;}kfree(input_vec);acomp_request_free(req);}for (i = 0; i < dtcount; i++) {unsigned int dlen = COMP_BUF_SIZE;int ilen = dtemplate[i].inlen;void *input_vec;input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL);if (!input_vec) {ret = -ENOMEM;goto out;}memset(output, 0, dlen);crypto_init_wait(&wait);sg_init_one(&src, input_vec, ilen);sg_init_one(&dst, output, dlen);req = acomp_request_alloc(tfm);if (!req) {pr_err("alg: acomp: request alloc failed for %s\n",algo);kfree(input_vec);ret = -ENOMEM;goto out;}acomp_request_set_params(req, &src, &dst, ilen, dlen);acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,crypto_req_done, &wait);ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);if (ret) {pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",i + 1, algo, -ret);kfree(input_vec);acomp_request_free(req);goto out;}if (req->dlen != dtemplate[i].outlen) {pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n",i + 1, algo, req->dlen);ret = -EINVAL;kfree(input_vec);acomp_request_free(req);goto out;}if (memcmp(output, dtemplate[i].output, req->dlen)) {pr_err("alg: acomp: Decompression test %d failed for %s\n",i + 1, algo);hexdump(output, req->dlen);ret = -EINVAL;kfree(input_vec);acomp_request_free(req);goto out;}kfree(input_vec);acomp_request_free(req);}ret = 0;out:kfree(decomp_out);kfree(output);return ret;
}

  • 这里需要说明的是,testmsg.c里的这个acomp的测试程序里加了wait的相关内容。这里应该是为了测试方便而加的,一般的异步接口里, 当硬件完成操作的时候,在中断函数里直接调用异步接口的回调函数就可以了。
  • request是为了异步而创建的,但是wait对象的存在的主要目的目前还不清楚

例外一个例子

 

总的来说,在内核态使用加密算法的过程分为以下几步:

  • 分配tranform对象   也就是具体的算法
  • 分配request对象  异步操作等待对象
  • 设置上下文 如加密密钥/验签公钥,填充数据源,给scatterlist设置缓冲区,给异步请求对象设置回调函数/初始化向量等,给密码算法对象设置密钥
  • 完成加密/解密/摘要/验签
  • 释放transform,request等对象
  • 如果是同步调用的方式,不需要创建request对象

参考链接

  • Linux内核crypto子系统深入理解_Linux教程_Linux公社-Linux系统门户网站
  • Linux内核 crypto文件夹 密码学知识学习_CHYabc123456hh的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446089.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux加密框架 crypto算法模板 以及CBC算法模板实例

参考链接 Linux加密框架中的主要数据结构&#xff08;四&#xff09;_家有一希的博客-CSDN博客algapi.h - include/crypto/algapi.h - Linux source code (v5.15.11) - Bootlin struct crypto_instance {struct crypto_alg alg;struct crypto_template *tmpl;union {/* Node i…

tomcat temp 大量 upload 文件_渗透测试之文件上传漏洞总结

文末下载上传环境源码客户端js检查一般都是在网页上写一段javascript脚本&#xff0c;校验上传文件的后缀名&#xff0c;有白名单形式也有黑名单形式。查看源代码可以看到有如下代码对上传文件类型进行了限制&#xff1a;我们可以看到对上传文件类型进行了限制。绕过方法1.我们…

Linux加密框架 crypto算法模板 以及HMAC算法模板实例

HMAC算法模板实例 HMAC算法模板的创建实例的接口是hmac_create函数hmac.c - crypto/hmac.c - Linux source code (v5.15.11) - Bootlin hmac_create输入的参数包括 算法模板 tmpl 和 算法模板实例参数 tbhmac_cretae函数返回的结果为0表示算法模板实例已经创建注册算法模…

linux加密框架 crypto 算法crypto_register_alg的注册流程

算法注册流程 静态算法模块初始化 分组算法模块初始化 AES算法模块&#xff08;aes_generic.c&#xff09;的初始化接口aes_init实现向加密框架注册AES算法的功能&#xff0c;如下所示。aes_generic.c - crypto/aes_generic.c - Linux source code (v5.15.12) - Bootlin sta…

linux加密框架 crypto 静态哈希算法crypto_register_shash注册流程

参考链接 Linux加密框架的算法管理&#xff08;一&#xff09;_家有一希的博客-CSDN博客_linux加密框架设计与实现shash.c - crypto/shash.c - Linux source code (v5.15.12) - Bootlin 函数介绍 crypto_register_shash函数实现向加密框架注册静态哈希算法的功能&#xff0c;…

多个线程访问统一对象的不同方法_C#多线程读写同一文件处理

在多线程访问读写同一个文件时&#xff0c;经常遇到异常&#xff1a;“文件正在由另一进程使用&#xff0c;因此该进程无法访问此文件”。多线程访问统一资源的异常&#xff0c;解决方案1&#xff0c;保证读写操作单线程执行&#xff0c;可以使用lock解决方案2&#xff0c;使用…

linux加密框架 crypto 通用算法注册接口__crypto_register_alg注册流程

函数介绍 __crypto_register_alg函数实现向加密框架注册算法&#xff08;包括静态算法和动态算法&#xff09;的功能&#xff0c;输入参数为算法说明alg&#xff0c;注册成功时返回算法注册用的算法幼虫larval&#xff0c;注册失败时返回失败原因。__crypto_register_alg函数执…

spark官方文档_Spark整合Ray思路漫谈

什么是Ray之前花了大概两到三天把Ray相关的论文&#xff0c;官网文档看了一遍&#xff0c;同时特意去找了一些中文资料看Ray当前在国内的发展情况(以及目前国内大部分人对Ray的认知程度)。先来简单介绍下我对Ray的认知。首先基因很重要&#xff0c;所以我们先需要探查下Ray最初…

linux加密框架 crypto 算法管理 - 算法查找接口 crypto_find_alg

算法查找接口crypto_find_alg 算法实例tfm是算法的一个可运行的副本&#xff0c;因此在创建算法实例前首先要查找确认算法是否已经注册有效&#xff0c;此时算法查找由函数crypto_find_alg实现。补充&#xff1a; struct crypto_tfm *tfm; crypto_tfm类型指针tfm可以理解为指代…

linux加密框架 crypto 算法管理 - 算法查找接口 crypto_alg_mod_lookup

参考链接 Linux加密框架的算法管理&#xff08;二&#xff09;_家有一希的博客-CSDN博客linux加密框架 crypto 算法管理 - 算法查找接口 crypto_find_alg_CHYabc123456hh的博客-CSDN博客 函数介绍 crypto_alg_mod_lookup函数输入参数包括待查找的算法名name、算法类型type和算…

qt triggered信号_Qt之网络编程UDP通信

点击上方“Qt学视觉”&#xff0c;选择“星标”公众号重磅干货&#xff0c;第一时间送达想要学习的同学们还请认真阅读每篇文章&#xff0c;相信你一定会有所收获UDP通信概述UDP(UserDatagramProtocol&#xff0c;用户数据报协议)是轻量的、不可靠的、面向数据报(datagram)、无…

adguard没有核心 core no_面试官:线程池如何按照core、max、queue的执行顺序去执行?...

前言这是一个真实的面试题。前几天一个朋友在群里分享了他刚刚面试候选者时问的问题&#xff1a;"线程池如何按照core、max、queue的执行循序去执行&#xff1f;"。我们都知道线程池中代码执行顺序是&#xff1a;corePool->workQueue->maxPool&#xff0c;源码…

linux加密框架 crypto 算法管理 - 算法查找接口 crypto_larval_lookup

参考链接 Linux加密框架的算法管理&#xff08;二&#xff09;_家有一希的博客-CSDN博客 crypto_larval_lookup函数介绍 crypto_larval_lookup函数的输入参数包括待查找的算法名name、算法类型type和算法类型屏蔽位mask&#xff0c;查找命中时返回查找到的算法或注册用算法幼…

linux加密框架 crypto 算法管理 - 算法查找接口 crypto_alg_lookup函数

参考链接 Linux加密框架的算法管理&#xff08;二&#xff09;_家有一希的博客-CSDN博客 函数介绍 static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,u32 mask) {struct crypto_alg *alg;u32 test 0;if (!((type | mask) & CRYPTO_ALG_TESTED))…

linux加密框架 crypto 算法管理 - 动态和静态算法管理

参考链接 Linux加密框架的算法管理&#xff08;三&#xff09;_家有一希的博客-CSDN博客 动态和静态算法管理 静态算法 加密框架中的算法分为静态算法和动态算法两种&#xff0c;其中静态算法指的是以"算法名.ko"形式存在的静态编译的算法模块&#xff0c;如aes.k…

linux加密框架 crypto 算法管理 - 算法检测

参考链接 Linux加密框架的算法管理&#xff08;四&#xff09;_家有一希的博客-CSDN博客 函数介绍 如前所述&#xff0c;无论是静态算法还是动态算法&#xff0c;算法注册的最后一步都是进行算法正确性检验&#xff0c;一般流程是先调用__crypto_register_alg函数进行通用的算…

select选中的值_selenium下拉框处理(select)

前言 web自动化中&#xff0c;常见的场景还有一个下拉框的选择&#xff0c;哪么在selenium中如何做下拉框的操作呢&#xff1f;selectselect在HTML中表示元素名&#xff0c;可创建单选或多选菜单。HTML中select长什么样子&#xff1a;select在HTML中元素名&#xff0c;下面有选…

linux加密框架 crypto 算法管理 - 创建哈希算法实例

crypto_alloc_ahash函数 加密框架中的哈希算法可以是同步方式实现的也可以是异步方式实现的&#xff0c;但是算法应用不关注哈希算法的实现方式&#xff0c;关注的是哈希算法提供的算法接口。为实现统一管理&#xff0c;加密框架默认哈希算法的实现方式为异步方式&#xff0c;…

发票管理软件_企业为什么需要ERP企业管理软件?

对于一个制造企业来说&#xff0c;生产是企业最大的动力&#xff0c;而生产也需要进行优化管理&#xff0c;一个好的生产管理方式会带给企业巨大的发展空间和利润价值。对于一个制造企业来说&#xff0c;生产是企业最大的动力&#xff0c;而生产也需要进行优化管理&#xff0c;…

linux加密框架 crypto 算法管理 - 应用角度讲解加密框架的运行流程

参考链接 Linux加密框架的应用示例&#xff08;一&#xff09;_家有一希的博客-CSDN博客 本文大纲 本节将从应用角度说明加密框架的运行流程&#xff0c;包括加密框架如何管理算法、如何动态创建算法&#xff0c;应用模块如何创建算法实例、如何通过算法实例调用算法接口等。…