/*
 * 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 "crypto/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,
};
