概述
tcrypt是Linux内核crypto子系统中的一个测试模块,主要是为内核实现的加密算法(包括加密、哈希、认证、AEAD、随机数生成器等)提供自检和性能基准测试功能。
tcrypt测试模块的源码位于linuxcrypto/tcrypt.c,编译时需要配置CONFIG_CRYPTO_TEST编译成模块。由于tcrypt仍然是调用内核算法测试框架,因此还需要关闭配置CONFIG_CRYPTO_MANAGER_DISABLE_TESTS,否则测试时始终返回成功,在linux/crypto/testmgr.c中实现如下:
// 这里关闭测试,始终返回成功#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS/* a perfect nop */intalg_test(constchar *driver, constchar *alg, u32 type, u32 mask){return0;}#else#include"testmgr.h"...
使用方法
tcrypt模块参数说明如下:
| | |
|---|
| | 指定要测试的算法名称(如 "sha256" 、 "ecb(aes)" 等),不指定时按 mode 选择算法。 |
| | |
| | 算法类型掩码,用于微调测试类型(例如,只测试加密、只测试解密、测试不同块大小等),一般不指定。 |
| | 选择测试模式。0:功能性自检(遍历所有算法);其他值如1表示 md5 ,2表示 sha1 等。 |
| | 性能测试持续时间(单位:秒)。0 表示用 CPU cycles 计时,否则用秒计时。 |
| | |
| | |
为了打印更多调试信息,首先得调整日志等级:
$ echo 8 > /proc/sys/kernel/printk
然后先对所有算法进行功能自检,命令如下:
$ insmod tcrypt.ko [ 1054.163425] tcrypt: testing md5[ 1054.167292] tcrypt: testing sha1[ 1054.173123] tcrypt: testing ecb(des)[ 1054.182485] tcrypt: testing cbc(des)[ 1054.191145] tcrypt: testing ctr(des)[ 1054.200304] tcrypt: testing ecb(des3_ede)[ 1054.215172] tcrypt: testing cbc(des3_ede)[ 1054.230910] tcrypt: testing ctr(des3_ede)[ 1054.252490] tcrypt: testing md4[ 1054.257099] alg: hash: failed to allocate transform for md4: -2[ 1054.263336] alg: self-tests for md4 using md4 failed (rc=-2)[ 1054.263362] tcrypt: testing sha256[ 1054.275092] tcrypt: testing ecb(blowfish)......[ 1059.426008] tcrypt: one or more tests failed!insmod: can't insert 'tcrypt.ko': unknown symbol in module, or unknown parameter
可以看出,有些算法测试通过,有些算法测试失败,这与编译时算法配置及内核算法是否实现有关。接下来我们针对某个算法进行测试。
功能测试
测试md5算法功能正确性:
$ insmod tcrypt.ko mode=1[ 1521.414509] tcrypt: testing md5[ 1521.418382] tcrypt: all tests passed[ 1521.784676] tcrypt: testing md5[ 1521.788553] tcrypt: all tests passedinsmod: can't insert 'tcrypt.ko': Resource temporarily unavailable
测试sha256算法功能正确性:
$ insmod tcrypt.ko mode=6[ 1574.714777] tcrypt: testing sha256[ 1574.720732] tcrypt: all tests passed[ 1574.974637] tcrypt: testing sha256[ 1574.980606] tcrypt: all tests passedinsmod: can't insert 'tcrypt.ko': Resource temporarily unavailable
测试aes算法功能正确性,有些分组模式测试失败,比如xtr(aes)、ofb(aes)等:
$ insmod tcrypt.ko mode=10[ 1632.113184] tcrypt: testing ecb(aes)[ 1632.118800] tcrypt: testing cbc(aes)[ 1632.124926] tcrypt: testing lrw(aes)[ 1632.130840] alg: skcipher: failed to allocate transform for lrw(aes): -2[ 1632.138485] alg: self-tests for lrw(aes) using lrw(aes) failed (rc=-2)[ 1632.138521] tcrypt: testing xts(aes)[ 1632.151151] alg: skcipher: failed to allocate transform for xts(aes): -2[ 1632.157897] alg: self-tests for xts(aes) using xts(aes) failed (rc=-2)[ 1632.157912] tcrypt: testing ctr(aes)[ 1632.172026] tcrypt: testing rfc3686(ctr(aes))[ 1632.188055] tcrypt: testing ofb(aes)[ 1632.194057] alg: skcipher: failed to allocate transform for ofb(aes): -2[ 1632.200801] alg: self-tests for ofb(aes) using ofb(aes) failed (rc=-2)[ 1632.200814] tcrypt: testing cfb(aes)[ 1632.213294] alg: skcipher: failed to allocate transform for cfb(aes): -2[ 1632.220036] alg: self-tests for cfb(aes) using cfb(aes) failed (rc=-2)[ 1632.220050] tcrypt: testing xctr(aes)[ 1632.233372] alg: skcipher: failed to allocate transform for xctr(aes): -2[ 1632.240203] alg: self-tests for xctr(aes) using xctr(aes) failed (rc=-2)[ 1632.240217] tcrypt: one or more tests failed![ 1632.364082] tcrypt: testing ecb(aes)[ 1632.369699] tcrypt: testing cbc(aes)[ 1632.375837] tcrypt: testing lrw(aes)[ 1632.381931] alg: skcipher: failed to allocate transform for lrw(aes): -2[ 1632.389360] alg: self-tests for lrw(aes) using lrw(aes) failed (rc=-2)[ 1632.389395] tcrypt: testing xts(aes)[ 1632.402095] alg: skcipher: failed to allocate transform for xts(aes): -2[ 1632.408839] alg: self-tests for xts(aes) using xts(aes) failed (rc=-2)[ 1632.408854] tcrypt: testing ctr(aes)[ 1632.423207] tcrypt: testing rfc3686(ctr(aes))[ 1632.439144] tcrypt: testing ofb(aes)[ 1632.445149] alg: skcipher: failed to allocate transform for ofb(aes): -2[ 1632.452023] alg: self-tests for ofb(aes) using ofb(aes) failed (rc=-2)[ 1632.452045] tcrypt: testing cfb(aes)[ 1632.464421] alg: skcipher: failed to allocate transform for cfb(aes): -2[ 1632.471418] alg: self-tests for cfb(aes) using cfb(aes) failed (rc=-2)[ 1632.471446] tcrypt: testing xctr(aes)[ 1632.484015] alg: skcipher: failed to allocate transform for xctr(aes): -2[ 1632.490844] alg: self-tests for xctr(aes) using xctr(aes) failed (rc=-2)[ 1632.490859] tcrypt: one or more tests failed!insmod: can't insert 'tcrypt.ko': unknown symbol in module, or unknown parameter
其他的算法测试命令,我们可以查看tcrypt.c源码确定mode的索引。
性能测试
测试模式mode=200以后都是速度性能测试,比如测试sha256算法的性能:
$ insmod tcrypt.ko mode=304[ 1935.962139] [ 1935.962139] testing speed of async sha256 (sha256-generic)[ 1935.969168] tcrypt: test 0 ( 16 byte blocks, 16 bytes per update, 1 updates): 87 cycles/operation, 5 cycles/byte[ 1935.980765] tcrypt: test 1 ( 64 byte blocks, 16 bytes per update, 4 updates): 237 cycles/operation, 3 cycles/byte[ 1935.992431] tcrypt: test 2 ( 64 byte blocks, 64 bytes per update, 1 updates): 149 cycles/operation, 2 cycles/byte[ 1936.004726] tcrypt: test 3 ( 256 byte blocks, 16 bytes per update, 16 updates): 474 cycles/operation, 1 cycles/byte[ 1936.016688] tcrypt: test 4 ( 256 byte blocks, 64 bytes per update, 4 updates): 357 cycles/operation, 1 cycles/byte[ 1936.030132] tcrypt: test 5 ( 256 byte blocks, 256 bytes per update, 1 updates): 332 cycles/operation, 1 cycles/byte[ 1936.042016] tcrypt: test 6 ( 1024 byte blocks, 16 bytes per update, 64 updates): 1611 cycles/operation, 1 cycles/byte[ 1936.055135] tcrypt: test 7 ( 1024 byte blocks, 256 bytes per update, 4 updates): 1088 cycles/operation, 1 cycles/byte[ 1936.067699] tcrypt: test 8 ( 1024 byte blocks, 1024 bytes per update, 1 updates): 1063 cycles/operation, 1 cycles/byte[ 1936.080215] tcrypt: test 9 ( 2048 byte blocks, 16 bytes per update, 128 updates): 2849 cycles/operation, 1 cycles/byte[ 1936.094525] tcrypt: test 10 ( 2048 byte blocks, 256 bytes per update, 8 updates): 2093 cycles/operation, 1 cycles/byte[ 1936.108057] tcrypt: test 11 ( 2048 byte blocks, 1024 bytes per update, 2 updates): 2048 cycles/operation, 1 cycles/byte[ 1936.121543] tcrypt: test 12 ( 2048 byte blocks, 2048 bytes per update, 1 updates): 2037 cycles/operation, 0 cycles/byte[ 1936.135021] tcrypt: test 13 ( 4096 byte blocks, 16 bytes per update, 256 updates): 5534 cycles/operation, 1 cycles/byte[ 1936.151980] tcrypt: test 14 ( 4096 byte blocks, 256 bytes per update, 16 updates): 4103 cycles/operation, 1 cycles/byte[ 1936.167529] tcrypt: test 15 ( 4096 byte blocks, 1024 bytes per update, 4 updates): 4060 cycles/operation, 0 cycles/byte[ 1936.183015] tcrypt: test 16 ( 4096 byte blocks, 4096 bytes per update, 1 updates): 3985 cycles/operation, 0 cycles/byte[ 1936.198439] tcrypt: test 17 ( 8192 byte blocks, 16 bytes per update, 512 updates): 10999 cycles/operation, 1 cycles/byte[ 1936.220881] tcrypt: test 18 ( 8192 byte blocks, 256 bytes per update, 32 updates): 8121 cycles/operation, 0 cycles/byte[ 1936.240472] tcrypt: test 19 ( 8192 byte blocks, 1024 bytes per update, 8 updates): 7938 cycles/operation, 0 cycles/byte[ 1936.259881] tcrypt: test 20 ( 8192 byte blocks, 4096 bytes per update, 2 updates): 7892 cycles/operation, 0 cycles/byte[ 1936.279252] tcrypt: test 21 ( 8192 byte blocks, 8192 bytes per update, 1 updates): 7891 cycles/operation, 0 cycles/byte[ 1936.298644] tcrypt: all tests passed......insmod: can't insert 'tcrypt.ko': Resource temporarily unavailable
测试aes算法的性能:
$ insmod tcrypt.ko mode=200[ 1991.730543] tcrypt: [ 1991.730543] testing speed of sync ecb(aes) (ecb(aes-generic)) encryption[ 1991.739587] tcrypt: test 0 (128 bit key, 16 byte blocks): 1 operation in 37 cycles (16 bytes)......[ 1991.954749] tcrypt: [ 1991.954749] testing speed of sync ecb(aes) (ecb(aes-generic)) decryption[ 1991.963654] tcrypt: test 0 (128 bit key, 16 byte blocks): 1 operation in 37 cycles (16 bytes)......[ 1992.178759] tcrypt: [ 1992.178759] testing speed of sync cbc(aes) (cbc(aes-generic)) encryption[ 1992.187663] tcrypt: test 0 (128 bit key, 16 byte blocks): 1 operation in 34 cycles (16 bytes)......[ 1992.389265] tcrypt: test 20 (256 bit key, 4096 byte blocks): 1 operation in 6425 cycles (4096 bytes)[ 1992.406908] tcrypt: [ 1992.406908] testing speed of sync cbc(aes) (cbc(aes-generic)) decryption[ 1992.415859] tcrypt: test 0 (128 bit key, 16 byte blocks): 1 operation in 41 cycles (16 bytes)......[ 1992.635816] tcrypt: failed to load transform for lrw(aes): -2[ 1992.643964] tcrypt: failed to load transform for lrw(aes): -2[ 1992.652118] tcrypt: failed to load transform for xts(aes): -2[ 1992.660082] tcrypt: failed to load transform for xts(aes): -2[ 1992.668461] tcrypt: failed to load transform for cts(cbc(aes)): -2[ 1992.677206] tcrypt: failed to load transform for cts(cbc(aes)): -2[ 1992.683724] tcrypt: [ 1992.683724] testing speed of sync ctr(aes) (ctr(aes-generic)) encryption[ 1992.692792] tcrypt: test 0 (128 bit key, 16 byte blocks): 1 operation in 39 cycles (16 bytes)......[ 1992.914889] tcrypt: [ 1992.914889] testing speed of sync ctr(aes) (ctr(aes-generic)) decryption[ 1992.923802] tcrypt: test 0 (128 bit key, 16 byte blocks): 1 operation in 34 cycles (16 bytes)......[ 1993.143769] tcrypt: failed to load transform for cfb(aes): -2[ 1993.151919] tcrypt: failed to load transform for cfb(aes): -2[ 1993.157709] tcrypt: all tests passed......[ 1994.745562] tcrypt: all tests passedinsmod: can't insert 'tcrypt.ko': Resource temporarily unavaila
问题解决
不知道大家注意到没有,在tcrypt模块测试结束后,总是报资源不可用错误:
insmod: can't insert 'tcrypt.ko': Resource temporarily unavailable
起初一直怀疑是crypto配置有问题,后面查看函数tcrypt_mod_init的代码,发现其始终返回错误(返回 -EAGAIN),故意为之,其是防止模块持续驻留在内存中,加载模块后自动卸载,所以报错是正常的:
/* We intentionaly return -EAGAIN to prevent keeping the module, * unless we're running in fips mode. It does all its work from * init() and doesn't offer any runtime functionality, but in * the fips case, checking for a successful load is helpful. * => we don't need it in the memory, do we? * -- mludvig */if (!fips_enabled) err = -EAGAIN;
参考
- Linux Crypto(9):tcrypt进行Crypto测试