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