]> git.proxmox.com Git - mirror_qemu.git/blob - block/crypto.c
luks: Turn invalid assertion into check
[mirror_qemu.git] / block / crypto.c
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 "sysemu/block-backend.h"
25 #include "crypto/block.h"
26 #include "qapi/opts-visitor.h"
27 #include "qapi/qapi-visit-crypto.h"
28 #include "qapi/qmp/qdict.h"
29 #include "qapi/qobject-input-visitor.h"
30 #include "qapi/error.h"
31 #include "qemu/option.h"
32 #include "block/crypto.h"
33
34 typedef struct BlockCrypto BlockCrypto;
35
36 struct BlockCrypto {
37 QCryptoBlock *block;
38 };
39
40
41 static int block_crypto_probe_generic(QCryptoBlockFormat format,
42 const uint8_t *buf,
43 int buf_size,
44 const char *filename)
45 {
46 if (qcrypto_block_has_format(format, buf, buf_size)) {
47 return 100;
48 } else {
49 return 0;
50 }
51 }
52
53
54 static ssize_t block_crypto_read_func(QCryptoBlock *block,
55 size_t offset,
56 uint8_t *buf,
57 size_t buflen,
58 void *opaque,
59 Error **errp)
60 {
61 BlockDriverState *bs = opaque;
62 ssize_t ret;
63
64 ret = bdrv_pread(bs->file, offset, buf, buflen);
65 if (ret < 0) {
66 error_setg_errno(errp, -ret, "Could not read encryption header");
67 return ret;
68 }
69 return ret;
70 }
71
72
73 struct BlockCryptoCreateData {
74 BlockBackend *blk;
75 uint64_t size;
76 };
77
78
79 static ssize_t block_crypto_write_func(QCryptoBlock *block,
80 size_t offset,
81 const uint8_t *buf,
82 size_t buflen,
83 void *opaque,
84 Error **errp)
85 {
86 struct BlockCryptoCreateData *data = opaque;
87 ssize_t ret;
88
89 ret = blk_pwrite(data->blk, offset, buf, buflen, 0);
90 if (ret < 0) {
91 error_setg_errno(errp, -ret, "Could not write encryption header");
92 return ret;
93 }
94 return ret;
95 }
96
97
98 static ssize_t block_crypto_init_func(QCryptoBlock *block,
99 size_t headerlen,
100 void *opaque,
101 Error **errp)
102 {
103 struct BlockCryptoCreateData *data = opaque;
104
105 /* User provided size should reflect amount of space made
106 * available to the guest, so we must take account of that
107 * which will be used by the crypto header
108 */
109 return blk_truncate(data->blk, data->size + headerlen, PREALLOC_MODE_OFF,
110 errp);
111 }
112
113
114 static QemuOptsList block_crypto_runtime_opts_luks = {
115 .name = "crypto",
116 .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
117 .desc = {
118 BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
119 { /* end of list */ }
120 },
121 };
122
123
124 static QemuOptsList block_crypto_create_opts_luks = {
125 .name = "crypto",
126 .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
127 .desc = {
128 {
129 .name = BLOCK_OPT_SIZE,
130 .type = QEMU_OPT_SIZE,
131 .help = "Virtual disk size"
132 },
133 BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
134 BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
135 BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
136 BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
137 BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
138 BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
139 BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
140 { /* end of list */ }
141 },
142 };
143
144
145 QCryptoBlockOpenOptions *
146 block_crypto_open_opts_init(QCryptoBlockFormat format,
147 QDict *opts,
148 Error **errp)
149 {
150 Visitor *v;
151 QCryptoBlockOpenOptions *ret = NULL;
152 Error *local_err = NULL;
153
154 ret = g_new0(QCryptoBlockOpenOptions, 1);
155 ret->format = format;
156
157 v = qobject_input_visitor_new_keyval(QOBJECT(opts));
158
159 visit_start_struct(v, NULL, NULL, 0, &local_err);
160 if (local_err) {
161 goto out;
162 }
163
164 switch (format) {
165 case Q_CRYPTO_BLOCK_FORMAT_LUKS:
166 visit_type_QCryptoBlockOptionsLUKS_members(
167 v, &ret->u.luks, &local_err);
168 break;
169
170 case Q_CRYPTO_BLOCK_FORMAT_QCOW:
171 visit_type_QCryptoBlockOptionsQCow_members(
172 v, &ret->u.qcow, &local_err);
173 break;
174
175 default:
176 error_setg(&local_err, "Unsupported block format %d", format);
177 break;
178 }
179 if (!local_err) {
180 visit_check_struct(v, &local_err);
181 }
182
183 visit_end_struct(v, NULL);
184
185 out:
186 if (local_err) {
187 error_propagate(errp, local_err);
188 qapi_free_QCryptoBlockOpenOptions(ret);
189 ret = NULL;
190 }
191 visit_free(v);
192 return ret;
193 }
194
195
196 QCryptoBlockCreateOptions *
197 block_crypto_create_opts_init(QCryptoBlockFormat format,
198 QDict *opts,
199 Error **errp)
200 {
201 Visitor *v;
202 QCryptoBlockCreateOptions *ret = NULL;
203 Error *local_err = NULL;
204
205 ret = g_new0(QCryptoBlockCreateOptions, 1);
206 ret->format = format;
207
208 v = qobject_input_visitor_new_keyval(QOBJECT(opts));
209
210 visit_start_struct(v, NULL, NULL, 0, &local_err);
211 if (local_err) {
212 goto out;
213 }
214
215 switch (format) {
216 case Q_CRYPTO_BLOCK_FORMAT_LUKS:
217 visit_type_QCryptoBlockCreateOptionsLUKS_members(
218 v, &ret->u.luks, &local_err);
219 break;
220
221 case Q_CRYPTO_BLOCK_FORMAT_QCOW:
222 visit_type_QCryptoBlockOptionsQCow_members(
223 v, &ret->u.qcow, &local_err);
224 break;
225
226 default:
227 error_setg(&local_err, "Unsupported block format %d", format);
228 break;
229 }
230 if (!local_err) {
231 visit_check_struct(v, &local_err);
232 }
233
234 visit_end_struct(v, NULL);
235
236 out:
237 if (local_err) {
238 error_propagate(errp, local_err);
239 qapi_free_QCryptoBlockCreateOptions(ret);
240 ret = NULL;
241 }
242 visit_free(v);
243 return ret;
244 }
245
246
247 static int block_crypto_open_generic(QCryptoBlockFormat format,
248 QemuOptsList *opts_spec,
249 BlockDriverState *bs,
250 QDict *options,
251 int flags,
252 Error **errp)
253 {
254 BlockCrypto *crypto = bs->opaque;
255 QemuOpts *opts = NULL;
256 Error *local_err = NULL;
257 int ret = -EINVAL;
258 QCryptoBlockOpenOptions *open_opts = NULL;
259 unsigned int cflags = 0;
260 QDict *cryptoopts = NULL;
261
262 bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
263 false, errp);
264 if (!bs->file) {
265 return -EINVAL;
266 }
267
268 bs->supported_write_flags = BDRV_REQ_FUA &
269 bs->file->bs->supported_write_flags;
270
271 opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
272 qemu_opts_absorb_qdict(opts, options, &local_err);
273 if (local_err) {
274 error_propagate(errp, local_err);
275 goto cleanup;
276 }
277
278 cryptoopts = qemu_opts_to_qdict(opts, NULL);
279
280 open_opts = block_crypto_open_opts_init(format, cryptoopts, errp);
281 if (!open_opts) {
282 goto cleanup;
283 }
284
285 if (flags & BDRV_O_NO_IO) {
286 cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
287 }
288 crypto->block = qcrypto_block_open(open_opts, NULL,
289 block_crypto_read_func,
290 bs,
291 cflags,
292 errp);
293
294 if (!crypto->block) {
295 ret = -EIO;
296 goto cleanup;
297 }
298
299 bs->encrypted = true;
300
301 ret = 0;
302 cleanup:
303 QDECREF(cryptoopts);
304 qapi_free_QCryptoBlockOpenOptions(open_opts);
305 return ret;
306 }
307
308
309 static int block_crypto_co_create_generic(BlockDriverState *bs,
310 int64_t size,
311 QCryptoBlockCreateOptions *opts,
312 Error **errp)
313 {
314 int ret;
315 BlockBackend *blk;
316 QCryptoBlock *crypto = NULL;
317 struct BlockCryptoCreateData data;
318
319 blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
320
321 ret = blk_insert_bs(blk, bs, errp);
322 if (ret < 0) {
323 goto cleanup;
324 }
325
326 data = (struct BlockCryptoCreateData) {
327 .blk = blk,
328 .size = size,
329 };
330
331 crypto = qcrypto_block_create(opts, NULL,
332 block_crypto_init_func,
333 block_crypto_write_func,
334 &data,
335 errp);
336
337 if (!crypto) {
338 ret = -EIO;
339 goto cleanup;
340 }
341
342 ret = 0;
343 cleanup:
344 qcrypto_block_free(crypto);
345 blk_unref(blk);
346 return ret;
347 }
348
349 static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
350 PreallocMode prealloc, Error **errp)
351 {
352 BlockCrypto *crypto = bs->opaque;
353 uint64_t payload_offset =
354 qcrypto_block_get_payload_offset(crypto->block);
355 assert(payload_offset < (INT64_MAX - offset));
356
357 offset += payload_offset;
358
359 return bdrv_truncate(bs->file, offset, prealloc, errp);
360 }
361
362 static void block_crypto_close(BlockDriverState *bs)
363 {
364 BlockCrypto *crypto = bs->opaque;
365 qcrypto_block_free(crypto->block);
366 }
367
368 static int block_crypto_reopen_prepare(BDRVReopenState *state,
369 BlockReopenQueue *queue, Error **errp)
370 {
371 /* nothing needs checking */
372 return 0;
373 }
374
375 /*
376 * 1 MB bounce buffer gives good performance / memory tradeoff
377 * when using cache=none|directsync.
378 */
379 #define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
380
381 static coroutine_fn int
382 block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
383 QEMUIOVector *qiov, int flags)
384 {
385 BlockCrypto *crypto = bs->opaque;
386 uint64_t cur_bytes; /* number of bytes in current iteration */
387 uint64_t bytes_done = 0;
388 uint8_t *cipher_data = NULL;
389 QEMUIOVector hd_qiov;
390 int ret = 0;
391 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
392 uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
393
394 assert(!flags);
395 assert(payload_offset < INT64_MAX);
396 assert(QEMU_IS_ALIGNED(offset, sector_size));
397 assert(QEMU_IS_ALIGNED(bytes, sector_size));
398
399 qemu_iovec_init(&hd_qiov, qiov->niov);
400
401 /* Bounce buffer because we don't wish to expose cipher text
402 * in qiov which points to guest memory.
403 */
404 cipher_data =
405 qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
406 qiov->size));
407 if (cipher_data == NULL) {
408 ret = -ENOMEM;
409 goto cleanup;
410 }
411
412 while (bytes) {
413 cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
414
415 qemu_iovec_reset(&hd_qiov);
416 qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
417
418 ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
419 cur_bytes, &hd_qiov, 0);
420 if (ret < 0) {
421 goto cleanup;
422 }
423
424 if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
425 cipher_data, cur_bytes, NULL) < 0) {
426 ret = -EIO;
427 goto cleanup;
428 }
429
430 qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
431
432 bytes -= cur_bytes;
433 bytes_done += cur_bytes;
434 }
435
436 cleanup:
437 qemu_iovec_destroy(&hd_qiov);
438 qemu_vfree(cipher_data);
439
440 return ret;
441 }
442
443
444 static coroutine_fn int
445 block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
446 QEMUIOVector *qiov, int flags)
447 {
448 BlockCrypto *crypto = bs->opaque;
449 uint64_t cur_bytes; /* number of bytes in current iteration */
450 uint64_t bytes_done = 0;
451 uint8_t *cipher_data = NULL;
452 QEMUIOVector hd_qiov;
453 int ret = 0;
454 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
455 uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
456
457 assert(!(flags & ~BDRV_REQ_FUA));
458 assert(payload_offset < INT64_MAX);
459 assert(QEMU_IS_ALIGNED(offset, sector_size));
460 assert(QEMU_IS_ALIGNED(bytes, sector_size));
461
462 qemu_iovec_init(&hd_qiov, qiov->niov);
463
464 /* Bounce buffer because we're not permitted to touch
465 * contents of qiov - it points to guest memory.
466 */
467 cipher_data =
468 qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
469 qiov->size));
470 if (cipher_data == NULL) {
471 ret = -ENOMEM;
472 goto cleanup;
473 }
474
475 while (bytes) {
476 cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
477
478 qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
479
480 if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
481 cipher_data, cur_bytes, NULL) < 0) {
482 ret = -EIO;
483 goto cleanup;
484 }
485
486 qemu_iovec_reset(&hd_qiov);
487 qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
488
489 ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
490 cur_bytes, &hd_qiov, flags);
491 if (ret < 0) {
492 goto cleanup;
493 }
494
495 bytes -= cur_bytes;
496 bytes_done += cur_bytes;
497 }
498
499 cleanup:
500 qemu_iovec_destroy(&hd_qiov);
501 qemu_vfree(cipher_data);
502
503 return ret;
504 }
505
506 static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
507 {
508 BlockCrypto *crypto = bs->opaque;
509 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
510 bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
511 }
512
513
514 static int64_t block_crypto_getlength(BlockDriverState *bs)
515 {
516 BlockCrypto *crypto = bs->opaque;
517 int64_t len = bdrv_getlength(bs->file->bs);
518
519 uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
520 assert(offset < INT64_MAX);
521
522 if (offset > len) {
523 return -EIO;
524 }
525
526 len -= offset;
527
528 return len;
529 }
530
531
532 static int block_crypto_probe_luks(const uint8_t *buf,
533 int buf_size,
534 const char *filename) {
535 return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
536 buf, buf_size, filename);
537 }
538
539 static int block_crypto_open_luks(BlockDriverState *bs,
540 QDict *options,
541 int flags,
542 Error **errp)
543 {
544 return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
545 &block_crypto_runtime_opts_luks,
546 bs, options, flags, errp);
547 }
548
549 static int coroutine_fn
550 block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
551 {
552 BlockdevCreateOptionsLUKS *luks_opts;
553 BlockDriverState *bs = NULL;
554 QCryptoBlockCreateOptions create_opts;
555 int ret;
556
557 assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
558 luks_opts = &create_options->u.luks;
559
560 bs = bdrv_open_blockdev_ref(luks_opts->file, errp);
561 if (bs == NULL) {
562 return -EIO;
563 }
564
565 create_opts = (QCryptoBlockCreateOptions) {
566 .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
567 .u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts),
568 };
569
570 ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
571 errp);
572 if (ret < 0) {
573 goto fail;
574 }
575
576 ret = 0;
577 fail:
578 bdrv_unref(bs);
579 return ret;
580 }
581
582 static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
583 QemuOpts *opts,
584 Error **errp)
585 {
586 QCryptoBlockCreateOptions *create_opts = NULL;
587 BlockDriverState *bs = NULL;
588 QDict *cryptoopts;
589 int64_t size;
590 int ret;
591
592 /* Parse options */
593 size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
594
595 cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
596 &block_crypto_create_opts_luks,
597 true);
598
599 create_opts = block_crypto_create_opts_init(Q_CRYPTO_BLOCK_FORMAT_LUKS,
600 cryptoopts, errp);
601 if (!create_opts) {
602 ret = -EINVAL;
603 goto fail;
604 }
605
606 /* Create protocol layer */
607 ret = bdrv_create_file(filename, opts, errp);
608 if (ret < 0) {
609 return ret;
610 }
611
612 bs = bdrv_open(filename, NULL, NULL,
613 BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
614 if (!bs) {
615 ret = -EINVAL;
616 goto fail;
617 }
618
619 /* Create format layer */
620 ret = block_crypto_co_create_generic(bs, size, create_opts, errp);
621 if (ret < 0) {
622 goto fail;
623 }
624
625 ret = 0;
626 fail:
627 bdrv_unref(bs);
628 qapi_free_QCryptoBlockCreateOptions(create_opts);
629 QDECREF(cryptoopts);
630 return ret;
631 }
632
633 static int block_crypto_get_info_luks(BlockDriverState *bs,
634 BlockDriverInfo *bdi)
635 {
636 BlockDriverInfo subbdi;
637 int ret;
638
639 ret = bdrv_get_info(bs->file->bs, &subbdi);
640 if (ret != 0) {
641 return ret;
642 }
643
644 bdi->unallocated_blocks_are_zero = false;
645 bdi->cluster_size = subbdi.cluster_size;
646
647 return 0;
648 }
649
650 static ImageInfoSpecific *
651 block_crypto_get_specific_info_luks(BlockDriverState *bs)
652 {
653 BlockCrypto *crypto = bs->opaque;
654 ImageInfoSpecific *spec_info;
655 QCryptoBlockInfo *info;
656
657 info = qcrypto_block_get_info(crypto->block, NULL);
658 if (!info) {
659 return NULL;
660 }
661 if (info->format != Q_CRYPTO_BLOCK_FORMAT_LUKS) {
662 qapi_free_QCryptoBlockInfo(info);
663 return NULL;
664 }
665
666 spec_info = g_new(ImageInfoSpecific, 1);
667 spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
668 spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);
669 *spec_info->u.luks.data = info->u.luks;
670
671 /* Blank out pointers we've just stolen to avoid double free */
672 memset(&info->u.luks, 0, sizeof(info->u.luks));
673
674 qapi_free_QCryptoBlockInfo(info);
675
676 return spec_info;
677 }
678
679 BlockDriver bdrv_crypto_luks = {
680 .format_name = "luks",
681 .instance_size = sizeof(BlockCrypto),
682 .bdrv_probe = block_crypto_probe_luks,
683 .bdrv_open = block_crypto_open_luks,
684 .bdrv_close = block_crypto_close,
685 .bdrv_child_perm = bdrv_format_default_perms,
686 .bdrv_co_create = block_crypto_co_create_luks,
687 .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
688 .bdrv_truncate = block_crypto_truncate,
689 .create_opts = &block_crypto_create_opts_luks,
690
691 .bdrv_reopen_prepare = block_crypto_reopen_prepare,
692 .bdrv_refresh_limits = block_crypto_refresh_limits,
693 .bdrv_co_preadv = block_crypto_co_preadv,
694 .bdrv_co_pwritev = block_crypto_co_pwritev,
695 .bdrv_getlength = block_crypto_getlength,
696 .bdrv_get_info = block_crypto_get_info_luks,
697 .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
698 };
699
700 static void block_crypto_init(void)
701 {
702 bdrv_register(&bdrv_crypto_luks);
703 }
704
705 block_init(block_crypto_init);