最近我无聊翻翻MT7688的datasheet,注意到居然支持AES加速,赶紧搜github找到了一个能用的OpenWRT驱动MTK_AES。
赶紧开搞,一路搞好好几天才慢慢摸索出linux的初步加密框架。内核的加密框架的应用层接口是AF_ALG 套接字形式,但是有一个专门的驱动模块crpytodev抽象出一个/dev/crypto设备,采用ioctl接口,而且根据官网数据对比性能更好。
于是选中OpenWRT自带的kmod-cryptodev模块,默认会选中kmod-crypto-core等一大堆依赖,其实最终只依赖aead.ko,编译好后全部加载驱动。由于系统库的加密是openssl提供的libcrypto加密库,所以需要开启openssl库的硬件加密选项 “Crypto acceleration support”(Libraries>SSL>libopenssl) ,顺便选中openssl-util工具进行测试。
-
测试未开启AES硬件加速
root@:/# openssl speed -evp aes-128-cbcDoing aes-128-cbc for 3s on 16 size blocks: 1242779 aes-128-cbc's in 2.96s Doing aes-128-cbc for 3s on 64 size blocks: 359528 aes-128-cbc's in 2.95sDoing aes-128-cbc for 3s on 256 size blocks: 93663 aes-128-cbc's in 2.95s Doing aes-128-cbc for 3s on 1024 size blocks: 23499 aes-128-cbc's in 2.92sDoing aes-128-cbc for 3s on 8192 size blocks: 2953 aes-128-cbc's in 2.96s bala...bala... The 'numbers' are in 1000s of bytes per second processed. type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes aes-128-cbc 6717.72k 7799.93k 8128.04k 8240.75k
-
测试开启AES硬件加速
root@:/# openssl speed -evp aes-128-cbcDoing aes-128-cbc for 3s on 16 size blocks: 276231 aes-128-cbc's in 0.65s Doing aes-128-cbc for 3s on 64 size blocks: 270678 aes-128-cbc's in 0.45sDoing aes-128-cbc for 3s on 256 size blocks: 243448 aes-128-cbc's in 0.29s Doing aes-128-cbc for 3s on 1024 size blocks: 179638 aes-128-cbc's in 0.34sDoing aes-128-cbc for 3s on 8192 size blocks: 45879 aes-128-cbc's in 0.11s bala...bala... type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes aes-128-cbc 6799.53k 38496.43k 214905.82k 541027.39k 3416734.25k
主要是看最后一行的吞吐量测试,效果惊人啊!!!!
不开启加速时数据吞吐量变化不大,毕竟这里的性能瓶颈是在AES软件实现这块,而开启硬件加速后,数据块越大效果越好,最后的8192字节块效果就提升了414倍。
这里openssl需要开启-evp选项,这样底层的crpyto库会优先选择硬件加速。openssl里的cryptodev引擎是EVP接口形式提供的,所以如果使用openssl库需要加速,必须用EVP接口。不过openssl测试工具默认的加密引擎engine会自动选择cryptodev,不用再手动指定-engine cryptodev了。
这里比较郁闷的是mtk_aes支持AES的ECB和CBC,但是openssl的libcrypto库的enc_cryptodev.c里只支持CBC,所有最终能加速的只能是AES的CBC了,估计ECB不太安全吧,连CBC也不是很安全,现在普遍用CTR吧。CBC只是比ECB多了个IV矩阵,保证每次加密不重样。
static struct { int id; int nid; int ivmax; int keylen;} ciphers[] = { { CRYPTO_ARC4, NID_rc4, 0, 16, }, { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, }, { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, },# ifdef CRYPTO_AES_CTR { CRYPTO_AES_CTR, NID_aes_128_ctr, 14, 16, }, { CRYPTO_AES_CTR, NID_aes_192_ctr, 14, 24, }, { CRYPTO_AES_CTR, NID_aes_256_ctr, 14, 32, },# endif { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, { 0, NID_undef, 0, 0, },};
接下来用AES CBC加密一个20M的文件:
root@:/tmp# head -c 20m /dev/zero >test root@:/tmp# time openssl enc -e -aes-128-cbc -in test -out test.out -kfile pgrade_pass real 0m 0.74suser 0m 0.10s sys 0m 0.63sroot@:/tmp# rmmod mtk_aes root@:/tmp# time openssl enc -e -aes-128-cbc -in test -out test.out -kfile upgrade_pass real 0m 3.33suser 0m 2.93s sys 0m 0.38s
提升了5倍。
我这里的openssl的版本是1.0.2e,最新的1.1版本支持AES的ECB的,我没试过,Cryptodev是1.7版本。现在应用就是以后加解密文件有点用,如果是优化ssh和scp估计也不是很好,比较这些应用瓶颈往往是网速,并且如果是小数据加密的话效果差别不大,只在大数据吞吐时才有差别。
文章来源:http://www.freezhongzi.info 波波的博客