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(QDict *opts, Error **errp) 152 { 153 Visitor *v; 154 QCryptoBlockOpenOptions *ret; 155 156 v = qobject_input_visitor_new_flat_confused(opts, errp); 157 if (!v) { 158 return NULL; 159 } 160 161 visit_type_QCryptoBlockOpenOptions(v, NULL, &ret, errp); 162 163 visit_free(v); 164 return ret; 165 } 166 167 168 QCryptoBlockCreateOptions * 169 block_crypto_create_opts_init(QDict *opts, Error **errp) 170 { 171 Visitor *v; 172 QCryptoBlockCreateOptions *ret; 173 174 v = qobject_input_visitor_new_flat_confused(opts, errp); 175 if (!v) { 176 return NULL; 177 } 178 179 visit_type_QCryptoBlockCreateOptions(v, NULL, &ret, errp); 180 181 visit_free(v); 182 return ret; 183 } 184 185 186 static int block_crypto_open_generic(QCryptoBlockFormat format, 187 QemuOptsList *opts_spec, 188 BlockDriverState *bs, 189 QDict *options, 190 int flags, 191 Error **errp) 192 { 193 BlockCrypto *crypto = bs->opaque; 194 QemuOpts *opts = NULL; 195 Error *local_err = NULL; 196 int ret = -EINVAL; 197 QCryptoBlockOpenOptions *open_opts = NULL; 198 unsigned int cflags = 0; 199 QDict *cryptoopts = NULL; 200 201 bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 202 false, errp); 203 if (!bs->file) { 204 return -EINVAL; 205 } 206 207 bs->supported_write_flags = BDRV_REQ_FUA & 208 bs->file->bs->supported_write_flags; 209 210 opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort); 211 qemu_opts_absorb_qdict(opts, options, &local_err); 212 if (local_err) { 213 error_propagate(errp, local_err); 214 goto cleanup; 215 } 216 217 cryptoopts = qemu_opts_to_qdict(opts, NULL); 218 qdict_put_str(cryptoopts, "format", QCryptoBlockFormat_str(format)); 219 220 open_opts = block_crypto_open_opts_init(cryptoopts, errp); 221 if (!open_opts) { 222 goto cleanup; 223 } 224 225 if (flags & BDRV_O_NO_IO) { 226 cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; 227 } 228 crypto->block = qcrypto_block_open(open_opts, NULL, 229 block_crypto_read_func, 230 bs, 231 cflags, 232 1, 233 errp); 234 235 if (!crypto->block) { 236 ret = -EIO; 237 goto cleanup; 238 } 239 240 bs->encrypted = true; 241 242 ret = 0; 243 cleanup: 244 qobject_unref(cryptoopts); 245 qapi_free_QCryptoBlockOpenOptions(open_opts); 246 return ret; 247 } 248 249 250 static int block_crypto_co_create_generic(BlockDriverState *bs, 251 int64_t size, 252 QCryptoBlockCreateOptions *opts, 253 Error **errp) 254 { 255 int ret; 256 BlockBackend *blk; 257 QCryptoBlock *crypto = NULL; 258 struct BlockCryptoCreateData data; 259 260 blk = blk_new(bdrv_get_aio_context(bs), 261 BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL); 262 263 ret = blk_insert_bs(blk, bs, errp); 264 if (ret < 0) { 265 goto cleanup; 266 } 267 268 data = (struct BlockCryptoCreateData) { 269 .blk = blk, 270 .size = size, 271 }; 272 273 crypto = qcrypto_block_create(opts, NULL, 274 block_crypto_init_func, 275 block_crypto_write_func, 276 &data, 277 errp); 278 279 if (!crypto) { 280 ret = -EIO; 281 goto cleanup; 282 } 283 284 ret = 0; 285 cleanup: 286 qcrypto_block_free(crypto); 287 blk_unref(blk); 288 return ret; 289 } 290 291 static int coroutine_fn 292 block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, 293 PreallocMode prealloc, Error **errp) 294 { 295 BlockCrypto *crypto = bs->opaque; 296 uint64_t payload_offset = 297 qcrypto_block_get_payload_offset(crypto->block); 298 299 if (payload_offset > INT64_MAX - offset) { 300 error_setg(errp, "The requested file size is too large"); 301 return -EFBIG; 302 } 303 304 offset += payload_offset; 305 306 return bdrv_co_truncate(bs->file, offset, prealloc, errp); 307 } 308 309 static void block_crypto_close(BlockDriverState *bs) 310 { 311 BlockCrypto *crypto = bs->opaque; 312 qcrypto_block_free(crypto->block); 313 } 314 315 static int block_crypto_reopen_prepare(BDRVReopenState *state, 316 BlockReopenQueue *queue, Error **errp) 317 { 318 /* nothing needs checking */ 319 return 0; 320 } 321 322 /* 323 * 1 MB bounce buffer gives good performance / memory tradeoff 324 * when using cache=none|directsync. 325 */ 326 #define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024) 327 328 static coroutine_fn int 329 block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, 330 QEMUIOVector *qiov, int flags) 331 { 332 BlockCrypto *crypto = bs->opaque; 333 uint64_t cur_bytes; /* number of bytes in current iteration */ 334 uint64_t bytes_done = 0; 335 uint8_t *cipher_data = NULL; 336 QEMUIOVector hd_qiov; 337 int ret = 0; 338 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); 339 uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block); 340 341 assert(!flags); 342 assert(payload_offset < INT64_MAX); 343 assert(QEMU_IS_ALIGNED(offset, sector_size)); 344 assert(QEMU_IS_ALIGNED(bytes, sector_size)); 345 346 qemu_iovec_init(&hd_qiov, qiov->niov); 347 348 /* Bounce buffer because we don't wish to expose cipher text 349 * in qiov which points to guest memory. 350 */ 351 cipher_data = 352 qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE, 353 qiov->size)); 354 if (cipher_data == NULL) { 355 ret = -ENOMEM; 356 goto cleanup; 357 } 358 359 while (bytes) { 360 cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE); 361 362 qemu_iovec_reset(&hd_qiov); 363 qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes); 364 365 ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done, 366 cur_bytes, &hd_qiov, 0); 367 if (ret < 0) { 368 goto cleanup; 369 } 370 371 if (qcrypto_block_decrypt(crypto->block, offset + bytes_done, 372 cipher_data, cur_bytes, NULL) < 0) { 373 ret = -EIO; 374 goto cleanup; 375 } 376 377 qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes); 378 379 bytes -= cur_bytes; 380 bytes_done += cur_bytes; 381 } 382 383 cleanup: 384 qemu_iovec_destroy(&hd_qiov); 385 qemu_vfree(cipher_data); 386 387 return ret; 388 } 389 390 391 static coroutine_fn int 392 block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, 393 QEMUIOVector *qiov, int flags) 394 { 395 BlockCrypto *crypto = bs->opaque; 396 uint64_t cur_bytes; /* number of bytes in current iteration */ 397 uint64_t bytes_done = 0; 398 uint8_t *cipher_data = NULL; 399 QEMUIOVector hd_qiov; 400 int ret = 0; 401 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); 402 uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block); 403 404 assert(!(flags & ~BDRV_REQ_FUA)); 405 assert(payload_offset < INT64_MAX); 406 assert(QEMU_IS_ALIGNED(offset, sector_size)); 407 assert(QEMU_IS_ALIGNED(bytes, sector_size)); 408 409 qemu_iovec_init(&hd_qiov, qiov->niov); 410 411 /* Bounce buffer because we're not permitted to touch 412 * contents of qiov - it points to guest memory. 413 */ 414 cipher_data = 415 qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE, 416 qiov->size)); 417 if (cipher_data == NULL) { 418 ret = -ENOMEM; 419 goto cleanup; 420 } 421 422 while (bytes) { 423 cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE); 424 425 qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes); 426 427 if (qcrypto_block_encrypt(crypto->block, offset + bytes_done, 428 cipher_data, cur_bytes, NULL) < 0) { 429 ret = -EIO; 430 goto cleanup; 431 } 432 433 qemu_iovec_reset(&hd_qiov); 434 qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes); 435 436 ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done, 437 cur_bytes, &hd_qiov, flags); 438 if (ret < 0) { 439 goto cleanup; 440 } 441 442 bytes -= cur_bytes; 443 bytes_done += cur_bytes; 444 } 445 446 cleanup: 447 qemu_iovec_destroy(&hd_qiov); 448 qemu_vfree(cipher_data); 449 450 return ret; 451 } 452 453 static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp) 454 { 455 BlockCrypto *crypto = bs->opaque; 456 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); 457 bs->bl.request_alignment = sector_size; /* No sub-sector I/O */ 458 } 459 460 461 static int64_t block_crypto_getlength(BlockDriverState *bs) 462 { 463 BlockCrypto *crypto = bs->opaque; 464 int64_t len = bdrv_getlength(bs->file->bs); 465 466 uint64_t offset = qcrypto_block_get_payload_offset(crypto->block); 467 assert(offset < INT64_MAX); 468 469 if (offset > len) { 470 return -EIO; 471 } 472 473 len -= offset; 474 475 return len; 476 } 477 478 479 static int block_crypto_probe_luks(const uint8_t *buf, 480 int buf_size, 481 const char *filename) { 482 return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS, 483 buf, buf_size, filename); 484 } 485 486 static int block_crypto_open_luks(BlockDriverState *bs, 487 QDict *options, 488 int flags, 489 Error **errp) 490 { 491 return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS, 492 &block_crypto_runtime_opts_luks, 493 bs, options, flags, errp); 494 } 495 496 static int coroutine_fn 497 block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp) 498 { 499 BlockdevCreateOptionsLUKS *luks_opts; 500 BlockDriverState *bs = NULL; 501 QCryptoBlockCreateOptions create_opts; 502 int ret; 503 504 assert(create_options->driver == BLOCKDEV_DRIVER_LUKS); 505 luks_opts = &create_options->u.luks; 506 507 bs = bdrv_open_blockdev_ref(luks_opts->file, errp); 508 if (bs == NULL) { 509 return -EIO; 510 } 511 512 create_opts = (QCryptoBlockCreateOptions) { 513 .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, 514 .u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts), 515 }; 516 517 ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts, 518 errp); 519 if (ret < 0) { 520 goto fail; 521 } 522 523 ret = 0; 524 fail: 525 bdrv_unref(bs); 526 return ret; 527 } 528 529 static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename, 530 QemuOpts *opts, 531 Error **errp) 532 { 533 QCryptoBlockCreateOptions *create_opts = NULL; 534 BlockDriverState *bs = NULL; 535 QDict *cryptoopts; 536 int64_t size; 537 int ret; 538 539 /* Parse options */ 540 size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); 541 542 cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL, 543 &block_crypto_create_opts_luks, 544 true); 545 546 qdict_put_str(cryptoopts, "format", "luks"); 547 create_opts = block_crypto_create_opts_init(cryptoopts, errp); 548 if (!create_opts) { 549 ret = -EINVAL; 550 goto fail; 551 } 552 553 /* Create protocol layer */ 554 ret = bdrv_create_file(filename, opts, errp); 555 if (ret < 0) { 556 goto fail; 557 } 558 559 bs = bdrv_open(filename, NULL, NULL, 560 BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp); 561 if (!bs) { 562 ret = -EINVAL; 563 goto fail; 564 } 565 566 /* Create format layer */ 567 ret = block_crypto_co_create_generic(bs, size, create_opts, errp); 568 if (ret < 0) { 569 goto fail; 570 } 571 572 ret = 0; 573 fail: 574 bdrv_unref(bs); 575 qapi_free_QCryptoBlockCreateOptions(create_opts); 576 qobject_unref(cryptoopts); 577 return ret; 578 } 579 580 static int block_crypto_get_info_luks(BlockDriverState *bs, 581 BlockDriverInfo *bdi) 582 { 583 BlockDriverInfo subbdi; 584 int ret; 585 586 ret = bdrv_get_info(bs->file->bs, &subbdi); 587 if (ret != 0) { 588 return ret; 589 } 590 591 bdi->unallocated_blocks_are_zero = false; 592 bdi->cluster_size = subbdi.cluster_size; 593 594 return 0; 595 } 596 597 static ImageInfoSpecific * 598 block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp) 599 { 600 BlockCrypto *crypto = bs->opaque; 601 ImageInfoSpecific *spec_info; 602 QCryptoBlockInfo *info; 603 604 info = qcrypto_block_get_info(crypto->block, errp); 605 if (!info) { 606 return NULL; 607 } 608 assert(info->format == Q_CRYPTO_BLOCK_FORMAT_LUKS); 609 610 spec_info = g_new(ImageInfoSpecific, 1); 611 spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS; 612 spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1); 613 *spec_info->u.luks.data = info->u.luks; 614 615 /* Blank out pointers we've just stolen to avoid double free */ 616 memset(&info->u.luks, 0, sizeof(info->u.luks)); 617 618 qapi_free_QCryptoBlockInfo(info); 619 620 return spec_info; 621 } 622 623 static const char *const block_crypto_strong_runtime_opts[] = { 624 BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, 625 626 NULL 627 }; 628 629 static BlockDriver bdrv_crypto_luks = { 630 .format_name = "luks", 631 .instance_size = sizeof(BlockCrypto), 632 .bdrv_probe = block_crypto_probe_luks, 633 .bdrv_open = block_crypto_open_luks, 634 .bdrv_close = block_crypto_close, 635 /* This driver doesn't modify LUKS metadata except when creating image. 636 * Allow share-rw=on as a special case. */ 637 .bdrv_child_perm = bdrv_filter_default_perms, 638 .bdrv_co_create = block_crypto_co_create_luks, 639 .bdrv_co_create_opts = block_crypto_co_create_opts_luks, 640 .bdrv_co_truncate = block_crypto_co_truncate, 641 .create_opts = &block_crypto_create_opts_luks, 642 643 .bdrv_reopen_prepare = block_crypto_reopen_prepare, 644 .bdrv_refresh_limits = block_crypto_refresh_limits, 645 .bdrv_co_preadv = block_crypto_co_preadv, 646 .bdrv_co_pwritev = block_crypto_co_pwritev, 647 .bdrv_getlength = block_crypto_getlength, 648 .bdrv_get_info = block_crypto_get_info_luks, 649 .bdrv_get_specific_info = block_crypto_get_specific_info_luks, 650 651 .strong_runtime_opts = block_crypto_strong_runtime_opts, 652 }; 653 654 static void block_crypto_init(void) 655 { 656 bdrv_register(&bdrv_crypto_luks); 657 } 658 659 block_init(block_crypto_init); 660