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