/*
 * 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(QCryptoHashAlgo alg,
                               bool is_hmac,
                               Error **errp)
{
    char *name;
    const char *alg_name;

    switch (alg) {
    case QCRYPTO_HASH_ALGO_MD5:
        alg_name = "md5";
        break;
    case QCRYPTO_HASH_ALGO_SHA1:
        alg_name = "sha1";
        break;
    case QCRYPTO_HASH_ALGO_SHA224:
        alg_name = "sha224";
        break;
    case QCRYPTO_HASH_ALGO_SHA256:
        alg_name = "sha256";
        break;
    case QCRYPTO_HASH_ALGO_SHA384:
        alg_name = "sha384";
        break;
    case QCRYPTO_HASH_ALGO_SHA512:
        alg_name = "sha512";
        break;
    case QCRYPTO_HASH_ALGO_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 QCryptoAFAlgo *
qcrypto_afalg_hash_hmac_ctx_new(QCryptoHashAlgo alg,
                                const uint8_t *key, size_t nkey,
                                bool is_hmac, Error **errp)
{
    QCryptoAFAlgo *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 QCryptoAFAlgo *
qcrypto_afalg_hash_ctx_new(QCryptoHashAlgo alg,
                           Error **errp)
{
    return qcrypto_afalg_hash_hmac_ctx_new(alg, NULL, 0, false, errp);
}

QCryptoAFAlgo *
qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgo 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(QCryptoAFAlgo *hmac,
                               QCryptoHashAlgo alg,
                               const struct iovec *iov,
                               size_t niov, uint8_t **result,
                               size_t *resultlen,
                               Error **errp)
{
    QCryptoAFAlgo *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(QCryptoHashAlgo 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)
{
    QCryptoAFAlgo *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,
};
