如前所述,无论是静态算法还是动态算法,算法注册的最后一步都是进行算法正确性检验,一般流程是先调用__crypto_register_alg函数进行通用的算法注册(即将待注册的算法添加到算法管理链表中),同时创建对应的检测用算法幼虫,然后调用crypto_wait_for_test函数启动算法正确性检验,并等待检验结束。 简单地说,算法正确性检验就是利用样本数据sampledata对算法接口进行计算正确性的验证。算法通过正确性检验的标志是算法标志cra_flags中置算法已检测标志CRYPTO_ALG_TESTED。算法通过正确性检验说明能够提供正常的服务,如加密/解密服务、计算消息摘要服务等。 crypto_wait_for_test函数用于启动算法正确性检验,并等待检验结束,输入参数为检测用算法幼虫larval,处理流程如下所示。 1)在crypto_wait_for_test函数中,调用crypto_probing_notify函数在加密通知链上发布算法正确性检验(CRYPTO_MSG_ALG_REGISTER)的通知,携带的参数为检测用算法幼虫对应的算法成虫,即待检验的算法。 2)静态算法(如AES算法)注册发布算法检验通知时,算法管理链表如下所示,其中aes_larval_t表示检测用算法幼虫,关联到对应的算法成虫(aes_larval_t->adult=aes_alg)。 3)动态算法(如"cbc(aes)"算法)注册发布算法检验通知时,算法管理链表如下所示,其中cbc_aes_larval_r表示注册用算法幼虫,cbc_aes_larval_t表示检测用算法幼虫,注册用算法幼虫还未关联到算法成虫,检测用算法幼虫关联到算法成虫(cbc_aes_larval_t->adult=cbc_aes_alg)。
算法检测启动发布算法检测通知后,加密通知链回调函数cryptomgr_notify将调用cryptomgr_schedule_test函数启动算法检测。 cryptomgr_schedule_test函数输入参数为待检测的算法alg,通过创建专门的算法检测线程处理算法正确性检验,处理流程如下所示。 1)算法正确性检验的参数数据结构为struct crypto_test_param,定义如下所示。
struct crypto_test_param { char driver[CRYPTO_MAX_ALG_NAME]; char alg[CRYPTO_MAX_ALG_NAME]; u32 type; };如上所示,算法正确性检验的参数包括算法驱动名driver、算法名alg和算法类型type。 2)cryptomgr_schedule_test函数将创建名为"cryptomgr_test"的内核线程(即算法检验线程)处理算法正确性检验,处理接口为cryptomgr_test。 3)在cryptomgr_test函数中,调用alg_test函数根据算法驱动名driver、算法名alg和算法类型type实现算法正确性检验。
算法检测结束在cryptomgr_test函数中,算法正确性检验结束后将调用crypto_alg_tested函数完成收尾工作。 crypto_alg_tested函数输入参数包括算法驱动名name和检验结果err(为0表示检验正确,非0表示检验失败),处理流程如下所示。 1)检测结束收尾时,需要通过算法幼虫的完成量唤醒等待注册、检验结束的线程。 在crypto_alg_tested函数中,首先根据输入的算法驱动名name查找对应的检测用算法幼虫test,如下所示。
test = (struct crypto_larval *)q; if (!strcmp(q->cra_driver_name, name)) goto found;然后根据检测用算法幼虫test关联到算法成虫alg,如果算法检测通过(err=0)则设置算法成功alg的已检验标志,同时将检测用算法幼虫设置为已死亡,表示检测用算法幼虫的使命终结,如下所示。
found: q->cra_flags |= CRYPTO_ALG_DEAD; alg = test->adult; if (err || list_empty(&alg->cra_list)) goto complete; alg->cra_flags |= CRYPTO_ALG_TESTED;再根据算法成虫alg查找对应的注册用算法幼虫larval,并进行关联,通过注册用算法幼虫唤醒所有等待注册结束的线程,如下所示。
larval->adult = alg; complete_all(&larval->completion);最后通过检测用算法幼虫test唤醒所有等待算法检验完成的线程,如下所示。
complete_all(&test->completion);2)算法检验结束收尾时,算法管理链表如下所示。 注意:算法检验收尾时,只是通过注册用和检验用算法幼虫唤醒等待算法注册完成的线程,并不清理注册过程中的中间变量(即注册用和检验用算法幼虫)。
