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