From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LVXww-0001mH-DS for qemu-devel@nongnu.org; Fri, 06 Feb 2009 16:09:22 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LVXws-0001hm-PS for qemu-devel@nongnu.org; Fri, 06 Feb 2009 16:09:19 -0500 Received: from [199.232.76.173] (port=51589 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LVXwr-0001h2-Qi for qemu-devel@nongnu.org; Fri, 06 Feb 2009 16:09:17 -0500 Received: from mx2.redhat.com ([66.187.237.31]:54581) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LVXwq-0007o8-LG for qemu-devel@nongnu.org; Fri, 06 Feb 2009 16:09:17 -0500 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n16L9FNa001182 for ; Fri, 6 Feb 2009 16:09:15 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n16L9FmX029499 for ; Fri, 6 Feb 2009 16:09:15 -0500 Received: from blackpad.localdomain (vpn-10-11.bos.redhat.com [10.16.10.11]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n16L9EhN014600 for ; Fri, 6 Feb 2009 16:09:14 -0500 From: Eduardo Habkost Date: Fri, 6 Feb 2009 19:08:56 -0200 Message-Id: <1233954540-4754-6-git-send-email-ehabkost@redhat.com> In-Reply-To: <1233954540-4754-1-git-send-email-ehabkost@redhat.com> References: <1233954540-4754-1-git-send-email-ehabkost@redhat.com> Subject: [Qemu-devel] [PATCH 5/9] qcow: make encryption support optional Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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 --- 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 + +#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 -#include "aes.h" #include +#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