/*
 * 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 "qemu/thread.h"
#include "qapi/error.h"
#include "crypto/pbkdf.h"
#ifndef _WIN32
#include <sys/resource.h>
#endif
#ifdef CONFIG_DARWIN
#include <mach/mach_init.h>
#include <mach/thread_act.h>
#include <mach/mach_port.h>
#endif


static int qcrypto_pbkdf2_get_thread_cpu(unsigned long long *val_ms,
                                         Error **errp)
{
#ifdef _WIN32
    FILETIME creation_time, exit_time, kernel_time, user_time;
    ULARGE_INTEGER thread_time;

    if (!GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time,
                        &kernel_time, &user_time)) {
        error_setg(errp, "Unable to get thread CPU usage");
        return -1;
    }

    thread_time.LowPart = user_time.dwLowDateTime;
    thread_time.HighPart = user_time.dwHighDateTime;

    /* QuadPart is units of 100ns and we want ms as unit */
    *val_ms = thread_time.QuadPart / 10000ll;
    return 0;
#elif defined(CONFIG_DARWIN)
    mach_port_t thread;
    kern_return_t kr;
    mach_msg_type_number_t count;
    thread_basic_info_data_t info;

    thread = mach_thread_self();
    count = THREAD_BASIC_INFO_COUNT;
    kr = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&info, &count);
    mach_port_deallocate(mach_task_self(), thread);
    if (kr != KERN_SUCCESS || (info.flags & TH_FLAGS_IDLE) != 0) {
        error_setg_errno(errp, errno, "Unable to get thread CPU usage");
        return -1;
    }

    *val_ms = ((info.user_time.seconds * 1000ll) +
               (info.user_time.microseconds / 1000));
    return 0;
#elif defined(RUSAGE_THREAD)
    struct rusage ru;
    if (getrusage(RUSAGE_THREAD, &ru) < 0) {
        error_setg_errno(errp, errno, "Unable to get thread CPU usage");
        return -1;
    }

    *val_ms = ((ru.ru_utime.tv_sec * 1000ll) +
               (ru.ru_utime.tv_usec / 1000));
    return 0;
#else
    *val_ms = 0;
    error_setg(errp, "Unable to calculate thread CPU usage on this platform");
    return -1;
#endif
}

typedef struct CountItersData {
    QCryptoHashAlgo hash;
    const uint8_t *key;
    size_t nkey;
    const uint8_t *salt;
    size_t nsalt;
    size_t nout;
    uint64_t iterations;
    Error **errp;
} CountItersData;

static void *threaded_qcrypto_pbkdf2_count_iters(void *data)
{
    CountItersData *iters_data = (CountItersData *) data;
    QCryptoHashAlgo hash = iters_data->hash;
    const uint8_t *key = iters_data->key;
    size_t nkey = iters_data->nkey;
    const uint8_t *salt = iters_data->salt;
    size_t nsalt = iters_data->nsalt;
    size_t nout = iters_data->nout;
    Error **errp = iters_data->errp;

    uint64_t ret = -1;
    g_autofree uint8_t *out = g_new(uint8_t, nout);
    uint64_t iterations = (1 << 15);
    unsigned long long delta_ms, start_ms, end_ms;

    while (1) {
        if (qcrypto_pbkdf2_get_thread_cpu(&start_ms, errp) < 0) {
            goto cleanup;
        }
        if (qcrypto_pbkdf2(hash,
                           key, nkey,
                           salt, nsalt,
                           iterations,
                           out, nout,
                           errp) < 0) {
            goto cleanup;
        }
        if (qcrypto_pbkdf2_get_thread_cpu(&end_ms, errp) < 0) {
            goto cleanup;
        }

        delta_ms = end_ms - start_ms;

        if (delta_ms == 0) { /* sanity check */
            error_setg(errp, "Unable to get accurate CPU usage");
            goto cleanup;
        } else if (delta_ms > 500) {
            break;
        } else if (delta_ms < 100) {
            iterations = iterations * 10;
        } else {
            iterations = (iterations * 1000 / delta_ms);
        }
    }

    iterations = iterations * 1000 / delta_ms;

    ret = iterations;

 cleanup:
    memset(out, 0, nout);
    iters_data->iterations = ret;
    return NULL;
}

uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgo hash,
                                    const uint8_t *key, size_t nkey,
                                    const uint8_t *salt, size_t nsalt,
                                    size_t nout,
                                    Error **errp)
{
    CountItersData data = {
        hash, key, nkey, salt, nsalt, nout, 0, errp
    };
    QemuThread thread;

    qemu_thread_create(&thread, "pbkdf2", threaded_qcrypto_pbkdf2_count_iters,
                       &data, QEMU_THREAD_JOINABLE);
    qemu_thread_join(&thread);

    return data.iterations;
}
