/*
 * QEMU Crypto block device 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 "qapi/error.h"
#include "blockpriv.h"
#include "block-qcow.h"
#include "block-luks.h"

static const QCryptoBlockDriver *qcrypto_block_drivers[] = {
    [Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow,
    [Q_CRYPTO_BLOCK_FORMAT_LUKS] = &qcrypto_block_driver_luks,
};


bool qcrypto_block_has_format(QCryptoBlockFormat format,
                              const uint8_t *buf,
                              size_t len)
{
    const QCryptoBlockDriver *driver;

    if (format >= G_N_ELEMENTS(qcrypto_block_drivers) ||
        !qcrypto_block_drivers[format]) {
        return false;
    }

    driver = qcrypto_block_drivers[format];

    return driver->has_format(buf, len);
}


QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
                                 const char *optprefix,
                                 QCryptoBlockReadFunc readfunc,
                                 void *opaque,
                                 unsigned int flags,
                                 size_t n_threads,
                                 Error **errp)
{
    QCryptoBlock *block = g_new0(QCryptoBlock, 1);

    block->format = options->format;

    if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) ||
        !qcrypto_block_drivers[options->format]) {
        error_setg(errp, "Unsupported block driver %s",
                   QCryptoBlockFormat_str(options->format));
        g_free(block);
        return NULL;
    }

    block->driver = qcrypto_block_drivers[options->format];

    if (block->driver->open(block, options, optprefix,
                            readfunc, opaque, flags, n_threads, errp) < 0)
    {
        g_free(block);
        return NULL;
    }

    qemu_mutex_init(&block->mutex);

    return block;
}


QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
                                   const char *optprefix,
                                   QCryptoBlockInitFunc initfunc,
                                   QCryptoBlockWriteFunc writefunc,
                                   void *opaque,
                                   Error **errp)
{
    QCryptoBlock *block = g_new0(QCryptoBlock, 1);

    block->format = options->format;

    if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) ||
        !qcrypto_block_drivers[options->format]) {
        error_setg(errp, "Unsupported block driver %s",
                   QCryptoBlockFormat_str(options->format));
        g_free(block);
        return NULL;
    }

    block->driver = qcrypto_block_drivers[options->format];

    if (block->driver->create(block, options, optprefix, initfunc,
                              writefunc, opaque, errp) < 0) {
        g_free(block);
        return NULL;
    }

    qemu_mutex_init(&block->mutex);

    return block;
}


static int qcrypto_block_headerlen_hdr_init_func(QCryptoBlock *block,
        size_t headerlen, void *opaque, Error **errp)
{
    size_t *headerlenp = opaque;

    /* Stash away the payload size */
    *headerlenp = headerlen;
    return 0;
}


static int qcrypto_block_headerlen_hdr_write_func(QCryptoBlock *block,
        size_t offset, const uint8_t *buf, size_t buflen,
        void *opaque, Error **errp)
{
    /* Discard the bytes, we're not actually writing to an image */
    return 0;
}


bool
qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts,
                                       const char *optprefix,
                                       size_t *len,
                                       Error **errp)
{
    /* Fake LUKS creation in order to determine the payload size */
    g_autoptr(QCryptoBlock) crypto =
        qcrypto_block_create(create_opts, optprefix,
                             qcrypto_block_headerlen_hdr_init_func,
                             qcrypto_block_headerlen_hdr_write_func,
                             len, errp);
    return crypto != NULL;
}

int qcrypto_block_amend_options(QCryptoBlock *block,
                                QCryptoBlockReadFunc readfunc,
                                QCryptoBlockWriteFunc writefunc,
                                void *opaque,
                                QCryptoBlockAmendOptions *options,
                                bool force,
                                Error **errp)
{
    if (options->format != block->format) {
        error_setg(errp,
                   "Cannot amend encryption format");
        return -1;
    }

    if (!block->driver->amend) {
        error_setg(errp,
                   "Crypto format %s doesn't support format options amendment",
                   QCryptoBlockFormat_str(block->format));
        return -1;
    }

    return block->driver->amend(block,
                                readfunc,
                                writefunc,
                                opaque,
                                options,
                                force,
                                errp);
}

QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
                                         Error **errp)
{
    QCryptoBlockInfo *info = g_new0(QCryptoBlockInfo, 1);

    info->format = block->format;

    if (block->driver->get_info &&
        block->driver->get_info(block, info, errp) < 0) {
        g_free(info);
        return NULL;
    }

    return info;
}


int qcrypto_block_decrypt(QCryptoBlock *block,
                          uint64_t offset,
                          uint8_t *buf,
                          size_t len,
                          Error **errp)
{
    return block->driver->decrypt(block, offset, buf, len, errp);
}


int qcrypto_block_encrypt(QCryptoBlock *block,
                          uint64_t offset,
                          uint8_t *buf,
                          size_t len,
                          Error **errp)
{
    return block->driver->encrypt(block, offset, buf, len, errp);
}


QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block)
{
    /* Ciphers should be accessed through pop/push method to be thread-safe.
     * Better, they should not be accessed externally at all (note, that
     * pop/push are static functions)
     * This function is used only in test with one thread (it's safe to skip
     * pop/push interface), so it's enough to assert it here:
     */
    assert(block->n_ciphers <= 1);
    return block->ciphers ? block->ciphers[0] : NULL;
}


static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block)
{
    QCryptoCipher *cipher;

    qemu_mutex_lock(&block->mutex);

    assert(block->n_free_ciphers > 0);
    block->n_free_ciphers--;
    cipher = block->ciphers[block->n_free_ciphers];

    qemu_mutex_unlock(&block->mutex);

    return cipher;
}


static void qcrypto_block_push_cipher(QCryptoBlock *block,
                                      QCryptoCipher *cipher)
{
    qemu_mutex_lock(&block->mutex);

    assert(block->n_free_ciphers < block->n_ciphers);
    block->ciphers[block->n_free_ciphers] = cipher;
    block->n_free_ciphers++;

    qemu_mutex_unlock(&block->mutex);
}


int qcrypto_block_init_cipher(QCryptoBlock *block,
                              QCryptoCipherAlgorithm alg,
                              QCryptoCipherMode mode,
                              const uint8_t *key, size_t nkey,
                              size_t n_threads, Error **errp)
{
    size_t i;

    assert(!block->ciphers && !block->n_ciphers && !block->n_free_ciphers);

    block->ciphers = g_new0(QCryptoCipher *, n_threads);

    for (i = 0; i < n_threads; i++) {
        block->ciphers[i] = qcrypto_cipher_new(alg, mode, key, nkey, errp);
        if (!block->ciphers[i]) {
            qcrypto_block_free_cipher(block);
            return -1;
        }
        block->n_ciphers++;
        block->n_free_ciphers++;
    }

    return 0;
}


void qcrypto_block_free_cipher(QCryptoBlock *block)
{
    size_t i;

    if (!block->ciphers) {
        return;
    }

    assert(block->n_ciphers == block->n_free_ciphers);

    for (i = 0; i < block->n_ciphers; i++) {
        qcrypto_cipher_free(block->ciphers[i]);
    }

    g_free(block->ciphers);
    block->ciphers = NULL;
    block->n_ciphers = block->n_free_ciphers = 0;
}

QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block)
{
    /* ivgen should be accessed under mutex. However, this function is used only
     * in test with one thread, so it's enough to assert it here:
     */
    assert(block->n_ciphers <= 1);
    return block->ivgen;
}


QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block)
{
    return block->kdfhash;
}


uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block)
{
    return block->payload_offset;
}


uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block)
{
    return block->sector_size;
}


void qcrypto_block_free(QCryptoBlock *block)
{
    if (!block) {
        return;
    }

    block->driver->cleanup(block);

    qcrypto_block_free_cipher(block);
    qcrypto_ivgen_free(block->ivgen);
    qemu_mutex_destroy(&block->mutex);
    g_free(block);
}


typedef int (*QCryptoCipherEncDecFunc)(QCryptoCipher *cipher,
                                        const void *in,
                                        void *out,
                                        size_t len,
                                        Error **errp);

static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher,
                                          size_t niv,
                                          QCryptoIVGen *ivgen,
                                          QemuMutex *ivgen_mutex,
                                          int sectorsize,
                                          uint64_t offset,
                                          uint8_t *buf,
                                          size_t len,
                                          QCryptoCipherEncDecFunc func,
                                          Error **errp)
{
    g_autofree uint8_t *iv = niv ? g_new0(uint8_t, niv) : NULL;
    int ret = -1;
    uint64_t startsector = offset / sectorsize;

    assert(QEMU_IS_ALIGNED(offset, sectorsize));
    assert(QEMU_IS_ALIGNED(len, sectorsize));

    while (len > 0) {
        size_t nbytes;
        if (niv) {
            if (ivgen_mutex) {
                qemu_mutex_lock(ivgen_mutex);
            }
            ret = qcrypto_ivgen_calculate(ivgen, startsector, iv, niv, errp);
            if (ivgen_mutex) {
                qemu_mutex_unlock(ivgen_mutex);
            }

            if (ret < 0) {
                return -1;
            }

            if (qcrypto_cipher_setiv(cipher,
                                     iv, niv,
                                     errp) < 0) {
                return -1;
            }
        }

        nbytes = len > sectorsize ? sectorsize : len;
        if (func(cipher, buf, buf, nbytes, errp) < 0) {
            return -1;
        }

        startsector++;
        buf += nbytes;
        len -= nbytes;
    }

    return 0;
}


int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *cipher,
                                        size_t niv,
                                        QCryptoIVGen *ivgen,
                                        int sectorsize,
                                        uint64_t offset,
                                        uint8_t *buf,
                                        size_t len,
                                        Error **errp)
{
    return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sectorsize,
                                          offset, buf, len,
                                          qcrypto_cipher_decrypt, errp);
}


int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *cipher,
                                        size_t niv,
                                        QCryptoIVGen *ivgen,
                                        int sectorsize,
                                        uint64_t offset,
                                        uint8_t *buf,
                                        size_t len,
                                        Error **errp)
{
    return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sectorsize,
                                          offset, buf, len,
                                          qcrypto_cipher_encrypt, errp);
}

int qcrypto_block_decrypt_helper(QCryptoBlock *block,
                                 int sectorsize,
                                 uint64_t offset,
                                 uint8_t *buf,
                                 size_t len,
                                 Error **errp)
{
    int ret;
    QCryptoCipher *cipher = qcrypto_block_pop_cipher(block);

    ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen,
                                         &block->mutex, sectorsize, offset, buf,
                                         len, qcrypto_cipher_decrypt, errp);

    qcrypto_block_push_cipher(block, cipher);

    return ret;
}

int qcrypto_block_encrypt_helper(QCryptoBlock *block,
                                 int sectorsize,
                                 uint64_t offset,
                                 uint8_t *buf,
                                 size_t len,
                                 Error **errp)
{
    int ret;
    QCryptoCipher *cipher = qcrypto_block_pop_cipher(block);

    ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen,
                                         &block->mutex, sectorsize, offset, buf,
                                         len, qcrypto_cipher_encrypt, errp);

    qcrypto_block_push_cipher(block, cipher);

    return ret;
}
