/*
 * QEMU Crypto hash algorithms
 *
 * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
 * 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
QCryptoHash *qcrypto_gcrypt_hash_new(QCryptoHashAlgo alg, Error **errp)
{
    QCryptoHash *hash;
    int ret;

    hash = g_new(QCryptoHash, 1);
    hash->alg = alg;
    hash->opaque = g_new(gcry_md_hd_t, 1);

    ret = gcry_md_open((gcry_md_hd_t *) hash->opaque,
                       qcrypto_hash_alg_map[alg], 0);
    if (ret < 0) {
        error_setg(errp,
                   "Unable to initialize hash algorithm: %s",
                   gcry_strerror(ret));
        g_free(hash->opaque);
        g_free(hash);
        return NULL;
    }
    return hash;
}

static
void qcrypto_gcrypt_hash_free(QCryptoHash *hash)
{
    gcry_md_hd_t *ctx = hash->opaque;

    if (ctx) {
        gcry_md_close(*ctx);
        g_free(ctx);
    }

    g_free(hash);
}


static
int qcrypto_gcrypt_hash_update(QCryptoHash *hash,
                               const struct iovec *iov,
                               size_t niov,
                               Error **errp)
{
    gcry_md_hd_t *ctx = hash->opaque;

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

    return 0;
}

static
int qcrypto_gcrypt_hash_finalize(QCryptoHash *hash,
                                 uint8_t **result,
                                 size_t *result_len,
                                 Error **errp)
{
    unsigned char *digest;
    gcry_md_hd_t *ctx = hash->opaque;

    *result_len = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[hash->alg]);
    if (*result_len == 0) {
        error_setg(errp, "Unable to get hash length");
        return -1;
    }

    *result = g_new(uint8_t, *result_len);

    /* Digest is freed by gcry_md_close(), copy it */
    digest = gcry_md_read(*ctx, 0);
    memcpy(*result, digest, *result_len);
    return 0;
}

QCryptoHashDriver qcrypto_hash_lib_driver = {
    .hash_new      = qcrypto_gcrypt_hash_new,
    .hash_update   = qcrypto_gcrypt_hash_update,
    .hash_finalize = qcrypto_gcrypt_hash_finalize,
    .hash_free     = qcrypto_gcrypt_hash_free,
};
