日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux加密框架 crypto 算法管理 - 哈希算法应用实例

發布時間:2023/12/13 linux 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux加密框架 crypto 算法管理 - 哈希算法应用实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考鏈接

  • Linux加密框架應用示例(二)_家有一希的博客-CSDN博客
  • linux加密框架 crypto 算法管理 - 應用角度講解加密框架的運行流程_CHYabc123456hh的博客-CSDN博客

在應用模塊中創建并初始化哈希算法實例

  • 假設某個SA配置使用的認證算法為"hmac(md5)"(即x->aalg->alg_name為"hmac(md5)"),在調用ah_init_state函數初始化SA狀態時,將創建認證算法對應的異步哈希算法實例ahash,并設置HMAC密鑰(密鑰數據保存在SA中,即x->aalg->alg_key

?ah_init_state函數

  • 調用ah_init_state函數初始化SA狀態
static int ah_init_state(struct xfrm_state *x) {struct ah_data *ahp = NULL;struct xfrm_algo_desc *aalg_desc;struct crypto_ahash *ahash;if (!x->aalg)goto error;if (x->encap)goto error;ahp = kzalloc(sizeof(*ahp), GFP_KERNEL);if (!ahp)return -ENOMEM;ahash = crypto_alloc_ahash(x->aalg->alg_name, 0, 0);if (IS_ERR(ahash))goto error;ahp->ahash = ahash;if (crypto_ahash_setkey(ahash, x->aalg->alg_key,(x->aalg->alg_key_len + 7) / 8))goto error;/** Lookup the algorithm description maintained by xfrm_algo,* verify crypto transform properties, and store information* we need for AH processing. This lookup cannot fail here* after a successful crypto_alloc_ahash().*/aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);BUG_ON(!aalg_desc);if (aalg_desc->uinfo.auth.icv_fullbits/8 !=crypto_ahash_digestsize(ahash)) {pr_info("%s: %s digestsize %u != %hu\n",__func__, x->aalg->alg_name,crypto_ahash_digestsize(ahash),aalg_desc->uinfo.auth.icv_fullbits / 8);goto error;}ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;ahp->icv_trunc_len = x->aalg->alg_trunc_len/8;if (x->props.flags & XFRM_STATE_ALIGN4)x->props.header_len = XFRM_ALIGN4(sizeof(struct ip_auth_hdr) +ahp->icv_trunc_len);elsex->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +ahp->icv_trunc_len);if (x->props.mode == XFRM_MODE_TUNNEL)x->props.header_len += sizeof(struct iphdr);x->data = ahp;return 0;error:if (ahp) {crypto_free_ahash(ahp->ahash);kfree(ahp);}return -EINVAL; }
  • 創建認證算法對應的異步哈希算法實例ahash
ahash = crypto_alloc_ahash(x->aalg->alg_name, 0, 0);if (IS_ERR(ahash))goto error;
  • 并設置HMAC密鑰(密鑰數據保存在SA中,即x->aalg->alg_key
ahp->ahash = ahash;if (crypto_ahash_setkey(ahash, x->aalg->alg_key,(x->aalg->alg_key_len + 7) / 8))goto error; /* Data for transformer */struct xfrm_algo_auth *aalg; //認證算法struct xfrm_algo *ealg; //加密算法struct xfrm_algo *calg; //壓縮算法struct xfrm_algo_aead *aead; //AEAD算法

  • 這一塊有點繞
  • 由于默認算法以異步方式實現,因此在ah_init_state函數中將調用crypto_alloc_ahash函數創建與認證算法"hmac(md5)"對應的異步哈希算法實例,記為hmac_md5_ahash
  • 由于MD5算法是以同步方式實現的,由其衍生的"hmac(md5)"算法也是以同步方式實現的,因此也會同步創建"hmac(md5)"算法的同步哈希算法實例,記為hmac_md5_shash
  • 由于"hmac(md5)"算法是在MD5算法基礎上構造的,具體的算法運算由MD5算法實現,因此還會同步創建MD5算法的同步哈希算法實例,記為md5_shash
  • 綜上所述,調用crypto_alloc_ahash函數實際上創建了三個算法實例,其中hmac_md5_ahash是面向具體算法應用(如IPSEC模塊)的,md5_shash是面向具體算法實現(如MD5算法)的,hmac_md5_shash負責將hmac_md5_ahash和md5_shash兩個算法實例串聯在一起,三個算法實例的關系如下所示。

創建哈希算法實例hmac_md5_ahash

  • 下面將按照函數調用關系逐步說明如何創建哈希算法實例hmac_md5_ahash。

1)ah_init_state函數

  • ah_init_state函數調用crypto_alloc_ahash函數異步哈希算法實例hmac_md5_ahash時,輸入參數包括算法alg_name(=“hmac(md5)”)、算法類型type(=0)和算法類型屏蔽字mask(=0)
ahash = crypto_alloc_ahash(x->aalg->alg_name, 0, 0);if (IS_ERR(ahash))goto error;
  • 從函數的輸入參數可知,ah_init_state函數不關心認證算法的實現方式,只關心是否有可提供服務的認證算法

2)crypto_alloc_ahash函數

  • 實際上crypto_alloc_ahash函數是一個包裹函數(wrapper),具體工作由crypto_alloc_tfm函數實現。crypto_alloc_tfm函數繼承了調用者所有的輸入參數。
  • ahash.c - crypto/ahash.c - Linux source code (v5.15.12) - Bootlin
  • 由于crypto_alloc_tfm函數并不是創建特定的算法實例(即特定數據結構指針),而是返回一個通用指針(即void *),由調用者具體解釋通用指針的含義(即將通用指針轉換為特定算法實例數據結構指針)。不同類型算法實例占用的內存空間不同、初始化流程存在差異,這些不同和差異由crypto_alloc_tfm函數的輸入參數frontend說明,在這里參數frontend按照字面理解為算法前端,按照數據結構實際上就是算法類型常量指針。
  • frontend的類型是?crypto_type
  • internal.h - crypto/internal.h - Linux source code (v5.15.12) - Bootlin??
  • 由于crypto_alloc_ahash函數用于創建異步哈希算法實例,因此在調用crypto_alloc_tfm函數時傳遞的frontend參數為異步哈希算法類型常量crypto_shash_type,調用結束后將crypto_alloc_tfm函數返回地通用指針隱式地強制轉換為異步哈希算法實例指針

3)crypto_alloc_tfm函數

  • api.c - crypto/api.c - Linux source code (v5.15.12) - Bootlin
  • crypto_alloc_tfm函數內部調用? crypto_alloc_tfm_node 函數
  • crypto_alloc_tfm_node 函數的基本邏輯是先調用crypto_find_alg函數查找符合條件(包括算法名alg_name、算法類型type和算法類型屏蔽字)的算法alg,然后再調用crypto_create_tfm_node函數創建與算法alg關聯的算法實例tfm。
void *crypto_alloc_tfm_node(const char *alg_name,const struct crypto_type *frontend, u32 type, u32 mask,int node) {void *tfm;int err;for (;;) {struct crypto_alg *alg;alg = crypto_find_alg(alg_name, frontend, type, mask);if (IS_ERR(alg)) {err = PTR_ERR(alg);goto err;}tfm = crypto_create_tfm_node(alg, frontend, node);if (!IS_ERR(tfm))return tfm;crypto_mod_put(alg);err = PTR_ERR(tfm);err:if (err != -EAGAIN)break;if (fatal_signal_pending(current)) {err = -EINTR;break;}}return ERR_PTR(err); } EXPORT_SYMBOL_GPL(crypto_alloc_tfm_node);
  • 假設第一次使用"hmac(md5)“算法,算法查找不命中,因此加密框架將根據算法模板(HMAC模板)和基礎算法(MD5算法)動態創建新的算法(通用算法說明記為hmac_md5_alg)并注冊。
  • 截至到目前為止,函數接口調用關系如下圖所示

?

  • ?crypto_find_alg 函數調用之前,alg_name指代hmac(md5),crypto_find_alg函數轉化之后輸出alg,alg已經指定的是hmac_md5_alg

3. 創建動態算法"hmac(md5)”

  • 1)crypto_find_alg函數
  • crypto_find_alg函數的主要功能是確認算法查找的預期算法類型(包括算法類型type以及算法類型屏蔽字mask)和算法查找接口lookup
  • api.c - crypto/api.c - Linux source code (v5.15.12) - Bootlin
struct crypto_alg *crypto_find_alg(const char *alg_name,const struct crypto_type *frontend,u32 type, u32 mask) {if (frontend) {type &= frontend->maskclear;mask &= frontend->maskclear;type |= frontend->type;mask |= frontend->maskset;}return crypto_alg_mod_lookup(alg_name, type, mask); } EXPORT_SYMBOL_GPL(crypto_find_alg);
  • 按照調用關系,此時傳遞給crypto_find_alg函數的算法前端frontend為異步哈希算法類型常量crypto_ahash_type,算法類型type和算法類型屏蔽字均為0,其中算法前端frontend與算法查找相關的成員變量如下所示。

static const struct crypto_type crypto_ahash_type = {.extsize = crypto_ahash_extsize,.init_tfm = crypto_ahash_init_tfm,.free = crypto_ahash_free_instance, #ifdef CONFIG_PROC_FS.show = crypto_ahash_show, #endif.report = crypto_ahash_report,.maskclear = ~CRYPTO_ALG_TYPE_MASK,.maskset = CRYPTO_ALG_TYPE_AHASH_MASK,.type = CRYPTO_ALG_TYPE_AHASH,.tfmsize = offsetof(struct crypto_ahash, base), };
  • 在調用算法查找接口lookup(默認接口crypto_alg_mod_lookup)時,算法類型type為CRYPTO_ALG_TYPE_AHASH,算法類型屏蔽字mask為CRYPTO_ALG_TYPE_AHASH_MASK。
  • 注意事項:未找到證據? 在遍歷算法管理鏈表查找算法前(crypto_larval_lookup函數),還會再次更新算法類型為type=type&mask=0x08(在算法類型定義中為CRYPTO_ALG_TYPE_HASH)。
  • api.c - crypto/api.c - Linux source code (v5.15.12) - Bootlin
  • api.c - crypto/api.c - Linux source code (v5.15.12) - Bootlin

  • 在遍歷管理算法鏈表時,如果((cra_flags ^ type) & mask)=0表示當前算法滿足查找條件中的算法類型要求,否則不滿足算法類型要求,也就是說只要是哈希算法,無論是同步方式實現還是異步方式實現,都滿足算法類型要求。
  • api.c - crypto/api.c - Linux source code (v5.15.12) - Bootlin

  • 2)crypto_alg_mod_lookup函數
  • 在crypto_alg_mod_lookup函數中,調用crypto_larval_lookup函數查找符合條件的算法。假設第一次使用"hmac(md5)"算法,算法查找不命中,在調用crypto_larval_lookup函數時將返回一個與查找算法同名的注冊用算法幼蟲,記為hmac_md5_larval_r。
  • 算法查找不命中時,加密框架嘗試動態創建符合條件的算法,調用crypto_probing_notify函數在加密通知鏈發布一個算法注冊(CRYPTO_MSG_ALG_REQUEST)通知,動態創建"hmac(md5)“算法,傳遞的參數由注冊用算法幼蟲hmac_md5_larval_r指定。
  • larvel 接收?crypto_larval_lookup? 返回的??算法同名的注冊用算法幼蟲,記為hmac_md5_larval_r
  • larvel 指定?hmac_md5_larval_r;
  • larvel 作為函數的形參輸入,由函數?crypto_probing_notify 進行 算法注冊
  • api.c - crypto/api.c - Linux source code (v5.15.12) - Bootlin

  • 發布算法注冊通知時,通過解析注冊用算法幼蟲hmac_md5_larval_r的算法名(即"hmac(md5)”)可獲取算法模板名hmac和基礎算法名md5,加上預期的算法類型共同組成傳遞給算法探測線程cryptomgr_probe的參數param。?

  • https://elixir.bootlin.com/linux/latest/source/crypto/algboss.c#L50
  • 算法探測線程運行時,根據算法模板名hmac查找到對應的算法模板hmac_tmpl。由于算法模板hmac_tmpl定義了create接口(即hmac_create函數),將調用之根據參數列表param->tb創建并注冊動態算法。

總結

以上是生活随笔為你收集整理的linux加密框架 crypto 算法管理 - 哈希算法应用实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。