/*
 * QEMU Crypto block device encryption QCow/QCow2 AES-CBC format
 *
 * 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 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/>.
 *
 */

/*
 * Note that the block encryption implemented in this file is broken
 * by design. This exists only to allow data to be liberated from
 * existing qcow[2] images and should not be used in any new areas.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"

#include "block-qcow.h"
#include "crypto/secret.h"

#define QCRYPTO_BLOCK_QCOW_SECTOR_SIZE 512


static bool
qcrypto_block_qcow_has_format(const uint8_t *buf G_GNUC_UNUSED,
                              size_t buf_size G_GNUC_UNUSED)
{
    return false;
}


static int
qcrypto_block_qcow_init(QCryptoBlock *block,
                        const char *keysecret,
                        Error **errp)
{
    char *password;
    int ret;
    uint8_t keybuf[16];
    int len;

    memset(keybuf, 0, 16);

    password = qcrypto_secret_lookup_as_utf8(keysecret, errp);
    if (!password) {
        return -1;
    }

    len = strlen(password);
    memcpy(keybuf, password, MIN(len, sizeof(keybuf)));
    g_free(password);

    block->niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128,
                                           QCRYPTO_CIPHER_MODE_CBC);
    block->ivgen = qcrypto_ivgen_new(QCRYPTO_IVGEN_ALG_PLAIN64,
                                     0, 0, NULL, 0, errp);
    if (!block->ivgen) {
        ret = -ENOTSUP;
        goto fail;
    }

    block->cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
                                       QCRYPTO_CIPHER_MODE_CBC,
                                       keybuf, G_N_ELEMENTS(keybuf),
                                       errp);
    if (!block->cipher) {
        ret = -ENOTSUP;
        goto fail;
    }

    block->sector_size = QCRYPTO_BLOCK_QCOW_SECTOR_SIZE;
    block->payload_offset = 0;

    return 0;

 fail:
    qcrypto_cipher_free(block->cipher);
    qcrypto_ivgen_free(block->ivgen);
    return ret;
}


static int
qcrypto_block_qcow_open(QCryptoBlock *block,
                        QCryptoBlockOpenOptions *options,
                        const char *optprefix,
                        QCryptoBlockReadFunc readfunc G_GNUC_UNUSED,
                        void *opaque G_GNUC_UNUSED,
                        unsigned int flags,
                        Error **errp)
{
    if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
        return 0;
    } else {
        if (!options->u.qcow.key_secret) {
            error_setg(errp,
                       "Parameter '%skey-secret' is required for cipher",
                       optprefix ? optprefix : "");
            return -1;
        }
        return qcrypto_block_qcow_init(block,
                                       options->u.qcow.key_secret, errp);
    }
}


static int
qcrypto_block_qcow_create(QCryptoBlock *block,
                          QCryptoBlockCreateOptions *options,
                          const char *optprefix,
                          QCryptoBlockInitFunc initfunc G_GNUC_UNUSED,
                          QCryptoBlockWriteFunc writefunc G_GNUC_UNUSED,
                          void *opaque G_GNUC_UNUSED,
                          Error **errp)
{
    if (!options->u.qcow.key_secret) {
        error_setg(errp, "Parameter '%skey-secret' is required for cipher",
                   optprefix ? optprefix : "");
        return -1;
    }
    /* QCow2 has no special header, since everything is hardwired */
    return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, errp);
}


static void
qcrypto_block_qcow_cleanup(QCryptoBlock *block)
{
}


static int
qcrypto_block_qcow_decrypt(QCryptoBlock *block,
                           uint64_t offset,
                           uint8_t *buf,
                           size_t len,
                           Error **errp)
{
    assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
    assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
    return qcrypto_block_decrypt_helper(block->cipher,
                                        block->niv, block->ivgen,
                                        QCRYPTO_BLOCK_QCOW_SECTOR_SIZE,
                                        offset, buf, len, errp);
}


static int
qcrypto_block_qcow_encrypt(QCryptoBlock *block,
                           uint64_t offset,
                           uint8_t *buf,
                           size_t len,
                           Error **errp)
{
    assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
    assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE));
    return qcrypto_block_encrypt_helper(block->cipher,
                                        block->niv, block->ivgen,
                                        QCRYPTO_BLOCK_QCOW_SECTOR_SIZE,
                                        offset, buf, len, errp);
}


const QCryptoBlockDriver qcrypto_block_driver_qcow = {
    .open = qcrypto_block_qcow_open,
    .create = qcrypto_block_qcow_create,
    .cleanup = qcrypto_block_qcow_cleanup,
    .decrypt = qcrypto_block_qcow_decrypt,
    .encrypt = qcrypto_block_qcow_encrypt,
    .has_format = qcrypto_block_qcow_has_format,
};
