QEMU/KVM 是否使用 Intel AES 指令来加密 qcow2 镜像(如果主机 CPU 有)?

9 cpu kvm encryption disk-encryption

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

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

所述簇的大小可以设置从512个字节至2M(64K似乎是默认值)。

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

我想知道的是 QEMU/KVM 是否使用Intel AES 指令来减轻主机 CPU 具有的性能损失?如果是这样,使用情况或性能是否在很大程度上取决于集群大小?

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

max*_*zig 8

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

确认

可以这样验证:

  1. CPU 有 AES-NI 吗?

    $ grep aes /proc/cpuinfo  -i
    
    Run Code Online (Sandbox Code Playgroud)

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

  2. 安装必要的调试包:

    # debuginfo-install qemu-img
    
    Run Code Online (Sandbox Code Playgroud)
  3. qemu-img在调试器中运行:

    $ gdb --args qemu-img convert -o encryption -O qcow2 disk1.img enc1.qcow2
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在未针对 AES-NI 优化的众所周知的 qemu 加密函数中设置断点:

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

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

结果

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

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];
Run Code Online (Sandbox Code Playgroud)

这意味着实际上不使用英特尔 AES 指令。

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

我通过对 QEMU 源代码的 grepping 推导出断点位置。在 Fedora 上,您可以像这样获得它:

$ fedpkg clone -a qemu
$ cd qemu
$ fedpkg source
$ tar xfv qemu-2.2.0-rc1.tar.bz2
$ cd qemu-2.2.0-rc1
Run Code Online (Sandbox Code Playgroud)

注意: gdb可以通过quit 命令退出。