/*
 * QEMU Crypto hash algorithms
 *
 * Copyright (c) 2015 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/>.
 *
 */

#include "crypto/hash.h"

#ifdef CONFIG_GNUTLS_HASH
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>

static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG_LAST] = {
    [QCRYPTO_HASH_ALG_MD5] = GNUTLS_DIG_MD5,
    [QCRYPTO_HASH_ALG_SHA1] = GNUTLS_DIG_SHA1,
    [QCRYPTO_HASH_ALG_SHA256] = GNUTLS_DIG_SHA256,
};

gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
{
    if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map)) {
        return true;
    }
    return false;
}

int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
                        const struct iovec *iov,
                        size_t niov,
                        uint8_t **result,
                        size_t *resultlen,
                        Error **errp)
{
    int i, ret;
    gnutls_hash_hd_t dig;

    if (alg >= G_N_ELEMENTS(qcrypto_hash_alg_map)) {
        error_setg(errp,
                   "Unknown hash algorithm %d",
                   alg);
        return -1;
    }

    ret = gnutls_hash_init(&dig, qcrypto_hash_alg_map[alg]);

    if (ret < 0) {
        error_setg(errp,
                   "Unable to initialize hash algorithm: %s",
                   gnutls_strerror(ret));
        return -1;
    }

    for (i = 0; i < niov; i++) {
        ret = gnutls_hash(dig, iov[i].iov_base, iov[i].iov_len);
        if (ret < 0) {
            error_setg(errp,
                       "Unable process hash data: %s",
                       gnutls_strerror(ret));
            goto error;
        }
    }

    ret = gnutls_hash_get_len(qcrypto_hash_alg_map[alg]);
    if (ret <= 0) {
        error_setg(errp,
                   "Unable to get hash length: %s",
                   gnutls_strerror(ret));
        goto error;
    }
    if (*resultlen == 0) {
        *resultlen = ret;
        *result = g_new0(uint8_t, *resultlen);
    } else if (*resultlen != ret) {
        error_setg(errp,
                   "Result buffer size %zu is smaller than hash %d",
                   *resultlen, ret);
        goto error;
    }

    gnutls_hash_deinit(dig, *result);
    return 0;

 error:
    gnutls_hash_deinit(dig, NULL);
    return -1;
}

#else /* ! CONFIG_GNUTLS_HASH */

gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg G_GNUC_UNUSED)
{
    return false;
}

int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
                        const struct iovec *iov G_GNUC_UNUSED,
                        size_t niov G_GNUC_UNUSED,
                        uint8_t **result G_GNUC_UNUSED,
                        size_t *resultlen G_GNUC_UNUSED,
                        Error **errp)
{
    error_setg(errp,
               "Hash algorithm %d not supported without GNUTLS",
               alg);
    return -1;
}

#endif /* ! CONFIG_GNUTLS_HASH */

int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
                       const char *buf,
                       size_t len,
                       uint8_t **result,
                       size_t *resultlen,
                       Error **errp)
{
    struct iovec iov = { .iov_base = (char *)buf,
                         .iov_len = len };
    return qcrypto_hash_bytesv(alg, &iov, 1, result, resultlen, errp);
}

static const char hex[] = "0123456789abcdef";

int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
                         const struct iovec *iov,
                         size_t niov,
                         char **digest,
                         Error **errp)
{
    uint8_t *result = NULL;
    size_t resultlen = 0;
    size_t i;

    if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) {
        return -1;
    }

    *digest = g_new0(char, (resultlen * 2) + 1);
    for (i = 0 ; i < resultlen ; i++) {
        (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
        (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
    }
    (*digest)[resultlen * 2] = '\0';
    g_free(result);
    return 0;
}

int qcrypto_hash_digest(QCryptoHashAlgorithm alg,
                        const char *buf,
                        size_t len,
                        char **digest,
                        Error **errp)
{
    struct iovec iov = { .iov_base = (char *)buf, .iov_len = len };

    return qcrypto_hash_digestv(alg, &iov, 1, digest, errp);
}

int qcrypto_hash_base64v(QCryptoHashAlgorithm alg,
                         const struct iovec *iov,
                         size_t niov,
                         char **base64,
                         Error **errp)
{
    uint8_t *result = NULL;
    size_t resultlen = 0;

    if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) {
        return -1;
    }

    *base64 = g_base64_encode(result, resultlen);
    g_free(result);
    return 0;
}

int qcrypto_hash_base64(QCryptoHashAlgorithm alg,
                        const char *buf,
                        size_t len,
                        char **base64,
                        Error **errp)
{
    struct iovec iov = { .iov_base = (char *)buf, .iov_len = len };

    return qcrypto_hash_base64v(alg, &iov, 1, base64, errp);
}
