/*
 * QEMU guest-visible random functions
 *
 * Copyright 2019 Linaro, Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 */

#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qemu/guest-random.h"
#include "crypto/random.h"


static __thread GRand *thread_rand;
static bool deterministic;


static int glib_random_bytes(void *buf, size_t len)
{
    GRand *rand = thread_rand;
    size_t i;
    uint32_t x;

    if (unlikely(rand == NULL)) {
        /* Thread not initialized for a cpu, or main w/o -seed.  */
        thread_rand = rand = g_rand_new();
    }

    for (i = 0; i + 4 <= len; i += 4) {
        x = g_rand_int(rand);
        __builtin_memcpy(buf + i, &x, 4);
    }
    if (i < len) {
        x = g_rand_int(rand);
        __builtin_memcpy(buf + i, &x, i - len);
    }
    return 0;
}

int qemu_guest_getrandom(void *buf, size_t len, Error **errp)
{
    if (unlikely(deterministic)) {
        /* Deterministic implementation using Glib's Mersenne Twister.  */
        return glib_random_bytes(buf, len);
    } else {
        /* Non-deterministic implementation using crypto routines.  */
        return qcrypto_random_bytes(buf, len, errp);
    }
}

void qemu_guest_getrandom_nofail(void *buf, size_t len)
{
    (void)qemu_guest_getrandom(buf, len, &error_fatal);
}

uint64_t qemu_guest_random_seed_thread_part1(void)
{
    if (deterministic) {
        uint64_t ret;
        glib_random_bytes(&ret, sizeof(ret));
        return ret;
    }
    return 0;
}

void qemu_guest_random_seed_thread_part2(uint64_t seed)
{
    g_assert(thread_rand == NULL);
    if (deterministic) {
        thread_rand =
            g_rand_new_with_seed_array((const guint32 *)&seed,
                                       sizeof(seed) / sizeof(guint32));
    }
}

int qemu_guest_random_seed_main(const char *optarg, Error **errp)
{
    unsigned long long seed;
    if (parse_uint_full(optarg, &seed, 0)) {
        error_setg(errp, "Invalid seed number: %s", optarg);
        return -1;
    } else {
        deterministic = true;
        qemu_guest_random_seed_thread_part2(seed);
        return 0;
    }
}
