[libvirt] [PATCH RFC 11/16] encryption: Add luks parsing for storageencryption

John Ferlan jferlan at redhat.com
Tue Jun 7 14:45:40 UTC 2016


Add parse and format of the luks/key secret including tests for
volume XML parsing.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 docs/formatstorageencryption.html.in               | 24 +++++++++++-
 docs/schemas/storagecommon.rng                     |  3 ++
 src/qemu/qemu_process.c                            |  6 +++
 src/storage/storage_backend.c                      |  3 +-
 src/storage/storage_backend_fs.c                   |  7 +++-
 src/storage/storage_backend_gluster.c              |  2 +
 src/util/virstorageencryption.c                    |  4 +-
 src/util/virstorageencryption.h                    |  2 +
 tests/qemuxml2argvdata/qemuxml2argv-luks-disks.xml | 41 ++++++++++++++++++++
 .../qemuxml2xmlout-luks-disks.xml                  | 45 ++++++++++++++++++++++
 tests/qemuxml2xmltest.c                            |  1 +
 tests/storagevolxml2xmlin/vol-luks.xml             | 21 ++++++++++
 tests/storagevolxml2xmlout/vol-luks.xml            | 21 ++++++++++
 tests/storagevolxml2xmltest.c                      |  1 +
 14 files changed, 175 insertions(+), 6 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-luks-disks.xml
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-luks-disks.xml
 create mode 100644 tests/storagevolxml2xmlin/vol-luks.xml
 create mode 100644 tests/storagevolxml2xmlout/vol-luks.xml

diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in
index 048cc8e..ae2e815 100644
--- a/docs/formatstorageencryption.html.in
+++ b/docs/formatstorageencryption.html.in
@@ -59,8 +59,20 @@
       the <code>secret</code> element is not present during volume creation,
       a secret is automatically generated and attached to the volume.
     </p>
+    <h3><a name="StorageEncryptionLuks">"luks" format</a></h3>
+    <p>
+      The <code>luks</code> format is specific to a luks encrypted volume
+      and the secret used in order to either encrypt or decrypt the volume.
+      A single <code><secret type='key'></code> element is expected.
+      The secret may be referenced via either a <code>uuid</code> or
+      <code>usage</code> attribute. One of the two must be present. When
+      present for volume creation, the secret will be used in order for
+      volume encryption.  When present for domain usage, the secret will
+      be used as the key to decrypt the volume.
+      <span class="since">Since 1.3.6</span>.
+    </p>
 
-    <h2><a name="example">Example</a></h2>
+    <h2><a name="example">Examples</a></h2>
 
     <p>
       Here is a simple example, specifying use of the <code>qcow</code> format:
@@ -70,5 +82,15 @@
       <encryption format='qcow'>
          <secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' />
       </encryption></pre>
+
+    <p>
+      Here is a simple example, specifying use of the <code>luks</code> format:
+    </p>
+    <pre>
+      <encryption format='luks'>
+         <secret type='key' usage='luks_example'/>
+      </encryption>
+    </pre>
+
   </body>
 </html>
diff --git a/docs/schemas/storagecommon.rng b/docs/schemas/storagecommon.rng
index c5b71de..44d4315 100644
--- a/docs/schemas/storagecommon.rng
+++ b/docs/schemas/storagecommon.rng
@@ -12,6 +12,7 @@
         <choice>
           <value>default</value>
           <value>qcow</value>
+          <value>luks</value>
         </choice>
       </attribute>
       <zeroOrMore>
@@ -25,6 +26,7 @@
       <attribute name='type'>
         <choice>
           <value>passphrase</value>
+          <value>key</value>
         </choice>
       </attribute>
       <choice>
@@ -81,6 +83,7 @@
       <value>fat</value>
       <value>vhd</value>
       <value>ploop</value>
+      <value>luks</value>
       <ref name='storageFormatBacking'/>
     </choice>
   </define>
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ce92e23..4178a42 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2407,6 +2407,12 @@ qemuProcessInitPasswords(virConnectPtr conn,
             !virDomainDiskGetSource(vm->def->disks[i]))
             continue;
 
+        if (vm->def->disks[i]->src->encryption->format !=
+            VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT &&
+            vm->def->disks[i]->src->encryption->format !=
+            VIR_STORAGE_ENCRYPTION_FORMAT_QCOW)
+            continue;
+
         VIR_FREE(secret);
         if (qemuProcessGetVolumeQcowPassphrase(conn,
                                                vm->def->disks[i],
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 11f6081..4965c9e 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -1027,8 +1027,7 @@ virStorageBackendCreateQemuImgCheckEncryption(int format,
         }
     } else {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("qcow volume encryption unsupported with "
-                         "volume format %s"), type);
+                       _("volume encryption unsupported with format %s"), type);
         return -1;
     }
 
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 22cfbc0..cf0ddb8 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -157,7 +157,12 @@ virStorageBackendProbeTarget(virStorageSourcePtr target,
         case VIR_STORAGE_FILE_QCOW2:
             (*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
             break;
-        default:
+
+        case VIR_STORAGE_FILE_LUKS:
+            (*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS;
+            break;
+
+        case VIR_STORAGE_ENCRYPTION_FORMAT_LAST:
             break;
         }
 
diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
index 0085052..eda060d 100644
--- a/src/storage/storage_backend_gluster.c
+++ b/src/storage/storage_backend_gluster.c
@@ -321,6 +321,8 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
         if (vol->target.format == VIR_STORAGE_FILE_QCOW ||
             vol->target.format == VIR_STORAGE_FILE_QCOW2)
             vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
+        if (vol->target.format == VIR_STORAGE_FILE_LUKS)
+            vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS;
     }
     vol->target.features = meta->features;
     meta->features = NULL;
diff --git a/src/util/virstorageencryption.c b/src/util/virstorageencryption.c
index aa1acbd..8db49ce 100644
--- a/src/util/virstorageencryption.c
+++ b/src/util/virstorageencryption.c
@@ -38,11 +38,11 @@
 #define VIR_FROM_THIS VIR_FROM_STORAGE
 
 VIR_ENUM_IMPL(virStorageEncryptionSecret,
-              VIR_STORAGE_ENCRYPTION_SECRET_TYPE_LAST, "passphrase")
+              VIR_STORAGE_ENCRYPTION_SECRET_TYPE_LAST, "passphrase", "key")
 
 VIR_ENUM_IMPL(virStorageEncryptionFormat,
               VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
-              "default", "qcow")
+              "default", "qcow", "luks")
 
 static void
 virStorageEncryptionSecretFree(virStorageEncryptionSecretPtr secret)
diff --git a/src/util/virstorageencryption.h b/src/util/virstorageencryption.h
index a81cb6e..0f3a33d 100644
--- a/src/util/virstorageencryption.h
+++ b/src/util/virstorageencryption.h
@@ -32,6 +32,7 @@
 
 typedef enum {
     VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE = 0,
+    VIR_STORAGE_ENCRYPTION_SECRET_TYPE_KEY,
 
     VIR_STORAGE_ENCRYPTION_SECRET_TYPE_LAST
 } virStorageEncryptionSecretType;
@@ -48,6 +49,7 @@ typedef enum {
     /* "default" is only valid for volume creation */
     VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT = 0,
     VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, /* Both qcow and qcow2 */
+    VIR_STORAGE_ENCRYPTION_FORMAT_LUKS,
 
     VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
 } virStorageEncryptionFormatType;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-luks-disks.xml b/tests/qemuxml2argvdata/qemuxml2argv-luks-disks.xml
new file mode 100644
index 0000000..29ea38a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-luks-disks.xml
@@ -0,0 +1,41 @@
+<domain type='qemu'>
+  <name>encryptdisk</name>
+  <uuid>496898a6-e6ff-f7c8-5dc2-3cf410945ee9</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>524288</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-i440fx-2.1'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='luks'/>
+      <source file='/storage/guest_disks/encryptdisk'/>
+      <target dev='vda' bus='virtio'/>
+      <encryption format='luks'>
+        <secret type='key' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/>
+      </encryption>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='luks'/>
+      <source file='/storage/guest_disks/encryptdisk2'/>
+      <target dev='vdb' bus='virtio'/>
+      <encryption format='luks'>
+        <secret type='key' usage='mycluster_myname'/>
+      </encryption>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-luks-disks.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-luks-disks.xml
new file mode 100644
index 0000000..c04506a
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-luks-disks.xml
@@ -0,0 +1,45 @@
+<domain type='qemu'>
+  <name>encryptdisk</name>
+  <uuid>496898a6-e6ff-f7c8-5dc2-3cf410945ee9</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>524288</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-i440fx-2.1'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='luks'/>
+      <source file='/storage/guest_disks/encryptdisk'/>
+      <target dev='vda' bus='virtio'/>
+      <encryption format='luks'>
+        <secret type='key' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/>
+      </encryption>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='luks'/>
+      <source file='/storage/guest_disks/encryptdisk2'/>
+      <target dev='vdb' bus='virtio'/>
+      <encryption format='luks'>
+        <secret type='key' usage='mycluster_myname'/>
+      </encryption>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </disk>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 59fdbd2..3862b3b 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -494,6 +494,7 @@ mymain(void)
 
     DO_TEST("encrypted-disk");
     DO_TEST("encrypted-disk-usage");
+    DO_TEST("luks-disks");
     DO_TEST("memtune");
     DO_TEST("memtune-unlimited");
     DO_TEST("blkiotune");
diff --git a/tests/storagevolxml2xmlin/vol-luks.xml b/tests/storagevolxml2xmlin/vol-luks.xml
new file mode 100644
index 0000000..11e0b50
--- /dev/null
+++ b/tests/storagevolxml2xmlin/vol-luks.xml
@@ -0,0 +1,21 @@
+<volume>
+  <name>LuksDemo.img</name>
+  <key>/var/lib/libvirt/images/LuksDemo.img</key>
+  <source>
+  </source>
+  <capacity unit="G">5</capacity>
+  <allocation>294912</allocation>
+  <target>
+    <path>/var/lib/libvirt/images/LuksDemo.img</path>
+    <format type='luks'/>
+    <permissions>
+      <mode>0644</mode>
+      <owner>0</owner>
+      <group>0</group>
+      <label>unconfined_u:object_r:virt_image_t:s0</label>
+    </permissions>
+    <encryption format='luks'>
+      <secret type='key' usage='mumblyfratz'/>
+    </encryption>
+  </target>
+</volume>
diff --git a/tests/storagevolxml2xmlout/vol-luks.xml b/tests/storagevolxml2xmlout/vol-luks.xml
new file mode 100644
index 0000000..6bb3606
--- /dev/null
+++ b/tests/storagevolxml2xmlout/vol-luks.xml
@@ -0,0 +1,21 @@
+<volume type='file'>
+  <name>LuksDemo.img</name>
+  <key>/var/lib/libvirt/images/LuksDemo.img</key>
+  <source>
+  </source>
+  <capacity unit='bytes'>5368709120</capacity>
+  <allocation unit='bytes'>294912</allocation>
+  <target>
+    <path>/var/lib/libvirt/images/LuksDemo.img</path>
+    <format type='luks'/>
+    <permissions>
+      <mode>0644</mode>
+      <owner>0</owner>
+      <group>0</group>
+      <label>unconfined_u:object_r:virt_image_t:s0</label>
+    </permissions>
+    <encryption format='luks'>
+      <secret type='key' usage='mumblyfratz'/>
+    </encryption>
+  </target>
+</volume>
diff --git a/tests/storagevolxml2xmltest.c b/tests/storagevolxml2xmltest.c
index 148d1e6..ebb39ab 100644
--- a/tests/storagevolxml2xmltest.c
+++ b/tests/storagevolxml2xmltest.c
@@ -105,6 +105,7 @@ mymain(void)
     DO_TEST("pool-dir", "vol-qcow2-lazy");
     DO_TEST("pool-dir", "vol-qcow2-0.10-lazy");
     DO_TEST("pool-dir", "vol-qcow2-nobacking");
+    DO_TEST("pool-dir", "vol-luks");
     DO_TEST("pool-disk", "vol-partition");
     DO_TEST("pool-logical", "vol-logical");
     DO_TEST("pool-logical", "vol-logical-backing");
-- 
2.5.5




More information about the libvir-list mailing list