qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 5/9] qcow: make encryption support optional


From: Eduardo Habkost
Subject: [Qemu-devel] [PATCH 5/9] qcow: make encryption support optional
Date: Fri, 6 Feb 2009 19:08:56 -0200

I will change it to use AES encryption support from libgcrypt, and making
it optional will allow qcow to be compiled if libgcrypt is not available.

Signed-off-by: Eduardo Habkost <address@hidden>
---
 block-qcow.c  |   41 ++++++++++++++++++++++++++++++++++++++---
 block-qcow2.c |   45 +++++++++++++++++++++++++++++++++++++++++----
 configure     |    8 ++++++++
 3 files changed, 87 insertions(+), 7 deletions(-)

diff --git a/block-qcow.c b/block-qcow.c
index 4fdd0d8..a283fa2 100644
--- a/block-qcow.c
+++ b/block-qcow.c
@@ -24,7 +24,10 @@
 #include "qemu-common.h"
 #include "block_int.h"
 #include <zlib.h>
+
+#ifdef CONFIG_QCOW_AES
 #include "aes.h"
+#endif
 
 /**************************************************************/
 /* QEMU COW block driver with compression and encryption support */
@@ -72,8 +75,10 @@ typedef struct BDRVQcowState {
     uint64_t cluster_cache_offset;
     uint32_t crypt_method; /* current crypt method, 0 if no key yet */
     uint32_t crypt_method_header;
+#ifdef CONFIG_QCOW_AES
     AES_KEY aes_encrypt_key;
     AES_KEY aes_decrypt_key;
+#endif
 } BDRVQcowState;
 
 static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
@@ -116,6 +121,10 @@ static int qcow_open(BlockDriverState *bs, const char 
*filename, int flags)
         goto fail;
     if (header.crypt_method > QCOW_CRYPT_MAX)
         goto fail;
+#ifndef CONFIG_QCOW_AES
+    if (header.crypt_method == QCOW_CRYPT_AES)
+        goto fail;
+#endif
     s->crypt_method_header = header.crypt_method;
     if (s->crypt_method_header)
         bs->encrypted = 1;
@@ -173,7 +182,8 @@ static int qcow_open(BlockDriverState *bs, const char 
*filename, int flags)
     return -1;
 }
 
-static int qcow_set_key(BlockDriverState *bs, const char *key)
+#ifdef CONFIG_QCOW_AES
+static int qcow_set_key_aes(BlockDriverState *bs, const char *key)
 {
     BDRVQcowState *s = bs->opaque;
     uint8_t keybuf[16];
@@ -214,7 +224,19 @@ static int qcow_set_key(BlockDriverState *bs, const char 
*key)
 #endif
     return 0;
 }
+#endif
+
+static int qcow_set_key(BlockDriverState *bs, const char *key)
+{
+#ifdef CONFIG_QCOW_AES
+    return qcow_set_key_aes(bs, key);
+#else
+    return -1;
+#endif
+}
+
 
+#ifdef CONFIG_QCOW_AES
 /* The crypt function is compatible with the linux cryptoloop
    algorithm for < 4 GB images. NOTE: out_buf == in_buf is
    supported */
@@ -239,6 +261,7 @@ static void encrypt_sectors(BDRVQcowState *s, int64_t 
sector_num,
         out_buf += 512;
     }
 }
+#endif
 
 /* 'allocate' is:
  *
@@ -345,6 +368,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
                 cluster_offset = (cluster_offset + s->cluster_size - 1) &
                     ~(s->cluster_size - 1);
                 bdrv_truncate(s->hd, cluster_offset + s->cluster_size);
+#ifdef CONFIG_QCOW_AES
                 /* if encrypted, we must initialize the cluster
                    content which won't be written */
                 if (s->crypt_method &&
@@ -364,6 +388,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
                         }
                     }
                 }
+#endif /* CONFIG_QCOW_AES */
             } else if (allocate == 2) {
                 cluster_offset |= QCOW_OFLAG_COMPRESSED |
                     (uint64_t)compressed_size << (63 - s->cluster_bits);
@@ -505,12 +530,16 @@ static int qcow_write(BlockDriverState *bs, int64_t 
sector_num,
                                             index_in_cluster + n);
         if (!cluster_offset)
             return -1;
+#ifdef CONFIG_QCOW_AES
         if (s->crypt_method) {
             encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
                             &s->aes_encrypt_key);
             ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
                               s->cluster_data, n * 512);
-        } else {
+        }
+        else
+#endif /* CONFIG_QCOW_AES */
+        {
             ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, 
buf, n * 512);
         }
         if (ret != n * 512)
@@ -556,11 +585,13 @@ static void qcow_aio_read_cb(void *opaque, int ret)
     } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
         /* nothing to do */
     } else {
+#ifdef CONFIG_QCOW_AES
         if (s->crypt_method) {
             encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
                             acb->n, 0,
                             &s->aes_decrypt_key);
         }
+#endif
     }
 
     acb->nb_sectors -= acb->n;
@@ -674,6 +705,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
         ret = -EIO;
         goto fail;
     }
+#ifdef CONFIG_QCOW_AES
     if (s->crypt_method) {
         if (!acb->cluster_data) {
             acb->cluster_data = qemu_mallocz(s->cluster_size);
@@ -685,7 +717,10 @@ static void qcow_aio_write_cb(void *opaque, int ret)
         encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
                         acb->n, 1, &s->aes_encrypt_key);
         src_buf = acb->cluster_data;
-    } else {
+    }
+    else
+#endif /* CONFIG_QCOW_AES */
+    {
         src_buf = acb->buf;
     }
     acb->hd_aiocb = bdrv_aio_write(s->hd,
diff --git a/block-qcow2.c b/block-qcow2.c
index d1503e9..6240976 100644
--- a/block-qcow2.c
+++ b/block-qcow2.c
@@ -24,9 +24,12 @@
 #include "qemu-common.h"
 #include "block_int.h"
 #include <zlib.h>
-#include "aes.h"
 #include <assert.h>
 
+#ifdef CONFIG_QCOW_AES
+#include "aes.h"
+#endif
+
 /*
   Differences with QCOW:
 
@@ -142,8 +145,10 @@ typedef struct BDRVQcowState {
 
     uint32_t crypt_method; /* current crypt method, 0 if no key yet */
     uint32_t crypt_method_header;
+#ifdef CONFIG_QCOW_AES
     AES_KEY aes_encrypt_key;
     AES_KEY aes_decrypt_key;
+#endif
 
     int64_t highest_alloc; /* highest cluester allocated (in clusters) */
     int64_t nc_free;       /* num of free clusters below highest_alloc */
@@ -231,6 +236,10 @@ static int qcow_open(BlockDriverState *bs, const char 
*filename, int flags)
         goto fail;
     if (header.crypt_method > QCOW_CRYPT_MAX)
         goto fail;
+#ifndef CONFIG_QCOW_AES
+    if (header.crypt_method == QCOW_CRYPT_AES)
+        goto fail;
+#endif
     s->crypt_method_header = header.crypt_method;
     if (s->crypt_method_header)
         bs->encrypted = 1;
@@ -307,7 +316,8 @@ static int qcow_open(BlockDriverState *bs, const char 
*filename, int flags)
     return -1;
 }
 
-static int qcow_set_key(BlockDriverState *bs, const char *key)
+#ifdef CONFIG_QCOW_AES
+static int qcow_set_key_aes(BlockDriverState *bs, const char *key)
 {
     BDRVQcowState *s = bs->opaque;
     uint8_t keybuf[16];
@@ -348,7 +358,19 @@ static int qcow_set_key(BlockDriverState *bs, const char 
*key)
 #endif
     return 0;
 }
+#endif
+
+
+static int qcow_set_key(BlockDriverState *bs, const char *key)
+{
+#ifdef CONFIG_QCOW_AES
+    return qcow_set_key_aes(bs, key);
+#else
+    return -1;
+#endif
+}
 
+#ifdef CONFIG_QCOW_AES
 /* The crypt function is compatible with the linux cryptoloop
    algorithm for < 4 GB images. NOTE: out_buf == in_buf is
    supported */
@@ -373,6 +395,7 @@ static void encrypt_sectors(BDRVQcowState *s, int64_t 
sector_num,
         out_buf += 512;
     }
 }
+#endif
 
 static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
                         uint64_t cluster_offset, int n_start, int n_end)
@@ -386,12 +409,14 @@ static int copy_sectors(BlockDriverState *bs, uint64_t 
start_sect,
     ret = qcow_read(bs, start_sect + n_start, s->cluster_data, n);
     if (ret < 0)
         return ret;
+#ifdef CONFIG_QCOW_AES
     if (s->crypt_method) {
         encrypt_sectors(s, start_sect + n_start,
                         s->cluster_data,
                         s->cluster_data, n, 1,
                         &s->aes_encrypt_key);
     }
+#endif
     ret = bdrv_write(s->hd, (cluster_offset >> 9) + n_start,
                      s->cluster_data, n);
     if (ret < 0)
@@ -1123,10 +1148,12 @@ static int qcow_read(BlockDriverState *bs, int64_t 
sector_num,
             ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, 
buf, n * 512);
             if (ret != n * 512)
                 return -1;
+#ifdef CONFIG_QCOW_AES
             if (s->crypt_method) {
                 encrypt_sectors(s, sector_num, buf, buf, n, 0,
                                 &s->aes_decrypt_key);
             }
+#endif
         }
         nb_sectors -= n;
         sector_num += n;
@@ -1155,12 +1182,16 @@ static int qcow_write(BlockDriverState *bs, int64_t 
sector_num,
                                               n_end, &n, &l2meta);
         if (!cluster_offset)
             return -1;
+#ifdef CONFIG_QCOW_AES
         if (s->crypt_method) {
             encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
                             &s->aes_encrypt_key);
             ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
                               s->cluster_data, n * 512);
-        } else {
+        }
+        else
+#endif
+        {
             ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, 
buf, n * 512);
         }
         if (ret != n * 512 || alloc_cluster_link_l2(bs, cluster_offset, 
&l2meta) < 0) {
@@ -1232,11 +1263,13 @@ fail:
     } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
         /* nothing to do */
     } else {
+#ifdef CONFIG_QCOW_AES
         if (s->crypt_method) {
             encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
                             acb->n, 0,
                             &s->aes_decrypt_key);
         }
+#endif
     }
 
     acb->nb_sectors -= acb->n;
@@ -1379,6 +1412,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
         ret = -EIO;
         goto fail;
     }
+#ifdef CONFIG_QCOW_AES
     if (s->crypt_method) {
         if (!acb->cluster_data) {
             acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS *
@@ -1387,7 +1421,10 @@ static void qcow_aio_write_cb(void *opaque, int ret)
         encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
                         acb->n, 1, &s->aes_encrypt_key);
         src_buf = acb->cluster_data;
-    } else {
+    }
+    else
+#endif
+    {
         src_buf = acb->buf;
     }
     acb->hd_aiocb = bdrv_aio_write(s->hd,
diff --git a/configure b/configure
index c3fbbbe..604055c 100755
--- a/configure
+++ b/configure
@@ -164,6 +164,7 @@ fmod_lib=""
 fmod_inc=""
 oss_lib=""
 vnc_tls="yes"
+qcow_aes="yes"
 bsd="no"
 linux="no"
 solaris="no"
@@ -387,6 +388,8 @@ for opt do
   ;;
   --disable-vnc-tls) vnc_tls="no"
   ;;
+  --disable-qcow-aes) qcow_aes="no"
+  ;;
   --disable-slirp) slirp="no"
   ;;
   --disable-vde) vde="no"
@@ -544,6 +547,7 @@ echo "                           Available cards: 
$audio_possible_cards"
 echo "  --enable-mixemu          enable mixer emulation"
 echo "  --disable-brlapi         disable BrlAPI"
 echo "  --disable-vnc-tls        disable TLS encryption for VNC server"
+echo "  --disable-qcow-aes       disable AES encrypton support on qcow"
 echo "  --disable-curses         disable curses output"
 echo "  --disable-bluez          disable bluez stack connectivity"
 echo "  --disable-kvm            disable KVM acceleration support"
@@ -1130,6 +1134,7 @@ if test "$vnc_tls" = "yes" ; then
     echo "    TLS CFLAGS    $vnc_tls_cflags"
     echo "    TLS LIBS      $vnc_tls_libs"
 fi
+echo "qcow encryption   $qcow_aes"
 if test -n "$sparc_cpu"; then
     echo "Target Sparc Arch $sparc_cpu"
 fi
@@ -1371,6 +1376,9 @@ if test "$vnc_tls" = "yes" ; then
   echo "CONFIG_VNC_TLS_LIBS=$vnc_tls_libs" >> $config_mak
   echo "#define CONFIG_VNC_TLS 1" >> $config_h
 fi
+if [ "$qcow_aes" = "yes" ];then
+  echo "#define CONFIG_QCOW_AES 1" >> $config_h
+fi
 qemu_version=`head $source_path/VERSION`
 echo "VERSION=$qemu_version" >>$config_mak
 echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h
-- 
1.6.0.2.GIT





reply via email to

[Prev in Thread] Current Thread [Next in Thread]