crypto_alloc_ahash函數
- 加密框架中的哈希算法可以是同步方式實現的也可以是異步方式實現的,但是算法應用不關注哈希算法的實現方式,關注的是哈希算法提供的算法接口。為實現統一管理,加密框架默認哈希算法的實現方式為異步方式,將哈希算法的外部接口統一定義為異步哈希算法接口。
- 算法實例是算法應用和加密框架之間的橋梁,算法應用通過算法實例實現算法調用。以哈希算法實例為例,在IPSEC框架的AH協議模塊中,協議狀態初始化(ah_init_state函數)時,將根據配置的認證算法名(x->aalg->alg_name)創建對應的異步哈希算法實例ahash,如下所示。
- ah4.c - net/ipv4/ah4.c - Linux source code (v5.15.12) - Bootlin
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;
}
- crypto_alloc_ahash函數的輸入參數包括算法名alg_name、算法類型type和算法類型屏蔽字mask,返回值為新創建的異步哈希算法實例,函數處理流程非常簡單,調用crypto_alloc_tfm函數創建算法alg_name對應的異步哈希算法實例。
struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type,u32 mask)
{return crypto_alloc_tfm(alg_name, &crypto_ahash_type, type, mask);
}
EXPORT_SYMBOL_GPL(crypto_alloc_ahash);
crypto_alloc_tfm函數
static inline void *crypto_alloc_tfm(const char *alg_name,const struct crypto_type *frontend, u32 type, u32 mask)
{return crypto_alloc_tfm_node(alg_name, frontend, type, mask, NUMA_NO_NODE);
}
- crypto_alloc_tfm函數的輸入參數包括算法名alg_name、算法前端fronted(即算法類型常量)、算法類型type和算法類型屏蔽字mask
- 處理流程如下圖所示。
- 1)crypto_alloc_tfm函數內部嵌套了一個函數crypto_alloc_tfm_node
- crypto_alloc_tfm_node函數 處理流程包括兩步,第一步調用crypto_find_alg函數查找符合條件的算法alg,第二步調用crypto_create_tfm_node函數根據算法alg創建對應的算法實例tfm。
- 2)crypto_alloc_tfm_node函數返回一個void*類型的通用指針(即內存地址),由直接或間接的調用者負責解釋通用指針的具體含義(即具體表示何種數據結構的指針)(使用的時候,將void*轉化為 具體使用的結構體指針),如crypto_alloc_ahash函數作為直接調用者將crypto_alloc_tfm函數返回的通用指針解釋為異步哈希算法實例的指針。
- 即 將void* 轉化為?crypto_ahash* 類型的指針
- api.c - crypto/api.c - Linux source code (v5.15.12) - Bootlin
- 3)crypto_alloc_ahash函數調用crypto_alloc_tfm函數時,輸入的算法前端為crypto_ahash_type,定義如下所示。
- ahash.c - crypto/ahash.c - Linux source code (v5.15.12) - Bootlin
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),
};
crypto_create_tfm_node函數的
- crypto_create_tfm_node函數的輸入參數包括通用算法說明alg和算法前端frontend
- 處理流程如下所示
- 1)在申請內存前,需要計算算法實例所需的內存空間total,包括個性化算法實例占用的內存空間tfmsize、通用算法實例占用的內存空間以及算法實例占用的額外內存空間extsize,如下圖所示。
- 個性化算法實例內存空間由算法前端的成員變量tfmsize確定,算法實例占用的額外內存空間由具體算法確定,通過算法前端的extsize接口獲取。創建異步哈希算法實例時,算法前端為crypto_ahash_type,tfmzise為offsetof(struct crypto_ahash, base),extsize接口為crypto_ahash_extsize函數
crypto_ahash_extsize函數
- ahash.c - crypto/ahash.c - Linux source code (v5.15.12) - Bootlin??
static unsigned int crypto_ahash_extsize(struct crypto_alg *alg)
{if (alg->cra_type != &crypto_ahash_type)return sizeof(struct crypto_shash *);return crypto_alg_extsize(alg);
}
- 如上所示,算法實例占用的額外內存空間與哈希算法實現方式有關
- 實現方式為異步方式時,額外內存空間為異步哈希算法上下文空間;
- 實現方式為同步方式時,額外內存空間用于保存同步哈希算法實現指針。
- 2)申請完內存空間mem后,需要初始化通用算法實例tfm,包括:
- a)通用算法實例tfm關聯到通用算法說明alg,?tfm->__crt_alg = alg;
- b)??調用算法前端frontend的init_tfm接口初始化tfm。創建異步哈希算法實例時,算法前端crypto_ahash_type定義的initial_tfm接口為crypto_ahash_init_tfm函數。
crypto_ahash_init_tfm函數的主要功能是利用異步哈希算法說明alg的算法接口初始化異步哈希算法實例hash的算法接口,但是如果算法的實現方式不是異步方式,將調用crypto_init_shash_ops_async函數使用同步哈希算法的異步實現接口(形如shash_async_xxx)初始化異步哈希算法實例的算法接口。 - c)如果通用算法說明alg定義了cra_init接口則調用其進一步初始化tfm。在加密框架中,一般情況下動態算法的算法說明都會定義cra_init接口,而靜態算法的算法說明都不定義cra_init接口,如HMAC模板創建的動態算法的算法說明的cra_init接口為hmac_init_tfm,而MD5算法的算法說明未定義cra_init接口
?