[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH WIP 03/30] qcow: add a 'keyid' parameter to qcow opt
From: |
Daniel P. Berrange |
Subject: |
[Qemu-block] [PATCH WIP 03/30] qcow: add a 'keyid' parameter to qcow options |
Date: |
Fri, 20 Nov 2015 18:04:03 +0000 |
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 a07b13f..d3cc129 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1693,6 +1693,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.
@@ -1956,7 +1971,7 @@
'null-co': 'BlockdevOptionsNull',
'parallels': 'BlockdevOptionsGenericFormat',
'qcow2': 'BlockdevOptionsQcow2',
- 'qcow': 'BlockdevOptionsGenericCOWFormat',
+ 'qcow': 'BlockdevOptionsQcow',
'qed': 'BlockdevOptionsGenericCOWFormat',
'quorum': 'BlockdevOptionsQuorum',
'raw': 'BlockdevOptionsGenericFormat',
--
2.5.0
[Qemu-block] [PATCH WIP 03/30] qcow: add a 'keyid' parameter to qcow options,
Daniel P. Berrange <=
[Qemu-block] [PATCH WIP 05/30] qom: add user_creatable_add & user_creatable_del methods, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 07/30] qemu-nbd: add support for --object command line arg, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 06/30] qemu-img: add support for --object command line arg, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 08/30] qemu-io: add support for --object command line arg, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 09/30] qemu-io: allow specifying image as a set of options args, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 16/30] crypto: add ability to query the cipher key, block & IV lens, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 15/30] qcow2: make qcow2_encrypt_sectors encrypt in place, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 17/30] crypto: add method for querying hash digest size, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 13/30] block: remove all encryption handling APIs, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 10/30] qemu-nbd: allow specifying image as a set of options args, Daniel P. Berrange, 2015/11/20