[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 06/17] qcow: add a 'keyid' parameter to qcow options
From: |
Daniel P. Berrange |
Subject: |
[Qemu-devel] [PATCH 06/17] qcow: add a 'keyid' parameter to qcow options |
Date: |
Mon, 19 Oct 2015 16:09:38 +0100 |
Add a 'keyid' parameter that refers to the ID of a
QCryptoSecret instance that provides the encryption key.
eg
$QEMU \
-object secret,id=sec0,filename=/home/berrange/encrypted.pw \
-drive file=/home/berrange/encrypted.qcow,keyid=sec0
Signed-off-by: Daniel P. Berrange <address@hidden>
---
block/qcow.c | 94 +++++++++++++++++++++++++++++++++++++++-------------
qapi/block-core.json | 17 +++++++++-
2 files changed, 87 insertions(+), 24 deletions(-)
diff --git a/block/qcow.c b/block/qcow.c
index 635085e..719ed7c 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -27,6 +27,7 @@
#include <zlib.h>
#include "qapi/qmp/qerror.h"
#include "crypto/cipher.h"
+#include "crypto/secret.h"
#include "migration/migration.h"
/**************************************************************/
@@ -40,6 +41,8 @@
#define QCOW_OFLAG_COMPRESSED (1LL << 63)
+#define QCOW_OPT_KEY_ID "keyid"
+
typedef struct QCowHeader {
uint32_t magic;
uint32_t version;
@@ -92,6 +95,43 @@ static int qcow_probe(const uint8_t *buf, int buf_size,
const char *filename)
return 0;
}
+static QCryptoCipher *qcow_get_cipher_from_key(const char *key,
+ Error **errp)
+{
+ uint8_t keybuf[16];
+ int len, i;
+
+ memset(keybuf, 0, 16);
+ len = strlen(key);
+ if (len > 16) {
+ len = 16;
+ }
+ /* XXX: we could compress the chars to 7 bits to increase
+ entropy */
+ for (i = 0; i < len; i++) {
+ keybuf[i] = key[i];
+ }
+
+ return qcrypto_cipher_new(
+ QCRYPTO_CIPHER_ALG_AES_128,
+ QCRYPTO_CIPHER_MODE_CBC,
+ keybuf, G_N_ELEMENTS(keybuf),
+ errp);
+}
+
+static QemuOptsList qcow_runtime_opts = {
+ .name = "qcow",
+ .head = QTAILQ_HEAD_INITIALIZER(qcow_runtime_opts.head),
+ .desc = {
+ {
+ .name = QCOW_OPT_KEY_ID,
+ .type = QEMU_OPT_STRING,
+ .help = "ID of the secret that provides the encryption key",
+ },
+ { /* end of list */ }
+ },
+};
+
static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -99,6 +139,10 @@ static int qcow_open(BlockDriverState *bs, QDict *options,
int flags,
unsigned int len, i, shift;
int ret;
QCowHeader header;
+ QemuOpts *opts = NULL;
+ const char *keyid;
+ char *key;
+ Error *local_err = NULL;
ret = bdrv_pread(bs->file->bs, 0, &header, sizeof(header));
if (ret < 0) {
@@ -147,6 +191,32 @@ static int qcow_open(BlockDriverState *bs, QDict *options,
int flags,
goto fail;
}
+ opts = qemu_opts_create(&qcow_runtime_opts, NULL, 0, &error_abort);
+ qemu_opts_absorb_qdict(opts, options, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ keyid = qemu_opt_get(opts, QCOW_OPT_KEY_ID);
+ if (keyid) {
+ key = qcrypto_secret_lookup_as_utf8(keyid,
+ errp);
+ if (!key) {
+ ret = -ENOENT;
+ goto fail;
+ }
+
+ s->cipher = qcow_get_cipher_from_key(key,
+ errp);
+ g_free(key);
+ if (!s->cipher) {
+ ret = -ENOSYS;
+ goto fail;
+ }
+ }
+
if (header.crypt_method > QCOW_CRYPT_AES) {
error_setg(errp, "invalid encryption method in qcow header");
ret = -EINVAL;
@@ -261,33 +331,11 @@ static int qcow_reopen_prepare(BDRVReopenState *state,
static int qcow_set_key(BlockDriverState *bs, const char *key)
{
BDRVQcowState *s = bs->opaque;
- uint8_t keybuf[16];
- int len, i;
- Error *err;
- memset(keybuf, 0, 16);
- len = strlen(key);
- if (len > 16)
- len = 16;
- /* XXX: we could compress the chars to 7 bits to increase
- entropy */
- for(i = 0;i < len;i++) {
- keybuf[i] = key[i];
- }
assert(bs->encrypted);
-
qcrypto_cipher_free(s->cipher);
- s->cipher = qcrypto_cipher_new(
- QCRYPTO_CIPHER_ALG_AES_128,
- QCRYPTO_CIPHER_MODE_CBC,
- keybuf, G_N_ELEMENTS(keybuf),
- &err);
-
+ s->cipher = qcow_get_cipher_from_key(key, NULL);
if (!s->cipher) {
- /* XXX would be nice if errors in this method could
- * be properly propagate to the caller. Would need
- * the bdrv_set_key() API signature to be fixed. */
- error_free(err);
return -1;
}
return 0;
diff --git a/qapi/block-core.json b/qapi/block-core.json
index bb2189e..513fe93 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1562,6 +1562,21 @@
'mode': 'Qcow2OverlapCheckMode' } }
##
+# @BlockdevOptionsQcow
+#
+# Driver specific block device options for qcow.
+#
+# @keyid: #optional ID of the "secret" object providing the
+# AES decryption key.
+#
+# Since: 2.5
+##
+{ 'struct': 'BlockdevOptionsQcow',
+ 'base': 'BlockdevOptionsGenericCOWFormat',
+ 'data': { '*keyid': 'str' } }
+
+
+##
# @BlockdevOptionsQcow2
#
# Driver specific block device options for qcow2.
@@ -1826,7 +1841,7 @@
'null-co': 'BlockdevOptionsNull',
'parallels': 'BlockdevOptionsGenericFormat',
'qcow2': 'BlockdevOptionsQcow2',
- 'qcow': 'BlockdevOptionsGenericCOWFormat',
+ 'qcow': 'BlockdevOptionsQcow',
'qed': 'BlockdevOptionsGenericCOWFormat',
'quorum': 'BlockdevOptionsQuorum',
'raw': 'BlockdevOptionsGenericFormat',
--
2.4.3
- Re: [Qemu-devel] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, (continued)
- Re: [Qemu-devel] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
- Re: [Qemu-devel] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Paolo Bonzini, 2015/10/19
- Re: [Qemu-devel] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
- Re: [Qemu-devel] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Paolo Bonzini, 2015/10/19
- Re: [Qemu-devel] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
- Re: [Qemu-devel] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Paolo Bonzini, 2015/10/19
- Re: [Qemu-devel] [PATCH 01/17] crypto: add QCryptoSecret object class for password/key handling, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 07/17] qcow2: add a 'keyid' parameter to qcow2 options, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 06/17] qcow: add a 'keyid' parameter to qcow options,
Daniel P. Berrange <=
[Qemu-devel] [PATCH 10/17] qemu-nbd: add support for --object command line arg, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 13/17] qemu-nbd: allow specifying image as a set of options args, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 08/17] qom: add user_creatable_add & user_creatable_del methods, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 12/17] qemu-io: allow specifying image as a set of options args, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 11/17] qemu-io: add support for --object command line arg, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 09/17] qemu-img: add support for --object command line arg, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 16/17] block: remove all encryption handling APIs, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 15/17] block: rip out all traces of password prompting, Daniel P. Berrange, 2015/10/19
[Qemu-devel] [PATCH 17/17] block: remove support for writing to qcow/qcow2 encrypted images, Daniel P. Berrange, 2015/10/19