-数据结构定义
在加密框架中,将根据算法模式(即算法模板)和基础算法动态创建的算法定义为算法模板实例,数据结构为struct crypto_instance,在root\include\crypto\algapi.h中定义如下所示。
struct crypto_instance {
struct crypto_alg alg;
struct crypto_template *tmpl;
struct hlist_node list;
void *__ctx[] CRYPTO_MINALIGN_ATTR;
};
算法模板实例数据结构为struct crypto_instance各成员变量含义如下所示:
1)alg:算法模板实例对应的算法说明。
2)tmpl:算法模板实例使用的算法模板。
3)list:算法模板实例在算法模板的实例哈希链表中对应的节点。
4)__ctx:算法模板实例的上下文。
由算法模板实例数据结构定义,算法模板实例也是一种算法,如分组算法根据算法模板(如CBC模式)创建的块加密算法。
-CBC算法模板实例
CBC算法模板的创建实例接口为crypto_cbc_alloc,输入参数为创建CBC算法模板实例的参数tb,返回值为新创建的算法模板实例。
crypto_cbc_alloc函数创建CBC算法模板流程如下所示。
1)crypto_cbc_alloc函数中用于创建算法模板实例的参数包括算法类型tb[0]和基础算法名tb[1],通过crypto_get_attr_alg函数获取基础算法alg。
crypto_get_attr_alg函数是一个内联函数,展开后如下所示,最终调用crypto_find_alg函数完成算法查找。
其中,crypto_attr_alg_name函数用于从参数tb[1]中获取基础算法名name。
2)crypto_alloc_instance函数根据算法模板名name和基础算法alg创建算法模板实例inst。
在crypto_alloc_instance函数中,首先调用crypto_alloc_instance2函数创建算法模板实例inst,然后调用crypto_init_spawn函数初始化算法卵spawn,将其与基础算法alg和算法模板实例inst关联在一起。
a)加密框架将动态算法类比为从算法卵中孵化的过程,并且通过算法卵将动态算法和基础算法关联在一起。算法卵数据结构struct crypto_spawn定义如下所示。
struct crypto_spawn {
struct list_head list;
struct crypto_alg *alg;
struct crypto_instance *inst;
const struct crypto_type *frontend;
u32 mask;
};
算法卵数据结构struct crypto_spawn各成员变量含义如下所示。
i)list:在基础算法的用户链表users中的链表节点;
ii)alg:关联的基础算法;
iii)inst:关联的算法模板实例;
iv)frontend:关联的算法实例前端,即算法类型常量;
v)mask:算法类型屏蔽位。
b)crypto_alloc_instance2函数名义上是创建算法模板实例,实际上还同步创建了对应的算法卵,同时根据第三个输入参数head决定是否在算法模板实例前预留空间,如下所示。
p = kzalloc(head + sizeof(*inst) + sizeof(struct crypto_spawn),
GFP_KERNEL);
crypto_alloc_instance函数调用crypto_alloc_instance2函数时,head为0,表示在算法模板实例前不预留空间。
假设"cbc(aes)"算法的算法模板实例定义为cbc_aes_inst,算法卵定义为cbc_aes_spawn,如下所示。
函数crypto_alloc_instance2的返回值类型为void *,调用者可根据需要将返回值p转换为对应的数据结构指针。
c)crypto_init_spawn函数用于初始化算法卵spawn,同时将其和算法模板实例inst、基础算法alg关联在一起,如下所示。
算法模板实例inst和算法卵spawn的关联不是通过数据结构实现的,而是通过内存地址连续实现的,这样通过算法模板实例的__ctx指针可以访问到对应的算法卵,由内联函数crypto_instance_ctx实现。
算法模板实例inst和基础算法alg的关联是通过算法卵spawn实现的。
3)CBC算法模板实例的算法说明初始化包括以下几部分:
a)继承基础算法的算法属性,如下:
inst->alg.cra_priority = alg->cra_priority;
inst->alg.cra_blocksize = alg->cra_blocksize;
inst->alg.cra_alignmask = alg->cra_alignmask;
b)设置其他算法通用属性,如下
inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
inst->alg.cra_type = &crypto_blkcipher_type;
inst->alg.cra_alignmask |= __alignof__(u32) - 1;
inst->alg.cra_ctxsize = sizeof(struct crypto_cbc_ctx);
inst->alg.cra_init = crypto_cbc_init_tfm;
inst->alg.cra_exit = crypto_cbc_exit_tfm;
其中比较重要的是CBC算法模板实例的算法类型为CRYPTO_ALG_TYPE_BLKCIPHER(即块加密算法),算法类型常量为crypto_blkcipher_type,同时需要设置算法实例的初始化接口和析构接口。
c)设置个性化算法属性(即块加密算法个性化算法属性),如下所示。
inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
inst->alg.cra_blkcipher.setkey = crypto_cbc_setkey;
inst->alg.cra_blkcipher.encrypt = crypto_cbc_encrypt;
inst->alg.cra_blkcipher.decrypt = crypto_cbc_decrypt;;
4)crypto_cbc_alloc函数中接口调用情况如下所示。
-数据结构定义
和哈希算法说明相同,哈希算法模板也定义了与通用算法模板实例区别的哈希算法模板实例,包括同步哈希算法模板实例和异步哈希算法模板实例,数据结构分别为struct shash_instance和struct ahash_instance。
在root\include\crypto\internal\hash.h中同步哈希算法模板实例数据结构定义如下所示。
struct shash_instance {
struct shash_alg alg;
};
同步哈希算法模板实例数据结构struct shash_instance只包括一个成员变量,即同步哈希算法说明alg。
与同步哈希算法说明是在通用算法说明基础上派生的不同,从同步哈希算法模板实例定义看不出与通用算法模板实例之间的关系。
与通用算法模板实例不同,哈希算法通过算法模板(如HMAC模板)创建的新算法还是哈希算法。另外,分组算法也可以通过算法模板(如XCBC模板)可以创建哈希算法。
-HMAC算法模板实例
HMAC算法模板的创建实例接口为hmac_create,输入参数包括算法模板tmpl和创建算法模板实例的参数tb,返回值为0表示算法模板实例已创建并注册。
hmac_create函数创建并注册算法模板实例的流程如下所示。
1)hmac_create函数中用于创建同步哈希算法模板实例的参数包括算法类型tb[0]和基础算法名tb[1],通过shash_attr_alg函数获取基础同步哈希算法salg,对应的通用算法说明为alg。
2)shash_alloc_instance函数用于根据算法模板名name和基础算法的通用算法说明alg创建同步哈希算法模板实例。
shash_alloc_instance函数调用crypto_alloc_instance2函数创建同步哈希算法模板实例,其中第三个输入参数head=sizeof(struct shash_alg) - sizeof(*alg),即同步哈希算法说明的个性化属性部分的数据长度。
假设"hmac(md5)"算法的同步哈希算法模板实例定义为hmac_md5_shash,对应的通用算法模板实例定义为hmac_md5_inst,算法卵定义为hmac_md5_spawn,如下图所示。
如上图所示,同步哈希算法模板实例和对应的通用算法模板实例共用通用算法说明数据结构,通过内联函数shash_crypto_instance可获取同步哈希算法模板实例对应的通用算法模板实例,通过内联函数shash_instance可获取通用算法模板实例对应的同步哈希算法模板实例。
3)crypto_alloc_instance2函数同步创建了对应的算法卵,同步哈希算法模板将这个算法卵重定义为同步哈希算法卵,数据结构为struct crypto_shash_spawn,定义如下所示,只包括一个通用算法卵base的成员变量。
struct crypto_shash_spawn {
struct crypto_spawn base;
};
通过内联函数shash_instance_ctx可获取同步哈希算法模板实例对应的同步哈希算法卵。
crypto_init_shash_spawn函数输入参数包括同步哈希算法卵spawn、同步哈希算法说明alg和通用算法模板实例inst,实现初始化算法卵和数据结构关联的功能,如下所示。
4)HMAC算法模板实例的通用算法说明初始化包括以下几部分:
a)继承基础同步哈希算法的属性,如下所示:
inst->alg.base.cra_priority = alg->cra_priority;
inst->alg.base.cra_blocksize = alg->cra_blocksize;
inst->alg.base.cra_alignmask = alg->cra_alignmask;
inst->alg.digestsize = salg->digestsize;
inst->alg.statesize = salg->statesize;
b)设置其他通用算法属性,如下所示:
inst->alg.base.cra_ctxsize = sizeof(struct hmac_ctx) +
ALIGN(ss * 2, crypto_tfm_ctx_alignment());
inst->alg.base.cra_init = hmac_init_tfm;
inst->alg.base.cra_exit = hmac_exit_tfm;
其中比较重要的是上下文空间大小cra_ctxsize,要求上下文空间必须满足一个HMAC上下文数据结构和两个基础同步哈希算法上下文的存储。
c)设置个性化算法属性中的算法接口,如下所示。
inst->alg.init = hmac_init;
inst->alg.update = hmac_update;
inst->alg.final = hmac_final;
inst->alg.finup = hmac_finup;
inst->alg.export = hmac_export;
inst->alg.import = hmac_import;
inst->alg.setkey = hmac_setkey;
5)哈希算法模板的创建实例接口(如hmac_create函数)与分组算法模板的创建实例接口(如crypto_cbc_alloc函数)的 一个最大的不同就是在创建完算法模板实例后,再调用shash_register_instance函数完成动态算法注册。
6)hmac_create函数中接口调用情况如下所示。