qemu/block/crypto.c
<<
>>
Prefs
   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 "qemu/cutils.h"
  34#include "crypto.h"
  35
  36typedef struct BlockCrypto BlockCrypto;
  37
  38struct BlockCrypto {
  39    QCryptoBlock *block;
  40};
  41
  42
  43static int block_crypto_probe_generic(QCryptoBlockFormat format,
  44                                      const uint8_t *buf,
  45                                      int buf_size,
  46                                      const char *filename)
  47{
  48    if (qcrypto_block_has_format(format, buf, buf_size)) {
  49        return 100;
  50    } else {
  51        return 0;
  52    }
  53}
  54
  55
  56static ssize_t block_crypto_read_func(QCryptoBlock *block,
  57                                      size_t offset,
  58                                      uint8_t *buf,
  59                                      size_t buflen,
  60                                      void *opaque,
  61                                      Error **errp)
  62{
  63    BlockDriverState *bs = opaque;
  64    ssize_t ret;
  65
  66    ret = bdrv_pread(bs->file, offset, buf, buflen);
  67    if (ret < 0) {
  68        error_setg_errno(errp, -ret, "Could not read encryption header");
  69        return ret;
  70    }
  71    return ret;
  72}
  73
  74
  75struct BlockCryptoCreateData {
  76    BlockBackend *blk;
  77    uint64_t size;
  78    PreallocMode prealloc;
  79};
  80
  81
  82static ssize_t block_crypto_write_func(QCryptoBlock *block,
  83                                       size_t offset,
  84                                       const uint8_t *buf,
  85                                       size_t buflen,
  86                                       void *opaque,
  87                                       Error **errp)
  88{
  89    struct BlockCryptoCreateData *data = opaque;
  90    ssize_t ret;
  91
  92    ret = blk_pwrite(data->blk, offset, buf, buflen, 0);
  93    if (ret < 0) {
  94        error_setg_errno(errp, -ret, "Could not write encryption header");
  95        return ret;
  96    }
  97    return ret;
  98}
  99
 100
 101static ssize_t block_crypto_init_func(QCryptoBlock *block,
 102                                      size_t headerlen,
 103                                      void *opaque,
 104                                      Error **errp)
 105{
 106    struct BlockCryptoCreateData *data = opaque;
 107
 108    if (data->size > INT64_MAX || headerlen > INT64_MAX - data->size) {
 109        error_setg(errp, "The requested file size is too large");
 110        return -EFBIG;
 111    }
 112
 113    /* User provided size should reflect amount of space made
 114     * available to the guest, so we must take account of that
 115     * which will be used by the crypto header
 116     */
 117    return blk_truncate(data->blk, data->size + headerlen, false,
 118                        data->prealloc, errp);
 119}
 120
 121
 122static QemuOptsList block_crypto_runtime_opts_luks = {
 123    .name = "crypto",
 124    .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
 125    .desc = {
 126        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
 127        { /* end of list */ }
 128    },
 129};
 130
 131
 132static QemuOptsList block_crypto_create_opts_luks = {
 133    .name = "crypto",
 134    .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
 135    .desc = {
 136        {
 137            .name = BLOCK_OPT_SIZE,
 138            .type = QEMU_OPT_SIZE,
 139            .help = "Virtual disk size"
 140        },
 141        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
 142        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
 143        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
 144        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
 145        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
 146        BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
 147        BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
 148        { /* end of list */ }
 149    },
 150};
 151
 152
 153QCryptoBlockOpenOptions *
 154block_crypto_open_opts_init(QDict *opts, Error **errp)
 155{
 156    Visitor *v;
 157    QCryptoBlockOpenOptions *ret;
 158
 159    v = qobject_input_visitor_new_flat_confused(opts, errp);
 160    if (!v) {
 161        return NULL;
 162    }
 163
 164    visit_type_QCryptoBlockOpenOptions(v, NULL, &ret, errp);
 165
 166    visit_free(v);
 167    return ret;
 168}
 169
 170
 171QCryptoBlockCreateOptions *
 172block_crypto_create_opts_init(QDict *opts, Error **errp)
 173{
 174    Visitor *v;
 175    QCryptoBlockCreateOptions *ret;
 176
 177    v = qobject_input_visitor_new_flat_confused(opts, errp);
 178    if (!v) {
 179        return NULL;
 180    }
 181
 182    visit_type_QCryptoBlockCreateOptions(v, NULL, &ret, errp);
 183
 184    visit_free(v);
 185    return ret;
 186}
 187
 188
 189static int block_crypto_open_generic(QCryptoBlockFormat format,
 190                                     QemuOptsList *opts_spec,
 191                                     BlockDriverState *bs,
 192                                     QDict *options,
 193                                     int flags,
 194                                     Error **errp)
 195{
 196    BlockCrypto *crypto = bs->opaque;
 197    QemuOpts *opts = NULL;
 198    Error *local_err = NULL;
 199    int ret = -EINVAL;
 200    QCryptoBlockOpenOptions *open_opts = NULL;
 201    unsigned int cflags = 0;
 202    QDict *cryptoopts = NULL;
 203
 204    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
 205                               false, errp);
 206    if (!bs->file) {
 207        return -EINVAL;
 208    }
 209
 210    bs->supported_write_flags = BDRV_REQ_FUA &
 211        bs->file->bs->supported_write_flags;
 212
 213    opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
 214    qemu_opts_absorb_qdict(opts, options, &local_err);
 215    if (local_err) {
 216        error_propagate(errp, local_err);
 217        goto cleanup;
 218    }
 219
 220    cryptoopts = qemu_opts_to_qdict(opts, NULL);
 221    qdict_put_str(cryptoopts, "format", QCryptoBlockFormat_str(format));
 222
 223    open_opts = block_crypto_open_opts_init(cryptoopts, errp);
 224    if (!open_opts) {
 225        goto cleanup;
 226    }
 227
 228    if (flags & BDRV_O_NO_IO) {
 229        cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
 230    }
 231    crypto->block = qcrypto_block_open(open_opts, NULL,
 232                                       block_crypto_read_func,
 233                                       bs,
 234                                       cflags,
 235                                       1,
 236                                       errp);
 237
 238    if (!crypto->block) {
 239        ret = -EIO;
 240        goto cleanup;
 241    }
 242
 243    bs->encrypted = true;
 244
 245    ret = 0;
 246 cleanup:
 247    qobject_unref(cryptoopts);
 248    qapi_free_QCryptoBlockOpenOptions(open_opts);
 249    return ret;
 250}
 251
 252
 253static int block_crypto_co_create_generic(BlockDriverState *bs,
 254                                          int64_t size,
 255                                          QCryptoBlockCreateOptions *opts,
 256                                          PreallocMode prealloc,
 257                                          Error **errp)
 258{
 259    int ret;
 260    BlockBackend *blk;
 261    QCryptoBlock *crypto = NULL;
 262    struct BlockCryptoCreateData data;
 263
 264    blk = blk_new(bdrv_get_aio_context(bs),
 265                  BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
 266
 267    ret = blk_insert_bs(blk, bs, errp);
 268    if (ret < 0) {
 269        goto cleanup;
 270    }
 271
 272    if (prealloc == PREALLOC_MODE_METADATA) {
 273        prealloc = PREALLOC_MODE_OFF;
 274    }
 275
 276    data = (struct BlockCryptoCreateData) {
 277        .blk = blk,
 278        .size = size,
 279        .prealloc = prealloc,
 280    };
 281
 282    crypto = qcrypto_block_create(opts, NULL,
 283                                  block_crypto_init_func,
 284                                  block_crypto_write_func,
 285                                  &data,
 286                                  errp);
 287
 288    if (!crypto) {
 289        ret = -EIO;
 290        goto cleanup;
 291    }
 292
 293    ret = 0;
 294 cleanup:
 295    qcrypto_block_free(crypto);
 296    blk_unref(blk);
 297    return ret;
 298}
 299
 300static int coroutine_fn
 301block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
 302                         PreallocMode prealloc, Error **errp)
 303{
 304    BlockCrypto *crypto = bs->opaque;
 305    uint64_t payload_offset =
 306        qcrypto_block_get_payload_offset(crypto->block);
 307
 308    if (payload_offset > INT64_MAX - offset) {
 309        error_setg(errp, "The requested file size is too large");
 310        return -EFBIG;
 311    }
 312
 313    offset += payload_offset;
 314
 315    return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
 316}
 317
 318static void block_crypto_close(BlockDriverState *bs)
 319{
 320    BlockCrypto *crypto = bs->opaque;
 321    qcrypto_block_free(crypto->block);
 322}
 323
 324static int block_crypto_reopen_prepare(BDRVReopenState *state,
 325                                       BlockReopenQueue *queue, Error **errp)
 326{
 327    /* nothing needs checking */
 328    return 0;
 329}
 330
 331/*
 332 * 1 MB bounce buffer gives good performance / memory tradeoff
 333 * when using cache=none|directsync.
 334 */
 335#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
 336
 337static coroutine_fn int
 338block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
 339                       QEMUIOVector *qiov, int flags)
 340{
 341    BlockCrypto *crypto = bs->opaque;
 342    uint64_t cur_bytes; /* number of bytes in current iteration */
 343    uint64_t bytes_done = 0;
 344    uint8_t *cipher_data = NULL;
 345    QEMUIOVector hd_qiov;
 346    int ret = 0;
 347    uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
 348    uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
 349
 350    assert(!flags);
 351    assert(payload_offset < INT64_MAX);
 352    assert(QEMU_IS_ALIGNED(offset, sector_size));
 353    assert(QEMU_IS_ALIGNED(bytes, sector_size));
 354
 355    qemu_iovec_init(&hd_qiov, qiov->niov);
 356
 357    /* Bounce buffer because we don't wish to expose cipher text
 358     * in qiov which points to guest memory.
 359     */
 360    cipher_data =
 361        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
 362                                              qiov->size));
 363    if (cipher_data == NULL) {
 364        ret = -ENOMEM;
 365        goto cleanup;
 366    }
 367
 368    while (bytes) {
 369        cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
 370
 371        qemu_iovec_reset(&hd_qiov);
 372        qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
 373
 374        ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
 375                             cur_bytes, &hd_qiov, 0);
 376        if (ret < 0) {
 377            goto cleanup;
 378        }
 379
 380        if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
 381                                  cipher_data, cur_bytes, NULL) < 0) {
 382            ret = -EIO;
 383            goto cleanup;
 384        }
 385
 386        qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
 387
 388        bytes -= cur_bytes;
 389        bytes_done += cur_bytes;
 390    }
 391
 392 cleanup:
 393    qemu_iovec_destroy(&hd_qiov);
 394    qemu_vfree(cipher_data);
 395
 396    return ret;
 397}
 398
 399
 400static coroutine_fn int
 401block_crypto_co_pwritev(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 & ~BDRV_REQ_FUA));
 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're not permitted to touch
 421     * contents of qiov - it 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_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
 435
 436        if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
 437                                  cipher_data, cur_bytes, NULL) < 0) {
 438            ret = -EIO;
 439            goto cleanup;
 440        }
 441
 442        qemu_iovec_reset(&hd_qiov);
 443        qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
 444
 445        ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
 446                              cur_bytes, &hd_qiov, flags);
 447        if (ret < 0) {
 448            goto cleanup;
 449        }
 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
 462static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
 463{
 464    BlockCrypto *crypto = bs->opaque;
 465    uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
 466    bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
 467}
 468
 469
 470static int64_t block_crypto_getlength(BlockDriverState *bs)
 471{
 472    BlockCrypto *crypto = bs->opaque;
 473    int64_t len = bdrv_getlength(bs->file->bs);
 474
 475    uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
 476    assert(offset < INT64_MAX);
 477
 478    if (offset > len) {
 479        return -EIO;
 480    }
 481
 482    len -= offset;
 483
 484    return len;
 485}
 486
 487
 488static BlockMeasureInfo *block_crypto_measure(QemuOpts *opts,
 489                                              BlockDriverState *in_bs,
 490                                              Error **errp)
 491{
 492    g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
 493    Error *local_err = NULL;
 494    BlockMeasureInfo *info;
 495    uint64_t size;
 496    size_t luks_payload_size;
 497    QDict *cryptoopts;
 498
 499    /*
 500     * Preallocation mode doesn't affect size requirements but we must consume
 501     * the option.
 502     */
 503    g_free(qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC));
 504
 505    size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
 506
 507    if (in_bs) {
 508        int64_t ssize = bdrv_getlength(in_bs);
 509
 510        if (ssize < 0) {
 511            error_setg_errno(&local_err, -ssize,
 512                             "Unable to get image virtual_size");
 513            goto err;
 514        }
 515
 516        size = ssize;
 517    }
 518
 519    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
 520            &block_crypto_create_opts_luks, true);
 521    qdict_put_str(cryptoopts, "format", "luks");
 522    create_opts = block_crypto_create_opts_init(cryptoopts, &local_err);
 523    qobject_unref(cryptoopts);
 524    if (!create_opts) {
 525        goto err;
 526    }
 527
 528    if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
 529                                                &luks_payload_size,
 530                                                &local_err)) {
 531        goto err;
 532    }
 533
 534    /*
 535     * Unallocated blocks are still encrypted so allocation status makes no
 536     * difference to the file size.
 537     */
 538    info = g_new(BlockMeasureInfo, 1);
 539    info->fully_allocated = luks_payload_size + size;
 540    info->required = luks_payload_size + size;
 541    return info;
 542
 543err:
 544    error_propagate(errp, local_err);
 545    return NULL;
 546}
 547
 548
 549static int block_crypto_probe_luks(const uint8_t *buf,
 550                                   int buf_size,
 551                                   const char *filename) {
 552    return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
 553                                      buf, buf_size, filename);
 554}
 555
 556static int block_crypto_open_luks(BlockDriverState *bs,
 557                                  QDict *options,
 558                                  int flags,
 559                                  Error **errp)
 560{
 561    return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
 562                                     &block_crypto_runtime_opts_luks,
 563                                     bs, options, flags, errp);
 564}
 565
 566static int coroutine_fn
 567block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
 568{
 569    BlockdevCreateOptionsLUKS *luks_opts;
 570    BlockDriverState *bs = NULL;
 571    QCryptoBlockCreateOptions create_opts;
 572    PreallocMode preallocation = PREALLOC_MODE_OFF;
 573    int ret;
 574
 575    assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
 576    luks_opts = &create_options->u.luks;
 577
 578    bs = bdrv_open_blockdev_ref(luks_opts->file, errp);
 579    if (bs == NULL) {
 580        return -EIO;
 581    }
 582
 583    create_opts = (QCryptoBlockCreateOptions) {
 584        .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
 585        .u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts),
 586    };
 587
 588    if (luks_opts->has_preallocation) {
 589        preallocation = luks_opts->preallocation;
 590    }
 591
 592    ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
 593                                         preallocation, errp);
 594    if (ret < 0) {
 595        goto fail;
 596    }
 597
 598    ret = 0;
 599fail:
 600    bdrv_unref(bs);
 601    return ret;
 602}
 603
 604static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
 605                                                         const char *filename,
 606                                                         QemuOpts *opts,
 607                                                         Error **errp)
 608{
 609    QCryptoBlockCreateOptions *create_opts = NULL;
 610    BlockDriverState *bs = NULL;
 611    QDict *cryptoopts;
 612    PreallocMode prealloc;
 613    char *buf = NULL;
 614    int64_t size;
 615    int ret;
 616    Error *local_err = NULL;
 617
 618    /* Parse options */
 619    size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
 620
 621    buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
 622    prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
 623                               PREALLOC_MODE_OFF, &local_err);
 624    g_free(buf);
 625    if (local_err) {
 626        error_propagate(errp, local_err);
 627        return -EINVAL;
 628    }
 629
 630    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
 631                                             &block_crypto_create_opts_luks,
 632                                             true);
 633
 634    qdict_put_str(cryptoopts, "format", "luks");
 635    create_opts = block_crypto_create_opts_init(cryptoopts, errp);
 636    if (!create_opts) {
 637        ret = -EINVAL;
 638        goto fail;
 639    }
 640
 641    /* Create protocol layer */
 642    ret = bdrv_create_file(filename, opts, errp);
 643    if (ret < 0) {
 644        goto fail;
 645    }
 646
 647    bs = bdrv_open(filename, NULL, NULL,
 648                   BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
 649    if (!bs) {
 650        ret = -EINVAL;
 651        goto fail;
 652    }
 653
 654    /* Create format layer */
 655    ret = block_crypto_co_create_generic(bs, size, create_opts, prealloc, errp);
 656    if (ret < 0) {
 657        goto fail;
 658    }
 659
 660    ret = 0;
 661fail:
 662    /*
 663     * If an error occurred, delete 'filename'. Even if the file existed
 664     * beforehand, it has been truncated and corrupted in the process.
 665     */
 666    if (ret && bs) {
 667        Error *local_delete_err = NULL;
 668        int r_del = bdrv_co_delete_file(bs, &local_delete_err);
 669        /*
 670         * ENOTSUP will happen if the block driver doesn't support
 671         * the 'bdrv_co_delete_file' interface. This is a predictable
 672         * scenario and shouldn't be reported back to the user.
 673         */
 674        if ((r_del < 0) && (r_del != -ENOTSUP)) {
 675            error_report_err(local_delete_err);
 676        }
 677    }
 678
 679    bdrv_unref(bs);
 680    qapi_free_QCryptoBlockCreateOptions(create_opts);
 681    qobject_unref(cryptoopts);
 682    return ret;
 683}
 684
 685static int block_crypto_get_info_luks(BlockDriverState *bs,
 686                                      BlockDriverInfo *bdi)
 687{
 688    BlockDriverInfo subbdi;
 689    int ret;
 690
 691    ret = bdrv_get_info(bs->file->bs, &subbdi);
 692    if (ret != 0) {
 693        return ret;
 694    }
 695
 696    bdi->unallocated_blocks_are_zero = false;
 697    bdi->cluster_size = subbdi.cluster_size;
 698
 699    return 0;
 700}
 701
 702static ImageInfoSpecific *
 703block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
 704{
 705    BlockCrypto *crypto = bs->opaque;
 706    ImageInfoSpecific *spec_info;
 707    QCryptoBlockInfo *info;
 708
 709    info = qcrypto_block_get_info(crypto->block, errp);
 710    if (!info) {
 711        return NULL;
 712    }
 713    assert(info->format == Q_CRYPTO_BLOCK_FORMAT_LUKS);
 714
 715    spec_info = g_new(ImageInfoSpecific, 1);
 716    spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
 717    spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);
 718    *spec_info->u.luks.data = info->u.luks;
 719
 720    /* Blank out pointers we've just stolen to avoid double free */
 721    memset(&info->u.luks, 0, sizeof(info->u.luks));
 722
 723    qapi_free_QCryptoBlockInfo(info);
 724
 725    return spec_info;
 726}
 727
 728static const char *const block_crypto_strong_runtime_opts[] = {
 729    BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
 730
 731    NULL
 732};
 733
 734static BlockDriver bdrv_crypto_luks = {
 735    .format_name        = "luks",
 736    .instance_size      = sizeof(BlockCrypto),
 737    .bdrv_probe         = block_crypto_probe_luks,
 738    .bdrv_open          = block_crypto_open_luks,
 739    .bdrv_close         = block_crypto_close,
 740    /* This driver doesn't modify LUKS metadata except when creating image.
 741     * Allow share-rw=on as a special case. */
 742    .bdrv_child_perm    = bdrv_filter_default_perms,
 743    .bdrv_co_create     = block_crypto_co_create_luks,
 744    .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
 745    .bdrv_co_truncate   = block_crypto_co_truncate,
 746    .create_opts        = &block_crypto_create_opts_luks,
 747
 748    .bdrv_reopen_prepare = block_crypto_reopen_prepare,
 749    .bdrv_refresh_limits = block_crypto_refresh_limits,
 750    .bdrv_co_preadv     = block_crypto_co_preadv,
 751    .bdrv_co_pwritev    = block_crypto_co_pwritev,
 752    .bdrv_getlength     = block_crypto_getlength,
 753    .bdrv_measure       = block_crypto_measure,
 754    .bdrv_get_info      = block_crypto_get_info_luks,
 755    .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
 756
 757    .strong_runtime_opts = block_crypto_strong_runtime_opts,
 758};
 759
 760static void block_crypto_init(void)
 761{
 762    bdrv_register(&bdrv_crypto_luks);
 763}
 764
 765block_init(block_crypto_init);
 766