xref: /openbmc/qemu/block/crypto.c (revision 3a37f239)
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 "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 "crypto.h"
35 
36 typedef struct BlockCrypto BlockCrypto;
37 
38 struct BlockCrypto {
39     QCryptoBlock *block;
40 };
41 
42 
43 static int block_crypto_probe_generic(QCryptoBlockFormat format,
44                                       const uint8_t *buf,
45                                       int buf_size,
46                                       const char *filename)
47 {
48     if (qcrypto_block_has_format(format, buf, buf_size)) {
49         return 100;
50     } else {
51         return 0;
52     }
53 }
54 
55 
56 static ssize_t block_crypto_read_func(QCryptoBlock *block,
57                                       size_t offset,
58                                       uint8_t *buf,
59                                       size_t buflen,
60                                       void *opaque,
61                                       Error **errp)
62 {
63     BlockDriverState *bs = opaque;
64     ssize_t ret;
65 
66     ret = bdrv_pread(bs->file, offset, buf, buflen);
67     if (ret < 0) {
68         error_setg_errno(errp, -ret, "Could not read encryption header");
69         return ret;
70     }
71     return ret;
72 }
73 
74 
75 struct BlockCryptoCreateData {
76     BlockBackend *blk;
77     uint64_t size;
78     PreallocMode prealloc;
79 };
80 
81 
82 static ssize_t 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     struct BlockCryptoCreateData *data = opaque;
90     ssize_t ret;
91 
92     ret = blk_pwrite(data->blk, offset, buf, buflen, 0);
93     if (ret < 0) {
94         error_setg_errno(errp, -ret, "Could not write encryption header");
95         return ret;
96     }
97     return ret;
98 }
99 
100 
101 static ssize_t block_crypto_init_func(QCryptoBlock *block,
102                                       size_t headerlen,
103                                       void *opaque,
104                                       Error **errp)
105 {
106     struct BlockCryptoCreateData *data = opaque;
107     Error *local_error = NULL;
108     int ret;
109 
110     if (data->size > INT64_MAX || headerlen > INT64_MAX - data->size) {
111         ret = -EFBIG;
112         goto error;
113     }
114 
115     /* User provided size should reflect amount of space made
116      * available to the guest, so we must take account of that
117      * which will be used by the crypto header
118      */
119     ret = blk_truncate(data->blk, data->size + headerlen, false,
120                        data->prealloc, 0, &local_error);
121 
122     if (ret >= 0) {
123         return ret;
124     }
125 
126 error:
127     if (ret == -EFBIG) {
128         /* Replace the error message with a better one */
129         error_free(local_error);
130         error_setg(errp, "The requested file size is too large");
131     } else {
132         error_propagate(errp, local_error);
133     }
134 
135     return ret;
136 }
137 
138 
139 static QemuOptsList block_crypto_runtime_opts_luks = {
140     .name = "crypto",
141     .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
142     .desc = {
143         BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
144         { /* end of list */ }
145     },
146 };
147 
148 
149 static QemuOptsList block_crypto_create_opts_luks = {
150     .name = "crypto",
151     .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
152     .desc = {
153         {
154             .name = BLOCK_OPT_SIZE,
155             .type = QEMU_OPT_SIZE,
156             .help = "Virtual disk size"
157         },
158         BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
159         BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
160         BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
161         BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
162         BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
163         BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
164         BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
165         { /* end of list */ }
166     },
167 };
168 
169 
170 QCryptoBlockOpenOptions *
171 block_crypto_open_opts_init(QDict *opts, Error **errp)
172 {
173     Visitor *v;
174     QCryptoBlockOpenOptions *ret;
175 
176     v = qobject_input_visitor_new_flat_confused(opts, errp);
177     if (!v) {
178         return NULL;
179     }
180 
181     visit_type_QCryptoBlockOpenOptions(v, NULL, &ret, errp);
182 
183     visit_free(v);
184     return ret;
185 }
186 
187 
188 QCryptoBlockCreateOptions *
189 block_crypto_create_opts_init(QDict *opts, Error **errp)
190 {
191     Visitor *v;
192     QCryptoBlockCreateOptions *ret;
193 
194     v = qobject_input_visitor_new_flat_confused(opts, errp);
195     if (!v) {
196         return NULL;
197     }
198 
199     visit_type_QCryptoBlockCreateOptions(v, NULL, &ret, errp);
200 
201     visit_free(v);
202     return ret;
203 }
204 
205 
206 static int block_crypto_open_generic(QCryptoBlockFormat format,
207                                      QemuOptsList *opts_spec,
208                                      BlockDriverState *bs,
209                                      QDict *options,
210                                      int flags,
211                                      Error **errp)
212 {
213     BlockCrypto *crypto = bs->opaque;
214     QemuOpts *opts = NULL;
215     Error *local_err = NULL;
216     int ret = -EINVAL;
217     QCryptoBlockOpenOptions *open_opts = NULL;
218     unsigned int cflags = 0;
219     QDict *cryptoopts = NULL;
220 
221     bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
222                                BDRV_CHILD_IMAGE, false, errp);
223     if (!bs->file) {
224         return -EINVAL;
225     }
226 
227     bs->supported_write_flags = BDRV_REQ_FUA &
228         bs->file->bs->supported_write_flags;
229 
230     opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
231     qemu_opts_absorb_qdict(opts, options, &local_err);
232     if (local_err) {
233         error_propagate(errp, local_err);
234         goto cleanup;
235     }
236 
237     cryptoopts = qemu_opts_to_qdict(opts, NULL);
238     qdict_put_str(cryptoopts, "format", QCryptoBlockFormat_str(format));
239 
240     open_opts = block_crypto_open_opts_init(cryptoopts, errp);
241     if (!open_opts) {
242         goto cleanup;
243     }
244 
245     if (flags & BDRV_O_NO_IO) {
246         cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
247     }
248     crypto->block = qcrypto_block_open(open_opts, NULL,
249                                        block_crypto_read_func,
250                                        bs,
251                                        cflags,
252                                        1,
253                                        errp);
254 
255     if (!crypto->block) {
256         ret = -EIO;
257         goto cleanup;
258     }
259 
260     bs->encrypted = true;
261 
262     ret = 0;
263  cleanup:
264     qobject_unref(cryptoopts);
265     qapi_free_QCryptoBlockOpenOptions(open_opts);
266     return ret;
267 }
268 
269 
270 static int block_crypto_co_create_generic(BlockDriverState *bs,
271                                           int64_t size,
272                                           QCryptoBlockCreateOptions *opts,
273                                           PreallocMode prealloc,
274                                           Error **errp)
275 {
276     int ret;
277     BlockBackend *blk;
278     QCryptoBlock *crypto = NULL;
279     struct BlockCryptoCreateData data;
280 
281     blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
282                           errp);
283     if (!blk) {
284         ret = -EPERM;
285         goto cleanup;
286     }
287 
288     if (prealloc == PREALLOC_MODE_METADATA) {
289         prealloc = PREALLOC_MODE_OFF;
290     }
291 
292     data = (struct BlockCryptoCreateData) {
293         .blk = blk,
294         .size = size,
295         .prealloc = prealloc,
296     };
297 
298     crypto = qcrypto_block_create(opts, NULL,
299                                   block_crypto_init_func,
300                                   block_crypto_write_func,
301                                   &data,
302                                   errp);
303 
304     if (!crypto) {
305         ret = -EIO;
306         goto cleanup;
307     }
308 
309     ret = 0;
310  cleanup:
311     qcrypto_block_free(crypto);
312     blk_unref(blk);
313     return ret;
314 }
315 
316 static int coroutine_fn
317 block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
318                          PreallocMode prealloc, BdrvRequestFlags flags,
319                          Error **errp)
320 {
321     BlockCrypto *crypto = bs->opaque;
322     uint64_t payload_offset =
323         qcrypto_block_get_payload_offset(crypto->block);
324 
325     if (payload_offset > INT64_MAX - offset) {
326         error_setg(errp, "The requested file size is too large");
327         return -EFBIG;
328     }
329 
330     offset += payload_offset;
331 
332     return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
333 }
334 
335 static void block_crypto_close(BlockDriverState *bs)
336 {
337     BlockCrypto *crypto = bs->opaque;
338     qcrypto_block_free(crypto->block);
339 }
340 
341 static int block_crypto_reopen_prepare(BDRVReopenState *state,
342                                        BlockReopenQueue *queue, Error **errp)
343 {
344     /* nothing needs checking */
345     return 0;
346 }
347 
348 /*
349  * 1 MB bounce buffer gives good performance / memory tradeoff
350  * when using cache=none|directsync.
351  */
352 #define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
353 
354 static coroutine_fn int
355 block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
356                        QEMUIOVector *qiov, int flags)
357 {
358     BlockCrypto *crypto = bs->opaque;
359     uint64_t cur_bytes; /* number of bytes in current iteration */
360     uint64_t bytes_done = 0;
361     uint8_t *cipher_data = NULL;
362     QEMUIOVector hd_qiov;
363     int ret = 0;
364     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
365     uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
366 
367     assert(!flags);
368     assert(payload_offset < INT64_MAX);
369     assert(QEMU_IS_ALIGNED(offset, sector_size));
370     assert(QEMU_IS_ALIGNED(bytes, sector_size));
371 
372     qemu_iovec_init(&hd_qiov, qiov->niov);
373 
374     /* Bounce buffer because we don't wish to expose cipher text
375      * in qiov which points to guest memory.
376      */
377     cipher_data =
378         qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
379                                               qiov->size));
380     if (cipher_data == NULL) {
381         ret = -ENOMEM;
382         goto cleanup;
383     }
384 
385     while (bytes) {
386         cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
387 
388         qemu_iovec_reset(&hd_qiov);
389         qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
390 
391         ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
392                              cur_bytes, &hd_qiov, 0);
393         if (ret < 0) {
394             goto cleanup;
395         }
396 
397         if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
398                                   cipher_data, cur_bytes, NULL) < 0) {
399             ret = -EIO;
400             goto cleanup;
401         }
402 
403         qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
404 
405         bytes -= cur_bytes;
406         bytes_done += cur_bytes;
407     }
408 
409  cleanup:
410     qemu_iovec_destroy(&hd_qiov);
411     qemu_vfree(cipher_data);
412 
413     return ret;
414 }
415 
416 
417 static coroutine_fn int
418 block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
419                         QEMUIOVector *qiov, int flags)
420 {
421     BlockCrypto *crypto = bs->opaque;
422     uint64_t cur_bytes; /* number of bytes in current iteration */
423     uint64_t bytes_done = 0;
424     uint8_t *cipher_data = NULL;
425     QEMUIOVector hd_qiov;
426     int ret = 0;
427     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
428     uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
429 
430     assert(!(flags & ~BDRV_REQ_FUA));
431     assert(payload_offset < INT64_MAX);
432     assert(QEMU_IS_ALIGNED(offset, sector_size));
433     assert(QEMU_IS_ALIGNED(bytes, sector_size));
434 
435     qemu_iovec_init(&hd_qiov, qiov->niov);
436 
437     /* Bounce buffer because we're not permitted to touch
438      * contents of qiov - it points to guest memory.
439      */
440     cipher_data =
441         qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
442                                               qiov->size));
443     if (cipher_data == NULL) {
444         ret = -ENOMEM;
445         goto cleanup;
446     }
447 
448     while (bytes) {
449         cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
450 
451         qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
452 
453         if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
454                                   cipher_data, cur_bytes, NULL) < 0) {
455             ret = -EIO;
456             goto cleanup;
457         }
458 
459         qemu_iovec_reset(&hd_qiov);
460         qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
461 
462         ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
463                               cur_bytes, &hd_qiov, flags);
464         if (ret < 0) {
465             goto cleanup;
466         }
467 
468         bytes -= cur_bytes;
469         bytes_done += cur_bytes;
470     }
471 
472  cleanup:
473     qemu_iovec_destroy(&hd_qiov);
474     qemu_vfree(cipher_data);
475 
476     return ret;
477 }
478 
479 static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
480 {
481     BlockCrypto *crypto = bs->opaque;
482     uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
483     bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
484 }
485 
486 
487 static int64_t block_crypto_getlength(BlockDriverState *bs)
488 {
489     BlockCrypto *crypto = bs->opaque;
490     int64_t len = bdrv_getlength(bs->file->bs);
491 
492     uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
493     assert(offset < INT64_MAX);
494 
495     if (offset > len) {
496         return -EIO;
497     }
498 
499     len -= offset;
500 
501     return len;
502 }
503 
504 
505 static BlockMeasureInfo *block_crypto_measure(QemuOpts *opts,
506                                               BlockDriverState *in_bs,
507                                               Error **errp)
508 {
509     g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
510     Error *local_err = NULL;
511     BlockMeasureInfo *info;
512     uint64_t size;
513     size_t luks_payload_size;
514     QDict *cryptoopts;
515 
516     /*
517      * Preallocation mode doesn't affect size requirements but we must consume
518      * the option.
519      */
520     g_free(qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC));
521 
522     size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
523 
524     if (in_bs) {
525         int64_t ssize = bdrv_getlength(in_bs);
526 
527         if (ssize < 0) {
528             error_setg_errno(&local_err, -ssize,
529                              "Unable to get image virtual_size");
530             goto err;
531         }
532 
533         size = ssize;
534     }
535 
536     cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
537             &block_crypto_create_opts_luks, true);
538     qdict_put_str(cryptoopts, "format", "luks");
539     create_opts = block_crypto_create_opts_init(cryptoopts, &local_err);
540     qobject_unref(cryptoopts);
541     if (!create_opts) {
542         goto err;
543     }
544 
545     if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
546                                                 &luks_payload_size,
547                                                 &local_err)) {
548         goto err;
549     }
550 
551     /*
552      * Unallocated blocks are still encrypted so allocation status makes no
553      * difference to the file size.
554      */
555     info = g_new0(BlockMeasureInfo, 1);
556     info->fully_allocated = luks_payload_size + size;
557     info->required = luks_payload_size + size;
558     return info;
559 
560 err:
561     error_propagate(errp, local_err);
562     return NULL;
563 }
564 
565 
566 static int block_crypto_probe_luks(const uint8_t *buf,
567                                    int buf_size,
568                                    const char *filename) {
569     return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
570                                       buf, buf_size, filename);
571 }
572 
573 static int block_crypto_open_luks(BlockDriverState *bs,
574                                   QDict *options,
575                                   int flags,
576                                   Error **errp)
577 {
578     return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
579                                      &block_crypto_runtime_opts_luks,
580                                      bs, options, flags, errp);
581 }
582 
583 static int coroutine_fn
584 block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
585 {
586     BlockdevCreateOptionsLUKS *luks_opts;
587     BlockDriverState *bs = NULL;
588     QCryptoBlockCreateOptions create_opts;
589     PreallocMode preallocation = PREALLOC_MODE_OFF;
590     int ret;
591 
592     assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
593     luks_opts = &create_options->u.luks;
594 
595     bs = bdrv_open_blockdev_ref(luks_opts->file, errp);
596     if (bs == NULL) {
597         return -EIO;
598     }
599 
600     create_opts = (QCryptoBlockCreateOptions) {
601         .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
602         .u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts),
603     };
604 
605     if (luks_opts->has_preallocation) {
606         preallocation = luks_opts->preallocation;
607     }
608 
609     ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
610                                          preallocation, errp);
611     if (ret < 0) {
612         goto fail;
613     }
614 
615     ret = 0;
616 fail:
617     bdrv_unref(bs);
618     return ret;
619 }
620 
621 static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
622                                                          const char *filename,
623                                                          QemuOpts *opts,
624                                                          Error **errp)
625 {
626     QCryptoBlockCreateOptions *create_opts = NULL;
627     BlockDriverState *bs = NULL;
628     QDict *cryptoopts;
629     PreallocMode prealloc;
630     char *buf = NULL;
631     int64_t size;
632     int ret;
633     Error *local_err = NULL;
634 
635     /* Parse options */
636     size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
637 
638     buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
639     prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
640                                PREALLOC_MODE_OFF, &local_err);
641     g_free(buf);
642     if (local_err) {
643         error_propagate(errp, local_err);
644         return -EINVAL;
645     }
646 
647     cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
648                                              &block_crypto_create_opts_luks,
649                                              true);
650 
651     qdict_put_str(cryptoopts, "format", "luks");
652     create_opts = block_crypto_create_opts_init(cryptoopts, errp);
653     if (!create_opts) {
654         ret = -EINVAL;
655         goto fail;
656     }
657 
658     /* Create protocol layer */
659     ret = bdrv_create_file(filename, opts, errp);
660     if (ret < 0) {
661         goto fail;
662     }
663 
664     bs = bdrv_open(filename, NULL, NULL,
665                    BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
666     if (!bs) {
667         ret = -EINVAL;
668         goto fail;
669     }
670 
671     /* Create format layer */
672     ret = block_crypto_co_create_generic(bs, size, create_opts, prealloc, errp);
673     if (ret < 0) {
674         goto fail;
675     }
676 
677     ret = 0;
678 fail:
679     /*
680      * If an error occurred, delete 'filename'. Even if the file existed
681      * beforehand, it has been truncated and corrupted in the process.
682      */
683     if (ret && bs) {
684         Error *local_delete_err = NULL;
685         int r_del = bdrv_co_delete_file(bs, &local_delete_err);
686         /*
687          * ENOTSUP will happen if the block driver doesn't support
688          * the 'bdrv_co_delete_file' interface. This is a predictable
689          * scenario and shouldn't be reported back to the user.
690          */
691         if ((r_del < 0) && (r_del != -ENOTSUP)) {
692             error_report_err(local_delete_err);
693         }
694     }
695 
696     bdrv_unref(bs);
697     qapi_free_QCryptoBlockCreateOptions(create_opts);
698     qobject_unref(cryptoopts);
699     return ret;
700 }
701 
702 static int block_crypto_get_info_luks(BlockDriverState *bs,
703                                       BlockDriverInfo *bdi)
704 {
705     BlockDriverInfo subbdi;
706     int ret;
707 
708     ret = bdrv_get_info(bs->file->bs, &subbdi);
709     if (ret != 0) {
710         return ret;
711     }
712 
713     bdi->unallocated_blocks_are_zero = false;
714     bdi->cluster_size = subbdi.cluster_size;
715 
716     return 0;
717 }
718 
719 static ImageInfoSpecific *
720 block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
721 {
722     BlockCrypto *crypto = bs->opaque;
723     ImageInfoSpecific *spec_info;
724     QCryptoBlockInfo *info;
725 
726     info = qcrypto_block_get_info(crypto->block, errp);
727     if (!info) {
728         return NULL;
729     }
730     assert(info->format == Q_CRYPTO_BLOCK_FORMAT_LUKS);
731 
732     spec_info = g_new(ImageInfoSpecific, 1);
733     spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
734     spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);
735     *spec_info->u.luks.data = info->u.luks;
736 
737     /* Blank out pointers we've just stolen to avoid double free */
738     memset(&info->u.luks, 0, sizeof(info->u.luks));
739 
740     qapi_free_QCryptoBlockInfo(info);
741 
742     return spec_info;
743 }
744 
745 static const char *const block_crypto_strong_runtime_opts[] = {
746     BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
747 
748     NULL
749 };
750 
751 static BlockDriver bdrv_crypto_luks = {
752     .format_name        = "luks",
753     .instance_size      = sizeof(BlockCrypto),
754     .bdrv_probe         = block_crypto_probe_luks,
755     .bdrv_open          = block_crypto_open_luks,
756     .bdrv_close         = block_crypto_close,
757     /* This driver doesn't modify LUKS metadata except when creating image.
758      * Allow share-rw=on as a special case. */
759     .bdrv_child_perm    = bdrv_default_perms,
760     .bdrv_co_create     = block_crypto_co_create_luks,
761     .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
762     .bdrv_co_truncate   = block_crypto_co_truncate,
763     .create_opts        = &block_crypto_create_opts_luks,
764 
765     .bdrv_reopen_prepare = block_crypto_reopen_prepare,
766     .bdrv_refresh_limits = block_crypto_refresh_limits,
767     .bdrv_co_preadv     = block_crypto_co_preadv,
768     .bdrv_co_pwritev    = block_crypto_co_pwritev,
769     .bdrv_getlength     = block_crypto_getlength,
770     .bdrv_measure       = block_crypto_measure,
771     .bdrv_get_info      = block_crypto_get_info_luks,
772     .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
773 
774     .is_format          = true,
775 
776     .strong_runtime_opts = block_crypto_strong_runtime_opts,
777 };
778 
779 static void block_crypto_init(void)
780 {
781     bdrv_register(&bdrv_crypto_luks);
782 }
783 
784 block_init(block_crypto_init);
785