MT7688 AES硬件加速

最近我无聊翻翻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-cbc
    Doing 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.95s
    Doing 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.92s
    Doing 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-cbc
    Doing 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.45s
    Doing 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.34s
    Doing 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.74s
user 0m 0.10s 
sys 0m 0.63s

root@:/tmp# rmmod mtk_aes 
root@:/tmp# time openssl enc -e -aes-128-cbc -in test -out test.out -kfile upgrade_pass 
real 0m 3.33s
user 0m 2.93s 
sys 0m 0.38s

提升了5倍。

我这里的openssl的版本是1.0.2e,最新的1.1版本支持AES的ECB的,我没试过,Cryptodev是1.7版本。现在应用就是以后加解密文件有点用,如果是优化ssh和scp估计也不是很好,比较这些应用瓶颈往往是网速,并且如果是小数据加密的话效果差别不大,只在大数据吞吐时才有差别。

发表评论

电子邮件地址不会被公开。 必填项已用*标注