/*
 * QEMU block full disk encryption
 *
 * Copyright (c) 2015-2016 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"

#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "crypto/block.h"
#include "qapi/opts-visitor.h"
#include "qapi/qapi-visit-crypto.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/cutils.h"
#include "qemu/memalign.h"
#include "crypto.h"

typedef struct BlockCrypto BlockCrypto;

struct BlockCrypto {
    QCryptoBlock *block;
    bool updating_keys;
};


static int block_crypto_probe_generic(QCryptoBlockFormat format,
                                      const uint8_t *buf,
                                      int buf_size,
                                      const char *filename)
{
    if (qcrypto_block_has_format(format, buf, buf_size)) {
        return 100;
    } else {
        return 0;
    }
}


static int block_crypto_read_func(QCryptoBlock *block,
                                  size_t offset,
                                  uint8_t *buf,
                                  size_t buflen,
                                  void *opaque,
                                  Error **errp)
{
    BlockDriverState *bs = opaque;
    ssize_t ret;

    ret = bdrv_pread(bs->file, offset, buflen, buf, 0);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not read encryption header");
        return ret;
    }
    return 0;
}

static int block_crypto_write_func(QCryptoBlock *block,
                                   size_t offset,
                                   const uint8_t *buf,
                                   size_t buflen,
                                   void *opaque,
                                   Error **errp)
{
    BlockDriverState *bs = opaque;
    ssize_t ret;

    ret = bdrv_pwrite(bs->file, offset, buflen, buf, 0);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not write encryption header");
        return ret;
    }
    return 0;
}


struct BlockCryptoCreateData {
    BlockBackend *blk;
    uint64_t size;
    PreallocMode prealloc;
};


static int block_crypto_create_write_func(QCryptoBlock *block,
                                          size_t offset,
                                          const uint8_t *buf,
                                          size_t buflen,
                                          void *opaque,
                                          Error **errp)
{
    struct BlockCryptoCreateData *data = opaque;
    ssize_t ret;

    ret = blk_pwrite(data->blk, offset, buflen, buf, 0);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not write encryption header");
        return ret;
    }
    return 0;
}

static int block_crypto_create_init_func(QCryptoBlock *block,
                                         size_t headerlen,
                                         void *opaque,
                                         Error **errp)
{
    struct BlockCryptoCreateData *data = opaque;
    Error *local_error = NULL;
    int ret;

    if (data->size > INT64_MAX || headerlen > INT64_MAX - data->size) {
        ret = -EFBIG;
        goto error;
    }

    /* User provided size should reflect amount of space made
     * available to the guest, so we must take account of that
     * which will be used by the crypto header
     */
    ret = blk_truncate(data->blk, data->size + headerlen, false,
                       data->prealloc, 0, &local_error);

    if (ret >= 0) {
        return 0;
    }

error:
    if (ret == -EFBIG) {
        /* Replace the error message with a better one */
        error_free(local_error);
        error_setg(errp, "The requested file size is too large");
    } else {
        error_propagate(errp, local_error);
    }

    return ret;
}


static QemuOptsList block_crypto_runtime_opts_luks = {
    .name = "crypto",
    .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
    .desc = {
        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
        { /* end of list */ }
    },
};


static QemuOptsList block_crypto_create_opts_luks = {
    .name = "crypto",
    .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
    .desc = {
        {
            .name = BLOCK_OPT_SIZE,
            .type = QEMU_OPT_SIZE,
            .help = "Virtual disk size"
        },
        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
        { /* end of list */ }
    },
};


static QemuOptsList block_crypto_amend_opts_luks = {
    .name = "crypto",
    .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
    .desc = {
        BLOCK_CRYPTO_OPT_DEF_LUKS_STATE(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET(""),
        BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
        { /* end of list */ }
    },
};

QCryptoBlockOpenOptions *
block_crypto_open_opts_init(QDict *opts, Error **errp)
{
    Visitor *v;
    QCryptoBlockOpenOptions *ret;

    v = qobject_input_visitor_new_flat_confused(opts, errp);
    if (!v) {
        return NULL;
    }

    visit_type_QCryptoBlockOpenOptions(v, NULL, &ret, errp);

    visit_free(v);
    return ret;
}


QCryptoBlockCreateOptions *
block_crypto_create_opts_init(QDict *opts, Error **errp)
{
    Visitor *v;
    QCryptoBlockCreateOptions *ret;

    v = qobject_input_visitor_new_flat_confused(opts, errp);
    if (!v) {
        return NULL;
    }

    visit_type_QCryptoBlockCreateOptions(v, NULL, &ret, errp);

    visit_free(v);
    return ret;
}

QCryptoBlockAmendOptions *
block_crypto_amend_opts_init(QDict *opts, Error **errp)
{
    Visitor *v;
    QCryptoBlockAmendOptions *ret;

    v = qobject_input_visitor_new_flat_confused(opts, errp);
    if (!v) {
        return NULL;
    }

    visit_type_QCryptoBlockAmendOptions(v, NULL, &ret, errp);

    visit_free(v);
    return ret;
}


static int block_crypto_open_generic(QCryptoBlockFormat format,
                                     QemuOptsList *opts_spec,
                                     BlockDriverState *bs,
                                     QDict *options,
                                     int flags,
                                     Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    QemuOpts *opts = NULL;
    int ret;
    QCryptoBlockOpenOptions *open_opts = NULL;
    unsigned int cflags = 0;
    QDict *cryptoopts = NULL;

    ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
    if (ret < 0) {
        return ret;
    }

    bs->supported_write_flags = BDRV_REQ_FUA &
        bs->file->bs->supported_write_flags;

    opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
    if (!qemu_opts_absorb_qdict(opts, options, errp)) {
        ret = -EINVAL;
        goto cleanup;
    }

    cryptoopts = qemu_opts_to_qdict(opts, NULL);
    qdict_put_str(cryptoopts, "format", QCryptoBlockFormat_str(format));

    open_opts = block_crypto_open_opts_init(cryptoopts, errp);
    if (!open_opts) {
        ret = -EINVAL;
        goto cleanup;
    }

    if (flags & BDRV_O_NO_IO) {
        cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
    }
    crypto->block = qcrypto_block_open(open_opts, NULL,
                                       block_crypto_read_func,
                                       bs,
                                       cflags,
                                       1,
                                       errp);

    if (!crypto->block) {
        ret = -EIO;
        goto cleanup;
    }

    bs->encrypted = true;

    ret = 0;
 cleanup:
    qobject_unref(cryptoopts);
    qapi_free_QCryptoBlockOpenOptions(open_opts);
    return ret;
}


static int coroutine_fn
block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
                               QCryptoBlockCreateOptions *opts,
                               PreallocMode prealloc, Error **errp)
{
    int ret;
    BlockBackend *blk;
    QCryptoBlock *crypto = NULL;
    struct BlockCryptoCreateData data;

    blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
                             errp);
    if (!blk) {
        ret = -EPERM;
        goto cleanup;
    }

    if (prealloc == PREALLOC_MODE_METADATA) {
        prealloc = PREALLOC_MODE_OFF;
    }

    data = (struct BlockCryptoCreateData) {
        .blk = blk,
        .size = size,
        .prealloc = prealloc,
    };

    crypto = qcrypto_block_create(opts, NULL,
                                  block_crypto_create_init_func,
                                  block_crypto_create_write_func,
                                  &data,
                                  errp);

    if (!crypto) {
        ret = -EIO;
        goto cleanup;
    }

    ret = 0;
 cleanup:
    qcrypto_block_free(crypto);
    blk_unref(blk);
    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
                         PreallocMode prealloc, BdrvRequestFlags flags,
                         Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    uint64_t payload_offset =
        qcrypto_block_get_payload_offset(crypto->block);

    if (payload_offset > INT64_MAX - offset) {
        error_setg(errp, "The requested file size is too large");
        return -EFBIG;
    }

    offset += payload_offset;

    return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
}

static void block_crypto_close(BlockDriverState *bs)
{
    BlockCrypto *crypto = bs->opaque;
    qcrypto_block_free(crypto->block);
}

static int block_crypto_reopen_prepare(BDRVReopenState *state,
                                       BlockReopenQueue *queue, Error **errp)
{
    /* nothing needs checking */
    return 0;
}

/*
 * 1 MB bounce buffer gives good performance / memory tradeoff
 * when using cache=none|directsync.
 */
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)

static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
                       QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    BlockCrypto *crypto = bs->opaque;
    uint64_t cur_bytes; /* number of bytes in current iteration */
    uint64_t bytes_done = 0;
    uint8_t *cipher_data = NULL;
    QEMUIOVector hd_qiov;
    int ret = 0;
    uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
    uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);

    assert(payload_offset < INT64_MAX);
    assert(QEMU_IS_ALIGNED(offset, sector_size));
    assert(QEMU_IS_ALIGNED(bytes, sector_size));

    qemu_iovec_init(&hd_qiov, qiov->niov);

    /* Bounce buffer because we don't wish to expose cipher text
     * in qiov which points to guest memory.
     */
    cipher_data =
        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
                                              qiov->size));
    if (cipher_data == NULL) {
        ret = -ENOMEM;
        goto cleanup;
    }

    while (bytes) {
        cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);

        qemu_iovec_reset(&hd_qiov);
        qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);

        ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
                             cur_bytes, &hd_qiov, 0);
        if (ret < 0) {
            goto cleanup;
        }

        if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
                                  cipher_data, cur_bytes, NULL) < 0) {
            ret = -EIO;
            goto cleanup;
        }

        qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);

        bytes -= cur_bytes;
        bytes_done += cur_bytes;
    }

 cleanup:
    qemu_iovec_destroy(&hd_qiov);
    qemu_vfree(cipher_data);

    return ret;
}


static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
                        QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    BlockCrypto *crypto = bs->opaque;
    uint64_t cur_bytes; /* number of bytes in current iteration */
    uint64_t bytes_done = 0;
    uint8_t *cipher_data = NULL;
    QEMUIOVector hd_qiov;
    int ret = 0;
    uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
    uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);

    flags &= ~BDRV_REQ_REGISTERED_BUF;

    assert(payload_offset < INT64_MAX);
    assert(QEMU_IS_ALIGNED(offset, sector_size));
    assert(QEMU_IS_ALIGNED(bytes, sector_size));

    qemu_iovec_init(&hd_qiov, qiov->niov);

    /* Bounce buffer because we're not permitted to touch
     * contents of qiov - it points to guest memory.
     */
    cipher_data =
        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
                                              qiov->size));
    if (cipher_data == NULL) {
        ret = -ENOMEM;
        goto cleanup;
    }

    while (bytes) {
        cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);

        qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);

        if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
                                  cipher_data, cur_bytes, NULL) < 0) {
            ret = -EIO;
            goto cleanup;
        }

        qemu_iovec_reset(&hd_qiov);
        qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);

        ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
                              cur_bytes, &hd_qiov, flags);
        if (ret < 0) {
            goto cleanup;
        }

        bytes -= cur_bytes;
        bytes_done += cur_bytes;
    }

 cleanup:
    qemu_iovec_destroy(&hd_qiov);
    qemu_vfree(cipher_data);

    return ret;
}

static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
    bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
}


static int64_t coroutine_fn GRAPH_RDLOCK
block_crypto_co_getlength(BlockDriverState *bs)
{
    BlockCrypto *crypto = bs->opaque;
    int64_t len = bdrv_co_getlength(bs->file->bs);

    uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
    assert(offset < INT64_MAX);

    if (offset > len) {
        return -EIO;
    }

    len -= offset;

    return len;
}


static BlockMeasureInfo *block_crypto_measure(QemuOpts *opts,
                                              BlockDriverState *in_bs,
                                              Error **errp)
{
    g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
    Error *local_err = NULL;
    BlockMeasureInfo *info;
    uint64_t size;
    size_t luks_payload_size;
    QDict *cryptoopts;

    /*
     * Preallocation mode doesn't affect size requirements but we must consume
     * the option.
     */
    g_free(qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC));

    size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);

    if (in_bs) {
        int64_t ssize = bdrv_getlength(in_bs);

        if (ssize < 0) {
            error_setg_errno(&local_err, -ssize,
                             "Unable to get image virtual_size");
            goto err;
        }

        size = ssize;
    }

    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
            &block_crypto_create_opts_luks, true);
    qdict_put_str(cryptoopts, "format", "luks");
    create_opts = block_crypto_create_opts_init(cryptoopts, &local_err);
    qobject_unref(cryptoopts);
    if (!create_opts) {
        goto err;
    }

    if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
                                                &luks_payload_size,
                                                &local_err)) {
        goto err;
    }

    /*
     * Unallocated blocks are still encrypted so allocation status makes no
     * difference to the file size.
     */
    info = g_new0(BlockMeasureInfo, 1);
    info->fully_allocated = luks_payload_size + size;
    info->required = luks_payload_size + size;
    return info;

err:
    error_propagate(errp, local_err);
    return NULL;
}


static int block_crypto_probe_luks(const uint8_t *buf,
                                   int buf_size,
                                   const char *filename) {
    return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
                                      buf, buf_size, filename);
}

static int block_crypto_open_luks(BlockDriverState *bs,
                                  QDict *options,
                                  int flags,
                                  Error **errp)
{
    return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
                                     &block_crypto_runtime_opts_luks,
                                     bs, options, flags, errp);
}

static int coroutine_fn
block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
{
    BlockdevCreateOptionsLUKS *luks_opts;
    BlockDriverState *bs = NULL;
    QCryptoBlockCreateOptions create_opts;
    PreallocMode preallocation = PREALLOC_MODE_OFF;
    int ret;

    assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
    luks_opts = &create_options->u.luks;

    bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
    if (bs == NULL) {
        return -EIO;
    }

    create_opts = (QCryptoBlockCreateOptions) {
        .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
        .u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts),
    };

    if (luks_opts->has_preallocation) {
        preallocation = luks_opts->preallocation;
    }

    ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
                                         preallocation, errp);
    if (ret < 0) {
        goto fail;
    }

    ret = 0;
fail:
    bdrv_unref(bs);
    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
                                 QemuOpts *opts, Error **errp)
{
    QCryptoBlockCreateOptions *create_opts = NULL;
    BlockDriverState *bs = NULL;
    QDict *cryptoopts;
    PreallocMode prealloc;
    char *buf = NULL;
    int64_t size;
    int ret;
    Error *local_err = NULL;

    /* Parse options */
    size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);

    buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
    prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
                               PREALLOC_MODE_OFF, &local_err);
    g_free(buf);
    if (local_err) {
        error_propagate(errp, local_err);
        return -EINVAL;
    }

    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
                                             &block_crypto_create_opts_luks,
                                             true);

    qdict_put_str(cryptoopts, "format", "luks");
    create_opts = block_crypto_create_opts_init(cryptoopts, errp);
    if (!create_opts) {
        ret = -EINVAL;
        goto fail;
    }

    /* Create protocol layer */
    ret = bdrv_co_create_file(filename, opts, errp);
    if (ret < 0) {
        goto fail;
    }

    bs = bdrv_co_open(filename, NULL, NULL,
                      BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
    if (!bs) {
        ret = -EINVAL;
        goto fail;
    }

    /* Create format layer */
    ret = block_crypto_co_create_generic(bs, size, create_opts, prealloc, errp);
    if (ret < 0) {
        goto fail;
    }

    ret = 0;
fail:
    /*
     * If an error occurred, delete 'filename'. Even if the file existed
     * beforehand, it has been truncated and corrupted in the process.
     */
    if (ret) {
        bdrv_co_delete_file_noerr(bs);
    }

    bdrv_unref(bs);
    qapi_free_QCryptoBlockCreateOptions(create_opts);
    qobject_unref(cryptoopts);
    return ret;
}

static int coroutine_fn
block_crypto_co_get_info_luks(BlockDriverState *bs, BlockDriverInfo *bdi)
{
    BlockDriverInfo subbdi;
    int ret;

    ret = bdrv_co_get_info(bs->file->bs, &subbdi);
    if (ret != 0) {
        return ret;
    }

    bdi->cluster_size = subbdi.cluster_size;

    return 0;
}

static ImageInfoSpecific *
block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    ImageInfoSpecific *spec_info;
    QCryptoBlockInfo *info;

    info = qcrypto_block_get_info(crypto->block, errp);
    if (!info) {
        return NULL;
    }
    assert(info->format == Q_CRYPTO_BLOCK_FORMAT_LUKS);

    spec_info = g_new(ImageInfoSpecific, 1);
    spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
    spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);
    *spec_info->u.luks.data = info->u.luks;

    /* Blank out pointers we've just stolen to avoid double free */
    memset(&info->u.luks, 0, sizeof(info->u.luks));

    qapi_free_QCryptoBlockInfo(info);

    return spec_info;
}

static int
block_crypto_amend_prepare(BlockDriverState *bs, Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    int ret;

    /* apply for exclusive read/write permissions to the underlying file */
    crypto->updating_keys = true;
    ret = bdrv_child_refresh_perms(bs, bs->file, errp);
    if (ret < 0) {
        /* Well, in this case we will not be updating any keys */
        crypto->updating_keys = false;
    }
    return ret;
}

static void
block_crypto_amend_cleanup(BlockDriverState *bs)
{
    BlockCrypto *crypto = bs->opaque;
    Error *errp = NULL;

    /* release exclusive read/write permissions to the underlying file */
    crypto->updating_keys = false;
    bdrv_child_refresh_perms(bs, bs->file, &errp);

    if (errp) {
        error_report_err(errp);
    }
}

static int
block_crypto_amend_options_generic_luks(BlockDriverState *bs,
                                        QCryptoBlockAmendOptions *amend_options,
                                        bool force,
                                        Error **errp)
{
    BlockCrypto *crypto = bs->opaque;

    assert(crypto);
    assert(crypto->block);

    return qcrypto_block_amend_options(crypto->block,
                                       block_crypto_read_func,
                                       block_crypto_write_func,
                                       bs,
                                       amend_options,
                                       force,
                                       errp);
}

static int
block_crypto_amend_options_luks(BlockDriverState *bs,
                                QemuOpts *opts,
                                BlockDriverAmendStatusCB *status_cb,
                                void *cb_opaque,
                                bool force,
                                Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    QDict *cryptoopts = NULL;
    QCryptoBlockAmendOptions *amend_options = NULL;
    int ret = -EINVAL;

    assert(crypto);
    assert(crypto->block);

    cryptoopts = qemu_opts_to_qdict(opts, NULL);
    qdict_put_str(cryptoopts, "format", "luks");
    amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
    qobject_unref(cryptoopts);
    if (!amend_options) {
        goto cleanup;
    }

    ret = block_crypto_amend_prepare(bs, errp);
    if (ret) {
        goto perm_cleanup;
    }
    ret = block_crypto_amend_options_generic_luks(bs, amend_options,
                                                  force, errp);

perm_cleanup:
    block_crypto_amend_cleanup(bs);
cleanup:
    qapi_free_QCryptoBlockAmendOptions(amend_options);
    return ret;
}

static int
coroutine_fn block_crypto_co_amend_luks(BlockDriverState *bs,
                                        BlockdevAmendOptions *opts,
                                        bool force,
                                        Error **errp)
{
    QCryptoBlockAmendOptions amend_opts;

    amend_opts = (QCryptoBlockAmendOptions) {
        .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
        .u.luks = *qapi_BlockdevAmendOptionsLUKS_base(&opts->u.luks),
    };
    return block_crypto_amend_options_generic_luks(bs, &amend_opts,
                                                   force, errp);
}

static void
block_crypto_child_perms(BlockDriverState *bs, BdrvChild *c,
                         const BdrvChildRole role,
                         BlockReopenQueue *reopen_queue,
                         uint64_t perm, uint64_t shared,
                         uint64_t *nperm, uint64_t *nshared)
{

    BlockCrypto *crypto = bs->opaque;

    bdrv_default_perms(bs, c, role, reopen_queue, perm, shared, nperm, nshared);

    /*
     * For backward compatibility, manually share the write
     * and resize permission
     */
    *nshared |= shared & (BLK_PERM_WRITE | BLK_PERM_RESIZE);
    /*
     * Since we are not fully a format driver, don't always request
     * the read/resize permission but only when explicitly
     * requested
     */
    *nperm &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
    *nperm |= perm & (BLK_PERM_WRITE | BLK_PERM_RESIZE);

    /*
     * This driver doesn't modify LUKS metadata except
     * when updating the encryption slots.
     * Thus unlike a proper format driver we don't ask for
     * shared write/read permission. However we need it
     * when we are updating the keys, to ensure that only we
     * have access to the device.
     *
     * Encryption update will set the crypto->updating_keys
     * during that period and refresh permissions
     *
     */
    if (crypto->updating_keys) {
        /* need exclusive write access for header update */
        *nperm |= BLK_PERM_WRITE;
        /* unshare read and write permission */
        *nshared &= ~(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE);
    }
}


static const char *const block_crypto_strong_runtime_opts[] = {
    BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,

    NULL
};

static BlockDriver bdrv_crypto_luks = {
    .format_name        = "luks",
    .instance_size      = sizeof(BlockCrypto),
    .bdrv_probe         = block_crypto_probe_luks,
    .bdrv_open          = block_crypto_open_luks,
    .bdrv_close         = block_crypto_close,
    .bdrv_child_perm    = block_crypto_child_perms,
    .bdrv_co_create     = block_crypto_co_create_luks,
    .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
    .bdrv_co_truncate   = block_crypto_co_truncate,
    .create_opts        = &block_crypto_create_opts_luks,
    .amend_opts         = &block_crypto_amend_opts_luks,

    .bdrv_reopen_prepare = block_crypto_reopen_prepare,
    .bdrv_refresh_limits = block_crypto_refresh_limits,
    .bdrv_co_preadv     = block_crypto_co_preadv,
    .bdrv_co_pwritev    = block_crypto_co_pwritev,
    .bdrv_co_getlength  = block_crypto_co_getlength,
    .bdrv_measure       = block_crypto_measure,
    .bdrv_co_get_info   = block_crypto_co_get_info_luks,
    .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
    .bdrv_amend_options = block_crypto_amend_options_luks,
    .bdrv_co_amend      = block_crypto_co_amend_luks,
    .bdrv_amend_pre_run = block_crypto_amend_prepare,
    .bdrv_amend_clean   = block_crypto_amend_cleanup,

    .is_format          = true,

    .strong_runtime_opts = block_crypto_strong_runtime_opts,
};

static void block_crypto_init(void)
{
    bdrv_register(&bdrv_crypto_luks);
}

block_init(block_crypto_init);
