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.pswp.cn/news/446089.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446089.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446089.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python成語填空_python定期循環成語?

我有一個工作單位我希望每N秒發生一次.如果我使用簡單化minute 60while True:doSomeWork()time.sleep(minute)取決于doSomeWork()花費的時間,實際循環周期將是一分鐘加上那個時間.如果doSomeWork()所花費的時間不是確定性的,則工作周期更加難以預測.我想做的就是這樣minute 6…

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表示算法模板實例已經創建注冊算法模…

python判斷密碼強度并輸出_密碼強度判斷

[python]代碼庫def pdsz(cd):nnnn Falsefor c in cd:if c.isnumeric():nnnn Truebreakreturn nnnndef pdzm(cd):nnnn Falsefor c in cd:if c.isupper():nnnn Truebreakreturn nnnndef pdhh(cd):nnnn Falsefor c in cd:if c.islower():nnnn Truebreakreturn nnnndef main(…

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…

python 方法的實例_python調用自定義函數的實例操作

在python中&#xff0c;想要調用自定義函數必須先聲明&#xff0c;然后才能調用。使用函數時&#xff0c;只要按照函數定義的形式&#xff0c;向函數傳遞必需的參數&#xff0c;就可以調用函數完成相應的功能或者獲得函數返回的處理結果。(1)聲明函數python中使用 def 可以聲明…

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最初…

python用http協議傳數據_python基礎 -- 簡單實現HTTP協議

標簽&#xff1a;一、直接代碼# -*- coding: utf-8 -*-import socket__author__ ‘lpe234‘__date__ ‘2015-03-12‘if __name__ ‘__main__‘:sock socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.bind((‘127.0.0.1‘, 8001))sock.listen(5)while True:connecti…

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;查找命中時返回查找到的算法或注冊用算法幼…

python ssh 遠程登錄路由器執行命令_ssh批量登錄并執行命令(python實現)

局域網內有一百多臺電腦&#xff0c;全部都是linux操作系統&#xff0c;所有電腦配置相同&#xff0c;系統完全相同(包括用戶名和密碼)&#xff0c;ip地址是自動分配的。現在有個任務是在這些電腦上執行某些命令&#xff0c;者說進行某些操作&#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…