/*
 * AWS nitro-enclave machine
 *
 * Copyright (c) 2024 Dorjoy Chowdhury <dorjoychy111@gmail.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 "qemu/error-report.h"
#include "qapi/error.h"
#include "qom/object_interfaces.h"

#include "chardev/char.h"
#include "hw/sysbus.h"
#include "hw/core/eif.h"
#include "hw/i386/x86.h"
#include "hw/i386/microvm.h"
#include "hw/i386/nitro_enclave.h"
#include "hw/virtio/virtio-mmio.h"
#include "hw/virtio/virtio-nsm.h"
#include "hw/virtio/vhost-user-vsock.h"
#include "system/hostmem.h"

static BusState *find_free_virtio_mmio_bus(void)
{
    BusChild *kid;
    BusState *bus = sysbus_get_default();

    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;
        if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MMIO)) {
            VirtIOMMIOProxy *mmio = VIRTIO_MMIO(OBJECT(dev));
            VirtioBusState *mmio_virtio_bus = &mmio->bus;
            BusState *mmio_bus = &mmio_virtio_bus->parent_obj;
            if (QTAILQ_EMPTY(&mmio_bus->children)) {
                return mmio_bus;
            }
        }
    }

    return NULL;
}

static void vhost_user_vsock_init(NitroEnclaveMachineState *nems)
{
    DeviceState *dev = qdev_new(TYPE_VHOST_USER_VSOCK);
    VHostUserVSock *vsock = VHOST_USER_VSOCK(dev);
    BusState *bus;

    if (!nems->vsock) {
        error_report("A valid chardev id for vhost-user-vsock device must be "
                     "provided using the 'vsock' machine option");
        exit(1);
    }

    bus = find_free_virtio_mmio_bus();
    if (!bus) {
        error_report("Failed to find bus for vhost-user-vsock device");
        exit(1);
    }

    Chardev *chardev = qemu_chr_find(nems->vsock);
    if (!chardev) {
        error_report("Failed to find chardev with id %s", nems->vsock);
        exit(1);
    }

    vsock->conf.chardev.chr = chardev;

    qdev_realize_and_unref(dev, bus, &error_fatal);
}

static void virtio_nsm_init(NitroEnclaveMachineState *nems)
{
    DeviceState *dev = qdev_new(TYPE_VIRTIO_NSM);
    VirtIONSM *vnsm = VIRTIO_NSM(dev);
    BusState *bus = find_free_virtio_mmio_bus();

    if (!bus) {
        error_report("Failed to find bus for virtio-nsm device.");
        exit(1);
    }

    qdev_prop_set_string(dev, "module-id", nems->id);

    qdev_realize_and_unref(dev, bus, &error_fatal);
    nems->vnsm = vnsm;
}

static void nitro_enclave_devices_init(NitroEnclaveMachineState *nems)
{
    vhost_user_vsock_init(nems);
    virtio_nsm_init(nems);
}

static void nitro_enclave_machine_state_init(MachineState *machine)
{
    NitroEnclaveMachineClass *ne_class =
        NITRO_ENCLAVE_MACHINE_GET_CLASS(machine);
    NitroEnclaveMachineState *ne_state = NITRO_ENCLAVE_MACHINE(machine);

    ne_class->parent_init(machine);
    nitro_enclave_devices_init(ne_state);
}

static void nitro_enclave_machine_reset(MachineState *machine, ResetType type)
{
    NitroEnclaveMachineClass *ne_class =
        NITRO_ENCLAVE_MACHINE_GET_CLASS(machine);
    NitroEnclaveMachineState *ne_state = NITRO_ENCLAVE_MACHINE(machine);

    ne_class->parent_reset(machine, type);

    memset(ne_state->vnsm->pcrs, 0, sizeof(ne_state->vnsm->pcrs));

    /* PCR0 */
    ne_state->vnsm->extend_pcr(ne_state->vnsm, 0, ne_state->image_hash,
                               QCRYPTO_HASH_DIGEST_LEN_SHA384);
    /* PCR1 */
    ne_state->vnsm->extend_pcr(ne_state->vnsm, 1, ne_state->bootstrap_hash,
                               QCRYPTO_HASH_DIGEST_LEN_SHA384);
    /* PCR2 */
    ne_state->vnsm->extend_pcr(ne_state->vnsm, 2, ne_state->app_hash,
                               QCRYPTO_HASH_DIGEST_LEN_SHA384);
    /* PCR3 */
    if (ne_state->parent_role) {
        ne_state->vnsm->extend_pcr(ne_state->vnsm, 3,
                                   (uint8_t *) ne_state->parent_role,
                                   strlen(ne_state->parent_role));
    }
    /* PCR4 */
    if (ne_state->parent_id) {
        ne_state->vnsm->extend_pcr(ne_state->vnsm, 4,
                                   (uint8_t *) ne_state->parent_id,
                                   strlen(ne_state->parent_id));
    }
    /* PCR8 */
    if (ne_state->signature_found) {
        ne_state->vnsm->extend_pcr(ne_state->vnsm, 8,
                                   ne_state->fingerprint_hash,
                                   QCRYPTO_HASH_DIGEST_LEN_SHA384);
    }

    /* First 16 PCRs are locked from boot and reserved for nitro enclave */
    for (int i = 0; i < 16; ++i) {
        ne_state->vnsm->lock_pcr(ne_state->vnsm, i);
    }
}

static void nitro_enclave_machine_initfn(Object *obj)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);
    X86MachineState *x86ms = X86_MACHINE(obj);
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    nems->id = g_strdup("i-234-enc5678");

    /* AWS nitro enclaves have PCIE and ACPI disabled */
    mms->pcie = ON_OFF_AUTO_OFF;
    x86ms->acpi = ON_OFF_AUTO_OFF;
}

static void x86_load_eif(X86MachineState *x86ms, FWCfgState *fw_cfg,
                         int acpi_data_size, bool pvh_enabled)
{
    Error *err = NULL;
    char *eif_kernel, *eif_initrd, *eif_cmdline;
    MachineState *machine = MACHINE(x86ms);
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(x86ms);

    if (!read_eif_file(machine->kernel_filename, machine->initrd_filename,
                       &eif_kernel, &eif_initrd, &eif_cmdline,
                       nems->image_hash, nems->bootstrap_hash,
                       nems->app_hash, nems->fingerprint_hash,
                       &(nems->signature_found), &err)) {
        error_report_err(err);
        exit(1);
    }

    g_free(machine->kernel_filename);
    machine->kernel_filename = eif_kernel;
    g_free(machine->initrd_filename);
    machine->initrd_filename = eif_initrd;

    /*
     * If kernel cmdline argument was provided, let's concatenate it to the
     * extracted EIF kernel cmdline.
     */
    if (machine->kernel_cmdline != NULL) {
        char *cmd = g_strdup_printf("%s %s", eif_cmdline,
                                    machine->kernel_cmdline);
        g_free(eif_cmdline);
        g_free(machine->kernel_cmdline);
        machine->kernel_cmdline = cmd;
    } else {
        machine->kernel_cmdline = eif_cmdline;
    }

    x86_load_linux(x86ms, fw_cfg, 0, true);

    unlink(machine->kernel_filename);
    unlink(machine->initrd_filename);
    return;
}

static bool create_memfd_backend(MachineState *ms, const char *path,
                                 Error **errp)
{
    Object *obj;
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    bool r = false;

    obj = object_new(TYPE_MEMORY_BACKEND_MEMFD);
    if (!object_property_set_int(obj, "size", ms->ram_size, errp)) {
        goto out;
    }
    object_property_add_child(object_get_objects_root(), mc->default_ram_id,
                              obj);

    if (!user_creatable_complete(USER_CREATABLE(obj), errp)) {
        goto out;
    }
    r = object_property_set_link(OBJECT(ms), "memory-backend", obj, errp);

out:
    object_unref(obj);
    return r;
}

static char *nitro_enclave_get_vsock_chardev_id(Object *obj, Error **errp)
{
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    return g_strdup(nems->vsock);
}

static void nitro_enclave_set_vsock_chardev_id(Object *obj, const char *value,
                                               Error **errp)
{
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    g_free(nems->vsock);
    nems->vsock = g_strdup(value);
}

static char *nitro_enclave_get_id(Object *obj, Error **errp)
{
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    return g_strdup(nems->id);
}

static void nitro_enclave_set_id(Object *obj, const char *value,
                                            Error **errp)
{
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    g_free(nems->id);
    nems->id = g_strdup(value);
}

static char *nitro_enclave_get_parent_role(Object *obj, Error **errp)
{
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    return g_strdup(nems->parent_role);
}

static void nitro_enclave_set_parent_role(Object *obj, const char *value,
                                          Error **errp)
{
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    g_free(nems->parent_role);
    nems->parent_role = g_strdup(value);
}

static char *nitro_enclave_get_parent_id(Object *obj, Error **errp)
{
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    return g_strdup(nems->parent_id);
}

static void nitro_enclave_set_parent_id(Object *obj, const char *value,
                                        Error **errp)
{
    NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);

    g_free(nems->parent_id);
    nems->parent_id = g_strdup(value);
}

static void nitro_enclave_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    MicrovmMachineClass *mmc = MICROVM_MACHINE_CLASS(oc);
    NitroEnclaveMachineClass *nemc = NITRO_ENCLAVE_MACHINE_CLASS(oc);

    mmc->x86_load_linux = x86_load_eif;

    mc->family = "nitro_enclave_i386";
    mc->desc = "AWS Nitro Enclave";

    nemc->parent_init = mc->init;
    mc->init = nitro_enclave_machine_state_init;

    nemc->parent_reset = mc->reset;
    mc->reset = nitro_enclave_machine_reset;

    mc->create_default_memdev = create_memfd_backend;

    object_class_property_add_str(oc, NITRO_ENCLAVE_VSOCK_CHARDEV_ID,
                                  nitro_enclave_get_vsock_chardev_id,
                                  nitro_enclave_set_vsock_chardev_id);
    object_class_property_set_description(oc, NITRO_ENCLAVE_VSOCK_CHARDEV_ID,
                                          "Set chardev id for vhost-user-vsock "
                                          "device");

    object_class_property_add_str(oc, NITRO_ENCLAVE_ID, nitro_enclave_get_id,
                                  nitro_enclave_set_id);
    object_class_property_set_description(oc, NITRO_ENCLAVE_ID,
                                          "Set enclave identifier");

    object_class_property_add_str(oc, NITRO_ENCLAVE_PARENT_ROLE,
                                  nitro_enclave_get_parent_role,
                                  nitro_enclave_set_parent_role);
    object_class_property_set_description(oc, NITRO_ENCLAVE_PARENT_ROLE,
                                          "Set parent instance IAM role ARN");

    object_class_property_add_str(oc, NITRO_ENCLAVE_PARENT_ID,
                                  nitro_enclave_get_parent_id,
                                  nitro_enclave_set_parent_id);
    object_class_property_set_description(oc, NITRO_ENCLAVE_PARENT_ID,
                                          "Set parent instance identifier");
}

static const TypeInfo nitro_enclave_machine_info = {
    .name          = TYPE_NITRO_ENCLAVE_MACHINE,
    .parent        = TYPE_MICROVM_MACHINE,
    .instance_size = sizeof(NitroEnclaveMachineState),
    .instance_init = nitro_enclave_machine_initfn,
    .class_size    = sizeof(NitroEnclaveMachineClass),
    .class_init    = nitro_enclave_class_init,
};

static void nitro_enclave_machine_init(void)
{
    type_register_static(&nitro_enclave_machine_info);
}
type_init(nitro_enclave_machine_init);
