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