/*
 * QEMU Crypto hmac algorithms (based on nettle)
 *
 * Copyright (c) 2016 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 "qapi/error.h"
#include "crypto/hmac.h"
#include <nettle/hmac.h>

typedef void (*qcrypto_nettle_hmac_setkey)(void *ctx,
              size_t key_length, const uint8_t *key);

typedef void (*qcrypto_nettle_hmac_update)(void *ctx,
              size_t length, const uint8_t *data);

typedef void (*qcrypto_nettle_hmac_digest)(void *ctx,
              size_t length, uint8_t *digest);

typedef struct QCryptoHmacNettle QCryptoHmacNettle;
struct QCryptoHmacNettle {
    union qcrypto_nettle_hmac_ctx {
        struct hmac_md5_ctx md5_ctx;
        struct hmac_sha1_ctx sha1_ctx;
        struct hmac_sha256_ctx sha256_ctx; /* equals hmac_sha224_ctx */
        struct hmac_sha512_ctx sha512_ctx; /* equals hmac_sha384_ctx */
        struct hmac_ripemd160_ctx ripemd160_ctx;
    } u;
};

struct qcrypto_nettle_hmac_alg {
    qcrypto_nettle_hmac_setkey setkey;
    qcrypto_nettle_hmac_update update;
    qcrypto_nettle_hmac_digest digest;
    size_t len;
} qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = {
    [QCRYPTO_HASH_ALG_MD5] = {
        .setkey = (qcrypto_nettle_hmac_setkey)hmac_md5_set_key,
        .update = (qcrypto_nettle_hmac_update)hmac_md5_update,
        .digest = (qcrypto_nettle_hmac_digest)hmac_md5_digest,
        .len = MD5_DIGEST_SIZE,
    },
    [QCRYPTO_HASH_ALG_SHA1] = {
        .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha1_set_key,
        .update = (qcrypto_nettle_hmac_update)hmac_sha1_update,
        .digest = (qcrypto_nettle_hmac_digest)hmac_sha1_digest,
        .len = SHA1_DIGEST_SIZE,
    },
    [QCRYPTO_HASH_ALG_SHA224] = {
        .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha224_set_key,
        .update = (qcrypto_nettle_hmac_update)hmac_sha224_update,
        .digest = (qcrypto_nettle_hmac_digest)hmac_sha224_digest,
        .len = SHA224_DIGEST_SIZE,
    },
    [QCRYPTO_HASH_ALG_SHA256] = {
        .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha256_set_key,
        .update = (qcrypto_nettle_hmac_update)hmac_sha256_update,
        .digest = (qcrypto_nettle_hmac_digest)hmac_sha256_digest,
        .len = SHA256_DIGEST_SIZE,
    },
    [QCRYPTO_HASH_ALG_SHA384] = {
        .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha384_set_key,
        .update = (qcrypto_nettle_hmac_update)hmac_sha384_update,
        .digest = (qcrypto_nettle_hmac_digest)hmac_sha384_digest,
        .len = SHA384_DIGEST_SIZE,
    },
    [QCRYPTO_HASH_ALG_SHA512] = {
        .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha512_set_key,
        .update = (qcrypto_nettle_hmac_update)hmac_sha512_update,
        .digest = (qcrypto_nettle_hmac_digest)hmac_sha512_digest,
        .len = SHA512_DIGEST_SIZE,
    },
    [QCRYPTO_HASH_ALG_RIPEMD160] = {
        .setkey = (qcrypto_nettle_hmac_setkey)hmac_ripemd160_set_key,
        .update = (qcrypto_nettle_hmac_update)hmac_ripemd160_update,
        .digest = (qcrypto_nettle_hmac_digest)hmac_ripemd160_digest,
        .len = RIPEMD160_DIGEST_SIZE,
    },
};

bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
{
    if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
        qcrypto_hmac_alg_map[alg].setkey != NULL) {
        return true;
    }

    return false;
}

QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
                              const uint8_t *key, size_t nkey,
                              Error **errp)
{
    QCryptoHmac *hmac;
    QCryptoHmacNettle *ctx;

    if (!qcrypto_hmac_supports(alg)) {
        error_setg(errp, "Unsupported hmac algorithm %s",
                   QCryptoHashAlgorithm_lookup[alg]);
        return NULL;
    }

    hmac = g_new0(QCryptoHmac, 1);
    hmac->alg = alg;

    ctx = g_new0(QCryptoHmacNettle, 1);

    qcrypto_hmac_alg_map[alg].setkey(&ctx->u, nkey, key);

    hmac->opaque = ctx;

    return hmac;
}

void qcrypto_hmac_free(QCryptoHmac *hmac)
{
    QCryptoHmacNettle *ctx;

    if (!hmac) {
        return;
    }

    ctx = hmac->opaque;

    g_free(ctx);
    g_free(hmac);
}

int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
                        const struct iovec *iov,
                        size_t niov,
                        uint8_t **result,
                        size_t *resultlen,
                        Error **errp)
{
    QCryptoHmacNettle *ctx;
    int i;

    ctx = (QCryptoHmacNettle *)hmac->opaque;

    for (i = 0; i < niov; ++i) {
        size_t len = iov[i].iov_len;
        uint8_t *base = iov[i].iov_base;
        while (len) {
            size_t shortlen = MIN(len, UINT_MAX);
            qcrypto_hmac_alg_map[hmac->alg].update(&ctx->u, len, base);
            len -= shortlen;
            base += len;
        }
    }

    if (*resultlen == 0) {
        *resultlen = qcrypto_hmac_alg_map[hmac->alg].len;
        *result = g_new0(uint8_t, *resultlen);
    } else if (*resultlen != qcrypto_hmac_alg_map[hmac->alg].len) {
        error_setg(errp,
                   "Result buffer size %zu is smaller than hash %zu",
                   *resultlen, qcrypto_hmac_alg_map[hmac->alg].len);
        return -1;
    }

    qcrypto_hmac_alg_map[hmac->alg].digest(&ctx->u, *resultlen, *result);

    return 0;
}
