The qcow2 image file format for KVM can use AES encryption. The encryption is applied at the cluster level:

Each sector within each cluster is independently encrypted using AES Cipher Block Chaining mode, using the sector's offset (relative to the start of the device) in little-endian format as the first 64 bits of the 128 bit initialisation vector.

The cluster size can be set from 512 bytes to 2M (64K appears to be the default).

One of the main issues with using qcow2 encryption is the performance hit for the CPU - every disk write or non-cached read needs to encrypt or unencrypt.

What I'd like to know is does QEMU/KVM use the Intel AES instructions to mitigate the performance hit if the host CPU has them? If so, does usage or performance depend significantly on cluster size?

Intel® AES instructions are a new set of instructions available beginning with the all new 2010 Intel® Core™ processor family based on the 32nm Intel® microarchitecture codename Westmere. These instructions enable fast and secure data encryption and decryption, using the Advanced Encryption Standard (AES) which is defined by FIPS Publication number 197. Since AES is currently the dominant block cipher, and it is used in various protocols, the new instructions are valuable for a wide range of applications.


At least with the Fedora 20 package qemu-img (1.6.2, 10.fc20) does not use AES-NI for AES crypto.


One can verify it like this:

  1. Does the CPU have AES-NI?

    $ grep aes /proc/cpuinfo  -i

    For example my Intel Core 7 has this extension.

  2. Install the necessary debug packages:

    # debuginfo-install qemu-img
  3. Run qemu-img in a debugger:

    $ gdb --args qemu-img convert -o encryption -O qcow2 disk1.img enc1.qcow2
  4. Set a break-point in a well known qemu encryption function that is not optimized for AES-NI:

    (gdb) b AES_encrypt
    Breakpoint 1 at 0x794b0: file util/aes.c, line 881.
  5. Run the program:

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


In my testing it does stop there:

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];

Meaning that, indeed, Intel AES instructions are not used.

My first thought was that qemu-img perhaps just uses libcrypto such that AES-NI is automatically used, when available. qemu-img even links against libcrypto (cf ldd $(which qemu-img)) - but it does not seem to use it for AES crypto. Hmm.

I derived the breakpoint location via grepping the QEMU source code. On Fedora you can get it like this:

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

NOTE: gdb can be exited via the quit command.

  • This answer far exceeded my expectations, thank you. Does QEMU use the same code when reading the images under normal operation? – user12810 Nov 26 '14 at 20:09

I'd like to share this thread regarding AES-NI support in the Westmere CPU in the version of QEMU:


The functionality was reviewed and accepted into the code stream.

Then there is another thread related to why the functionality seems lacking in 2.2:


The thread seems to indicate there is a method of enabling this feature, but with possible negative consequences due incompatibilities with libvirt and CPU detection. Personally I'd love to see this feature re-introduced.

  • interesting, though it's nothing to do with the question, which is not about emulation and passing through AES-NI to the guest, but whether the host uses it for encryption (the guest does not even know if it's volumes are encrypted, it's transparent). – user12810 Mar 22 '15 at 14:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy