[Top][All Lists]
[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
- [Qemu-devel] [PATCH 0/9] encryption code changes, Eduardo Habkost, 2009/02/06
- [Qemu-devel] [PATCH 6/9] vnc: make DES-challenge authentication (aka "VNC auth") optional, Eduardo Habkost, 2009/02/06
- [Qemu-devel] [PATCH 2/9] drive_init: Don't try to read passwords before monitor setup, Eduardo Habkost, 2009/02/06
- [Qemu-devel] [PATCH 7/9] configure: add check for libgcrypt, Eduardo Habkost, 2009/02/06
- [Qemu-devel] [PATCH 4/9] qcow: define QCOW_CRYPT_MAX, Eduardo Habkost, 2009/02/06
- [Qemu-devel] [PATCH 3/9] monitor_readline: poll pending bottom halves before readline_start(), Eduardo Habkost, 2009/02/06
- [Qemu-devel] [PATCH 5/9] qcow: make encryption support optional,
Eduardo Habkost <=
- [Qemu-devel] [PATCH 1/9] vnc: abort on unknown options, Eduardo Habkost, 2009/02/06
- [Qemu-devel] [PATCH 8/9] qcow: use libgcrypt AES implementation, Eduardo Habkost, 2009/02/06
- [Qemu-devel] [PATCH 9/9] vnc: use libgcrypt for DES-challenge authentication, Eduardo Habkost, 2009/02/06
- [Qemu-devel] Re: [PATCH 0/9] encryption code changes, Jan Kiszka, 2009/02/06
- Re: [Qemu-devel] [PATCH 0/9] encryption code changes, Anthony Liguori, 2009/02/06
- Re: [Qemu-devel] [PATCH 0/9] encryption code changes, Daniel P. Berrange, 2009/02/07
- Re: [Qemu-devel] [PATCH 0/9] encryption code changes, Anthony Liguori, 2009/02/14