/*
 * QEMU Crypto PBKDF support (Password-Based Key Derivation Function)
 *
 * Copyright (c) 2015-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 <nettle/pbkdf2.h>
#include <nettle/hmac.h>
#include "qapi/error.h"
#include "crypto/pbkdf.h"


bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash)
{
    switch (hash) {
    case QCRYPTO_HASH_ALGO_SHA1:
    case QCRYPTO_HASH_ALGO_SHA224:
    case QCRYPTO_HASH_ALGO_SHA256:
    case QCRYPTO_HASH_ALGO_SHA384:
    case QCRYPTO_HASH_ALGO_SHA512:
    case QCRYPTO_HASH_ALGO_RIPEMD160:
#ifdef CONFIG_CRYPTO_SM3
    case QCRYPTO_HASH_ALGO_SM3:
#endif
        return true;
    default:
        return false;
    }
}

int qcrypto_pbkdf2(QCryptoHashAlgo hash,
                   const uint8_t *key, size_t nkey,
                   const uint8_t *salt, size_t nsalt,
                   uint64_t iterations,
                   uint8_t *out, size_t nout,
                   Error **errp)
{
    union {
        struct hmac_md5_ctx md5;
        struct hmac_sha1_ctx sha1;
        struct hmac_sha224_ctx sha224;
        struct hmac_sha256_ctx sha256;
        struct hmac_sha384_ctx sha384;
        struct hmac_sha512_ctx sha512;
        struct hmac_ripemd160_ctx ripemd160;
#ifdef CONFIG_CRYPTO_SM3
        struct hmac_sm3_ctx sm3;
#endif
    } ctx;

    if (iterations > UINT_MAX) {
        error_setg_errno(errp, ERANGE,
                         "PBKDF iterations %llu must be less than %u",
                         (long long unsigned)iterations, UINT_MAX);
        return -1;
    }

    switch (hash) {
    case QCRYPTO_HASH_ALGO_MD5:
        hmac_md5_set_key(&ctx.md5, nkey, key);
        PBKDF2(&ctx.md5, hmac_md5_update, hmac_md5_digest,
               MD5_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
        break;

    case QCRYPTO_HASH_ALGO_SHA1:
        hmac_sha1_set_key(&ctx.sha1, nkey, key);
        PBKDF2(&ctx.sha1, hmac_sha1_update, hmac_sha1_digest,
               SHA1_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
        break;

    case QCRYPTO_HASH_ALGO_SHA224:
        hmac_sha224_set_key(&ctx.sha224, nkey, key);
        PBKDF2(&ctx.sha224, hmac_sha224_update, hmac_sha224_digest,
               SHA224_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
        break;

    case QCRYPTO_HASH_ALGO_SHA256:
        hmac_sha256_set_key(&ctx.sha256, nkey, key);
        PBKDF2(&ctx.sha256, hmac_sha256_update, hmac_sha256_digest,
               SHA256_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
        break;

    case QCRYPTO_HASH_ALGO_SHA384:
        hmac_sha384_set_key(&ctx.sha384, nkey, key);
        PBKDF2(&ctx.sha384, hmac_sha384_update, hmac_sha384_digest,
               SHA384_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
        break;

    case QCRYPTO_HASH_ALGO_SHA512:
        hmac_sha512_set_key(&ctx.sha512, nkey, key);
        PBKDF2(&ctx.sha512, hmac_sha512_update, hmac_sha512_digest,
               SHA512_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
        break;

    case QCRYPTO_HASH_ALGO_RIPEMD160:
        hmac_ripemd160_set_key(&ctx.ripemd160, nkey, key);
        PBKDF2(&ctx.ripemd160, hmac_ripemd160_update, hmac_ripemd160_digest,
               RIPEMD160_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
        break;
#ifdef CONFIG_CRYPTO_SM3
    case QCRYPTO_HASH_ALGO_SM3:
        hmac_sm3_set_key(&ctx.sm3, nkey, key);
        PBKDF2(&ctx.sm3, hmac_sm3_update, hmac_sm3_digest,
               SM3_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
        break;
#endif

    default:
        error_setg_errno(errp, ENOSYS,
                         "PBKDF does not support hash algorithm %s",
                         QCryptoHashAlgo_str(hash));
        return -1;
    }
    return 0;
}
