Linux加密框架的算法管理(二)

算法查找流程

  1. 算法查找接口crypto_find_alg

算法实例tfm是算法的一个可运行的副本,因此在创建算法实例前首先要查找确认算法是否已经注册有效,此时算法查找由函数crypto_find_alg实现。
crypto_find_alg函数输入参数包括算法名name、算法前端frontend、算法类型type和算法类型屏蔽位mask,查找命中时返回查找到的算法alg,查找未命中时返回异常。
crypto_find_alg函数的处理逻辑比较简单,调用查找接口lookup进行算法查找。如果算法前端frontend定义了查找接口,lookup=frontend->lookup,否则lookup=crypto_alg_mod_lookup。
算法前端frontend的数据类型为struct crypto_type,即通用算法说明中的算法类型常量。加密框架中定义的大部分算法类型常量,如同步哈希算法类型常量crypto_shash_type、异步哈希算法类型常量crypto_ahash_type、块加密算法类型常量crypto_blkcipher_type都未定义lookup接口,因此调用crypto_find_alg函数使用的查找接口都是默认查找接口crypto_alg_mod_lookup,这样crypto_find_alg函数相当于crypto_alg_mod_lookup函数的包裹函数。
输入参数中的算法类型type表示最佳的算法类型,type&mask表示允许使用的算法类型。异步哈希算法实例前端crypto_ahash_type中,type=CRYPTO_ALG_TYPE_AHASH(0x09)表示最佳的算法类型为异步哈希算法,mask=CRYPTO_ALG_TYPE_AHASH_MASK(0x0C),而type&mask=0x08(CRYPTO_ALG_TYPE_HASH)表示只要是哈希算法就行,不强求实现方式。

  1. 算法查找接口crypto_alg_mod_lookup

crypto_alg_mod_lookup函数输入参数包括待查找的算法名name、算法类型type和算法类型屏蔽位mask,查找命中时返回查找到的算法alg,查找未命中时返回异常。
crypto_alg_mod_lookup函数执行流程如下所示。
Linux加密框架的算法管理(二)_第1张图片
1)crypto_alg_mod_lookup函数的基本逻辑为要么从算法管理链表已注册的算法中查找到符合条件的算法,要么按照查找条件动态创建并注册新的算法。从外部调用者角度看,这两种情况都是查找命中。
2)外部应用使用的算法必须是经过正确性检验(即算法标志中已置CRYPTO_ALG_TESTED状态位)的,因此在查找前更新待查找算法的算法类型type和算法类型屏蔽位mask,确保后续查找到的算法是经过正确性检验的、可用的算法。
3)算法查找流程由crypto_larval_lookup函数实现,其基本逻辑为要么从算法管理链表已注册的算法中查找到符合条件的算法,要么按照查找条件创建与待查找算法同名的算法幼虫。crypto_larval_lookup函数的返回值为通用算法说明alg,通过检查其算法标志cra_flags的CRYPTO_ALG_LARVAL状态位确认alg是否为算法幼虫(由内联函数crypto_is_larval实现)。如果想查找名为"md5"的哈希算法,查找返回的是MD5算法的通用算法说明md5_alg;如果想查找名为"hmac(md5)"的哈希算法,假设第一次使用该算法,算法管理链表中未注册该算法,因此查找返回的是同名的算法幼虫对应的通用算法说明。
4)如果查找到的是算法幼虫,即当前线程创建的注册用算法幼虫,在加密通知链发布创建动态算法的通知,由专门的内核线程负责创建并注册动态算法,算法查找线程调用crypto_larval_wait函数等待算法注册完成,然后调用crypto_larval_kill函数清理注册用算法幼虫。
5)crypto_alg_mod_lookup函数中接口调用情况如下所示。
Linux加密框架的算法管理(二)_第2张图片

  1. 算法查找接口crypto_larval_lookup

crypto_larval_lookup函数的输入参数包括待查找的算法名name、算法类型type和算法类型屏蔽位mask,查找命中时返回查找到的算法或注册用算法幼虫,查找未命中时返回异常。
crypto_larval_lookup函数执行流程如下所示。
Linux加密框架的算法管理(二)_第3张图片
1)在算法查找前首先确认算法名是否有效,如果算法名为空,终止查找流程,返回异常。
2)算法查找流程由函数crypto_alg_lookup实现,返回值为空说明未查找到符合的算法,否则为查找到符合条件的算法(可能是算法幼虫)。
3)在crypto_larval_lookup函数中,最多可能进行三次算法查找,其中前两次显式地调用crypto_alg_lookup函数进行,第三次在crypto_larval_add函数中进行。
4)在第一次未查找到算法时,尝试通过request_module函数按算法名自动加载静态算法模块(算法名.ko),然后进行第二次查找。
5)如果第二次仍然未查找到算法,调用crypto_larval_add函数创建同名的算法幼虫(称之为注册用算法幼虫,算法优先级为-1),创建完成后会进行第三次查找,如下所示。
Linux加密框架的算法管理(二)_第4张图片

crypto_larval_add函数要么返回第三次查找命中的算法(如果是算法幼虫,则调用crypto_larval_wait函数等待算法注册完成,返回新注册的算法)要么返回创建的注册用算法幼虫(已添加到算法管理链表中)。
6)如果前两次查找命中,但查找到的是算法幼虫(可能是注册用算法幼虫也可能是检测用算法幼虫),说明符合要求的算法正在注册中,调用crypto_larval_wait函数等待算法注册完成,返回注册成功的算法。如果是检测用算法幼虫,注册完成的标志是算法成虫已完成正确性检验;如果是注册用算法幼虫,注册完成的标志是已设置有效的算法成虫(并且已完成正确性检验)。
7)crypto_larval_lookup函数中接口调用情况如下所示。
Linux加密框架的算法管理(二)_第5张图片

  1. 算法查找接口crypto_alg_lookup函数

crypto_alg_lookup函数的输入参数包括待查找的算法名name、算法类型type和算法类型屏蔽位mask,查找命中时返回查找到的算法或算法幼虫,查找未命中时返回异常。
crypto_alg_lookup函数实际上只是一个包裹函数,在锁定算法管理链表访问信号量crypto_alg_sem的前提下调用__crypto_alg_lookup函数完成算法查找。
__crypto_alg_lookup函数的输入参数和返回值与crypto_alg_lookup函数完全相同,其处理流程如下所示。
Linux加密框架的算法管理(二)_第6张图片
1)__crypto_alg_lookup函数的基本逻辑是从算法管理链表中查找符合条件的算法,查找命中时返回算法(可能是算法幼虫),查找未命中时返回空指针。
2)在查找算法时,遵循以下原则:
a)算法不能处于濒死(moribund)状态。
b)算法类型必须满足查找要求,即(q->cra_flags ^ type) & mask=0。
c)算法可以是已注册的算法或者正在注册算法的算法幼虫(可能是注册用算法幼虫也可能是检测用算法幼虫),如果是注册用算法幼虫,算法类型屏蔽位必须满足查找要求。注册用算法幼虫和检测用算法幼虫的区别之一是检测用算法幼虫设置了算法驱动名。
d)算法名符合查找要求精确符合exac和模糊符合fuzzy两种情况,如下所示。

exact = !strcmp(q->cra_driver_name, name);
fuzzy = !strcmp(q->cra_name, name);

模糊符合时还要求算法的优先级要高于预期优先级best。查找到精确符合的算法时,退出查找流程,返回精确符合的算法;查找到模糊符合的算法时,必须确保返回的是优先级最高的模糊符合算法。
e)查找到符合要求的算法时,调用crypto_mod_get函数持有该算法,即增加算法的引用计数。
3)在查找算法时,可能出现以下几种情况:
a)算法管理链表上有已注册且检验合格的符合要求的算法,则返回对应的算法。
b)算法管理链表中没有符合要求的算法,查找返回空指针,外部将按算法名加载算法模块(静态算法模块)或创建注册用算法幼虫,发起创建动态算法,等待算法注册完成,返回新注册的算法。
c)查找时,其他外部应用已发起创建动态算法,但未完成,此时算法管理链表中只有一个符合要求的注册用算法幼虫,返回注册用算法幼虫,外部等待算法注册检验完成,返回新注册的算法。
d)查找时,其他外部应用以发起创建动态算法,已完成,但正确性检验未完成,此时算法管理链表中有符合要求的注册用算法幼虫和检测用算法幼虫,而已注册的算法未检验合格故不符合要求,检测用算法幼虫优先级(>0)高于注册用算法幼虫(-1),因此返回检验用算法幼虫,外部等待算法检验结束,返回新注册的算法。

  1. 算法查找接口之间的差异

上述三组算法查找接口crypto_find_alg/crypto_alg_mod_lookup、crypto_larval_lookup和crypto_alg_lookup/__crypto_alg_lookup的输入参数类型是相同的,但是返回值有很大差异,
1)crypto_find_alg/crypto_alg_mod_lookup函数是面向应用的,因此查找命中时返回的是符合查找要求的算法,查找未命中时返回异常。
2)crypto_alg_lookup(__crypto_alg_lookup)函数是面向算法管理链表的,因此查找命中返回的是符合查找要求的算法(可能是注册用算法幼虫或检测用算法幼虫),查找未命中时返回的是空指针。
3)crypto_larval_lookup函数处于算法查找的中间层,最多三次调用crypto_alg_lookup/__crypto_alg_lookup函数查找符合要求的算法,如果是算法幼虫,则等待算法注册后返回新注册的算法。即使连续三次查找均未命中也会创建注册用算法幼虫,触发调用者向加密通知链发布创建动态算法的通知。

你可能感兴趣的:(加密框架)