如果主机 CPU 有的话,QEMU/KVM 是否使用 Intel AES 指令来加密 qcow2 映像?

如果主机 CPU 有的话,QEMU/KVM 是否使用 Intel AES 指令来加密 qcow2 映像?

KVM 的 qcow2 映像文件格式可以使用AES加密。已应用加密在集群级别:

每个簇内的每个扇区都使用 AES 密码块链接模式独立加密,使用小端格式的扇区偏移量(相对于设备的开头)作为 128 位初始化向量的前 64 位。

簇的大小可以设置为512字节转2M(64K 似乎是默认值)。

使用 qcow2 加密的主要问题之一是对 CPU 的性能影响 - 每个磁盘写入或非缓存读取都需要加密或解密。

我想知道 QEMU/KVM 是否使用英特尔 AES 指令如果主机 CPU 有它们,可以减轻性能损失吗?如果是这样,使用情况或性能是否很大程度上取决于集群大小?

英特尔® AES 指令是从基于 32 纳米英特尔® 微架构代号 Westmere 的全新 2010 英特尔® 酷睿™ 处理器家族开始提供的一组新指令。这些指令使用 FIPS 出版物号 197 定义的高级加密标准 (AES) 实现快速、安全的数据加密和解密。由于 AES 目前是占主导地位的分组密码,并且用于各种协议中,因此新指令很有价值适用于广泛的应用。

答案1

至少与Fedora 20软件包qemu-img(1.6.2、10.fc20)不使用AES-NI对于 AES 加密。

确认

可以这样验证:

  1. CPU 有 AES-NI 吗?

    $ grep aes /proc/cpuinfo  -i
    

    例如我的 Intel Core 7 有这个扩展。

  2. 安装必要的调试包:

    # debuginfo-install qemu-img
    
  3. qemu-img在调试器中运行:

    $ gdb --args qemu-img convert -o encryption -O qcow2 disk1.img enc1.qcow2
    
  4. 在一个众所周知的 qemu 加密函数中设置一个断点,该函数未针对 AES-NI 进行优化:

    (gdb) b AES_encrypt
    Breakpoint 1 at 0x794b0: file util/aes.c, line 881.
    
  5. 运行程序:

    (gdb) r
    Starting program: /usr/bin/qemu-img convert -o encryption -O qcow2 disk1.img enc1.qcow2
    

结果

在我的测试中它确实停在那里:

Breakpoint 1, AES_encrypt (in=0x7ffff7fabd60 "...", key=0x555555c1b510) at util/aes.c:881
881          const AES_KEY *key) {
(gdb) n
889     assert(in && out && key);
(gdb) n
881          const AES_KEY *key) {
(gdb) n
889     assert(in && out && key);
(gdb) n
896     s0 = GETU32(in     ) ^ rk[0];
(gdb) n
897     s1 = GETU32(in +  4) ^ rk[1];

这意味着实际上未使用 Intel AES 指令。

我的第一个想法是,qemu-img也许只是使用libcrypto自动使用 AES-NI(如果可用)。qemu-img甚至链接到 libcrypto (cf ldd $(which qemu-img)) - 但它似乎没有将其用于 AES 加密。唔。

我通过 grep QEMU 源代码得出了断点位置。在 Fedora 上你可以这样得到它:

$ fedpkg clone -a qemu
$ cd qemu
$ fedpkg source
$ tar xfv qemu-2.2.0-rc1.tar.bz2
$ cd qemu-2.2.0-rc1

笔记: gdb可以通过uit命令退出q

答案2

我想分享这个关于 1.7.10.4 版本 QEMU 中 Westmere CPU 中 AES-NI 支持的线程:

http://lists.gnu.org/archive/html/qemu-devel/2013-03/msg05374.html

该功能经过审查并被接受到代码流中。

然后还有另一个线程与为什么 2.2 中似乎缺乏该功能相关:

https://www.redhat.com/archives/libvirt-users/2015-February/msg00007.html

该线程似乎表明有一种启用此功能的方法,但由于与 libvirt 和 CPU 检测不兼容,可能会产生负面后果。就我个人而言,我很乐意看到重新引入此功能。

相关内容