/*
 * QEMU Random Number Generator Backend
 *
 * Copyright IBM, Corp. 2012
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/rng-random.h"
#include "qemu/rng.h"
#include "qapi/qmp/qerror.h"
#include "qemu/main-loop.h"

struct RndRandom
{
    RngBackend parent;

    int fd;
    char *filename;

    EntropyReceiveFunc *receive_func;
    void *opaque;
    size_t size;
};

/**
 * A simple and incomplete backend to request entropy from /dev/random.
 *
 * This backend exposes an additional "filename" property that can be used to
 * set the filename to use to open the backend.
 */

static void entropy_available(void *opaque)
{
    RndRandom *s = RNG_RANDOM(opaque);
    uint8_t buffer[s->size];
    ssize_t len;

    len = read(s->fd, buffer, s->size);
    if (len < 0 && errno == EAGAIN) {
        return;
    }
    g_assert(len != -1);

    s->receive_func(s->opaque, buffer, len);
    s->receive_func = NULL;

    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
}

static void rng_random_request_entropy(RngBackend *b, size_t size,
                                        EntropyReceiveFunc *receive_entropy,
                                        void *opaque)
{
    RndRandom *s = RNG_RANDOM(b);

    if (s->receive_func) {
        s->receive_func(s->opaque, NULL, 0);
    }

    s->receive_func = receive_entropy;
    s->opaque = opaque;
    s->size = size;

    qemu_set_fd_handler(s->fd, entropy_available, NULL, s);
}

static void rng_random_opened(RngBackend *b, Error **errp)
{
    RndRandom *s = RNG_RANDOM(b);

    if (s->filename == NULL) {
        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
                  "filename", "a valid filename");
    } else {
        s->fd = open(s->filename, O_RDONLY | O_NONBLOCK);

        if (s->fd == -1) {
            error_set(errp, QERR_OPEN_FILE_FAILED, s->filename);
        }
    }
}

static char *rng_random_get_filename(Object *obj, Error **errp)
{
    RndRandom *s = RNG_RANDOM(obj);

    if (s->filename) {
        return g_strdup(s->filename);
    }

    return NULL;
}

static void rng_random_set_filename(Object *obj, const char *filename,
                                 Error **errp)
{
    RngBackend *b = RNG_BACKEND(obj);
    RndRandom *s = RNG_RANDOM(obj);

    if (b->opened) {
        error_set(errp, QERR_PERMISSION_DENIED);
        return;
    }

    if (s->filename) {
        g_free(s->filename);
    }

    s->filename = g_strdup(filename);
}

static void rng_random_init(Object *obj)
{
    RndRandom *s = RNG_RANDOM(obj);

    object_property_add_str(obj, "filename",
                            rng_random_get_filename,
                            rng_random_set_filename,
                            NULL);

    s->filename = g_strdup("/dev/random");
}

static void rng_random_finalize(Object *obj)
{
    RndRandom *s = RNG_RANDOM(obj);

    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);

    if (s->fd != -1) {
        close(s->fd);
    }

    g_free(s->filename);
}

static void rng_random_class_init(ObjectClass *klass, void *data)
{
    RngBackendClass *rbc = RNG_BACKEND_CLASS(klass);

    rbc->request_entropy = rng_random_request_entropy;
    rbc->opened = rng_random_opened;
}

static const TypeInfo rng_random_info = {
    .name = TYPE_RNG_RANDOM,
    .parent = TYPE_RNG_BACKEND,
    .instance_size = sizeof(RndRandom),
    .class_init = rng_random_class_init,
    .instance_init = rng_random_init,
    .instance_finalize = rng_random_finalize,
};

static void register_types(void)
{
    type_register_static(&rng_random_info);
}

type_init(register_types);
