cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

crypto.c (27875B)


      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.1 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    bool updating_keys;
     41};
     42
     43
     44static int block_crypto_probe_generic(QCryptoBlockFormat format,
     45                                      const uint8_t *buf,
     46                                      int buf_size,
     47                                      const char *filename)
     48{
     49    if (qcrypto_block_has_format(format, buf, buf_size)) {
     50        return 100;
     51    } else {
     52        return 0;
     53    }
     54}
     55
     56
     57static ssize_t block_crypto_read_func(QCryptoBlock *block,
     58                                      size_t offset,
     59                                      uint8_t *buf,
     60                                      size_t buflen,
     61                                      void *opaque,
     62                                      Error **errp)
     63{
     64    BlockDriverState *bs = opaque;
     65    ssize_t ret;
     66
     67    ret = bdrv_pread(bs->file, offset, buf, buflen);
     68    if (ret < 0) {
     69        error_setg_errno(errp, -ret, "Could not read encryption header");
     70        return ret;
     71    }
     72    return ret;
     73}
     74
     75static ssize_t block_crypto_write_func(QCryptoBlock *block,
     76                                       size_t offset,
     77                                       const uint8_t *buf,
     78                                       size_t buflen,
     79                                       void *opaque,
     80                                       Error **errp)
     81{
     82    BlockDriverState *bs = opaque;
     83    ssize_t ret;
     84
     85    ret = bdrv_pwrite(bs->file, offset, buf, buflen);
     86    if (ret < 0) {
     87        error_setg_errno(errp, -ret, "Could not write encryption header");
     88        return ret;
     89    }
     90    return ret;
     91}
     92
     93
     94struct BlockCryptoCreateData {
     95    BlockBackend *blk;
     96    uint64_t size;
     97    PreallocMode prealloc;
     98};
     99
    100
    101static ssize_t block_crypto_create_write_func(QCryptoBlock *block,
    102                                              size_t offset,
    103                                              const uint8_t *buf,
    104                                              size_t buflen,
    105                                              void *opaque,
    106                                              Error **errp)
    107{
    108    struct BlockCryptoCreateData *data = opaque;
    109    ssize_t ret;
    110
    111    ret = blk_pwrite(data->blk, offset, buf, buflen, 0);
    112    if (ret < 0) {
    113        error_setg_errno(errp, -ret, "Could not write encryption header");
    114        return ret;
    115    }
    116    return ret;
    117}
    118
    119static ssize_t block_crypto_create_init_func(QCryptoBlock *block,
    120                                             size_t headerlen,
    121                                             void *opaque,
    122                                             Error **errp)
    123{
    124    struct BlockCryptoCreateData *data = opaque;
    125    Error *local_error = NULL;
    126    int ret;
    127
    128    if (data->size > INT64_MAX || headerlen > INT64_MAX - data->size) {
    129        ret = -EFBIG;
    130        goto error;
    131    }
    132
    133    /* User provided size should reflect amount of space made
    134     * available to the guest, so we must take account of that
    135     * which will be used by the crypto header
    136     */
    137    ret = blk_truncate(data->blk, data->size + headerlen, false,
    138                       data->prealloc, 0, &local_error);
    139
    140    if (ret >= 0) {
    141        return ret;
    142    }
    143
    144error:
    145    if (ret == -EFBIG) {
    146        /* Replace the error message with a better one */
    147        error_free(local_error);
    148        error_setg(errp, "The requested file size is too large");
    149    } else {
    150        error_propagate(errp, local_error);
    151    }
    152
    153    return ret;
    154}
    155
    156
    157static QemuOptsList block_crypto_runtime_opts_luks = {
    158    .name = "crypto",
    159    .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
    160    .desc = {
    161        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
    162        { /* end of list */ }
    163    },
    164};
    165
    166
    167static QemuOptsList block_crypto_create_opts_luks = {
    168    .name = "crypto",
    169    .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
    170    .desc = {
    171        {
    172            .name = BLOCK_OPT_SIZE,
    173            .type = QEMU_OPT_SIZE,
    174            .help = "Virtual disk size"
    175        },
    176        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
    177        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
    178        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
    179        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
    180        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
    181        BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
    182        BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
    183        { /* end of list */ }
    184    },
    185};
    186
    187
    188static QemuOptsList block_crypto_amend_opts_luks = {
    189    .name = "crypto",
    190    .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
    191    .desc = {
    192        BLOCK_CRYPTO_OPT_DEF_LUKS_STATE(""),
    193        BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(""),
    194        BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET(""),
    195        BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET(""),
    196        BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
    197        { /* end of list */ }
    198    },
    199};
    200
    201QCryptoBlockOpenOptions *
    202block_crypto_open_opts_init(QDict *opts, Error **errp)
    203{
    204    Visitor *v;
    205    QCryptoBlockOpenOptions *ret;
    206
    207    v = qobject_input_visitor_new_flat_confused(opts, errp);
    208    if (!v) {
    209        return NULL;
    210    }
    211
    212    visit_type_QCryptoBlockOpenOptions(v, NULL, &ret, errp);
    213
    214    visit_free(v);
    215    return ret;
    216}
    217
    218
    219QCryptoBlockCreateOptions *
    220block_crypto_create_opts_init(QDict *opts, Error **errp)
    221{
    222    Visitor *v;
    223    QCryptoBlockCreateOptions *ret;
    224
    225    v = qobject_input_visitor_new_flat_confused(opts, errp);
    226    if (!v) {
    227        return NULL;
    228    }
    229
    230    visit_type_QCryptoBlockCreateOptions(v, NULL, &ret, errp);
    231
    232    visit_free(v);
    233    return ret;
    234}
    235
    236QCryptoBlockAmendOptions *
    237block_crypto_amend_opts_init(QDict *opts, Error **errp)
    238{
    239    Visitor *v;
    240    QCryptoBlockAmendOptions *ret;
    241
    242    v = qobject_input_visitor_new_flat_confused(opts, errp);
    243    if (!v) {
    244        return NULL;
    245    }
    246
    247    visit_type_QCryptoBlockAmendOptions(v, NULL, &ret, errp);
    248
    249    visit_free(v);
    250    return ret;
    251}
    252
    253
    254static int block_crypto_open_generic(QCryptoBlockFormat format,
    255                                     QemuOptsList *opts_spec,
    256                                     BlockDriverState *bs,
    257                                     QDict *options,
    258                                     int flags,
    259                                     Error **errp)
    260{
    261    BlockCrypto *crypto = bs->opaque;
    262    QemuOpts *opts = NULL;
    263    int ret = -EINVAL;
    264    QCryptoBlockOpenOptions *open_opts = NULL;
    265    unsigned int cflags = 0;
    266    QDict *cryptoopts = NULL;
    267
    268    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
    269                               BDRV_CHILD_IMAGE, false, errp);
    270    if (!bs->file) {
    271        return -EINVAL;
    272    }
    273
    274    bs->supported_write_flags = BDRV_REQ_FUA &
    275        bs->file->bs->supported_write_flags;
    276
    277    opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
    278    if (!qemu_opts_absorb_qdict(opts, options, errp)) {
    279        goto cleanup;
    280    }
    281
    282    cryptoopts = qemu_opts_to_qdict(opts, NULL);
    283    qdict_put_str(cryptoopts, "format", QCryptoBlockFormat_str(format));
    284
    285    open_opts = block_crypto_open_opts_init(cryptoopts, errp);
    286    if (!open_opts) {
    287        goto cleanup;
    288    }
    289
    290    if (flags & BDRV_O_NO_IO) {
    291        cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
    292    }
    293    crypto->block = qcrypto_block_open(open_opts, NULL,
    294                                       block_crypto_read_func,
    295                                       bs,
    296                                       cflags,
    297                                       1,
    298                                       errp);
    299
    300    if (!crypto->block) {
    301        ret = -EIO;
    302        goto cleanup;
    303    }
    304
    305    bs->encrypted = true;
    306
    307    ret = 0;
    308 cleanup:
    309    qobject_unref(cryptoopts);
    310    qapi_free_QCryptoBlockOpenOptions(open_opts);
    311    return ret;
    312}
    313
    314
    315static int block_crypto_co_create_generic(BlockDriverState *bs,
    316                                          int64_t size,
    317                                          QCryptoBlockCreateOptions *opts,
    318                                          PreallocMode prealloc,
    319                                          Error **errp)
    320{
    321    int ret;
    322    BlockBackend *blk;
    323    QCryptoBlock *crypto = NULL;
    324    struct BlockCryptoCreateData data;
    325
    326    blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
    327                          errp);
    328    if (!blk) {
    329        ret = -EPERM;
    330        goto cleanup;
    331    }
    332
    333    if (prealloc == PREALLOC_MODE_METADATA) {
    334        prealloc = PREALLOC_MODE_OFF;
    335    }
    336
    337    data = (struct BlockCryptoCreateData) {
    338        .blk = blk,
    339        .size = size,
    340        .prealloc = prealloc,
    341    };
    342
    343    crypto = qcrypto_block_create(opts, NULL,
    344                                  block_crypto_create_init_func,
    345                                  block_crypto_create_write_func,
    346                                  &data,
    347                                  errp);
    348
    349    if (!crypto) {
    350        ret = -EIO;
    351        goto cleanup;
    352    }
    353
    354    ret = 0;
    355 cleanup:
    356    qcrypto_block_free(crypto);
    357    blk_unref(blk);
    358    return ret;
    359}
    360
    361static int coroutine_fn
    362block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
    363                         PreallocMode prealloc, BdrvRequestFlags flags,
    364                         Error **errp)
    365{
    366    BlockCrypto *crypto = bs->opaque;
    367    uint64_t payload_offset =
    368        qcrypto_block_get_payload_offset(crypto->block);
    369
    370    if (payload_offset > INT64_MAX - offset) {
    371        error_setg(errp, "The requested file size is too large");
    372        return -EFBIG;
    373    }
    374
    375    offset += payload_offset;
    376
    377    return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
    378}
    379
    380static void block_crypto_close(BlockDriverState *bs)
    381{
    382    BlockCrypto *crypto = bs->opaque;
    383    qcrypto_block_free(crypto->block);
    384}
    385
    386static int block_crypto_reopen_prepare(BDRVReopenState *state,
    387                                       BlockReopenQueue *queue, Error **errp)
    388{
    389    /* nothing needs checking */
    390    return 0;
    391}
    392
    393/*
    394 * 1 MB bounce buffer gives good performance / memory tradeoff
    395 * when using cache=none|directsync.
    396 */
    397#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
    398
    399static coroutine_fn int
    400block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
    401                       QEMUIOVector *qiov, BdrvRequestFlags flags)
    402{
    403    BlockCrypto *crypto = bs->opaque;
    404    uint64_t cur_bytes; /* number of bytes in current iteration */
    405    uint64_t bytes_done = 0;
    406    uint8_t *cipher_data = NULL;
    407    QEMUIOVector hd_qiov;
    408    int ret = 0;
    409    uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
    410    uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
    411
    412    assert(!flags);
    413    assert(payload_offset < INT64_MAX);
    414    assert(QEMU_IS_ALIGNED(offset, sector_size));
    415    assert(QEMU_IS_ALIGNED(bytes, sector_size));
    416
    417    qemu_iovec_init(&hd_qiov, qiov->niov);
    418
    419    /* Bounce buffer because we don't wish to expose cipher text
    420     * in qiov which points to guest memory.
    421     */
    422    cipher_data =
    423        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
    424                                              qiov->size));
    425    if (cipher_data == NULL) {
    426        ret = -ENOMEM;
    427        goto cleanup;
    428    }
    429
    430    while (bytes) {
    431        cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
    432
    433        qemu_iovec_reset(&hd_qiov);
    434        qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
    435
    436        ret = bdrv_co_preadv(bs->file, payload_offset + offset + bytes_done,
    437                             cur_bytes, &hd_qiov, 0);
    438        if (ret < 0) {
    439            goto cleanup;
    440        }
    441
    442        if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
    443                                  cipher_data, cur_bytes, NULL) < 0) {
    444            ret = -EIO;
    445            goto cleanup;
    446        }
    447
    448        qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
    449
    450        bytes -= cur_bytes;
    451        bytes_done += cur_bytes;
    452    }
    453
    454 cleanup:
    455    qemu_iovec_destroy(&hd_qiov);
    456    qemu_vfree(cipher_data);
    457
    458    return ret;
    459}
    460
    461
    462static coroutine_fn int
    463block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
    464                        QEMUIOVector *qiov, BdrvRequestFlags flags)
    465{
    466    BlockCrypto *crypto = bs->opaque;
    467    uint64_t cur_bytes; /* number of bytes in current iteration */
    468    uint64_t bytes_done = 0;
    469    uint8_t *cipher_data = NULL;
    470    QEMUIOVector hd_qiov;
    471    int ret = 0;
    472    uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
    473    uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
    474
    475    assert(!(flags & ~BDRV_REQ_FUA));
    476    assert(payload_offset < INT64_MAX);
    477    assert(QEMU_IS_ALIGNED(offset, sector_size));
    478    assert(QEMU_IS_ALIGNED(bytes, sector_size));
    479
    480    qemu_iovec_init(&hd_qiov, qiov->niov);
    481
    482    /* Bounce buffer because we're not permitted to touch
    483     * contents of qiov - it points to guest memory.
    484     */
    485    cipher_data =
    486        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
    487                                              qiov->size));
    488    if (cipher_data == NULL) {
    489        ret = -ENOMEM;
    490        goto cleanup;
    491    }
    492
    493    while (bytes) {
    494        cur_bytes = MIN(bytes, BLOCK_CRYPTO_MAX_IO_SIZE);
    495
    496        qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
    497
    498        if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
    499                                  cipher_data, cur_bytes, NULL) < 0) {
    500            ret = -EIO;
    501            goto cleanup;
    502        }
    503
    504        qemu_iovec_reset(&hd_qiov);
    505        qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes);
    506
    507        ret = bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_done,
    508                              cur_bytes, &hd_qiov, flags);
    509        if (ret < 0) {
    510            goto cleanup;
    511        }
    512
    513        bytes -= cur_bytes;
    514        bytes_done += cur_bytes;
    515    }
    516
    517 cleanup:
    518    qemu_iovec_destroy(&hd_qiov);
    519    qemu_vfree(cipher_data);
    520
    521    return ret;
    522}
    523
    524static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
    525{
    526    BlockCrypto *crypto = bs->opaque;
    527    uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
    528    bs->bl.request_alignment = sector_size; /* No sub-sector I/O */
    529}
    530
    531
    532static int64_t block_crypto_getlength(BlockDriverState *bs)
    533{
    534    BlockCrypto *crypto = bs->opaque;
    535    int64_t len = bdrv_getlength(bs->file->bs);
    536
    537    uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
    538    assert(offset < INT64_MAX);
    539
    540    if (offset > len) {
    541        return -EIO;
    542    }
    543
    544    len -= offset;
    545
    546    return len;
    547}
    548
    549
    550static BlockMeasureInfo *block_crypto_measure(QemuOpts *opts,
    551                                              BlockDriverState *in_bs,
    552                                              Error **errp)
    553{
    554    g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
    555    Error *local_err = NULL;
    556    BlockMeasureInfo *info;
    557    uint64_t size;
    558    size_t luks_payload_size;
    559    QDict *cryptoopts;
    560
    561    /*
    562     * Preallocation mode doesn't affect size requirements but we must consume
    563     * the option.
    564     */
    565    g_free(qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC));
    566
    567    size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
    568
    569    if (in_bs) {
    570        int64_t ssize = bdrv_getlength(in_bs);
    571
    572        if (ssize < 0) {
    573            error_setg_errno(&local_err, -ssize,
    574                             "Unable to get image virtual_size");
    575            goto err;
    576        }
    577
    578        size = ssize;
    579    }
    580
    581    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
    582            &block_crypto_create_opts_luks, true);
    583    qdict_put_str(cryptoopts, "format", "luks");
    584    create_opts = block_crypto_create_opts_init(cryptoopts, &local_err);
    585    qobject_unref(cryptoopts);
    586    if (!create_opts) {
    587        goto err;
    588    }
    589
    590    if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
    591                                                &luks_payload_size,
    592                                                &local_err)) {
    593        goto err;
    594    }
    595
    596    /*
    597     * Unallocated blocks are still encrypted so allocation status makes no
    598     * difference to the file size.
    599     */
    600    info = g_new0(BlockMeasureInfo, 1);
    601    info->fully_allocated = luks_payload_size + size;
    602    info->required = luks_payload_size + size;
    603    return info;
    604
    605err:
    606    error_propagate(errp, local_err);
    607    return NULL;
    608}
    609
    610
    611static int block_crypto_probe_luks(const uint8_t *buf,
    612                                   int buf_size,
    613                                   const char *filename) {
    614    return block_crypto_probe_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
    615                                      buf, buf_size, filename);
    616}
    617
    618static int block_crypto_open_luks(BlockDriverState *bs,
    619                                  QDict *options,
    620                                  int flags,
    621                                  Error **errp)
    622{
    623    return block_crypto_open_generic(Q_CRYPTO_BLOCK_FORMAT_LUKS,
    624                                     &block_crypto_runtime_opts_luks,
    625                                     bs, options, flags, errp);
    626}
    627
    628static int coroutine_fn
    629block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
    630{
    631    BlockdevCreateOptionsLUKS *luks_opts;
    632    BlockDriverState *bs = NULL;
    633    QCryptoBlockCreateOptions create_opts;
    634    PreallocMode preallocation = PREALLOC_MODE_OFF;
    635    int ret;
    636
    637    assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
    638    luks_opts = &create_options->u.luks;
    639
    640    bs = bdrv_open_blockdev_ref(luks_opts->file, errp);
    641    if (bs == NULL) {
    642        return -EIO;
    643    }
    644
    645    create_opts = (QCryptoBlockCreateOptions) {
    646        .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
    647        .u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts),
    648    };
    649
    650    if (luks_opts->has_preallocation) {
    651        preallocation = luks_opts->preallocation;
    652    }
    653
    654    ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
    655                                         preallocation, errp);
    656    if (ret < 0) {
    657        goto fail;
    658    }
    659
    660    ret = 0;
    661fail:
    662    bdrv_unref(bs);
    663    return ret;
    664}
    665
    666static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
    667                                                         const char *filename,
    668                                                         QemuOpts *opts,
    669                                                         Error **errp)
    670{
    671    QCryptoBlockCreateOptions *create_opts = NULL;
    672    BlockDriverState *bs = NULL;
    673    QDict *cryptoopts;
    674    PreallocMode prealloc;
    675    char *buf = NULL;
    676    int64_t size;
    677    int ret;
    678    Error *local_err = NULL;
    679
    680    /* Parse options */
    681    size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
    682
    683    buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
    684    prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
    685                               PREALLOC_MODE_OFF, &local_err);
    686    g_free(buf);
    687    if (local_err) {
    688        error_propagate(errp, local_err);
    689        return -EINVAL;
    690    }
    691
    692    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
    693                                             &block_crypto_create_opts_luks,
    694                                             true);
    695
    696    qdict_put_str(cryptoopts, "format", "luks");
    697    create_opts = block_crypto_create_opts_init(cryptoopts, errp);
    698    if (!create_opts) {
    699        ret = -EINVAL;
    700        goto fail;
    701    }
    702
    703    /* Create protocol layer */
    704    ret = bdrv_create_file(filename, opts, errp);
    705    if (ret < 0) {
    706        goto fail;
    707    }
    708
    709    bs = bdrv_open(filename, NULL, NULL,
    710                   BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
    711    if (!bs) {
    712        ret = -EINVAL;
    713        goto fail;
    714    }
    715
    716    /* Create format layer */
    717    ret = block_crypto_co_create_generic(bs, size, create_opts, prealloc, errp);
    718    if (ret < 0) {
    719        goto fail;
    720    }
    721
    722    ret = 0;
    723fail:
    724    /*
    725     * If an error occurred, delete 'filename'. Even if the file existed
    726     * beforehand, it has been truncated and corrupted in the process.
    727     */
    728    if (ret) {
    729        bdrv_co_delete_file_noerr(bs);
    730    }
    731
    732    bdrv_unref(bs);
    733    qapi_free_QCryptoBlockCreateOptions(create_opts);
    734    qobject_unref(cryptoopts);
    735    return ret;
    736}
    737
    738static int block_crypto_get_info_luks(BlockDriverState *bs,
    739                                      BlockDriverInfo *bdi)
    740{
    741    BlockDriverInfo subbdi;
    742    int ret;
    743
    744    ret = bdrv_get_info(bs->file->bs, &subbdi);
    745    if (ret != 0) {
    746        return ret;
    747    }
    748
    749    bdi->cluster_size = subbdi.cluster_size;
    750
    751    return 0;
    752}
    753
    754static ImageInfoSpecific *
    755block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
    756{
    757    BlockCrypto *crypto = bs->opaque;
    758    ImageInfoSpecific *spec_info;
    759    QCryptoBlockInfo *info;
    760
    761    info = qcrypto_block_get_info(crypto->block, errp);
    762    if (!info) {
    763        return NULL;
    764    }
    765    assert(info->format == Q_CRYPTO_BLOCK_FORMAT_LUKS);
    766
    767    spec_info = g_new(ImageInfoSpecific, 1);
    768    spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
    769    spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);
    770    *spec_info->u.luks.data = info->u.luks;
    771
    772    /* Blank out pointers we've just stolen to avoid double free */
    773    memset(&info->u.luks, 0, sizeof(info->u.luks));
    774
    775    qapi_free_QCryptoBlockInfo(info);
    776
    777    return spec_info;
    778}
    779
    780static int
    781block_crypto_amend_options_generic_luks(BlockDriverState *bs,
    782                                        QCryptoBlockAmendOptions *amend_options,
    783                                        bool force,
    784                                        Error **errp)
    785{
    786    BlockCrypto *crypto = bs->opaque;
    787    int ret;
    788
    789    assert(crypto);
    790    assert(crypto->block);
    791
    792    /* apply for exclusive read/write permissions to the underlying file*/
    793    crypto->updating_keys = true;
    794    ret = bdrv_child_refresh_perms(bs, bs->file, errp);
    795    if (ret) {
    796        goto cleanup;
    797    }
    798
    799    ret = qcrypto_block_amend_options(crypto->block,
    800                                      block_crypto_read_func,
    801                                      block_crypto_write_func,
    802                                      bs,
    803                                      amend_options,
    804                                      force,
    805                                      errp);
    806cleanup:
    807    /* release exclusive read/write permissions to the underlying file*/
    808    crypto->updating_keys = false;
    809    bdrv_child_refresh_perms(bs, bs->file, errp);
    810    return ret;
    811}
    812
    813static int
    814block_crypto_amend_options_luks(BlockDriverState *bs,
    815                                QemuOpts *opts,
    816                                BlockDriverAmendStatusCB *status_cb,
    817                                void *cb_opaque,
    818                                bool force,
    819                                Error **errp)
    820{
    821    BlockCrypto *crypto = bs->opaque;
    822    QDict *cryptoopts = NULL;
    823    QCryptoBlockAmendOptions *amend_options = NULL;
    824    int ret = -EINVAL;
    825
    826    assert(crypto);
    827    assert(crypto->block);
    828
    829    cryptoopts = qemu_opts_to_qdict(opts, NULL);
    830    qdict_put_str(cryptoopts, "format", "luks");
    831    amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
    832    qobject_unref(cryptoopts);
    833    if (!amend_options) {
    834        goto cleanup;
    835    }
    836    ret = block_crypto_amend_options_generic_luks(bs, amend_options,
    837                                                  force, errp);
    838cleanup:
    839    qapi_free_QCryptoBlockAmendOptions(amend_options);
    840    return ret;
    841}
    842
    843static int
    844coroutine_fn block_crypto_co_amend_luks(BlockDriverState *bs,
    845                                        BlockdevAmendOptions *opts,
    846                                        bool force,
    847                                        Error **errp)
    848{
    849    QCryptoBlockAmendOptions amend_opts;
    850
    851    amend_opts = (QCryptoBlockAmendOptions) {
    852        .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
    853        .u.luks = *qapi_BlockdevAmendOptionsLUKS_base(&opts->u.luks),
    854    };
    855    return block_crypto_amend_options_generic_luks(bs, &amend_opts,
    856                                                   force, errp);
    857}
    858
    859static void
    860block_crypto_child_perms(BlockDriverState *bs, BdrvChild *c,
    861                         const BdrvChildRole role,
    862                         BlockReopenQueue *reopen_queue,
    863                         uint64_t perm, uint64_t shared,
    864                         uint64_t *nperm, uint64_t *nshared)
    865{
    866
    867    BlockCrypto *crypto = bs->opaque;
    868
    869    bdrv_default_perms(bs, c, role, reopen_queue, perm, shared, nperm, nshared);
    870
    871    /*
    872     * For backward compatibility, manually share the write
    873     * and resize permission
    874     */
    875    *nshared |= shared & (BLK_PERM_WRITE | BLK_PERM_RESIZE);
    876    /*
    877     * Since we are not fully a format driver, don't always request
    878     * the read/resize permission but only when explicitly
    879     * requested
    880     */
    881    *nperm &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
    882    *nperm |= perm & (BLK_PERM_WRITE | BLK_PERM_RESIZE);
    883
    884    /*
    885     * This driver doesn't modify LUKS metadata except
    886     * when updating the encryption slots.
    887     * Thus unlike a proper format driver we don't ask for
    888     * shared write/read permission. However we need it
    889     * when we are updating the keys, to ensure that only we
    890     * have access to the device.
    891     *
    892     * Encryption update will set the crypto->updating_keys
    893     * during that period and refresh permissions
    894     *
    895     */
    896    if (crypto->updating_keys) {
    897        /* need exclusive write access for header update */
    898        *nperm |= BLK_PERM_WRITE;
    899        /* unshare read and write permission */
    900        *nshared &= ~(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE);
    901    }
    902}
    903
    904
    905static const char *const block_crypto_strong_runtime_opts[] = {
    906    BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
    907
    908    NULL
    909};
    910
    911static BlockDriver bdrv_crypto_luks = {
    912    .format_name        = "luks",
    913    .instance_size      = sizeof(BlockCrypto),
    914    .bdrv_probe         = block_crypto_probe_luks,
    915    .bdrv_open          = block_crypto_open_luks,
    916    .bdrv_close         = block_crypto_close,
    917    .bdrv_child_perm    = block_crypto_child_perms,
    918    .bdrv_co_create     = block_crypto_co_create_luks,
    919    .bdrv_co_create_opts = block_crypto_co_create_opts_luks,
    920    .bdrv_co_truncate   = block_crypto_co_truncate,
    921    .create_opts        = &block_crypto_create_opts_luks,
    922    .amend_opts         = &block_crypto_amend_opts_luks,
    923
    924    .bdrv_reopen_prepare = block_crypto_reopen_prepare,
    925    .bdrv_refresh_limits = block_crypto_refresh_limits,
    926    .bdrv_co_preadv     = block_crypto_co_preadv,
    927    .bdrv_co_pwritev    = block_crypto_co_pwritev,
    928    .bdrv_getlength     = block_crypto_getlength,
    929    .bdrv_measure       = block_crypto_measure,
    930    .bdrv_get_info      = block_crypto_get_info_luks,
    931    .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
    932    .bdrv_amend_options = block_crypto_amend_options_luks,
    933    .bdrv_co_amend      = block_crypto_co_amend_luks,
    934
    935    .is_format          = true,
    936
    937    .strong_runtime_opts = block_crypto_strong_runtime_opts,
    938};
    939
    940static void block_crypto_init(void)
    941{
    942    bdrv_register(&bdrv_crypto_luks);
    943}
    944
    945block_init(block_crypto_init);