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