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