/*
 * EIF (Enclave Image Format) related helpers
 *
 * 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/bswap.h"
#include "qapi/error.h"
#include "crypto/hash.h"
#include "crypto/x509-utils.h"
#include <zlib.h> /* for crc32 */
#include <cbor.h>

#include "hw/core/eif.h"

#define MAX_SECTIONS 32

/* members are ordered according to field order in .eif file */
typedef struct EifHeader {
    uint8_t  magic[4]; /* must be .eif in ascii i.e., [46, 101, 105, 102] */
    uint16_t version;
    uint16_t flags;
    uint64_t default_memory;
    uint64_t default_cpus;
    uint16_t reserved;
    uint16_t section_cnt;
    uint64_t section_offsets[MAX_SECTIONS];
    uint64_t section_sizes[MAX_SECTIONS];
    uint32_t unused;
    uint32_t eif_crc32;
} QEMU_PACKED EifHeader;

/* members are ordered according to field order in .eif file */
typedef struct EifSectionHeader {
    /*
     * 0 = invalid, 1 = kernel, 2 = cmdline, 3 = ramdisk, 4 = signature,
     * 5 = metadata
     */
    uint16_t section_type;
    uint16_t flags;
    uint64_t section_size;
} QEMU_PACKED EifSectionHeader;

enum EifSectionTypes {
    EIF_SECTION_INVALID = 0,
    EIF_SECTION_KERNEL = 1,
    EIF_SECTION_CMDLINE = 2,
    EIF_SECTION_RAMDISK = 3,
    EIF_SECTION_SIGNATURE = 4,
    EIF_SECTION_METADATA = 5,
    EIF_SECTION_MAX = 6,
};

static const char *section_type_to_string(uint16_t type)
{
    const char *str;
    switch (type) {
    case EIF_SECTION_INVALID:
        str = "invalid";
        break;
    case EIF_SECTION_KERNEL:
        str = "kernel";
        break;
    case EIF_SECTION_CMDLINE:
        str = "cmdline";
        break;
    case EIF_SECTION_RAMDISK:
        str = "ramdisk";
        break;
    case EIF_SECTION_SIGNATURE:
        str = "signature";
        break;
    case EIF_SECTION_METADATA:
        str = "metadata";
        break;
    default:
        str = "unknown";
        break;
    }

    return str;
}

static bool read_eif_header(FILE *f, EifHeader *header, uint32_t *crc,
                            Error **errp)
{
    size_t got;
    size_t header_size = sizeof(*header);

    got = fread(header, 1, header_size, f);
    if (got != header_size) {
        error_setg(errp, "Failed to read EIF header");
        return false;
    }

    if (memcmp(header->magic, ".eif", 4) != 0) {
        error_setg(errp, "Invalid EIF image. Magic mismatch.");
        return false;
    }

    /* Exclude header->eif_crc32 field from CRC calculation */
    *crc = crc32(*crc, (uint8_t *)header, header_size - 4);

    header->version = be16_to_cpu(header->version);
    header->flags = be16_to_cpu(header->flags);
    header->default_memory = be64_to_cpu(header->default_memory);
    header->default_cpus = be64_to_cpu(header->default_cpus);
    header->reserved = be16_to_cpu(header->reserved);
    header->section_cnt = be16_to_cpu(header->section_cnt);

    for (int i = 0; i < MAX_SECTIONS; ++i) {
        header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]);
    }

    for (int i = 0; i < MAX_SECTIONS; ++i) {
        header->section_sizes[i] = be64_to_cpu(header->section_sizes[i]);
        if (header->section_sizes[i] > SSIZE_MAX) {
            error_setg(errp, "Invalid EIF image. Section size out of bounds");
            return false;
        }
    }

    header->unused = be32_to_cpu(header->unused);
    header->eif_crc32 = be32_to_cpu(header->eif_crc32);
    return true;
}

static bool read_eif_section_header(FILE *f, EifSectionHeader *section_header,
                                    uint32_t *crc, Error **errp)
{
    size_t got;
    size_t section_header_size = sizeof(*section_header);

    got = fread(section_header, 1, section_header_size, f);
    if (got != section_header_size) {
        error_setg(errp, "Failed to read EIF section header");
        return false;
    }

    *crc = crc32(*crc, (uint8_t *)section_header, section_header_size);

    section_header->section_type = be16_to_cpu(section_header->section_type);
    section_header->flags = be16_to_cpu(section_header->flags);
    section_header->section_size = be64_to_cpu(section_header->section_size);
    return true;
}

/*
 * Upon success, the caller is responsible for unlinking and freeing *tmp_path.
 */
static bool get_tmp_file(const char *template, char **tmp_path, Error **errp)
{
    int tmp_fd;

    *tmp_path = NULL;
    tmp_fd = g_file_open_tmp(template, tmp_path, NULL);
    if (tmp_fd < 0 || *tmp_path == NULL) {
        error_setg(errp, "Failed to create temporary file for template %s",
                   template);
        return false;
    }

    close(tmp_fd);
    return true;
}

static void safe_fclose(FILE *f)
{
    if (f) {
        fclose(f);
    }
}

static void safe_unlink(char *f)
{
    if (f) {
        unlink(f);
    }
}

/*
 * Upon success, the caller is reponsible for unlinking and freeing *kernel_path
 */
static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path,
                            uint8_t *kernel, uint32_t *crc, Error **errp)
{
    size_t got;
    FILE *tmp_file = NULL;

    *kernel_path = NULL;
    if (!get_tmp_file("eif-kernel-XXXXXX", kernel_path, errp)) {
        goto cleanup;
    }

    tmp_file = fopen(*kernel_path, "wb");
    if (tmp_file == NULL) {
        error_setg_errno(errp, errno, "Failed to open temporary file %s",
                         *kernel_path);
        goto cleanup;
    }

    got = fread(kernel, 1, size, f);
    if ((uint64_t) got != size) {
        error_setg(errp, "Failed to read EIF kernel section data");
        goto cleanup;
    }

    got = fwrite(kernel, 1, size, tmp_file);
    if ((uint64_t) got != size) {
        error_setg(errp, "Failed to write EIF kernel section data to temporary"
                   " file");
        goto cleanup;
    }

    *crc = crc32(*crc, kernel, size);
    fclose(tmp_file);

    return true;

 cleanup:
    safe_fclose(tmp_file);

    safe_unlink(*kernel_path);
    g_free(*kernel_path);
    *kernel_path = NULL;

    return false;
}

static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline,
                             uint32_t *crc, Error **errp)
{
    size_t got = fread(cmdline, 1, size, f);
    if ((uint64_t) got != size) {
        error_setg(errp, "Failed to read EIF cmdline section data");
        return false;
    }

    *crc = crc32(*crc, (uint8_t *)cmdline, size);
    return true;
}

static bool read_eif_ramdisk(FILE *eif, FILE *initrd, uint64_t size,
                             uint8_t *ramdisk, uint32_t *crc, Error **errp)
{
    size_t got;

    got = fread(ramdisk, 1, size, eif);
    if ((uint64_t) got != size) {
        error_setg(errp, "Failed to read EIF ramdisk section data");
        return false;
    }

    got = fwrite(ramdisk, 1, size, initrd);
    if ((uint64_t) got != size) {
        error_setg(errp, "Failed to write EIF ramdisk data to temporary file");
        return false;
    }

    *crc = crc32(*crc, ramdisk, size);
    return true;
}

static bool get_signature_fingerprint_sha384(FILE *eif, uint64_t size,
                                             uint8_t *sha384,
                                             uint32_t *crc,
                                             Error **errp)
{
    size_t got;
    g_autofree uint8_t *sig = NULL;
    g_autofree uint8_t *cert = NULL;
    cbor_item_t *item = NULL;
    cbor_item_t *pcr0 = NULL;
    size_t len;
    size_t hash_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
    struct cbor_pair *pair;
    struct cbor_load_result result;
    bool ret = false;

    sig = g_try_malloc(size);
    if (!sig) {
        error_setg(errp, "Out of memory reading signature section");
        goto cleanup;
    }

    got = fread(sig, 1, size, eif);
    if ((uint64_t) got != size) {
        error_setg(errp, "Failed to read EIF signature section data");
        goto cleanup;
    }

    *crc = crc32(*crc, sig, size);

    item = cbor_load(sig, size, &result);
    if (!item || result.error.code != CBOR_ERR_NONE) {
        error_setg(errp, "Failed to load signature section data as CBOR");
        goto cleanup;
    }
    if (!cbor_isa_array(item) || cbor_array_size(item) < 1) {
        error_setg(errp, "Invalid signature CBOR");
        goto cleanup;
    }
    pcr0 = cbor_array_get(item, 0);
    if (!pcr0) {
        error_setg(errp, "Failed to get PCR0 signature");
        goto cleanup;
    }
    if (!cbor_isa_map(pcr0) || cbor_map_size(pcr0) != 2) {
        error_setg(errp, "Invalid signature CBOR");
        goto cleanup;
    }
    pair = cbor_map_handle(pcr0);
    if (!cbor_isa_string(pair->key) || cbor_string_length(pair->key) != 19 ||
        memcmp(cbor_string_handle(pair->key), "signing_certificate", 19) != 0) {
        error_setg(errp, "Invalid signautre CBOR");
        goto cleanup;
    }
    if (!cbor_isa_array(pair->value)) {
        error_setg(errp, "Invalid signature CBOR");
        goto cleanup;
    }
    len = cbor_array_size(pair->value);
    if (len == 0) {
        error_setg(errp, "Invalid signature CBOR");
        goto cleanup;
    }
    cert = g_try_malloc(len);
    if (!cert) {
        error_setg(errp, "Out of memory reading signature section");
        goto cleanup;
    }

    for (int i = 0; i < len; ++i) {
        cbor_item_t *tmp = cbor_array_get(pair->value, i);
        if (!tmp) {
            error_setg(errp, "Invalid signature CBOR");
            goto cleanup;
        }
        if (!cbor_isa_uint(tmp) || cbor_int_get_width(tmp) != CBOR_INT_8) {
            cbor_decref(&tmp);
            error_setg(errp, "Invalid signature CBOR");
            goto cleanup;
        }
        cert[i] = cbor_get_uint8(tmp);
        cbor_decref(&tmp);
    }

    if (qcrypto_get_x509_cert_fingerprint(cert, len, QCRYPTO_HASH_ALGO_SHA384,
                                          sha384, &hash_len, errp)) {
        goto cleanup;
    }

    ret = true;

 cleanup:
    if (pcr0) {
        cbor_decref(&pcr0);
    }
    if (item) {
        cbor_decref(&item);
    }
    return ret;
}

/* Expects file to have offset 0 before this function is called */
static long get_file_size(FILE *f, Error **errp)
{
    long size;

    if (fseek(f, 0, SEEK_END) != 0) {
        error_setg_errno(errp, errno, "Failed to seek to the end of file");
        return -1;
    }

    size = ftell(f);
    if (size == -1) {
        error_setg_errno(errp, errno, "Failed to get offset");
        return -1;
    }

    if (fseek(f, 0, SEEK_SET) != 0) {
        error_setg_errno(errp, errno, "Failed to seek back to the start");
        return -1;
    }

    return size;
}

static bool get_SHA384_digest(GList *list, uint8_t *digest, Error **errp)
{
    size_t digest_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
    size_t list_len = g_list_length(list);
    struct iovec *iovec_list = g_new0(struct iovec, list_len);
    bool ret = true;
    GList *l;
    int i;

    for (i = 0, l = list; l != NULL; l = l->next, i++) {
        iovec_list[i] = *(struct iovec *) l->data;
    }

    if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALGO_SHA384, iovec_list, list_len,
                            &digest, &digest_len, errp) < 0) {
        ret = false;
    }

    g_free(iovec_list);
    return ret;
}

static void free_iovec(struct iovec *iov)
{
    if (iov) {
        g_free(iov->iov_base);
        g_free(iov);
    }
}

/*
 * Upon success, the caller is reponsible for unlinking and freeing
 * *kernel_path, *initrd_path and freeing *cmdline.
 */
bool read_eif_file(const char *eif_path, const char *machine_initrd,
                   char **kernel_path, char **initrd_path, char **cmdline,
                   uint8_t *image_sha384, uint8_t *bootstrap_sha384,
                   uint8_t *app_sha384, uint8_t *fingerprint_sha384,
                   bool *signature_found, Error **errp)
{
    FILE *f = NULL;
    FILE *machine_initrd_f = NULL;
    FILE *initrd_path_f = NULL;
    long machine_initrd_size;
    uint32_t crc = 0;
    EifHeader eif_header;
    bool seen_sections[EIF_SECTION_MAX] = {false};
    /* kernel + ramdisks + cmdline sha384 hash */
    GList *iov_PCR0 = NULL;
    /* kernel + boot ramdisk + cmdline sha384 hash */
    GList *iov_PCR1 = NULL;
    /* application ramdisk(s) hash */
    GList *iov_PCR2 = NULL;
    uint8_t *ptr = NULL;
    struct iovec *iov_ptr = NULL;

    *signature_found = false;
    *kernel_path = *initrd_path = *cmdline = NULL;

    f = fopen(eif_path, "rb");
    if (f == NULL) {
        error_setg_errno(errp, errno, "Failed to open %s", eif_path);
        goto cleanup;
    }

    if (!read_eif_header(f, &eif_header, &crc, errp)) {
        goto cleanup;
    }

    if (eif_header.version < 4) {
        error_setg(errp, "Expected EIF version 4 or greater");
        goto cleanup;
    }

    if (eif_header.flags != 0) {
        error_setg(errp, "Expected EIF flags to be 0");
        goto cleanup;
    }

    if (eif_header.section_cnt > MAX_SECTIONS) {
        error_setg(errp, "EIF header section count must not be greater than "
                   "%d but found %d", MAX_SECTIONS, eif_header.section_cnt);
        goto cleanup;
    }

    for (int i = 0; i < eif_header.section_cnt; ++i) {
        EifSectionHeader hdr;
        uint16_t section_type;

        if (eif_header.section_offsets[i] > OFF_MAX) {
            error_setg(errp, "Invalid EIF image. Section offset out of bounds");
            goto cleanup;
        }
        if (fseek(f, eif_header.section_offsets[i], SEEK_SET) != 0) {
            error_setg_errno(errp, errno, "Failed to offset to %" PRIu64 " in EIF file",
                             eif_header.section_offsets[i]);
            goto cleanup;
        }

        if (!read_eif_section_header(f, &hdr, &crc, errp)) {
            goto cleanup;
        }

        if (hdr.flags != 0) {
            error_setg(errp, "Expected EIF section header flags to be 0");
            goto cleanup;
        }

        if (eif_header.section_sizes[i] != hdr.section_size) {
            error_setg(errp, "EIF section size mismatch between header and "
                       "section header: header %" PRIu64 ", section header %" PRIu64,
                       eif_header.section_sizes[i],
                       hdr.section_size);
            goto cleanup;
        }

        section_type = hdr.section_type;

        switch (section_type) {
        case EIF_SECTION_KERNEL:
            if (seen_sections[EIF_SECTION_KERNEL]) {
                error_setg(errp, "Invalid EIF image. More than 1 kernel "
                           "section");
                goto cleanup;
            }

            ptr = g_try_malloc(hdr.section_size);
            if (!ptr) {
                error_setg(errp, "Out of memory reading kernel section");
                goto cleanup;
            }

            iov_ptr = g_malloc(sizeof(struct iovec));
            iov_ptr->iov_base = ptr;
            iov_ptr->iov_len = hdr.section_size;

            iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
            iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);

            if (!read_eif_kernel(f, hdr.section_size, kernel_path, ptr, &crc,
                                 errp)) {
                goto cleanup;
            }

            break;
        case EIF_SECTION_CMDLINE:
        {
            uint64_t size;
            uint8_t *cmdline_copy;
            if (seen_sections[EIF_SECTION_CMDLINE]) {
                error_setg(errp, "Invalid EIF image. More than 1 cmdline "
                           "section");
                goto cleanup;
            }
            size = hdr.section_size;
            *cmdline = g_try_malloc(size + 1);
            if (!*cmdline) {
                error_setg(errp, "Out of memory reading command line section");
                goto cleanup;
            }
            if (!read_eif_cmdline(f, size, *cmdline, &crc, errp)) {
                goto cleanup;
            }
            (*cmdline)[size] = '\0';

            /*
             * We make a copy of '*cmdline' for putting it in iovecs so that
             * we can easily free all the iovec entries later as we cannot
             * free '*cmdline' which is used by the caller.
             */
            cmdline_copy = g_memdup2(*cmdline, size);

            iov_ptr = g_malloc(sizeof(struct iovec));
            iov_ptr->iov_base = cmdline_copy;
            iov_ptr->iov_len = size;

            iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
            iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);
            break;
        }
        case EIF_SECTION_RAMDISK:
        {
            if (!seen_sections[EIF_SECTION_RAMDISK]) {
                /*
                 * If this is the first time we are seeing a ramdisk section,
                 * we need to create the initrd temporary file.
                 */
                if (!get_tmp_file("eif-initrd-XXXXXX", initrd_path, errp)) {
                    goto cleanup;
                }
                initrd_path_f = fopen(*initrd_path, "wb");
                if (initrd_path_f == NULL) {
                    error_setg_errno(errp, errno, "Failed to open file %s",
                                     *initrd_path);
                    goto cleanup;
                }
            }

            ptr = g_try_malloc(hdr.section_size);
            if (!ptr) {
                error_setg(errp, "Out of memory reading initrd section");
                goto cleanup;
            }

            iov_ptr = g_malloc(sizeof(struct iovec));
            iov_ptr->iov_base = ptr;
            iov_ptr->iov_len = hdr.section_size;

            iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
            /*
             * If it's the first ramdisk, we need to hash it into bootstrap
             * i.e., iov_PCR1, otherwise we need to hash it into app i.e.,
             * iov_PCR2.
             */
            if (!seen_sections[EIF_SECTION_RAMDISK]) {
                iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);
            } else {
                iov_PCR2 = g_list_append(iov_PCR2, iov_ptr);
            }

            if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, ptr,
                                  &crc, errp)) {
                goto cleanup;
            }

            break;
        }
        case EIF_SECTION_SIGNATURE:
            *signature_found = true;
            if (!get_signature_fingerprint_sha384(f, hdr.section_size,
                                                  fingerprint_sha384, &crc,
                                                  errp)) {
                goto cleanup;
            }
            break;
        default:
            /* other sections including invalid or unknown sections */
        {
            uint8_t *buf;
            size_t got;
            uint64_t size = hdr.section_size;
            buf = g_try_malloc(size);
            if (!buf) {
                error_setg(errp, "Out of memory reading unknown section");
                goto cleanup;
            }
            got = fread(buf, 1, size, f);
            if ((uint64_t) got != size) {
                g_free(buf);
                error_setg(errp, "Failed to read EIF %s section data",
                           section_type_to_string(section_type));
                goto cleanup;
            }
            crc = crc32(crc, buf, size);
            g_free(buf);
            break;
        }
        }

        if (section_type < EIF_SECTION_MAX) {
            seen_sections[section_type] = true;
        }
    }

    if (!seen_sections[EIF_SECTION_KERNEL]) {
        error_setg(errp, "Invalid EIF image. No kernel section.");
        goto cleanup;
    }
    if (!seen_sections[EIF_SECTION_CMDLINE]) {
        error_setg(errp, "Invalid EIF image. No cmdline section.");
        goto cleanup;
    }
    if (!seen_sections[EIF_SECTION_RAMDISK]) {
        error_setg(errp, "Invalid EIF image. No ramdisk section.");
        goto cleanup;
    }

    if (eif_header.eif_crc32 != crc) {
        error_setg(errp, "CRC mismatch. Expected %u but header has %u.",
                   crc, eif_header.eif_crc32);
        goto cleanup;
    }

    /*
     * Let's append the initrd file from "-initrd" option if any. Although
     * we pass the crc pointer to read_eif_ramdisk, it is not useful anymore.
     * We have already done the crc mismatch check above this code.
     */
    if (machine_initrd) {
        machine_initrd_f = fopen(machine_initrd, "rb");
        if (machine_initrd_f == NULL) {
            error_setg_errno(errp, errno, "Failed to open initrd file %s",
                             machine_initrd);
            goto cleanup;
        }

        machine_initrd_size = get_file_size(machine_initrd_f, errp);
        if (machine_initrd_size == -1) {
            goto cleanup;
        }

        ptr = g_try_malloc(machine_initrd_size);
        if (!ptr) {
            error_setg(errp, "Out of memory reading initrd file");
            goto cleanup;
        }

        iov_ptr = g_malloc(sizeof(struct iovec));
        iov_ptr->iov_base = ptr;
        iov_ptr->iov_len = machine_initrd_size;

        iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
        iov_PCR2 = g_list_append(iov_PCR2, iov_ptr);

        if (!read_eif_ramdisk(machine_initrd_f, initrd_path_f,
                              machine_initrd_size, ptr, &crc, errp)) {
            goto cleanup;
        }
    }

    if (!get_SHA384_digest(iov_PCR0, image_sha384, errp)) {
        goto cleanup;
    }
    if (!get_SHA384_digest(iov_PCR1, bootstrap_sha384, errp)) {
        goto cleanup;
    }
    if (!get_SHA384_digest(iov_PCR2, app_sha384, errp)) {
        goto cleanup;
    }

    /*
     * We only need to free iov_PCR0 entries because iov_PCR1 and
     * iov_PCR2 iovec entries are subsets of iov_PCR0 iovec entries.
     */
    g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec);
    g_list_free(iov_PCR1);
    g_list_free(iov_PCR2);
    fclose(f);
    fclose(initrd_path_f);
    safe_fclose(machine_initrd_f);
    return true;

 cleanup:
    g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec);
    g_list_free(iov_PCR1);
    g_list_free(iov_PCR2);

    safe_fclose(f);
    safe_fclose(initrd_path_f);
    safe_fclose(machine_initrd_f);

    safe_unlink(*kernel_path);
    g_free(*kernel_path);
    *kernel_path = NULL;

    safe_unlink(*initrd_path);
    g_free(*initrd_path);
    *initrd_path = NULL;

    g_free(*cmdline);
    *cmdline = NULL;

    return false;
}
