/*
 * QEMU Crypto af_alg-backend hash/hmac support
 *
 * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
 *
 * Authors:
 *    Longpeng(Mike) <longpeng2@huawei.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * (at your option) any later version.  See the COPYING file in the
 * top-level directory.
 */
#include "qemu/osdep.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "crypto/hash.h"
#include "crypto/hmac.h"
#include "hashpriv.h"
#include "hmacpriv.h"

static char *
qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg,
                               bool is_hmac,
                               Error **errp)
{
    char *name;
    const char *alg_name;

    switch (alg) {
    case QCRYPTO_HASH_ALG_MD5:
        alg_name = "md5";
        break;
    case QCRYPTO_HASH_ALG_SHA1:
        alg_name = "sha1";
        break;
    case QCRYPTO_HASH_ALG_SHA224:
        alg_name = "sha224";
        break;
    case QCRYPTO_HASH_ALG_SHA256:
        alg_name = "sha256";
        break;
    case QCRYPTO_HASH_ALG_SHA384:
        alg_name = "sha384";
        break;
    case QCRYPTO_HASH_ALG_SHA512:
        alg_name = "sha512";
        break;
    case QCRYPTO_HASH_ALG_RIPEMD160:
        alg_name = "rmd160";
        break;

    default:
        error_setg(errp, "Unsupported hash algorithm %d", alg);
        return NULL;
    }

    if (is_hmac) {
        name = g_strdup_printf("hmac(%s)", alg_name);
    } else {
        name = g_strdup_printf("%s", alg_name);
    }

    return name;
}

static QCryptoAFAlg *
qcrypto_afalg_hash_hmac_ctx_new(QCryptoHashAlgorithm alg,
                                const uint8_t *key, size_t nkey,
                                bool is_hmac, Error **errp)
{
    QCryptoAFAlg *afalg;
    char *name;

    name = qcrypto_afalg_hash_format_name(alg, is_hmac, errp);
    if (!name) {
        return NULL;
    }

    afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_HASH, name, errp);
    if (!afalg) {
        g_free(name);
        return NULL;
    }

    g_free(name);

    /* HMAC needs setkey */
    if (is_hmac) {
        if (setsockopt(afalg->tfmfd, SOL_ALG, ALG_SET_KEY,
                       key, nkey) != 0) {
            error_setg_errno(errp, errno, "Set hmac key failed");
            qcrypto_afalg_comm_free(afalg);
            return NULL;
        }
    }

    return afalg;
}

static QCryptoAFAlg *
qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg,
                           Error **errp)
{
    return qcrypto_afalg_hash_hmac_ctx_new(alg, NULL, 0, false, errp);
}

QCryptoAFAlg *
qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg,
                           const uint8_t *key, size_t nkey,
                           Error **errp)
{
    return qcrypto_afalg_hash_hmac_ctx_new(alg, key, nkey, true, errp);
}

static int
qcrypto_afalg_hash_hmac_bytesv(QCryptoAFAlg *hmac,
                               QCryptoHashAlgorithm alg,
                               const struct iovec *iov,
                               size_t niov, uint8_t **result,
                               size_t *resultlen,
                               Error **errp)
{
    QCryptoAFAlg *afalg;
    struct iovec outv;
    int ret = 0;
    bool is_hmac = (hmac != NULL) ? true : false;
    const int expect_len = qcrypto_hash_digest_len(alg);

    if (*resultlen == 0) {
        *resultlen = expect_len;
        *result = g_new0(uint8_t, *resultlen);
    } else if (*resultlen != expect_len) {
        error_setg(errp,
                   "Result buffer size %zu is not match hash %d",
                   *resultlen, expect_len);
        return -1;
    }

    if (is_hmac) {
        afalg = hmac;
    } else {
        afalg = qcrypto_afalg_hash_ctx_new(alg, errp);
        if (!afalg) {
            return -1;
        }
    }

    /* send data to kernel's crypto core */
    ret = iov_send_recv(afalg->opfd, iov, niov,
                        0, iov_size(iov, niov), true);
    if (ret < 0) {
        error_setg_errno(errp, errno, "Send data to afalg-core failed");
        goto out;
    }

    /* hash && get result */
    outv.iov_base = *result;
    outv.iov_len = *resultlen;
    ret = iov_send_recv(afalg->opfd, &outv, 1,
                        0, iov_size(&outv, 1), false);
    if (ret < 0) {
        error_setg_errno(errp, errno, "Recv result from afalg-core failed");
    } else {
        ret = 0;
    }

out:
    if (!is_hmac) {
        qcrypto_afalg_comm_free(afalg);
    }
    return ret;
}

static int
qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
                          const struct iovec *iov,
                          size_t niov, uint8_t **result,
                          size_t *resultlen,
                          Error **errp)
{
    return qcrypto_afalg_hash_hmac_bytesv(NULL, alg, iov, niov, result,
                                          resultlen, errp);
}

static int
qcrypto_afalg_hmac_bytesv(QCryptoHmac *hmac,
                          const struct iovec *iov,
                          size_t niov, uint8_t **result,
                          size_t *resultlen,
                          Error **errp)
{
    return qcrypto_afalg_hash_hmac_bytesv(hmac->opaque, hmac->alg,
                                          iov, niov, result, resultlen,
                                          errp);
}

static void qcrypto_afalg_hmac_ctx_free(QCryptoHmac *hmac)
{
    QCryptoAFAlg *afalg;

    afalg = hmac->opaque;
    qcrypto_afalg_comm_free(afalg);
}

QCryptoHashDriver qcrypto_hash_afalg_driver = {
    .hash_bytesv = qcrypto_afalg_hash_bytesv,
};

QCryptoHmacDriver qcrypto_hmac_afalg_driver = {
    .hmac_bytesv = qcrypto_afalg_hmac_bytesv,
    .hmac_free = qcrypto_afalg_hmac_ctx_free,
};
