xref: /openbmc/qemu/block/crypto.c (revision d0112eb4)
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.1 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 "block/qdict.h"
25 #include "sysemu/block-backend.h"
26 #include "crypto/block.h"
27 #include "qapi/opts-visitor.h"
28 #include "qapi/qapi-visit-crypto.h"
29 #include "qapi/qobject-input-visitor.h"
30 #include "qapi/error.h"
31 #include "qemu/module.h"
32 #include "qemu/option.h"
33 #include "qemu/cutils.h"
34 #include "qemu/memalign.h"
35 #include "crypto.h"
36 
37 typedef struct BlockCrypto BlockCrypto;
38 
39 struct BlockCrypto {
40     QCryptoBlock *block;
41     bool updating_keys;
42     BdrvChild *header;  /* Reference to the detached LUKS header */
43 };
44 
45 
46 static int block_crypto_probe_generic(QCryptoBlockFormat format,
47                                       const uint8_t *buf,
48                                       int buf_size,
49                                       const char *filename)
50 {
51     if (qcrypto_block_has_format(format, buf, buf_size)) {
52         return 100;
53     } else {
54         return 0;
55     }
56 }
57 
58 
59 static int block_crypto_read_func(QCryptoBlock *block,
60                                   size_t offset,
61                                   uint8_t *buf,
62                                   size_t buflen,
63                                   void *opaque,
64                                   Error **errp)
65 {
66     BlockDriverState *bs = opaque;
67     BlockCrypto *crypto = bs->opaque;
68     ssize_t ret;
69 
70     GLOBAL_STATE_CODE();
71     GRAPH_RDLOCK_GUARD_MAINLOOP();
72 
73     ret = bdrv_pread(crypto->header ? crypto->header : bs->file,
74                      offset, buflen, buf, 0);
75     if (ret < 0) {
76         error_setg_errno(errp, -ret, "Could not read encryption header");
77         return ret;
78     }
79     return 0;
80 }
81 
82 static int block_crypto_write_func(QCryptoBlock *block,
83                                    size_t offset,
84                                    const uint8_t *buf,
85                                    size_t buflen,
86                                    void *opaque,
87                                    Error **errp)
88 {
89     BlockDriverState *bs = opaque;
90     BlockCrypto *crypto = bs->opaque;
91     ssize_t ret;
92 
93     GLOBAL_STATE_CODE();
94     GRAPH_RDLOCK_GUARD_MAINLOOP();
95 
96     ret = bdrv_pwrite(crypto->header ? crypto->header : bs->file,
97                       offset, buflen, buf, 0);
98     if (ret < 0) {
99         error_setg_errno(errp, -ret, "Could not write encryption header");
100         return ret;
101     }
102     return 0;
103 }
104 
105 
106 struct BlockCryptoCreateData {
107     BlockBackend *blk;
108     uint64_t size;
109     PreallocMode prealloc;
110 };
111 
112 
113 static int coroutine_fn GRAPH_UNLOCKED
114 block_crypto_create_write_func(QCryptoBlock *block, size_t offset,
115                                const uint8_t *buf, size_t buflen, void *opaque,
116                                Error **errp)
117 {
118     struct BlockCryptoCreateData *data = opaque;
119     ssize_t ret;
120 
121     ret = blk_pwrite(data->blk, offset, buflen, buf, 0);
122     if (ret < 0) {
123         error_setg_errno(errp, -ret, "Could not write encryption header");
124         return ret;
125     }
126     return 0;
127 }
128 
129 static int coroutine_fn GRAPH_UNLOCKED
130 block_crypto_create_init_func(QCryptoBlock *block, size_t headerlen,
131                               void *opaque, Error **errp)
132 {
133     struct BlockCryptoCreateData *data = opaque;
134     Error *local_error = NULL;
135     int ret;
136 
137     if (data->size > INT64_MAX || headerlen > INT64_MAX - data->size) {
138         ret = -EFBIG;
139         goto error;
140     }
141 
142     /* User provided size should reflect amount of space made
143      * available to the guest, so we must take account of that
144      * which will be used by the crypto header
145      */
146     ret = blk_truncate(data->blk, data->size + headerlen, false,
147                        data->prealloc, 0, &local_error);
148 
149     if (ret >= 0) {
150         return 0;
151     }
152 
153 error:
154     if (ret == -EFBIG) {
155         /* Replace the error message with a better one */
156         error_free(local_error);
157         error_setg(errp, "The requested file size is too large");
158     } else {
159         error_propagate(errp, local_error);
160     }
161 
162     return ret;
163 }
164 
165 static int coroutine_fn GRAPH_UNLOCKED
166 block_crypto_co_format_luks_payload(BlockdevCreateOptionsLUKS *luks_opts,
167                                     Error **errp)
168 {
169     BlockDriverState *bs = NULL;
170     BlockBackend *blk = NULL;
171     Error *local_error = NULL;
172     int ret;
173 
174     if (luks_opts->size > INT64_MAX) {
175         return -EFBIG;
176     }
177 
178     bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
179     if (bs == NULL) {
180         return -EIO;
181     }
182 
183     blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE,
184                              BLK_PERM_ALL, errp);
185     if (!blk) {
186         ret = -EPERM;
187         goto fail;
188     }
189 
190     ret = blk_truncate(blk, luks_opts->size, true,
191                        luks_opts->preallocation, 0, &local_error);
192     if (ret < 0) {
193         if (ret == -EFBIG) {
194             /* Replace the error message with a better one */
195             error_free(local_error);
196             error_setg(errp, "The requested file size is too large");
197         }
198         goto fail;
199     }
200 
201     ret = 0;
202 
203 fail:
204     bdrv_co_unref(bs);
205     return ret;
206 }
207 
208 static QemuOptsList block_crypto_runtime_opts_luks = {
209     .name = "crypto",
210     .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
211     .desc = {
212         BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
213         { /* end of list */ }
214     },
215 };
216 
217 
218 static QemuOptsList block_crypto_create_opts_luks = {
219     .name = "crypto",
220     .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
221     .desc = {
222         {
223             .name = BLOCK_OPT_SIZE,
224             .type = QEMU_OPT_SIZE,
225             .help = "Virtual disk size"
226         },
227         BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
228         BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
229         BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
230         BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
231         BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
232         BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
233         BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
234         { /* end of list */ }
235     },
236 };
237 
238 
239 static QemuOptsList block_crypto_amend_opts_luks = {
240     .name = "crypto",
241     .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
242     .desc = {
243         BLOCK_CRYPTO_OPT_DEF_LUKS_STATE(""),
244         BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(""),
245         BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET(""),
246         BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET(""),
247         BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
248         { /* end of list */ }
249     },
250 };
251 
252 QCryptoBlockOpenOptions *
253 block_crypto_open_opts_init(QDict *opts, Error **errp)
254 {
255     Visitor *v;
256     QCryptoBlockOpenOptions *ret;
257 
258     v = qobject_input_visitor_new_flat_confused(opts, errp);
259     if (!v) {
260         return NULL;
261     }
262 
263     visit_type_QCryptoBlockOpenOptions(v, NULL, &ret, errp);
264 
265     visit_free(v);
266     return ret;
267 }
268 
269 
270 QCryptoBlockCreateOptions *
271 block_crypto_create_opts_init(QDict *opts, Error **errp)
272 {
273     Visitor *v;
274     QCryptoBlockCreateOptions *ret;
275 
276     v = qobject_input_visitor_new_flat_confused(opts, errp);
277     if (!v) {
278         return NULL;
279     }
280 
281     visit_type_QCryptoBlockCreateOptions(v, NULL, &ret, errp);
282 
283     visit_free(v);
284     return ret;
285 }
286 
287 QCryptoBlockAmendOptions *
288 block_crypto_amend_opts_init(QDict *opts, Error **errp)
289 {
290     Visitor *v;
291     QCryptoBlockAmendOptions *ret;
292 
293     v = qobject_input_visitor_new_flat_confused(opts, errp);
294     if (!v) {
295         return NULL;
296     }
297 
298     visit_type_QCryptoBlockAmendOptions(v, NULL, &ret, errp);
299 
300     visit_free(v);
301     return ret;
302 }
303 
304 
305 static int block_crypto_open_generic(QCryptoBlockFormat format,
306                                      QemuOptsList *opts_spec,
307                                      BlockDriverState *bs,
308                                      QDict *options,
309                                      int flags,
310                                      Error **errp)
311 {
312     ERRP_GUARD();
313 
314     BlockCrypto *crypto = bs->opaque;
315     QemuOpts *opts = NULL;
316     int ret;
317     QCryptoBlockOpenOptions *open_opts = NULL;
318     unsigned int cflags = 0;
319     QDict *cryptoopts = NULL;
320 
321     GLOBAL_STATE_CODE();
322 
323     ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
324     if (ret < 0) {
325         return ret;
326     }
327 
328     crypto->header = bdrv_open_child(NULL, options, "header", bs,
329                                      &child_of_bds, BDRV_CHILD_METADATA,
330                                      true, errp);
331     if (*errp != NULL) {
332         return -EINVAL;
333     }
334 
335     GRAPH_RDLOCK_GUARD_MAINLOOP();
336 
337     bs->supported_write_flags = BDRV_REQ_FUA &
338         bs->file->bs->supported_write_flags;
339 
340     opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
341     if (!qemu_opts_absorb_qdict(opts, options, errp)) {
342         ret = -EINVAL;
343         goto cleanup;
344     }
345 
346     cryptoopts = qemu_opts_to_qdict(opts, NULL);
347     qdict_put_str(cryptoopts, "format", QCryptoBlockFormat_str(format));
348 
349     open_opts = block_crypto_open_opts_init(cryptoopts, errp);
350     if (!open_opts) {
351         ret = -EINVAL;
352         goto cleanup;
353     }
354 
355     if (flags & BDRV_O_NO_IO) {
356         cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
357     }
358     if (crypto->header != NULL) {
359         cflags |= QCRYPTO_BLOCK_OPEN_DETACHED;
360     }
361     crypto->block = qcrypto_block_open(open_opts, NULL,
362                                        block_crypto_read_func,
363                                        bs,
364                                        cflags,
365                                        1,
366                                        errp);
367 
368     if (!crypto->block) {
369         ret = -EIO;
370         goto cleanup;
371     }
372 
373     bs->encrypted = true;
374 
375     ret = 0;
376  cleanup:
377     qobject_unref(cryptoopts);
378     qapi_free_QCryptoBlockOpenOptions(open_opts);
379     return ret;
380 }
381 
382 
383 static int coroutine_fn GRAPH_UNLOCKED
384 block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
385                                QCryptoBlockCreateOptions *opts,
386                                PreallocMode prealloc,
387                                unsigned int flags,
388                                Error **errp)
389 {
390     int ret;
391     BlockBackend *blk;
392     QCryptoBlock *crypto = NULL;
393     struct BlockCryptoCreateData data;
394 
395     blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
396                              errp);
397     if (!blk) {
398         ret = -EPERM;
399         goto cleanup;
400     }
401 
402     if (prealloc == PREALLOC_MODE_METADATA) {
403         prealloc = PREALLOC_MODE_OFF;
404     }
405 
406     data = (struct BlockCryptoCreateData) {
407         .blk = blk,
408         .size = size,
409         .prealloc = prealloc,
410     };
411 
412     crypto = qcrypto_block_create(opts, NULL,
413                                   block_crypto_create_init_func,
414                                   block_crypto_create_write_func,
415                                   &data,
416                                   flags,
417                                   errp);
418 
419     if (!crypto) {
420         ret = -EIO;
421         goto cleanup;
422     }
423 
424     ret = 0;
425  cleanup:
426     qcrypto_block_free(crypto);
427     blk_co_unref(blk);
428     return ret;
429 }
430 
431 static int coroutine_fn GRAPH_RDLOCK
432 block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
433                          PreallocMode prealloc, BdrvRequestFlags flags,
434                          Error **errp)
435 {
436     BlockCrypto *crypto = bs->opaque;
437     uint64_t payload_offset =
438         qcrypto_block_get_payload_offset(crypto->block);
439 
440     if (payload_offset > INT64_MAX - offset) {
441         error_setg(errp, "The requested file size is too large");
442         return -EFBIG;
443     }
444 
445     offset += payload_offset;
446 
447     return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
448 }
449 
450 static void block_crypto_close(BlockDriverState *bs)
451 {
452     BlockCrypto *crypto = bs->opaque;
453     qcrypto_block_free(crypto->block);
454 }
455 
456 static int block_crypto_reopen_prepare(BDRVReopenState *state,
457                                        BlockReopenQueue *queue, Error **errp)
458 {
459     /* nothing needs checking */
460     return 0;
461 }
462 
463 /*
464  * 1 MB bounce buffer gives good performance / memory tradeoff
465  * when using cache=none|directsync.
466  */
467 #define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
468 
469 static int coroutine_fn GRAPH_RDLOCK
470 block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
471                        QEMUIOVector *qiov, BdrvRequestFlags flags)
472 {
473     BlockCrypto *crypto = bs->opaque;
474     uint64_t cur_bytes; /* number of bytes in current iteration */
475     uint64_t bytes_done = 0;
476     uint8_t *cipher_data = NULL;
477     QEMUIOVector hd_qiov;
478     int ret = 0;
479     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
480     uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
481 
482     assert(payload_offset < INT64_MAX);
483     assert(QEMU_IS_ALIGNED(offset, sector_size));
484     assert(QEMU_IS_ALIGNED(bytes, sector_size));
485 
486     qemu_iovec_init(&hd_qiov, qiov->niov);
487 
488     /* Bounce buffer because we don't wish to expose cipher text
489      * in qiov which points to guest memory.
490      */
491     cipher_data =
492         qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
493                                               qiov->size));
494     if (cipher_data == NULL) {
495         ret = -ENOMEM;
496         goto cleanup;
497     }
498 
499     while (bytes) {
500         cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
501 
502         qemu_iovec_reset(&hd_qiov);
503         qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
504 
505         ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
506                              cur_bytes, &hd_qiov, 0);
507         if (ret < 0) {
508             goto cleanup;
509         }
510 
511         if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
512                                   cipher_data, cur_bytes, NULL) < 0) {
513             ret = -EIO;
514             goto cleanup;
515         }
516 
517         qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
518 
519         bytes -= cur_bytes;
520         bytes_done += cur_bytes;
521     }
522 
523  cleanup:
524     qemu_iovec_destroy(&hd_qiov);
525     qemu_vfree(cipher_data);
526 
527     return ret;
528 }
529 
530 
531 static int coroutine_fn GRAPH_RDLOCK
532 block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
533                         QEMUIOVector *qiov, BdrvRequestFlags flags)
534 {
535     BlockCrypto *crypto = bs->opaque;
536     uint64_t cur_bytes; /* number of bytes in current iteration */
537     uint64_t bytes_done = 0;
538     uint8_t *cipher_data = NULL;
539     QEMUIOVector hd_qiov;
540     int ret = 0;
541     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
542     uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
543 
544     flags &= ~BDRV_REQ_REGISTERED_BUF;
545 
546     assert(payload_offset < INT64_MAX);
547     assert(QEMU_IS_ALIGNED(offset, sector_size));
548     assert(QEMU_IS_ALIGNED(bytes, sector_size));
549 
550     qemu_iovec_init(&hd_qiov, qiov->niov);
551 
552     /* Bounce buffer because we're not permitted to touch
553      * contents of qiov - it points to guest memory.
554      */
555     cipher_data =
556         qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
557                                               qiov->size));
558     if (cipher_data == NULL) {
559         ret = -ENOMEM;
560         goto cleanup;
561     }
562 
563     while (bytes) {
564         cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
565 
566         qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
567 
568         if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
569                                   cipher_data, cur_bytes, NULL) < 0) {
570             ret = -EIO;
571             goto cleanup;
572         }
573 
574         qemu_iovec_reset(&hd_qiov);
575         qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
576 
577         ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
578                               cur_bytes, &hd_qiov, flags);
579         if (ret < 0) {
580             goto cleanup;
581         }
582 
583         bytes -= cur_bytes;
584         bytes_done += cur_bytes;
585     }
586 
587  cleanup:
588     qemu_iovec_destroy(&hd_qiov);
589     qemu_vfree(cipher_data);
590 
591     return ret;
592 }
593 
594 static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
595 {
596     BlockCrypto *crypto = bs->opaque;
597     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
598     bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
599 }
600 
601 
602 static int64_t coroutine_fn GRAPH_RDLOCK
603 block_crypto_co_getlength(BlockDriverState *bs)
604 {
605     BlockCrypto *crypto = bs->opaque;
606     int64_t len = bdrv_co_getlength(bs->file->bs);
607 
608     uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
609     assert(offset < INT64_MAX);
610 
611     if (offset > len) {
612         return -EIO;
613     }
614 
615     len -= offset;
616 
617     return len;
618 }
619 
620 
621 static BlockMeasureInfo *block_crypto_measure(QemuOpts *opts,
622                                               BlockDriverState *in_bs,
623                                               Error **errp)
624 {
625     g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
626     Error *local_err = NULL;
627     BlockMeasureInfo *info;
628     uint64_t size;
629     size_t luks_payload_size;
630     QDict *cryptoopts;
631 
632     /*
633      * Preallocation mode doesn't affect size requirements but we must consume
634      * the option.
635      */
636     g_free(qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC));
637 
638     size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
639 
640     if (in_bs) {
641         int64_t ssize = bdrv_getlength(in_bs);
642 
643         if (ssize < 0) {
644             error_setg_errno(&local_err, -ssize,
645                              "Unable to get image virtual_size");
646             goto err;
647         }
648 
649         size = ssize;
650     }
651 
652     cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
653             &block_crypto_create_opts_luks, true);
654     qdict_put_str(cryptoopts, "format", "luks");
655     create_opts = block_crypto_create_opts_init(cryptoopts, &local_err);
656     qobject_unref(cryptoopts);
657     if (!create_opts) {
658         goto err;
659     }
660 
661     if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
662                                                 &luks_payload_size,
663                                                 &local_err)) {
664         goto err;
665     }
666 
667     /*
668      * Unallocated blocks are still encrypted so allocation status makes no
669      * difference to the file size.
670      */
671     info = g_new0(BlockMeasureInfo, 1);
672     info->fully_allocated = luks_payload_size + size;
673     info->required = luks_payload_size + size;
674     return info;
675 
676 err:
677     error_propagate(errp, local_err);
678     return NULL;
679 }
680 
681 
682 static int block_crypto_probe_luks(const uint8_t *buf,
683                                    int buf_size,
684                                    const char *filename) {
685     return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
686                                       buf, buf_size, filename);
687 }
688 
689 static int block_crypto_open_luks(BlockDriverState *bs,
690                                   QDict *options,
691                                   int flags,
692                                   Error **errp)
693 {
694     return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
695                                      &block_crypto_runtime_opts_luks,
696                                      bs, options, flags, errp);
697 }
698 
699 static int coroutine_fn GRAPH_UNLOCKED
700 block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
701 {
702     BlockdevCreateOptionsLUKS *luks_opts;
703     BlockDriverState *hdr_bs = NULL;
704     BlockDriverState *bs = NULL;
705     QCryptoBlockCreateOptions create_opts;
706     PreallocMode preallocation = PREALLOC_MODE_OFF;
707     unsigned int cflags = 0;
708     int ret;
709 
710     assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
711     luks_opts = &create_options->u.luks;
712 
713     if (luks_opts->header == NULL && luks_opts->file == NULL) {
714         error_setg(errp, "Either the parameter 'header' or 'file' must "
715                    "be specified");
716         return -EINVAL;
717     }
718 
719     if ((luks_opts->preallocation != PREALLOC_MODE_OFF) &&
720         (luks_opts->file == NULL)) {
721         error_setg(errp, "Parameter 'preallocation' requires 'file' to be "
722                    "specified for formatting LUKS disk");
723         return -EINVAL;
724     }
725 
726     create_opts = (QCryptoBlockCreateOptions) {
727         .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
728         .u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts),
729     };
730 
731     if (luks_opts->has_preallocation) {
732         preallocation = luks_opts->preallocation;
733     }
734 
735     if (luks_opts->header) {
736         /* LUKS volume with detached header */
737         hdr_bs = bdrv_co_open_blockdev_ref(luks_opts->header, errp);
738         if (hdr_bs == NULL) {
739             return -EIO;
740         }
741 
742         cflags |= QCRYPTO_BLOCK_CREATE_DETACHED;
743 
744         /* Format the LUKS header node */
745         ret = block_crypto_co_create_generic(hdr_bs, 0, &create_opts,
746                                              PREALLOC_MODE_OFF, cflags, errp);
747         if (ret < 0) {
748             goto fail;
749         }
750 
751         /* Format the LUKS payload node */
752         if (luks_opts->file) {
753             ret = block_crypto_co_format_luks_payload(luks_opts, errp);
754             if (ret < 0) {
755                 goto fail;
756             }
757         }
758     } else if (luks_opts->file) {
759         /* LUKS volume with none-detached header */
760         bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
761         if (bs == NULL) {
762             return -EIO;
763         }
764 
765         ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
766                                              preallocation, cflags, errp);
767         if (ret < 0) {
768             goto fail;
769         }
770     }
771 
772     ret = 0;
773 fail:
774     if (hdr_bs != NULL) {
775         bdrv_co_unref(hdr_bs);
776     }
777 
778     if (bs != NULL) {
779         bdrv_co_unref(bs);
780     }
781     return ret;
782 }
783 
784 static int coroutine_fn GRAPH_UNLOCKED
785 block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
786                                  QemuOpts *opts, Error **errp)
787 {
788     QCryptoBlockCreateOptions *create_opts = NULL;
789     BlockDriverState *bs = NULL;
790     QDict *cryptoopts;
791     PreallocMode prealloc;
792     char *buf = NULL;
793     int64_t size;
794     int ret;
795     Error *local_err = NULL;
796 
797     /* Parse options */
798     size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
799 
800     buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
801     prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
802                                PREALLOC_MODE_OFF, &local_err);
803     g_free(buf);
804     if (local_err) {
805         error_propagate(errp, local_err);
806         return -EINVAL;
807     }
808 
809     cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
810                                              &block_crypto_create_opts_luks,
811                                              true);
812 
813     qdict_put_str(cryptoopts, "format", "luks");
814     create_opts = block_crypto_create_opts_init(cryptoopts, errp);
815     if (!create_opts) {
816         ret = -EINVAL;
817         goto fail;
818     }
819 
820     /* Create protocol layer */
821     ret = bdrv_co_create_file(filename, opts, errp);
822     if (ret < 0) {
823         goto fail;
824     }
825 
826     bs = bdrv_co_open(filename, NULL, NULL,
827                       BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
828     if (!bs) {
829         ret = -EINVAL;
830         goto fail;
831     }
832 
833     /* Create format layer */
834     ret = block_crypto_co_create_generic(bs, size, create_opts,
835                                          prealloc, 0, errp);
836     if (ret < 0) {
837         goto fail;
838     }
839 
840     ret = 0;
841 fail:
842     /*
843      * If an error occurred, delete 'filename'. Even if the file existed
844      * beforehand, it has been truncated and corrupted in the process.
845      */
846     if (ret) {
847         bdrv_graph_co_rdlock();
848         bdrv_co_delete_file_noerr(bs);
849         bdrv_graph_co_rdunlock();
850     }
851 
852     bdrv_co_unref(bs);
853     qapi_free_QCryptoBlockCreateOptions(create_opts);
854     qobject_unref(cryptoopts);
855     return ret;
856 }
857 
858 static int coroutine_fn GRAPH_RDLOCK
859 block_crypto_co_get_info_luks(BlockDriverState *bs, BlockDriverInfo *bdi)
860 {
861     BlockDriverInfo subbdi;
862     int ret;
863 
864     ret = bdrv_co_get_info(bs->file->bs, &subbdi);
865     if (ret != 0) {
866         return ret;
867     }
868 
869     bdi->cluster_size = subbdi.cluster_size;
870 
871     return 0;
872 }
873 
874 static ImageInfoSpecific *
875 block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
876 {
877     BlockCrypto *crypto = bs->opaque;
878     ImageInfoSpecific *spec_info;
879     QCryptoBlockInfo *info;
880 
881     info = qcrypto_block_get_info(crypto->block, errp);
882     if (!info) {
883         return NULL;
884     }
885     assert(info->format == Q_CRYPTO_BLOCK_FORMAT_LUKS);
886 
887     spec_info = g_new(ImageInfoSpecific, 1);
888     spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
889     spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);
890     *spec_info->u.luks.data = info->u.luks;
891 
892     /* Blank out pointers we've just stolen to avoid double free */
893     memset(&info->u.luks, 0, sizeof(info->u.luks));
894 
895     qapi_free_QCryptoBlockInfo(info);
896 
897     return spec_info;
898 }
899 
900 static int GRAPH_RDLOCK
901 block_crypto_amend_prepare(BlockDriverState *bs, Error **errp)
902 {
903     BlockCrypto *crypto = bs->opaque;
904     int ret;
905 
906     /* apply for exclusive read/write permissions to the underlying file */
907     crypto->updating_keys = true;
908     ret = bdrv_child_refresh_perms(bs, bs->file, errp);
909     if (ret < 0) {
910         /* Well, in this case we will not be updating any keys */
911         crypto->updating_keys = false;
912     }
913     return ret;
914 }
915 
916 static void GRAPH_RDLOCK
917 block_crypto_amend_cleanup(BlockDriverState *bs)
918 {
919     BlockCrypto *crypto = bs->opaque;
920     Error *errp = NULL;
921 
922     /* release exclusive read/write permissions to the underlying file */
923     crypto->updating_keys = false;
924     bdrv_child_refresh_perms(bs, bs->file, &errp);
925 
926     if (errp) {
927         error_report_err(errp);
928     }
929 }
930 
931 static int
932 block_crypto_amend_options_generic_luks(BlockDriverState *bs,
933                                         QCryptoBlockAmendOptions *amend_options,
934                                         bool force,
935                                         Error **errp)
936 {
937     BlockCrypto *crypto = bs->opaque;
938 
939     assert(crypto);
940     assert(crypto->block);
941 
942     return qcrypto_block_amend_options(crypto->block,
943                                        block_crypto_read_func,
944                                        block_crypto_write_func,
945                                        bs,
946                                        amend_options,
947                                        force,
948                                        errp);
949 }
950 
951 static int GRAPH_RDLOCK
952 block_crypto_amend_options_luks(BlockDriverState *bs,
953                                 QemuOpts *opts,
954                                 BlockDriverAmendStatusCB *status_cb,
955                                 void *cb_opaque,
956                                 bool force,
957                                 Error **errp)
958 {
959     BlockCrypto *crypto = bs->opaque;
960     QDict *cryptoopts = NULL;
961     QCryptoBlockAmendOptions *amend_options = NULL;
962     int ret = -EINVAL;
963 
964     assert(crypto);
965     assert(crypto->block);
966 
967     cryptoopts = qemu_opts_to_qdict(opts, NULL);
968     qdict_put_str(cryptoopts, "format", "luks");
969     amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
970     qobject_unref(cryptoopts);
971     if (!amend_options) {
972         goto cleanup;
973     }
974 
975     ret = block_crypto_amend_prepare(bs, errp);
976     if (ret) {
977         goto perm_cleanup;
978     }
979     ret = block_crypto_amend_options_generic_luks(bs, amend_options,
980                                                   force, errp);
981 
982 perm_cleanup:
983     block_crypto_amend_cleanup(bs);
984 cleanup:
985     qapi_free_QCryptoBlockAmendOptions(amend_options);
986     return ret;
987 }
988 
989 static int
990 coroutine_fn block_crypto_co_amend_luks(BlockDriverState *bs,
991                                         BlockdevAmendOptions *opts,
992                                         bool force,
993                                         Error **errp)
994 {
995     QCryptoBlockAmendOptions amend_opts;
996 
997     amend_opts = (QCryptoBlockAmendOptions) {
998         .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
999         .u.luks = *qapi_BlockdevAmendOptionsLUKS_base(&opts->u.luks),
1000     };
1001     return block_crypto_amend_options_generic_luks(bs, &amend_opts,
1002                                                    force, errp);
1003 }
1004 
1005 static void
1006 block_crypto_child_perms(BlockDriverState *bs, BdrvChild *c,
1007                          const BdrvChildRole role,
1008                          BlockReopenQueue *reopen_queue,
1009                          uint64_t perm, uint64_t shared,
1010                          uint64_t *nperm, uint64_t *nshared)
1011 {
1012 
1013     BlockCrypto *crypto = bs->opaque;
1014 
1015     bdrv_default_perms(bs, c, role, reopen_queue, perm, shared, nperm, nshared);
1016 
1017     /*
1018      * For backward compatibility, manually share the write
1019      * and resize permission
1020      */
1021     *nshared |= shared & (BLK_PERM_WRITE | BLK_PERM_RESIZE);
1022     /*
1023      * Since we are not fully a format driver, don't always request
1024      * the read/resize permission but only when explicitly
1025      * requested
1026      */
1027     *nperm &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
1028     *nperm |= perm & (BLK_PERM_WRITE | BLK_PERM_RESIZE);
1029 
1030     /*
1031      * This driver doesn't modify LUKS metadata except
1032      * when updating the encryption slots.
1033      * Thus unlike a proper format driver we don't ask for
1034      * shared write/read permission. However we need it
1035      * when we are updating the keys, to ensure that only we
1036      * have access to the device.
1037      *
1038      * Encryption update will set the crypto->updating_keys
1039      * during that period and refresh permissions
1040      *
1041      */
1042     if (crypto->updating_keys) {
1043         /* need exclusive write access for header update */
1044         *nperm |= BLK_PERM_WRITE;
1045         /* unshare read and write permission */
1046         *nshared &= ~(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE);
1047     }
1048 }
1049 
1050 
1051 static const char *const block_crypto_strong_runtime_opts[] = {
1052     BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
1053 
1054     NULL
1055 };
1056 
1057 static BlockDriver bdrv_crypto_luks = {
1058     .format_name        = "luks",
1059     .instance_size      = sizeof(BlockCrypto),
1060     .bdrv_probe         = block_crypto_probe_luks,
1061     .bdrv_open          = block_crypto_open_luks,
1062     .bdrv_close         = block_crypto_close,
1063     .bdrv_child_perm    = block_crypto_child_perms,
1064     .bdrv_co_create     = block_crypto_co_create_luks,
1065     .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
1066     .bdrv_co_truncate   = block_crypto_co_truncate,
1067     .create_opts        = &block_crypto_create_opts_luks,
1068     .amend_opts         = &block_crypto_amend_opts_luks,
1069 
1070     .bdrv_reopen_prepare = block_crypto_reopen_prepare,
1071     .bdrv_refresh_limits = block_crypto_refresh_limits,
1072     .bdrv_co_preadv     = block_crypto_co_preadv,
1073     .bdrv_co_pwritev    = block_crypto_co_pwritev,
1074     .bdrv_co_getlength  = block_crypto_co_getlength,
1075     .bdrv_measure       = block_crypto_measure,
1076     .bdrv_co_get_info   = block_crypto_co_get_info_luks,
1077     .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
1078     .bdrv_amend_options = block_crypto_amend_options_luks,
1079     .bdrv_co_amend      = block_crypto_co_amend_luks,
1080     .bdrv_amend_pre_run = block_crypto_amend_prepare,
1081     .bdrv_amend_clean   = block_crypto_amend_cleanup,
1082 
1083     .is_format          = true,
1084 
1085     .strong_runtime_opts = block_crypto_strong_runtime_opts,
1086 };
1087 
1088 static void block_crypto_init(void)
1089 {
1090     bdrv_register(&bdrv_crypto_luks);
1091 }
1092 
1093 block_init(block_crypto_init);
1094