分类: LINUX
2022-11-04 10:57:43
之前看到的资料说是注册了算法后,系统会自动进行测试,待测试通过会才会真正把算法注册到系统。于是分析了下算法测试的代码,看这个测试逻辑是不是可以覆盖新注册的算法。先来看下内核的测试逻辑。在crypto_register_alg的逻辑中调用crypto_wait_for_test,这个函数看起来会进行算法的测试,但新加入的算法一定会被测试到么?带着这个疑问,继续跟踪了代码:
crypto_wait_for_test
├── cryptomgr_notify
│ ├── cryptomgr_schedule_test
│ ├──cryptomgr_test
│ ├──alg_test
│ ├──alg_find_test(alg)
│ ├──alg_find_test(driver)
│ ├──alg_test_descs[i].test
alg_test首先会根据算法名称(alg)和驱动名(driver)称查找算法,算法名和驱动名称是什么呢?比如硬件加密卡的驱动要注册加密算法ecb(aes),driver取名hw_ecb_aes,这里alg=” ecb(aes)”,driver=”hw_ecb_aes”。根据算法名称查找alg_test_descs数据,可以得到如下结构:
{
.alg = "ecb(aes)",
.test = alg_test_skcipher, //测试函数名称
.fips_allowed = 1,
.suite = {
.cipher = __VECS(aes_tv_template) //测试套
}
}
suite.cipher是用例数据,aes_tv_template的其结构体定义如下,其中包含ptest和ctest,可以猜出测试套是调用加密函数来对ptext加密,再把结果和ctext进行对比,以此来验证加密算法的正确性:
struct cipher_testvec {
const char *key;
const char *iv;
const char *iv_out;
const char *ptext; //明文
const char *ctext; //密文
unsigned char wk; /* weak key flag */
unsigned short klen;
unsigned int len;
bool fips_skip;
bool generates_iv;
int setkey_error;
int crypt_error;
};
继续分析函数alg_test_skcipher:
alg_test_skcipher
├── crypto_alloc_skcipher(driver,…) // driver的名字,本例中为hw_ecb_aes
├── test_skcipher
│ ├── test_skcipher_vec
│ ├──test_skcipher_vec_cfg //cfg有各种,可以覆盖较多的场景
│ ├──crypto_skcipher_encrypt
│ ├──crypto_skcipher_alg(tfm)->encrypt(req); //调用驱动实现的函数
│ ├──crypto_wait_req
│ ├──verify_correct_output
前面提到,alg_find_test会查找两次,一般driver实现不会在alg_test_descs里增加项,因此第二次查找找不到entry。看到这里终于可以放心了,对于alg_test_descs中登记在册的算法,硬件实现的接口都会被测试到。如果硬件实现的是一种新的算法呢?基于alg_test_desc会被测试到么?答案是否定的,hisi_sec2硬件实现了xts(sm4),由于我使用的5.10内核中没有这个算法的测试项,会打印一条日志alg: No test for xts(sm4)(hisi_sec_xts(sm4))。