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 388 /* 389 * 1 MB bounce buffer gives good performance / memory tradeoff 390 * when using cache=none|directsync. 391 */ 392 #define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024) 393 394 static coroutine_fn int 395 block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, 396 QEMUIOVector *qiov, int flags) 397 { 398 BlockCrypto *crypto = bs->opaque; 399 uint64_t cur_bytes; /* number of bytes in current iteration */ 400 uint64_t bytes_done = 0; 401 uint8_t *cipher_data = NULL; 402 QEMUIOVector hd_qiov; 403 int ret = 0; 404 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); 405 uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block); 406 407 assert(!flags); 408 assert(payload_offset < INT64_MAX); 409 assert(QEMU_IS_ALIGNED(offset, sector_size)); 410 assert(QEMU_IS_ALIGNED(bytes, sector_size)); 411 412 qemu_iovec_init(&hd_qiov, qiov->niov); 413 414 /* Bounce buffer because we don't wish to expose cipher text 415 * in qiov which points to guest memory. 416 */ 417 cipher_data = 418 qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE, 419 qiov->size)); 420 if (cipher_data == NULL) { 421 ret = -ENOMEM; 422 goto cleanup; 423 } 424 425 while (bytes) { 426 cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE); 427 428 qemu_iovec_reset(&hd_qiov); 429 qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes); 430 431 ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done, 432 cur_bytes, &hd_qiov, 0); 433 if (ret < 0) { 434 goto cleanup; 435 } 436 437 if (qcrypto_block_decrypt(crypto->block, offset + bytes_done, 438 cipher_data, cur_bytes, NULL) < 0) { 439 ret = -EIO; 440 goto cleanup; 441 } 442 443 qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes); 444 445 bytes -= cur_bytes; 446 bytes_done += cur_bytes; 447 } 448 449 cleanup: 450 qemu_iovec_destroy(&hd_qiov); 451 qemu_vfree(cipher_data); 452 453 return ret; 454 } 455 456 457 static coroutine_fn int 458 block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, 459 QEMUIOVector *qiov, int flags) 460 { 461 BlockCrypto *crypto = bs->opaque; 462 uint64_t cur_bytes; /* number of bytes in current iteration */ 463 uint64_t bytes_done = 0; 464 uint8_t *cipher_data = NULL; 465 QEMUIOVector hd_qiov; 466 int ret = 0; 467 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); 468 uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block); 469 470 assert(!(flags & ~BDRV_REQ_FUA)); 471 assert(payload_offset < INT64_MAX); 472 assert(QEMU_IS_ALIGNED(offset, sector_size)); 473 assert(QEMU_IS_ALIGNED(bytes, sector_size)); 474 475 qemu_iovec_init(&hd_qiov, qiov->niov); 476 477 /* Bounce buffer because we're not permitted to touch 478 * contents of qiov - it points to guest memory. 479 */ 480 cipher_data = 481 qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE, 482 qiov->size)); 483 if (cipher_data == NULL) { 484 ret = -ENOMEM; 485 goto cleanup; 486 } 487 488 while (bytes) { 489 cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE); 490 491 qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes); 492 493 if (qcrypto_block_encrypt(crypto->block, offset + bytes_done, 494 cipher_data, cur_bytes, NULL) < 0) { 495 ret = -EIO; 496 goto cleanup; 497 } 498 499 qemu_iovec_reset(&hd_qiov); 500 qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes); 501 502 ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done, 503 cur_bytes, &hd_qiov, flags); 504 if (ret < 0) { 505 goto cleanup; 506 } 507 508 bytes -= cur_bytes; 509 bytes_done += cur_bytes; 510 } 511 512 cleanup: 513 qemu_iovec_destroy(&hd_qiov); 514 qemu_vfree(cipher_data); 515 516 return ret; 517 } 518 519 static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp) 520 { 521 BlockCrypto *crypto = bs->opaque; 522 uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); 523 bs->bl.request_alignment = sector_size; /* No sub-sector I/O */ 524 } 525 526 527 static int64_t block_crypto_getlength(BlockDriverState *bs) 528 { 529 BlockCrypto *crypto = bs->opaque; 530 int64_t len = bdrv_getlength(bs->file->bs); 531 532 uint64_t offset = qcrypto_block_get_payload_offset(crypto->block); 533 assert(offset < INT64_MAX); 534 assert(offset < len); 535 536 len -= offset; 537 538 return len; 539 } 540 541 542 static int block_crypto_probe_luks(const uint8_t *buf, 543 int buf_size, 544 const char *filename) { 545 return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS, 546 buf, buf_size, filename); 547 } 548 549 static int block_crypto_open_luks(BlockDriverState *bs, 550 QDict *options, 551 int flags, 552 Error **errp) 553 { 554 return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS, 555 &block_crypto_runtime_opts_luks, 556 bs, options, flags, errp); 557 } 558 559 static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename, 560 QemuOpts *opts, 561 Error **errp) 562 { 563 return block_crypto_create_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS, 564 filename, opts, errp); 565 } 566 567 static int block_crypto_get_info_luks(BlockDriverState *bs, 568 BlockDriverInfo *bdi) 569 { 570 BlockDriverInfo subbdi; 571 int ret; 572 573 ret = bdrv_get_info(bs->file->bs, &subbdi); 574 if (ret != 0) { 575 return ret; 576 } 577 578 bdi->unallocated_blocks_are_zero = false; 579 bdi->cluster_size = subbdi.cluster_size; 580 581 return 0; 582 } 583 584 static ImageInfoSpecific * 585 block_crypto_get_specific_info_luks(BlockDriverState *bs) 586 { 587 BlockCrypto *crypto = bs->opaque; 588 ImageInfoSpecific *spec_info; 589 QCryptoBlockInfo *info; 590 591 info = qcrypto_block_get_info(crypto->block, NULL); 592 if (!info) { 593 return NULL; 594 } 595 if (info->format != Q_CRYPTO_BLOCK_FORMAT_LUKS) { 596 qapi_free_QCryptoBlockInfo(info); 597 return NULL; 598 } 599 600 spec_info = g_new(ImageInfoSpecific, 1); 601 spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS; 602 spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1); 603 *spec_info->u.luks.data = info->u.luks; 604 605 /* Blank out pointers we've just stolen to avoid double free */ 606 memset(&info->u.luks, 0, sizeof(info->u.luks)); 607 608 qapi_free_QCryptoBlockInfo(info); 609 610 return spec_info; 611 } 612 613 BlockDriver bdrv_crypto_luks = { 614 .format_name = "luks", 615 .instance_size = sizeof(BlockCrypto), 616 .bdrv_probe = block_crypto_probe_luks, 617 .bdrv_open = block_crypto_open_luks, 618 .bdrv_close = block_crypto_close, 619 .bdrv_child_perm = bdrv_format_default_perms, 620 .bdrv_co_create_opts = block_crypto_co_create_opts_luks, 621 .bdrv_truncate = block_crypto_truncate, 622 .create_opts = &block_crypto_create_opts_luks, 623 624 .bdrv_refresh_limits = block_crypto_refresh_limits, 625 .bdrv_co_preadv = block_crypto_co_preadv, 626 .bdrv_co_pwritev = block_crypto_co_pwritev, 627 .bdrv_getlength = block_crypto_getlength, 628 .bdrv_get_info = block_crypto_get_info_luks, 629 .bdrv_get_specific_info = block_crypto_get_specific_info_luks, 630 }; 631 632 static void block_crypto_init(void) 633 { 634 bdrv_register(&bdrv_crypto_luks); 635 } 636 637 block_init(block_crypto_init); 638