/*
 * QEMU Crypto hash algorithms
 *
 * Copyright (c) 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 <gcrypt.h>
#include "qapi/error.h"
#include "crypto/hash.h"
#include "hashpriv.h"


static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALGO__MAX] = {
    [QCRYPTO_HASH_ALGO_MD5] = GCRY_MD_MD5,
    [QCRYPTO_HASH_ALGO_SHA1] = GCRY_MD_SHA1,
    [QCRYPTO_HASH_ALGO_SHA224] = GCRY_MD_SHA224,
    [QCRYPTO_HASH_ALGO_SHA256] = GCRY_MD_SHA256,
    [QCRYPTO_HASH_ALGO_SHA384] = GCRY_MD_SHA384,
    [QCRYPTO_HASH_ALGO_SHA512] = GCRY_MD_SHA512,
    [QCRYPTO_HASH_ALGO_RIPEMD160] = GCRY_MD_RMD160,
};

gboolean qcrypto_hash_supports(QCryptoHashAlgo alg)
{
    if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) &&
        qcrypto_hash_alg_map[alg] != GCRY_MD_NONE) {
        return true;
    }
    return false;
}


static int
qcrypto_gcrypt_hash_bytesv(QCryptoHashAlgo alg,
                           const struct iovec *iov,
                           size_t niov,
                           uint8_t **result,
                           size_t *resultlen,
                           Error **errp)
{
    int i, ret;
    gcry_md_hd_t md;
    unsigned char *digest;

    if (!qcrypto_hash_supports(alg)) {
        error_setg(errp,
                   "Unknown hash algorithm %d",
                   alg);
        return -1;
    }

    ret = gcry_md_open(&md, qcrypto_hash_alg_map[alg], 0);

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

    for (i = 0; i < niov; i++) {
        gcry_md_write(md, iov[i].iov_base, iov[i].iov_len);
    }

    ret = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[alg]);
    if (ret <= 0) {
        error_setg(errp,
                   "Unable to get hash length: %s",
                   gcry_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;
    }

    digest = gcry_md_read(md, 0);
    if (!digest) {
        error_setg(errp,
                   "No digest produced");
        goto error;
    }
    memcpy(*result, digest, *resultlen);

    gcry_md_close(md);
    return 0;

 error:
    gcry_md_close(md);
    return -1;
}


QCryptoHashDriver qcrypto_hash_lib_driver = {
    .hash_bytesv = qcrypto_gcrypt_hash_bytesv,
};
