/*
 * QEMU Crypto anti forensic information splitter
 *
 * Copyright (c) 2015-2016 Red Hat, Inc.
 *
 * Derived from cryptsetup package lib/luks1/af.c
 *
 * Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
 * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/bswap.h"
#include "crypto/afsplit.h"
#include "crypto/random.h"


static void qcrypto_afsplit_xor(size_t blocklen,
                                const uint8_t *in1,
                                const uint8_t *in2,
                                uint8_t *out)
{
    size_t i;
    for (i = 0; i < blocklen; i++) {
        out[i] = in1[i] ^ in2[i];
    }
}


static int qcrypto_afsplit_hash(QCryptoHashAlgo hash,
                                size_t blocklen,
                                uint8_t *block,
                                Error **errp)
{
    size_t digestlen = qcrypto_hash_digest_len(hash);

    size_t hashcount = blocklen / digestlen;
    size_t finallen = blocklen % digestlen;
    uint32_t i;

    if (finallen) {
        hashcount++;
    } else {
        finallen = digestlen;
    }

    for (i = 0; i < hashcount; i++) {
        g_autofree uint8_t *out = NULL;
        size_t outlen = 0;
        uint32_t iv = cpu_to_be32(i);
        struct iovec in[] = {
            { .iov_base = &iv,
              .iov_len = sizeof(iv) },
            { .iov_base = block + (i * digestlen),
              .iov_len = (i == (hashcount - 1)) ? finallen : digestlen },
        };

        if (qcrypto_hash_bytesv(hash,
                                in,
                                G_N_ELEMENTS(in),
                                &out, &outlen,
                                errp) < 0) {
            return -1;
        }

        assert(outlen == digestlen);
        memcpy(block + (i * digestlen), out,
               (i == (hashcount - 1)) ? finallen : digestlen);
    }

    return 0;
}


int qcrypto_afsplit_encode(QCryptoHashAlgo hash,
                           size_t blocklen,
                           uint32_t stripes,
                           const uint8_t *in,
                           uint8_t *out,
                           Error **errp)
{
    g_autofree uint8_t *block = g_new0(uint8_t, blocklen);
    size_t i;

    for (i = 0; i < (stripes - 1); i++) {
        if (qcrypto_random_bytes(out + (i * blocklen), blocklen, errp) < 0) {
            return -1;
        }

        qcrypto_afsplit_xor(blocklen,
                            out + (i * blocklen),
                            block,
                            block);
        if (qcrypto_afsplit_hash(hash, blocklen, block,
                                 errp) < 0) {
            return -1;
        }
    }
    qcrypto_afsplit_xor(blocklen,
                        in,
                        block,
                        out + (i * blocklen));
    return 0;
}


int qcrypto_afsplit_decode(QCryptoHashAlgo hash,
                           size_t blocklen,
                           uint32_t stripes,
                           const uint8_t *in,
                           uint8_t *out,
                           Error **errp)
{
    g_autofree uint8_t *block = g_new0(uint8_t, blocklen);
    size_t i;

    for (i = 0; i < (stripes - 1); i++) {
        qcrypto_afsplit_xor(blocklen,
                            in + (i * blocklen),
                            block,
                            block);
        if (qcrypto_afsplit_hash(hash, blocklen, block,
                                 errp) < 0) {
            return -1;
        }
    }

    qcrypto_afsplit_xor(blocklen,
                        in + (i * blocklen),
                        block,
                        out);
    return 0;
}
