]> Git Repo - qemu.git/blob - block/crypto.c
luks: Separate image file creation from formatting
[qemu.git] / block / crypto.c
1 /*
2  * QEMU block full disk encryption
3  *
4  * Copyright (c) 2015-2016 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "qemu/osdep.h"
22
23 #include "block/block_int.h"
24 #include "sysemu/block-backend.h"
25 #include "crypto/block.h"
26 #include "qapi/opts-visitor.h"
27 #include "qapi/qapi-visit-crypto.h"
28 #include "qapi/qmp/qdict.h"
29 #include "qapi/qobject-input-visitor.h"
30 #include "qapi/error.h"
31 #include "qemu/option.h"
32 #include "block/crypto.h"
33
34 typedef struct BlockCrypto BlockCrypto;
35
36 struct BlockCrypto {
37     QCryptoBlock *block;
38 };
39
40
41 static int block_crypto_probe_generic(QCryptoBlockFormat format,
42                                       const uint8_t *buf,
43                                       int buf_size,
44                                       const char *filename)
45 {
46     if (qcrypto_block_has_format(format, buf, buf_size)) {
47         return 100;
48     } else {
49         return 0;
50     }
51 }
52
53
54 static ssize_t block_crypto_read_func(QCryptoBlock *block,
55                                       size_t offset,
56                                       uint8_t *buf,
57                                       size_t buflen,
58                                       void *opaque,
59                                       Error **errp)
60 {
61     BlockDriverState *bs = opaque;
62     ssize_t ret;
63
64     ret = bdrv_pread(bs->file, offset, buf, buflen);
65     if (ret < 0) {
66         error_setg_errno(errp, -ret, "Could not read encryption header");
67         return ret;
68     }
69     return ret;
70 }
71
72
73 struct BlockCryptoCreateData {
74     BlockBackend *blk;
75     uint64_t size;
76 };
77
78
79 static ssize_t block_crypto_write_func(QCryptoBlock *block,
80                                        size_t offset,
81                                        const uint8_t *buf,
82                                        size_t buflen,
83                                        void *opaque,
84                                        Error **errp)
85 {
86     struct BlockCryptoCreateData *data = opaque;
87     ssize_t ret;
88
89     ret = blk_pwrite(data->blk, offset, buf, buflen, 0);
90     if (ret < 0) {
91         error_setg_errno(errp, -ret, "Could not write encryption header");
92         return ret;
93     }
94     return ret;
95 }
96
97
98 static ssize_t block_crypto_init_func(QCryptoBlock *block,
99                                       size_t headerlen,
100                                       void *opaque,
101                                       Error **errp)
102 {
103     struct BlockCryptoCreateData *data = opaque;
104
105     /* User provided size should reflect amount of space made
106      * available to the guest, so we must take account of that
107      * which will be used by the crypto header
108      */
109     return blk_truncate(data->blk, data->size + headerlen, PREALLOC_MODE_OFF,
110                         errp);
111 }
112
113
114 static QemuOptsList block_crypto_runtime_opts_luks = {
115     .name = "crypto",
116     .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
117     .desc = {
118         BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
119         { /* end of list */ }
120     },
121 };
122
123
124 static QemuOptsList block_crypto_create_opts_luks = {
125     .name = "crypto",
126     .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
127     .desc = {
128         {
129             .name = BLOCK_OPT_SIZE,
130             .type = QEMU_OPT_SIZE,
131             .help = "Virtual disk size"
132         },
133         BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
134         BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
135         BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
136         BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
137         BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
138         BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
139         BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
140         { /* end of list */ }
141     },
142 };
143
144
145 QCryptoBlockOpenOptions *
146 block_crypto_open_opts_init(QCryptoBlockFormat format,
147                             QDict *opts,
148                             Error **errp)
149 {
150     Visitor *v;
151     QCryptoBlockOpenOptions *ret = NULL;
152     Error *local_err = NULL;
153
154     ret = g_new0(QCryptoBlockOpenOptions, 1);
155     ret->format = format;
156
157     v = qobject_input_visitor_new_keyval(QOBJECT(opts));
158
159     visit_start_struct(v, NULL, NULL, 0, &local_err);
160     if (local_err) {
161         goto out;
162     }
163
164     switch (format) {
165     case Q_CRYPTO_BLOCK_FORMAT_LUKS:
166         visit_type_QCryptoBlockOptionsLUKS_members(
167             v, &ret->u.luks, &local_err);
168         break;
169
170     case Q_CRYPTO_BLOCK_FORMAT_QCOW:
171         visit_type_QCryptoBlockOptionsQCow_members(
172             v, &ret->u.qcow, &local_err);
173         break;
174
175     default:
176         error_setg(&local_err, "Unsupported block format %d", format);
177         break;
178     }
179     if (!local_err) {
180         visit_check_struct(v, &local_err);
181     }
182
183     visit_end_struct(v, NULL);
184
185  out:
186     if (local_err) {
187         error_propagate(errp, local_err);
188         qapi_free_QCryptoBlockOpenOptions(ret);
189         ret = NULL;
190     }
191     visit_free(v);
192     return ret;
193 }
194
195
196 QCryptoBlockCreateOptions *
197 block_crypto_create_opts_init(QCryptoBlockFormat format,
198                               QDict *opts,
199                               Error **errp)
200 {
201     Visitor *v;
202     QCryptoBlockCreateOptions *ret = NULL;
203     Error *local_err = NULL;
204
205     ret = g_new0(QCryptoBlockCreateOptions, 1);
206     ret->format = format;
207
208     v = qobject_input_visitor_new_keyval(QOBJECT(opts));
209
210     visit_start_struct(v, NULL, NULL, 0, &local_err);
211     if (local_err) {
212         goto out;
213     }
214
215     switch (format) {
216     case Q_CRYPTO_BLOCK_FORMAT_LUKS:
217         visit_type_QCryptoBlockCreateOptionsLUKS_members(
218             v, &ret->u.luks, &local_err);
219         break;
220
221     case Q_CRYPTO_BLOCK_FORMAT_QCOW:
222         visit_type_QCryptoBlockOptionsQCow_members(
223             v, &ret->u.qcow, &local_err);
224         break;
225
226     default:
227         error_setg(&local_err, "Unsupported block format %d", format);
228         break;
229     }
230     if (!local_err) {
231         visit_check_struct(v, &local_err);
232     }
233
234     visit_end_struct(v, NULL);
235
236  out:
237     if (local_err) {
238         error_propagate(errp, local_err);
239         qapi_free_QCryptoBlockCreateOptions(ret);
240         ret = NULL;
241     }
242     visit_free(v);
243     return ret;
244 }
245
246
247 static int block_crypto_open_generic(QCryptoBlockFormat format,
248                                      QemuOptsList *opts_spec,
249                                      BlockDriverState *bs,
250                                      QDict *options,
251                                      int flags,
252                                      Error **errp)
253 {
254     BlockCrypto *crypto = bs->opaque;
255     QemuOpts *opts = NULL;
256     Error *local_err = NULL;
257     int ret = -EINVAL;
258     QCryptoBlockOpenOptions *open_opts = NULL;
259     unsigned int cflags = 0;
260     QDict *cryptoopts = NULL;
261
262     bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
263                                false, errp);
264     if (!bs->file) {
265         return -EINVAL;
266     }
267
268     bs->supported_write_flags = BDRV_REQ_FUA &
269         bs->file->bs->supported_write_flags;
270
271     opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
272     qemu_opts_absorb_qdict(opts, options, &local_err);
273     if (local_err) {
274         error_propagate(errp, local_err);
275         goto cleanup;
276     }
277
278     cryptoopts = qemu_opts_to_qdict(opts, NULL);
279
280     open_opts = block_crypto_open_opts_init(format, cryptoopts, errp);
281     if (!open_opts) {
282         goto cleanup;
283     }
284
285     if (flags & BDRV_O_NO_IO) {
286         cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
287     }
288     crypto->block = qcrypto_block_open(open_opts, NULL,
289                                        block_crypto_read_func,
290                                        bs,
291                                        cflags,
292                                        errp);
293
294     if (!crypto->block) {
295         ret = -EIO;
296         goto cleanup;
297     }
298
299     bs->encrypted = true;
300
301     ret = 0;
302  cleanup:
303     QDECREF(cryptoopts);
304     qapi_free_QCryptoBlockOpenOptions(open_opts);
305     return ret;
306 }
307
308
309 static int block_crypto_create_generic(QCryptoBlockFormat format,
310                                        const char *filename,
311                                        QemuOpts *opts,
312                                        Error **errp)
313 {
314     int ret = -EINVAL;
315     QCryptoBlockCreateOptions *create_opts = NULL;
316     QCryptoBlock *crypto = NULL;
317     struct BlockCryptoCreateData data = {
318         .size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
319                          BDRV_SECTOR_SIZE),
320     };
321     QDict *cryptoopts;
322
323     /* Parse options */
324     cryptoopts = qemu_opts_to_qdict(opts, NULL);
325
326     create_opts = block_crypto_create_opts_init(format, cryptoopts, errp);
327     if (!create_opts) {
328         return -1;
329     }
330
331     /* Create protocol layer */
332     ret = bdrv_create_file(filename, opts, errp);
333     if (ret < 0) {
334         return ret;
335     }
336
337     data.blk = blk_new_open(filename, NULL, NULL,
338                             BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
339                             errp);
340     if (!data.blk) {
341         return -EINVAL;
342     }
343
344     /* Create format layer */
345     crypto = qcrypto_block_create(create_opts, NULL,
346                                   block_crypto_init_func,
347                                   block_crypto_write_func,
348                                   &data,
349                                   errp);
350
351     if (!crypto) {
352         ret = -EIO;
353         goto cleanup;
354     }
355
356     ret = 0;
357  cleanup:
358     QDECREF(cryptoopts);
359     qcrypto_block_free(crypto);
360     blk_unref(data.blk);
361     qapi_free_QCryptoBlockCreateOptions(create_opts);
362     return ret;
363 }
364
365 static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
366                                  PreallocMode prealloc, Error **errp)
367 {
368     BlockCrypto *crypto = bs->opaque;
369     uint64_t payload_offset =
370         qcrypto_block_get_payload_offset(crypto->block);
371     assert(payload_offset < (INT64_MAX - offset));
372
373     offset += payload_offset;
374
375     return bdrv_truncate(bs->file, offset, prealloc, errp);
376 }
377
378 static void block_crypto_close(BlockDriverState *bs)
379 {
380     BlockCrypto *crypto = bs->opaque;
381     qcrypto_block_free(crypto->block);
382 }
383
384 static int block_crypto_reopen_prepare(BDRVReopenState *state,
385                                        BlockReopenQueue *queue, Error **errp)
386 {
387     /* nothing needs checking */
388     return 0;
389 }
390
391 /*
392  * 1 MB bounce buffer gives good performance / memory tradeoff
393  * when using cache=none|directsync.
394  */
395 #define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
396
397 static coroutine_fn int
398 block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
399                        QEMUIOVector *qiov, int flags)
400 {
401     BlockCrypto *crypto = bs->opaque;
402     uint64_t cur_bytes; /* number of bytes in current iteration */
403     uint64_t bytes_done = 0;
404     uint8_t *cipher_data = NULL;
405     QEMUIOVector hd_qiov;
406     int ret = 0;
407     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
408     uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
409
410     assert(!flags);
411     assert(payload_offset < INT64_MAX);
412     assert(QEMU_IS_ALIGNED(offset, sector_size));
413     assert(QEMU_IS_ALIGNED(bytes, sector_size));
414
415     qemu_iovec_init(&hd_qiov, qiov->niov);
416
417     /* Bounce buffer because we don't wish to expose cipher text
418      * in qiov which points to guest memory.
419      */
420     cipher_data =
421         qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
422                                               qiov->size));
423     if (cipher_data == NULL) {
424         ret = -ENOMEM;
425         goto cleanup;
426     }
427
428     while (bytes) {
429         cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
430
431         qemu_iovec_reset(&hd_qiov);
432         qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
433
434         ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
435                              cur_bytes, &hd_qiov, 0);
436         if (ret < 0) {
437             goto cleanup;
438         }
439
440         if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
441                                   cipher_data, cur_bytes, NULL) < 0) {
442             ret = -EIO;
443             goto cleanup;
444         }
445
446         qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
447
448         bytes -= cur_bytes;
449         bytes_done += cur_bytes;
450     }
451
452  cleanup:
453     qemu_iovec_destroy(&hd_qiov);
454     qemu_vfree(cipher_data);
455
456     return ret;
457 }
458
459
460 static coroutine_fn int
461 block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
462                         QEMUIOVector *qiov, int flags)
463 {
464     BlockCrypto *crypto = bs->opaque;
465     uint64_t cur_bytes; /* number of bytes in current iteration */
466     uint64_t bytes_done = 0;
467     uint8_t *cipher_data = NULL;
468     QEMUIOVector hd_qiov;
469     int ret = 0;
470     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
471     uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
472
473     assert(!(flags & ~BDRV_REQ_FUA));
474     assert(payload_offset < INT64_MAX);
475     assert(QEMU_IS_ALIGNED(offset, sector_size));
476     assert(QEMU_IS_ALIGNED(bytes, sector_size));
477
478     qemu_iovec_init(&hd_qiov, qiov->niov);
479
480     /* Bounce buffer because we're not permitted to touch
481      * contents of qiov - it points to guest memory.
482      */
483     cipher_data =
484         qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
485                                               qiov->size));
486     if (cipher_data == NULL) {
487         ret = -ENOMEM;
488         goto cleanup;
489     }
490
491     while (bytes) {
492         cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
493
494         qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
495
496         if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
497                                   cipher_data, cur_bytes, NULL) < 0) {
498             ret = -EIO;
499             goto cleanup;
500         }
501
502         qemu_iovec_reset(&hd_qiov);
503         qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
504
505         ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
506                               cur_bytes, &hd_qiov, flags);
507         if (ret < 0) {
508             goto cleanup;
509         }
510
511         bytes -= cur_bytes;
512         bytes_done += cur_bytes;
513     }
514
515  cleanup:
516     qemu_iovec_destroy(&hd_qiov);
517     qemu_vfree(cipher_data);
518
519     return ret;
520 }
521
522 static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
523 {
524     BlockCrypto *crypto = bs->opaque;
525     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
526     bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
527 }
528
529
530 static int64_t block_crypto_getlength(BlockDriverState *bs)
531 {
532     BlockCrypto *crypto = bs->opaque;
533     int64_t len = bdrv_getlength(bs->file->bs);
534
535     uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
536     assert(offset < INT64_MAX);
537     assert(offset < len);
538
539     len -= offset;
540
541     return len;
542 }
543
544
545 static int block_crypto_probe_luks(const uint8_t *buf,
546                                    int buf_size,
547                                    const char *filename) {
548     return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
549                                       buf, buf_size, filename);
550 }
551
552 static int block_crypto_open_luks(BlockDriverState *bs,
553                                   QDict *options,
554                                   int flags,
555                                   Error **errp)
556 {
557     return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
558                                      &block_crypto_runtime_opts_luks,
559                                      bs, options, flags, errp);
560 }
561
562 static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
563                                                          QemuOpts *opts,
564                                                          Error **errp)
565 {
566     return block_crypto_create_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
567                                        filename, opts, errp);
568 }
569
570 static int block_crypto_get_info_luks(BlockDriverState *bs,
571                                       BlockDriverInfo *bdi)
572 {
573     BlockDriverInfo subbdi;
574     int ret;
575
576     ret = bdrv_get_info(bs->file->bs, &subbdi);
577     if (ret != 0) {
578         return ret;
579     }
580
581     bdi->unallocated_blocks_are_zero = false;
582     bdi->cluster_size = subbdi.cluster_size;
583
584     return 0;
585 }
586
587 static ImageInfoSpecific *
588 block_crypto_get_specific_info_luks(BlockDriverState *bs)
589 {
590     BlockCrypto *crypto = bs->opaque;
591     ImageInfoSpecific *spec_info;
592     QCryptoBlockInfo *info;
593
594     info = qcrypto_block_get_info(crypto->block, NULL);
595     if (!info) {
596         return NULL;
597     }
598     if (info->format != Q_CRYPTO_BLOCK_FORMAT_LUKS) {
599         qapi_free_QCryptoBlockInfo(info);
600         return NULL;
601     }
602
603     spec_info = g_new(ImageInfoSpecific, 1);
604     spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
605     spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);
606     *spec_info->u.luks.data = info->u.luks;
607
608     /* Blank out pointers we've just stolen to avoid double free */
609     memset(&info->u.luks, 0, sizeof(info->u.luks));
610
611     qapi_free_QCryptoBlockInfo(info);
612
613     return spec_info;
614 }
615
616 BlockDriver bdrv_crypto_luks = {
617     .format_name        = "luks",
618     .instance_size      = sizeof(BlockCrypto),
619     .bdrv_probe         = block_crypto_probe_luks,
620     .bdrv_open          = block_crypto_open_luks,
621     .bdrv_close         = block_crypto_close,
622     .bdrv_child_perm    = bdrv_format_default_perms,
623     .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
624     .bdrv_truncate      = block_crypto_truncate,
625     .create_opts        = &block_crypto_create_opts_luks,
626
627     .bdrv_reopen_prepare = block_crypto_reopen_prepare,
628     .bdrv_refresh_limits = block_crypto_refresh_limits,
629     .bdrv_co_preadv     = block_crypto_co_preadv,
630     .bdrv_co_pwritev    = block_crypto_co_pwritev,
631     .bdrv_getlength     = block_crypto_getlength,
632     .bdrv_get_info      = block_crypto_get_info_luks,
633     .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
634 };
635
636 static void block_crypto_init(void)
637 {
638     bdrv_register(&bdrv_crypto_luks);
639 }
640
641 block_init(block_crypto_init);
This page took 0.058232 seconds and 4 git commands to generate.