/*
 * AWS Nitro Secure Module (NSM) device
 *
 * 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/iov.h"
#include "qemu/guest-random.h"
#include "qapi/error.h"

#include "crypto/hash.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-nsm.h"
#include "hw/virtio/cbor-helpers.h"
#include "standard-headers/linux/virtio_ids.h"

#define NSM_REQUEST_MAX_SIZE      0x1000
#define NSM_RESPONSE_BUF_SIZE     0x3000
#define NSM_RND_BUF_SIZE          256

enum NSMResponseTypes {
    NSM_SUCCESS = 0,
    NSM_INVALID_ARGUMENT = 1,
    NSM_INVALID_INDEX = 2,
    NSM_READONLY_INDEX = 3,
    NSM_INVALID_OPERATION = 4,
    NSM_BUFFER_TOO_SMALL = 5,
    NSM_INPUT_TOO_LARGE = 6,
    NSM_INTERNAL_ERROR = 7,
};

static const char *error_string(enum NSMResponseTypes type)
{
    const char *str;
    switch (type) {
    case NSM_INVALID_ARGUMENT:
        str = "InvalidArgument";
        break;
    case NSM_INVALID_INDEX:
        str = "InvalidIndex";
        break;
    case NSM_READONLY_INDEX:
        str = "ReadOnlyIndex";
        break;
    case NSM_INVALID_OPERATION:
        str = "InvalidOperation";
        break;
    case NSM_BUFFER_TOO_SMALL:
        str = "BufferTooSmall";
        break;
    case NSM_INPUT_TOO_LARGE:
        str = "InputTooLarge";
        break;
    default:
        str = "InternalError";
        break;
    }

    return str;
}

/*
 * Error response structure:
 *
 * {
 *   Map(1) {
 *     key = String("Error"),
 *     value = String(error_name)
 *   }
 * }
 *
 * where error_name can be one of the following:
 *   InvalidArgument
 *   InvalidIndex
 *   InvalidResponse
 *   ReadOnlyIndex
 *   InvalidOperation
 *   BufferTooSmall
 *   InputTooLarge
 *   InternalError
 */

static bool error_response(struct iovec *response, enum NSMResponseTypes error,
                           Error **errp)
{
    cbor_item_t *root;
    size_t len;
    bool r = false;

    root = cbor_new_definite_map(1);
    if (!root) {
        goto err;
    }

    if (!qemu_cbor_add_string_to_map(root, "Error", error_string(error))) {
        goto err;
    }

    len = cbor_serialize(root, response->iov_base, response->iov_len);
    if (len == 0) {
        error_setg(errp, "Response buffer is small for %s response",
                   error_string(error));
        goto out;
    }
    response->iov_len = len;
    r = true;

 out:
    if (root) {
        cbor_decref(&root);
    }
    return r;

 err:
    error_setg(errp, "Failed to initialize %s response", error_string(error));
    goto out;
}

/*
 * GetRandom response structure:
 *
 * {
 *   Map(1) {
 *     key = String("GetRandom"),
 *     value = Map(1) {
 *       key = String("random"),
 *       value = Byte_String()
 *     }
 *   }
 * }
 */
static bool handle_get_random(VirtIONSM *vnsm, struct iovec *request,
                              struct iovec *response, Error **errp)
{
    cbor_item_t *root, *nested_map;
    size_t len;
    uint8_t rnd[NSM_RND_BUF_SIZE];
    bool r = false;

    root = cbor_new_definite_map(1);
    if (!root) {
        goto err;
    }

    if (!qemu_cbor_add_map_to_map(root, "GetRandom", 1, &nested_map)) {
        goto err;
    }

    qemu_guest_getrandom_nofail(rnd, NSM_RND_BUF_SIZE);

    if (!qemu_cbor_add_bytestring_to_map(nested_map, "random", rnd,
                                         NSM_RND_BUF_SIZE)) {
        goto err;
    }

    len = cbor_serialize(root, response->iov_base, response->iov_len);
    if (len == 0) {
        if (error_response(response, NSM_INPUT_TOO_LARGE, errp)) {
            r = true;
        }
        goto out;
    }

    response->iov_len = len;
    r = true;

 out:
    if (root) {
        cbor_decref(&root);
    }
    return r;

 err:
    error_setg(errp, "Failed to initialize GetRandom response");
    goto out;
}

/*
 * DescribeNSM response structure:
 *
 * {
 *   Map(1) {
 *     key = String("DescribeNSM"),
 *     value = Map(7) {
 *       key = String("digest"),
 *       value = String("SHA384"),
 *       key = String("max_pcrs"),
 *       value = Uint8(32),
 *       key = String("module_id"),
 *       value = String("i-1234-enc5678"),
 *       key = String("locked_pcrs"),
 *       value = Array<Uint8>(),
 *       key = String("version_major"),
 *       value = Uint8(1),
 *       key = String("version_minor"),
 *       value = Uint8(0),
 *       key = String("version_patch"),
 *       value = Uint8(0)
 *     }
 *   }
 * }
 */
static bool handle_describe_nsm(VirtIONSM *vnsm, struct iovec *request,
                                struct iovec *response, Error **errp)
{
    cbor_item_t *root, *nested_map;
    uint16_t locked_pcrs_cnt = 0;
    uint8_t locked_pcrs_ind[NSM_MAX_PCRS];
    size_t len;
    bool r = false;

    root = cbor_new_definite_map(1);
    if (!root) {
        goto err;
    }

    if (!qemu_cbor_add_map_to_map(root, "DescribeNSM", 7, &nested_map)) {
        goto err;
    }

    if (!qemu_cbor_add_string_to_map(nested_map, "digest", vnsm->digest)) {
        goto err;
    }

    if (!qemu_cbor_add_uint8_to_map(nested_map, "max_pcrs", vnsm->max_pcrs)) {
        goto err;
    }

    if (!qemu_cbor_add_string_to_map(nested_map, "module_id",
                                     vnsm->module_id)) {
        goto err;
    }

    for (uint8_t i = 0; i < NSM_MAX_PCRS; ++i) {
        if (vnsm->pcrs[i].locked) {
            locked_pcrs_ind[locked_pcrs_cnt++] = i;
        }
    }
    if (!qemu_cbor_add_uint8_array_to_map(nested_map, "locked_pcrs",
                                          locked_pcrs_ind, locked_pcrs_cnt)) {
        goto err;
    }

    if (!qemu_cbor_add_uint8_to_map(nested_map, "version_major",
                                    vnsm->version_major)) {
        goto err;
    }

    if (!qemu_cbor_add_uint8_to_map(nested_map, "version_minor",
                                    vnsm->version_minor)) {
        goto err;
    }

    if (!qemu_cbor_add_uint8_to_map(nested_map, "version_patch",
                                    vnsm->version_patch)) {
        goto err;
    }

    len = cbor_serialize(root, response->iov_base, response->iov_len);
    if (len == 0) {
        if (error_response(response, NSM_INPUT_TOO_LARGE, errp)) {
            r = true;
        }
        goto out;
    }

    response->iov_len = len;
    r = true;

 out:
    if (root) {
        cbor_decref(&root);
    }
    return r;

 err:
    error_setg(errp, "Failed to initialize DescribeNSM response");
    goto out;
}

/*
 * DescribePCR request structure:
 *
 * {
 *   Map(1) {
 *     key = String("DescribePCR"),
 *     value = Map(1) {
 *       key = String("index"),
 *       value = Uint8(pcr)
 *     }
 *   }
 * }
 */
typedef struct NSMDescribePCRReq {
    uint8_t index;
} NSMDescribePCRReq;

static enum NSMResponseTypes get_nsm_describe_pcr_req(
    uint8_t *req, size_t len,
    NSMDescribePCRReq *nsm_req)
{
    size_t size;
    uint8_t *str;
    struct cbor_pair *pair;
    cbor_item_t *item = NULL;
    struct cbor_load_result result;
    enum NSMResponseTypes r = NSM_INVALID_OPERATION;

    item = cbor_load(req, len, &result);
    if (!item || result.error.code != CBOR_ERR_NONE) {
        goto cleanup;
    }

    pair = cbor_map_handle(item);
    if (!cbor_isa_map(pair->value)) {
        goto cleanup;
    }
    size = cbor_map_size(pair->value);
    if (size < 1) {
        goto cleanup;
    }

    pair = cbor_map_handle(pair->value);
    for (int i = 0; i < size; ++i) {
        if (!cbor_isa_string(pair[i].key)) {
            continue;
        }

        str = cbor_string_handle(pair[i].key);
        if (str && cbor_string_length(pair[i].key) == 5 &&
            memcmp(str, "index", 5) == 0) {
            if (!cbor_isa_uint(pair[i].value) ||
                cbor_int_get_width(pair[i].value) != CBOR_INT_8) {
                break;
            }

            nsm_req->index = cbor_get_uint8(pair[i].value);
            r = NSM_SUCCESS;
            break;
        }
    }

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

/*
 * DescribePCR response structure:
 *
 * {
 *   Map(1) {
 *     key = String("DescribePCR"),
 *     value = Map(2) {
 *       key = String("data"),
 *       value = Byte_String(),
 *       key = String("lock"),
 *       value = Bool()
 *     }
 *   }
 * }
 */
static bool handle_describe_pcr(VirtIONSM *vnsm, struct iovec *request,
                                struct iovec *response, Error **errp)
{
    cbor_item_t *root = NULL;
    cbor_item_t *nested_map;
    size_t len;
    NSMDescribePCRReq nsm_req;
    enum NSMResponseTypes type;
    struct PCRInfo *pcr;
    bool r = false;

    type = get_nsm_describe_pcr_req(request->iov_base, request->iov_len,
                                    &nsm_req);
    if (type != NSM_SUCCESS) {
        if (error_response(response, type, errp)) {
            r = true;
        }
        goto out;
    }
    if (nsm_req.index >= vnsm->max_pcrs) {
        if (error_response(response, NSM_INVALID_INDEX, errp)) {
            r = true;
        }
        goto out;
    }
    pcr = &(vnsm->pcrs[nsm_req.index]);

    root = cbor_new_definite_map(1);
    if (!root) {
        goto err;
    }

    if (!qemu_cbor_add_map_to_map(root, "DescribePCR", 2, &nested_map)) {
        goto err;
    }

    if (!qemu_cbor_add_bytestring_to_map(nested_map, "data", pcr->data,
                                         QCRYPTO_HASH_DIGEST_LEN_SHA384)) {
        goto err;
    }

    if (!qemu_cbor_add_bool_to_map(nested_map, "lock", pcr->locked)) {
        goto err;
    }

    len = cbor_serialize(root, response->iov_base, response->iov_len);
    if (len == 0) {
        if (error_response(response, NSM_INPUT_TOO_LARGE, errp)) {
            r = true;
        }
        goto out;
    }

    response->iov_len = len;
    r = true;

 out:
    if (root) {
        cbor_decref(&root);
    }
    return r;

 err:
    error_setg(errp, "Failed to initialize DescribePCR response");
    goto out;
}

/*
 * ExtendPCR request structure:
 *
 * {
 *   Map(1) {
 *     key = String("ExtendPCR"),
 *     value = Map(2) {
 *       key = String("index"),
 *       value = Uint8(pcr),
 *       key = String("data"),
 *       value = Byte_String(data),
 *     }
 *   }
 * }
 */
typedef struct NSMExtendPCRReq {
    uint8_t index;
    uint16_t data_len;
    uint8_t data[NSM_REQUEST_MAX_SIZE];
} NSMExtendPCRReq;

static enum NSMResponseTypes get_nsm_extend_pcr_req(uint8_t *req, size_t len,
                                                    NSMExtendPCRReq *nsm_req)
{
    cbor_item_t *item = NULL;
    size_t size ;
    uint8_t *str;
    bool index_found = false;
    bool data_found = false;
    struct cbor_pair *pair;
    struct cbor_load_result result;
    enum NSMResponseTypes r = NSM_INVALID_OPERATION;

    item = cbor_load(req, len, &result);
    if (!item || result.error.code != CBOR_ERR_NONE) {
        goto cleanup;
    }

    pair = cbor_map_handle(item);
    if (!cbor_isa_map(pair->value)) {
        goto cleanup;
    }
    size = cbor_map_size(pair->value);
    if (size < 2) {
        goto cleanup;
    }

    pair = cbor_map_handle(pair->value);
    for (int i = 0; i < size; ++i) {
        if (!cbor_isa_string(pair[i].key)) {
            continue;
        }
        str = cbor_string_handle(pair[i].key);
        if (!str) {
            continue;
        }

        if (cbor_string_length(pair[i].key) == 5 &&
            memcmp(str, "index", 5) == 0) {
            if (!cbor_isa_uint(pair[i].value) ||
                cbor_int_get_width(pair[i].value) != CBOR_INT_8) {
                goto cleanup;
            }
            nsm_req->index = cbor_get_uint8(pair[i].value);
            index_found = true;
            continue;
        }

        if (cbor_string_length(pair[i].key) == 4 &&
            memcmp(str, "data", 4) == 0) {
            if (!cbor_isa_bytestring(pair[i].value)) {
                goto cleanup;
            }
            str = cbor_bytestring_handle(pair[i].value);
            if (!str) {
                goto cleanup;
            }
            nsm_req->data_len = cbor_bytestring_length(pair[i].value);
            /*
             * nsm_req->data_len will be smaller than NSM_REQUEST_MAX_SIZE as
             * we already check for the max request size before processing
             * any request. So it's safe to copy.
             */
            memcpy(nsm_req->data, str, nsm_req->data_len);
            data_found = true;
            continue;
        }
    }

    if (index_found && data_found) {
        r = NSM_SUCCESS;
    }

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

/*
 * ExtendPCR response structure:
 *
 * {
 *   Map(1) {
 *     key = String("ExtendPCR"),
 *     value = Map(1) {
 *       key = String("data"),
 *       value = Byte_String()
 *     }
 *   }
 * }
 */
static bool handle_extend_pcr(VirtIONSM *vnsm, struct iovec *request,
                              struct iovec *response, Error **errp)
{
    cbor_item_t *root = NULL;
    cbor_item_t *nested_map;
    size_t len;
    struct PCRInfo *pcr;
    enum NSMResponseTypes type;
    bool r = false;
    g_autofree NSMExtendPCRReq *nsm_req = g_malloc(sizeof(NSMExtendPCRReq));

    type = get_nsm_extend_pcr_req(request->iov_base, request->iov_len,
                                  nsm_req);
    if (type != NSM_SUCCESS) {
        if (error_response(response, type, errp)) {
            r = true;
        }
        goto out;
    }
    if (nsm_req->index >= vnsm->max_pcrs) {
        if (error_response(response, NSM_INVALID_INDEX, errp)) {
            r = true;
        }
        goto out;
    }

    pcr = &(vnsm->pcrs[nsm_req->index]);

    if (pcr->locked) {
        if (error_response(response, NSM_READONLY_INDEX, errp)) {
            r = true;
        }
        goto out;
    }

    if (!vnsm->extend_pcr(vnsm, nsm_req->index, nsm_req->data,
                          nsm_req->data_len)) {
        if (error_response(response, NSM_INTERNAL_ERROR, errp)) {
            r = true;
        }
        goto out;
    }

    root = cbor_new_definite_map(1);
    if (!root) {
        goto err;
    }

    if (!qemu_cbor_add_map_to_map(root, "ExtendPCR", 1, &nested_map)) {
        goto err;
    }

    if (!qemu_cbor_add_bytestring_to_map(nested_map, "data", pcr->data,
                                         QCRYPTO_HASH_DIGEST_LEN_SHA384)) {
        goto err;
    }

    len = cbor_serialize(root, response->iov_base, response->iov_len);
    if (len == 0) {
        if (error_response(response, NSM_BUFFER_TOO_SMALL, errp)) {
            r = true;
        }
        goto out;
    }

    response->iov_len = len;
    r = true;

 out:
    if (root) {
        cbor_decref(&root);
    }
    return r;

 err:
    error_setg(errp, "Failed to initialize DescribePCR response");
    goto out;
}

/*
 * LockPCR request structure:
 *
 * {
 *   Map(1) {
 *     key = String("LockPCR"),
 *     value = Map(1) {
 *       key = String("index"),
 *       value = Uint8(pcr)
 *     }
 *   }
 * }
 */
typedef struct NSMLockPCRReq {
    uint8_t index;
} NSMLockPCRReq;

static enum NSMResponseTypes get_nsm_lock_pcr_req(uint8_t *req, size_t len,
                                                  NSMLockPCRReq *nsm_req)
{
    cbor_item_t *item = NULL;
    size_t size;
    uint8_t *str;
    struct cbor_pair *pair;
    struct cbor_load_result result;
    enum NSMResponseTypes r = NSM_INVALID_OPERATION;

    item = cbor_load(req, len, &result);
    if (!item || result.error.code != CBOR_ERR_NONE) {
        goto cleanup;
    }

    pair = cbor_map_handle(item);
    if (!cbor_isa_map(pair->value)) {
        goto cleanup;
    }
    size = cbor_map_size(pair->value);
    if (size < 1) {
        goto cleanup;
    }

    pair = cbor_map_handle(pair->value);
    for (int i = 0; i < size; ++i) {
        if (!cbor_isa_string(pair[i].key)) {
            continue;
        }
        str = cbor_string_handle(pair[i].key);
        if (str && cbor_string_length(pair[i].key) == 5 &&
            memcmp(str, "index", 5) == 0) {
            if (!cbor_isa_uint(pair[i].value) ||
                cbor_int_get_width(pair[i].value) != CBOR_INT_8) {
                break;
            }

            nsm_req->index = cbor_get_uint8(pair[i].value);
            r = NSM_SUCCESS;
            break;
        }
    }

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

/*
 * LockPCR success response structure:
 * {
 *   String("LockPCR")
 * }
 */
static bool handle_lock_pcr(VirtIONSM *vnsm, struct iovec *request,
                            struct iovec *response, Error **errp)
{
    cbor_item_t *root = NULL;
    size_t len;
    NSMLockPCRReq nsm_req;
    enum NSMResponseTypes type;
    struct PCRInfo *pcr;
    bool r = false;

    type = get_nsm_lock_pcr_req(request->iov_base, request->iov_len, &nsm_req);
    if (type != NSM_SUCCESS) {
        if (error_response(response, type, errp)) {
            r = true;
        }
        goto cleanup;
    }
    if (nsm_req.index >= vnsm->max_pcrs) {
        if (error_response(response, NSM_INVALID_INDEX, errp)) {
            r = true;
        }
        goto cleanup;
    }

    pcr = &(vnsm->pcrs[nsm_req.index]);

    if (pcr->locked) {
        if (error_response(response, NSM_READONLY_INDEX, errp)) {
            r = true;
        }
        goto cleanup;
    }

    pcr->locked = true;

    root = cbor_build_string("LockPCR");
    if (!root) {
        goto err;
    }

    len = cbor_serialize(root, response->iov_base, response->iov_len);
    if (len == 0) {
        if (error_response(response, NSM_BUFFER_TOO_SMALL, errp)) {
            r = true;
        }
        goto cleanup;
    }

    response->iov_len = len;
    r = true;
    goto cleanup;

 err:
    error_setg(errp, "Failed to initialize LockPCR response");

 cleanup:
    if (root) {
        cbor_decref(&root);
    }
    return r;
}

/*
 * LockPCRs request structure:
 *
 * {
 *   Map(1) {
 *     key = String("LockPCRs"),
 *     value = Map(1) {
 *       key = String("range"),
 *       value = Uint8(pcr)
 *     }
 *   }
 * }
 */
typedef struct NSMLockPCRsReq {
    uint16_t range;
} NSMLockPCRsReq;

static enum NSMResponseTypes get_nsm_lock_pcrs_req(uint8_t *req, size_t len,
                                                   NSMLockPCRsReq *nsm_req)
{
    cbor_item_t *item = NULL;
    size_t size;
    uint8_t *str;
    struct cbor_pair *pair;
    struct cbor_load_result result;
    enum NSMResponseTypes r = NSM_INVALID_OPERATION;

    item = cbor_load(req, len, &result);
    if (!item || result.error.code != CBOR_ERR_NONE) {
        goto cleanup;
    }

    pair = cbor_map_handle(item);
    if (!cbor_isa_map(pair->value)) {
        goto cleanup;
    }
    size = cbor_map_size(pair->value);
    if (size < 1) {
        goto cleanup;
    }

    pair = cbor_map_handle(pair->value);
    for (int i = 0; i < size; ++i) {
        if (!cbor_isa_string(pair[i].key)) {
            continue;
        }
        str = cbor_string_handle(pair[i].key);
        if (str && cbor_string_length(pair[i].key) == 5 &&
            memcmp(str, "range", 5) == 0) {
            if (!cbor_isa_uint(pair[i].value) ||
                cbor_int_get_width(pair[i].value) != CBOR_INT_8) {
                break;
            }

            nsm_req->range = cbor_get_uint8(pair[i].value);
            r = NSM_SUCCESS;
            break;
        }
    }

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

/*
 * LockPCRs success response structure:
 * {
 *   String("LockPCRs")
 * }
 */
static bool handle_lock_pcrs(VirtIONSM *vnsm, struct iovec *request,
                             struct iovec *response, Error **errp)
{
    cbor_item_t *root = NULL;
    size_t len;
    NSMLockPCRsReq nsm_req;
    enum NSMResponseTypes type;
    bool r = false;

    type = get_nsm_lock_pcrs_req(request->iov_base, request->iov_len, &nsm_req);
    if (type != NSM_SUCCESS) {
        if (error_response(response, type, errp)) {
            r = true;
        }
        goto cleanup;
    }
    if (nsm_req.range > vnsm->max_pcrs) {
        if (error_response(response, NSM_INVALID_INDEX, errp)) {
            r = true;
        }
        goto cleanup;
    }

    for (int i = 0; i < nsm_req.range; ++i) {
        vnsm->pcrs[i].locked = true;
    }

    root = cbor_build_string("LockPCRs");
    if (!root) {
        goto err;
    }

    len = cbor_serialize(root, response->iov_base, response->iov_len);
    if (len == 0) {
        if (error_response(response, NSM_BUFFER_TOO_SMALL, errp)) {
            r = true;
        }
        goto cleanup;
    }

    response->iov_len = len;
    r = true;
    goto cleanup;

 err:
    error_setg(errp, "Failed to initialize response");

 cleanup:
    if (root) {
        cbor_decref(&root);
    }
    return r;
}

/*
 * Attestation request structure:
 *
 *   Map(1) {
 *     key = String("Attestation"),
 *     value = Map(3) {
 *       key = String("user_data"),
 *       value = Byte_String() || null, // Optional
 *       key = String("nonce"),
 *       value = Byte_String() || null, // Optional
 *       key = String("public_key"),
 *       value = Byte_String() || null, // Optional
 *     }
 *   }
 * }
 */

struct AttestationProperty {
    bool is_null; /* True if property is not present in map or is null */
    uint16_t len;
    uint8_t buf[NSM_REQUEST_MAX_SIZE];
};

typedef struct NSMAttestationReq {
    struct AttestationProperty public_key;
    struct AttestationProperty user_data;
    struct AttestationProperty nonce;
} NSMAttestationReq;

static bool fill_attestation_property(struct AttestationProperty *prop,
                                      cbor_item_t *value)
{
    uint8_t *str;
    bool ret = false;

    if (cbor_is_null(value)) {
        prop->is_null = true;
        ret = true;
        goto out;
    } else if (cbor_isa_bytestring(value)) {
        str = cbor_bytestring_handle(value);
        if (!str) {
            goto out;
        }
        prop->len = cbor_bytestring_length(value);
    } else if (cbor_isa_string(value)) {
        str = cbor_string_handle(value);
        if (!str) {
            goto out;
        }
        prop->len = cbor_string_length(value);
    } else {
        goto out;
    }

    /*
     * prop->len will be smaller than NSM_REQUEST_MAX_SIZE as we
     * already check for the max request size before processing
     * any request. So it's safe to copy.
     */
    memcpy(prop->buf, str, prop->len);
    prop->is_null = false;
    ret = true;

 out:
    return ret;
}

static enum NSMResponseTypes get_nsm_attestation_req(uint8_t *req, size_t len,
                                                     NSMAttestationReq *nsm_req)
{
    cbor_item_t *item = NULL;
    size_t size;
    uint8_t *str;
    struct cbor_pair *pair;
    struct cbor_load_result result;
    enum NSMResponseTypes r = NSM_INVALID_OPERATION;

    nsm_req->public_key.is_null = true;
    nsm_req->user_data.is_null = true;
    nsm_req->nonce.is_null = true;

    item = cbor_load(req, len, &result);
    if (!item || result.error.code != CBOR_ERR_NONE) {
        goto cleanup;
    }

    pair = cbor_map_handle(item);
    if (!cbor_isa_map(pair->value)) {
        goto cleanup;
    }
    size = cbor_map_size(pair->value);
    if (size == 0) {
        r = NSM_SUCCESS;
        goto cleanup;
    }

    pair = cbor_map_handle(pair->value);
    for (int i = 0; i < size; ++i) {
        if (!cbor_isa_string(pair[i].key)) {
            continue;
        }

        str = cbor_string_handle(pair[i].key);
        if (!str) {
            continue;
        }

        if (cbor_string_length(pair[i].key) == 10 &&
            memcmp(str, "public_key", 10) == 0) {
            if (!fill_attestation_property(&(nsm_req->public_key),
                                           pair[i].value)) {
                goto cleanup;
            }
            continue;
        }

        if (cbor_string_length(pair[i].key) == 9 &&
            memcmp(str, "user_data", 9) == 0) {
            if (!fill_attestation_property(&(nsm_req->user_data),
                                           pair[i].value)) {
                goto cleanup;
            }
            continue;
        }

        if (cbor_string_length(pair[i].key) == 5 &&
            memcmp(str, "nonce", 5) == 0) {
            if (!fill_attestation_property(&(nsm_req->nonce), pair[i].value)) {
                goto cleanup;
            }
            continue;
        }
    }

    r = NSM_SUCCESS;

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

static bool add_protected_header_to_cose(cbor_item_t *cose)
{
    cbor_item_t *map = NULL;
    cbor_item_t *key = NULL;
    cbor_item_t *value = NULL;
    cbor_item_t *bs = NULL;
    size_t len;
    bool r = false;
    size_t buf_len = 4096;
    g_autofree uint8_t *buf = g_malloc(buf_len);

    map = cbor_new_definite_map(1);
    if (!map) {
        goto cleanup;
    }
    key = cbor_build_uint8(1);
    if (!key) {
        goto cleanup;
    }
    value = cbor_new_int8();
    if (!value) {
        goto cleanup;
    }
    cbor_mark_negint(value);
    /* we don't actually sign the data, so we use -1 as the 'alg' value */
    cbor_set_uint8(value, 0);

    if (!qemu_cbor_map_add(map, key, value)) {
        goto cleanup;
    }

    len = cbor_serialize(map, buf, buf_len);
    if (len == 0) {
        goto cleanup_map;
    }

    bs = cbor_build_bytestring(buf, len);
    if (!bs) {
        goto cleanup_map;
    }
    if (!qemu_cbor_array_push(cose, bs)) {
        cbor_decref(&bs);
        goto cleanup_map;
    }
    r = true;
    goto cleanup_map;

 cleanup:
    if (key) {
        cbor_decref(&key);
    }
    if (value) {
        cbor_decref(&value);
    }

 cleanup_map:
    if (map) {
        cbor_decref(&map);
    }
    return r;
}

static bool add_unprotected_header_to_cose(cbor_item_t *cose)
{
    cbor_item_t *map = cbor_new_definite_map(0);
    if (!map) {
        goto cleanup;
    }
    if (!qemu_cbor_array_push(cose, map)) {
        goto cleanup;
    }

    return true;

 cleanup:
    if (map) {
        cbor_decref(&map);
    }
    return false;
}

static bool add_ca_bundle_to_payload(cbor_item_t *map)
{
    cbor_item_t *key_cbor = NULL;
    cbor_item_t *value_cbor = NULL;
    cbor_item_t *bs = NULL;
    uint8_t zero[64] = {0};

    key_cbor = cbor_build_string("cabundle");
    if (!key_cbor) {
        goto cleanup;
    }
    value_cbor = cbor_new_definite_array(1);
    if (!value_cbor) {
        goto cleanup;
    }
    bs = cbor_build_bytestring(zero, 64);
    if (!bs) {
        goto cleanup;
    }
    if (!qemu_cbor_array_push(value_cbor, bs)) {
        cbor_decref(&bs);
        goto cleanup;
    }
    if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
        goto cleanup;
    }

    return true;

 cleanup:
    if (key_cbor) {
        cbor_decref(&key_cbor);
    }
    if (value_cbor) {
        cbor_decref(&value_cbor);
    }
    return false;
}

static bool add_payload_to_cose(cbor_item_t *cose, VirtIONSM *vnsm,
                                NSMAttestationReq *req)
{
    cbor_item_t *root = NULL;
    cbor_item_t *nested_map;
    cbor_item_t *bs = NULL;
    size_t locked_cnt;
    uint8_t ind[NSM_MAX_PCRS];
    size_t payload_map_size = 9;
    size_t len;
    struct PCRInfo *pcr;
    uint8_t zero[64] = {0};
    bool r = false;
    size_t buf_len = 16384;
    g_autofree uint8_t *buf = g_malloc(buf_len);

    root = cbor_new_definite_map(payload_map_size);
    if (!root) {
        goto cleanup;
    }
    if (!qemu_cbor_add_string_to_map(root, "module_id", vnsm->module_id)) {
        goto cleanup;
    }
    if (!qemu_cbor_add_string_to_map(root, "digest", vnsm->digest)) {
        goto cleanup;
    }
    if (!qemu_cbor_add_uint64_to_map(root, "timestamp",
                                     (uint64_t) time(NULL) * 1000)) {
        goto cleanup;
    }

    locked_cnt = 0;
    for (uint8_t i = 0; i < NSM_MAX_PCRS; ++i) {
        if (vnsm->pcrs[i].locked) {
            ind[locked_cnt++] = i;
        }
    }
    if (!qemu_cbor_add_map_to_map(root, "pcrs", locked_cnt, &nested_map)) {
        goto cleanup;
    }
    for (uint8_t i = 0; i < locked_cnt; ++i) {
        pcr = &(vnsm->pcrs[ind[i]]);
        if (!qemu_cbor_add_uint8_key_bytestring_to_map(
                nested_map, ind[i],
                pcr->data,
                QCRYPTO_HASH_DIGEST_LEN_SHA384)) {
            goto cleanup;
        }
    }
    if (!qemu_cbor_add_bytestring_to_map(root, "certificate", zero, 64)) {
        goto cleanup;
    }
    if (!add_ca_bundle_to_payload(root)) {
        goto cleanup;
    }

    if (req->public_key.is_null) {
        if (!qemu_cbor_add_null_to_map(root, "public_key")) {
            goto cleanup;
        }
    } else if (!qemu_cbor_add_bytestring_to_map(root, "public_key",
                                                req->public_key.buf,
                                                req->public_key.len)) {
        goto cleanup;
    }

    if (req->user_data.is_null) {
        if (!qemu_cbor_add_null_to_map(root, "user_data")) {
            goto cleanup;
        }
    } else if (!qemu_cbor_add_bytestring_to_map(root, "user_data",
                                                req->user_data.buf,
                                                req->user_data.len)) {
            goto cleanup;
    }

    if (req->nonce.is_null) {
        if (!qemu_cbor_add_null_to_map(root, "nonce")) {
            goto cleanup;
        }
    } else if (!qemu_cbor_add_bytestring_to_map(root, "nonce",
                                                req->nonce.buf,
                                                req->nonce.len)) {
        goto cleanup;
    }

    len = cbor_serialize(root, buf, buf_len);
    if (len == 0) {
        goto cleanup;
    }

    bs = cbor_build_bytestring(buf, len);
    if (!bs) {
        goto cleanup;
    }
    if (!qemu_cbor_array_push(cose, bs)) {
        cbor_decref(&bs);
        goto cleanup;
    }

    r = true;

 cleanup:
    if (root) {
        cbor_decref(&root);
    }
    return r;
}

static bool add_signature_to_cose(cbor_item_t *cose)
{
    cbor_item_t *bs = NULL;
    uint8_t zero[64] = {0};

    /* we don't actually sign the data, so we just put 64 zero bytes */
    bs = cbor_build_bytestring(zero, 64);
    if (!bs) {
        goto cleanup;
    }

    if (!qemu_cbor_array_push(cose, bs)) {
        goto cleanup;
    }

    return true;

 cleanup:
    if (bs) {
        cbor_decref(&bs);
    }
    return false;
}

/*
 * Attestation response structure:
 *
 * {
 *   Map(1) {
 *     key = String("Attestation"),
 *     value = Map(1) {
 *       key = String("document"),
 *       value = Byte_String()
 *     }
 *   }
 * }
 *
 * The document is a serialized COSE sign1 blob of the structure:
 * {
 *   Array(4) {
 *     [0] { ByteString() }, // serialized protected header
 *     [1] { Map(0) },       // 0 length map
 *     [2] { ByteString() }, // serialized payload
 *     [3] { ByteString() }, // signature
 *   }
 * }
 *
 * where [0] protected header is a serialized CBOR blob of the structure:
 * {
 *   Map(1) {
 *     key = Uint8(1)         // alg
 *     value = NegativeInt8() // Signing algorithm
 *   }
 * }
 *
 * [2] payload is serialized CBOR blob of the structure:
 * {
 *   Map(9) {
 *     [0] { key = String("module_id"), value = String(module_id) },
 *     [1] { key = String("digest"), value = String("SHA384") },
 *     [2] {
 *           key = String("timestamp"),
 *           value = Uint64(unix epoch of  when document was created)
 *         },
 *     [3] {
 *           key = String("pcrs"),
 *           value = Map(locked_pcr_cnt) {
 *                       key = Uint8(pcr_index),
 *                       value = ByteString(pcr_data)
 *                   },
 *         },
 *     [4] {
 *           key = String("certificate"),
 *           value = ByteString(Signing certificate)
 *         },
 *     [5] { key = String("cabundle"), value = Array(N) { ByteString()... } },
 *     [6] { key = String("public_key"), value = ByteString() || null },
 *     [7] { key = String("user_data"), value = ByteString() || null},
 *     [8] { key = String("nonce"), value = ByteString() || null},
 *   }
 * }
 */
static bool handle_attestation(VirtIONSM *vnsm, struct iovec *request,
                               struct iovec *response, Error **errp)
{
    cbor_item_t *root = NULL;
    cbor_item_t *cose = NULL;
    cbor_item_t *nested_map;
    size_t len;
    enum NSMResponseTypes type;
    bool r = false;
    size_t buf_len = 16384;
    g_autofree uint8_t *buf = g_malloc(buf_len);
    g_autofree NSMAttestationReq *nsm_req = g_malloc(sizeof(NSMAttestationReq));

    nsm_req->public_key.is_null = true;
    nsm_req->user_data.is_null = true;
    nsm_req->nonce.is_null = true;

    type = get_nsm_attestation_req(request->iov_base, request->iov_len,
                                   nsm_req);
    if (type != NSM_SUCCESS) {
        if (error_response(response, type, errp)) {
            r = true;
        }
        goto out;
    }

    cose = cbor_new_definite_array(4);
    if (!cose) {
        goto err;
    }
    if (!add_protected_header_to_cose(cose)) {
        goto err;
    }
    if (!add_unprotected_header_to_cose(cose)) {
        goto err;
    }
    if (!add_payload_to_cose(cose, vnsm, nsm_req)) {
        goto err;
    }
    if (!add_signature_to_cose(cose)) {
        goto err;
    }

    len = cbor_serialize(cose, buf, buf_len);
    if (len == 0) {
        goto err;
    }

    root = cbor_new_definite_map(1);
    if (!root) {
        goto err;
    }
    if (!qemu_cbor_add_map_to_map(root, "Attestation", 1, &nested_map)) {
        goto err;
    }
    if (!qemu_cbor_add_bytestring_to_map(nested_map, "document", buf, len)) {
        goto err;
    }

    len = cbor_serialize(root, response->iov_base, response->iov_len);
    if (len == 0) {
        if (error_response(response, NSM_INPUT_TOO_LARGE, errp)) {
            r = true;
        }
        goto out;
    }

    response->iov_len = len;
    r = true;

 out:
    if (root) {
        cbor_decref(&root);
    }
    if (cose) {
        cbor_decref(&cose);
    }
    return r;

 err:
    error_setg(errp, "Failed to initialize Attestation response");
    goto out;
}

enum CBOR_ROOT_TYPE {
    CBOR_ROOT_TYPE_STRING = 0,
    CBOR_ROOT_TYPE_MAP = 1,
};

struct nsm_cmd {
    char name[16];
    /*
     * There are 2 types of request
     * 1) String(); "GetRandom", "DescribeNSM"
     * 2) Map(1) { key: String(), value: ... }
     */
    enum CBOR_ROOT_TYPE root_type;
    bool (*response_fn)(VirtIONSM *vnsm, struct iovec *request,
                        struct iovec *response, Error **errp);
};

const struct nsm_cmd nsm_cmds[] = {
    { "GetRandom",   CBOR_ROOT_TYPE_STRING,  handle_get_random },
    { "DescribeNSM", CBOR_ROOT_TYPE_STRING,  handle_describe_nsm },
    { "DescribePCR", CBOR_ROOT_TYPE_MAP,     handle_describe_pcr },
    { "ExtendPCR",   CBOR_ROOT_TYPE_MAP,     handle_extend_pcr },
    { "LockPCR",     CBOR_ROOT_TYPE_MAP,     handle_lock_pcr },
    { "LockPCRs",    CBOR_ROOT_TYPE_MAP,     handle_lock_pcrs },
    { "Attestation", CBOR_ROOT_TYPE_MAP,     handle_attestation },
};

static const struct nsm_cmd *get_nsm_request_cmd(uint8_t *buf, size_t len)
{
    size_t size;
    uint8_t *req;
    enum CBOR_ROOT_TYPE root_type;
    struct cbor_load_result result;
    cbor_item_t *item = cbor_load(buf, len, &result);
    if (!item || result.error.code != CBOR_ERR_NONE) {
        goto cleanup;
    }

    if (cbor_isa_string(item)) {
        size = cbor_string_length(item);
        req = cbor_string_handle(item);
        root_type = CBOR_ROOT_TYPE_STRING;
    } else if (cbor_isa_map(item) && cbor_map_size(item) == 1) {
        struct cbor_pair *handle = cbor_map_handle(item);
        if (cbor_isa_string(handle->key)) {
            size = cbor_string_length(handle->key);
            req = cbor_string_handle(handle->key);
            root_type = CBOR_ROOT_TYPE_MAP;
        } else {
            goto cleanup;
        }
    } else {
        goto cleanup;
    }

    if  (size == 0 || req == NULL) {
        goto cleanup;
    }

    for (int i = 0; i < ARRAY_SIZE(nsm_cmds); ++i) {
        if (nsm_cmds[i].root_type == root_type &&
            strlen(nsm_cmds[i].name) == size &&
            memcmp(nsm_cmds[i].name, req, size) == 0) {
            cbor_decref(&item);
            return &nsm_cmds[i];
        }
    }

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

static bool get_nsm_request_response(VirtIONSM *vnsm, struct iovec *req,
                                     struct iovec *resp, Error **errp)
{
    const struct nsm_cmd *cmd;

    if (req->iov_len > NSM_REQUEST_MAX_SIZE) {
        if (error_response(resp, NSM_INPUT_TOO_LARGE, errp)) {
            return true;
        }
        error_setg(errp, "Failed to initialize InputTooLarge response");
        return false;
    }

    cmd = get_nsm_request_cmd(req->iov_base, req->iov_len);

    if (cmd == NULL) {
        if (error_response(resp, NSM_INVALID_OPERATION, errp)) {
            return true;
        }
        error_setg(errp, "Failed to initialize InvalidOperation response");
        return false;
    }

    return cmd->response_fn(vnsm, req, resp, errp);
}

static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
{
    g_autofree VirtQueueElement *out_elem = NULL;
    g_autofree VirtQueueElement *in_elem = NULL;
    VirtIONSM *vnsm = VIRTIO_NSM(vdev);
    Error *err = NULL;
    size_t sz;
    struct iovec req = {.iov_base = NULL, .iov_len = 0};
    struct iovec res = {.iov_base = NULL, .iov_len = 0};

    out_elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
    if (!out_elem) {
        /* nothing in virtqueue */
        return;
    }

    sz = iov_size(out_elem->out_sg, out_elem->out_num);
    if (sz == 0) {
        virtio_error(vdev, "Expected non-zero sized request buffer in "
                     "virtqueue");
        goto cleanup;
    }

    in_elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
    if (!in_elem) {
        virtio_error(vdev, "Expected response buffer after request buffer "
                     "in virtqueue");
        goto cleanup;
    }
    if (iov_size(in_elem->in_sg, in_elem->in_num) != NSM_RESPONSE_BUF_SIZE) {
        virtio_error(vdev, "Expected response buffer of length 0x3000");
        goto cleanup;
    }

    req.iov_base = g_malloc(sz);
    req.iov_len = iov_to_buf(out_elem->out_sg, out_elem->out_num, 0,
                             req.iov_base, sz);
    if (req.iov_len != sz) {
        virtio_error(vdev, "Failed to copy request buffer");
        goto cleanup;
    }

    res.iov_base = g_malloc(NSM_RESPONSE_BUF_SIZE);
    res.iov_len = NSM_RESPONSE_BUF_SIZE;

    if (!get_nsm_request_response(vnsm, &req, &res, &err)) {
        error_report_err(err);
        virtio_error(vdev, "Failed to get NSM request response");
        goto cleanup;
    }

    sz = iov_from_buf(in_elem->in_sg, in_elem->in_num, 0, res.iov_base,
                      res.iov_len);
    if (sz != res.iov_len) {
        virtio_error(vdev, "Failed to copy response buffer");
        goto cleanup;
    }

    g_free(req.iov_base);
    g_free(res.iov_base);
    virtqueue_push(vq, out_elem, 0);
    virtqueue_push(vq, in_elem, in_elem->in_sg->iov_len);
    virtio_notify(vdev, vq);
    return;

 cleanup:
    g_free(req.iov_base);
    g_free(res.iov_base);
    if (out_elem) {
        virtqueue_detach_element(vq, out_elem, 0);
    }
    if (in_elem) {
        virtqueue_detach_element(vq, in_elem, 0);
    }
    return;
}

static uint64_t get_features(VirtIODevice *vdev, uint64_t f, Error **errp)
{
    return f;
}

static bool extend_pcr(VirtIONSM *vnsm, int ind, uint8_t *data, uint16_t len)
{
    Error *err = NULL;
    struct PCRInfo *pcr = &(vnsm->pcrs[ind]);
    size_t digest_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
    uint8_t result[QCRYPTO_HASH_DIGEST_LEN_SHA384];
    uint8_t *ptr = result;
    struct iovec iov[2] = {
        { .iov_base = pcr->data, .iov_len = QCRYPTO_HASH_DIGEST_LEN_SHA384 },
        { .iov_base = data, .iov_len = len },
    };

    if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALGO_SHA384, iov, 2, &ptr, &digest_len,
                            &err) < 0) {
        return false;
    }

    memcpy(pcr->data, result, QCRYPTO_HASH_DIGEST_LEN_SHA384);
    return true;
}

static void lock_pcr(VirtIONSM *vnsm, int ind)
{
    vnsm->pcrs[ind].locked = true;
}

static void virtio_nsm_device_realize(DeviceState *dev, Error **errp)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIONSM *vnsm = VIRTIO_NSM(dev);

    vnsm->max_pcrs = NSM_MAX_PCRS;
    vnsm->digest = (char *) "SHA384";
    if (vnsm->module_id == NULL) {
        vnsm->module_id = (char *) "i-234-enc5678";
    }
    vnsm->version_major = 1;
    vnsm->version_minor = 0;
    vnsm->version_patch = 0;
    vnsm->extend_pcr = extend_pcr;
    vnsm->lock_pcr = lock_pcr;

    virtio_init(vdev, VIRTIO_ID_NITRO_SEC_MOD, 0);

    vnsm->vq = virtio_add_queue(vdev, 2, handle_input);
}

static void virtio_nsm_device_unrealize(DeviceState *dev)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);

    virtio_del_queue(vdev, 0);
    virtio_cleanup(vdev);
}

static const VMStateDescription vmstate_pcr_info_entry = {
    .name = "pcr_info_entry",
    .minimum_version_id = 1,
    .version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_BOOL(locked, struct PCRInfo),
        VMSTATE_UINT8_ARRAY(data, struct PCRInfo,
                            QCRYPTO_HASH_DIGEST_LEN_SHA384),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_virtio_nsm_device = {
    .name = "virtio-nsm-device",
    .minimum_version_id = 1,
    .version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_STRUCT_ARRAY(pcrs, VirtIONSM, NSM_MAX_PCRS, 1,
                             vmstate_pcr_info_entry, struct PCRInfo),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_virtio_nsm = {
    .name = "virtio-nsm",
    .minimum_version_id = 1,
    .version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_VIRTIO_DEVICE,
        VMSTATE_END_OF_LIST()
    },
};

static Property virtio_nsm_properties[] = {
    DEFINE_PROP_STRING("module-id", VirtIONSM, module_id),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_nsm_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    device_class_set_props(dc, virtio_nsm_properties);
    dc->vmsd = &vmstate_virtio_nsm;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    vdc->realize = virtio_nsm_device_realize;
    vdc->unrealize = virtio_nsm_device_unrealize;
    vdc->get_features = get_features;
    vdc->vmsd = &vmstate_virtio_nsm_device;
}

static const TypeInfo virtio_nsm_info = {
    .name = TYPE_VIRTIO_NSM,
    .parent = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(VirtIONSM),
    .class_init = virtio_nsm_class_init,
};

static void virtio_register_types(void)
{
    type_register_static(&virtio_nsm_info);
}

type_init(virtio_register_types)
