/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <trusty/keymaster.h>
#include <trusty/keymaster_serializable.h>
#include <trusty/rpmb.h>
#include <trusty/trusty_ipc.h>
#include <trusty/util.h>

#define LOCAL_LOG 0

static struct trusty_ipc_chan km_chan;
static bool initialized;
static int trusty_km_version = 2;
static const size_t kMaxCaRequestSize = 10000;
static const size_t kMaxSendSize = 4000;
static const size_t kUuidSize = 32;

#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif

#ifndef NELEMS
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
#endif

static int km_send_request(uint32_t cmd, const void* req, size_t req_len) {
    struct keymaster_message header = {.cmd = cmd};
    int num_iovecs = req ? 2 : 1;

    struct trusty_ipc_iovec req_iovs[2] = {
            {.base = &header, .len = sizeof(header)},
            {.base = (void*)req, .len = req_len},
    };

    return trusty_ipc_send(&km_chan, req_iovs, num_iovecs, true);
}

/* Checks that the command opcode in |header| matches |ex-ected_cmd|. Checks
 * that |tipc_result| is a valid response size. Returns negative on error.
 */
static int check_response_error(uint32_t expected_cmd,
                                struct keymaster_message header,
                                int32_t tipc_result) {
    if (tipc_result < 0) {
        trusty_error("failed (%d) to recv response\n", tipc_result);
        return tipc_result;
    }
    if ((size_t)tipc_result < sizeof(struct keymaster_message)) {
        trusty_error("invalid response size (%d)\n", tipc_result);
        return TRUSTY_ERR_GENERIC;
    }
    if ((header.cmd & ~(KEYMASTER_STOP_BIT)) !=
        (expected_cmd | KEYMASTER_RESP_BIT)) {
        trusty_error("malformed response\n");
        return TRUSTY_ERR_GENERIC;
    }
    return tipc_result;
}

/* Reads the raw response to |resp| up to a maximum size of |resp_len|. Format
 * of each message frame read from the secure side:
 *
 * command header : 4 bytes
 * opaque bytes   : MAX(KEYMASTER_MAX_BUFFER_LENGTH, x) bytes
 *
 * The individual message frames from the secure side are reassembled
 * into |resp|, stripping each frame's command header. Returns the number
 * of bytes written to |resp| on success, negative on error.
 */
static int km_read_raw_response(uint32_t cmd, void* resp, size_t resp_len) {
    struct keymaster_message header = {.cmd = cmd};
    int rc = TRUSTY_ERR_GENERIC;
    size_t max_resp_len = resp_len;
    struct trusty_ipc_iovec resp_iovs[2] = {
            {.base = &header, .len = sizeof(header)},
            {.base = resp,
             .len = MIN(KEYMASTER_MAX_BUFFER_LENGTH, max_resp_len)}};

    if (!resp) {
        return TRUSTY_ERR_GENERIC;
    }
    resp_len = 0;
    while (true) {
        resp_iovs[1].base = (uint8_t*)resp + resp_len;
        resp_iovs[1].len = MIN(KEYMASTER_MAX_BUFFER_LENGTH,
                               (int)max_resp_len - (int)resp_len);

        rc = trusty_ipc_recv(&km_chan, resp_iovs, NELEMS(resp_iovs), true);
        rc = check_response_error(cmd, header, rc);
        if (rc < 0) {
            return rc;
        }
        resp_len += ((size_t)rc - sizeof(struct keymaster_message));
        if (header.cmd & KEYMASTER_STOP_BIT || resp_len >= max_resp_len) {
            break;
        }
    }

    return resp_len;
}

/* Reads a Keymaster Response message with a sized buffer. The format
 * of the response is as follows:
 *
 * command header : 4 bytes
 * error          : 4 bytes
 * data length    : 4 bytes
 * data           : |data length| bytes
 *
 * On success, |error|, |resp_data|, and |resp_data_len| are filled
 * successfully. Returns a trusty_err.
 */
static int km_read_data_response(uint32_t cmd,
                                 int32_t* error,
                                 uint8_t* resp_data,
                                 uint32_t* resp_data_len) {
    struct keymaster_message header = {.cmd = cmd};
    int rc = TRUSTY_ERR_GENERIC;
    size_t max_resp_len = *resp_data_len;
    uint32_t resp_data_bytes = 0;
    /* On the first read, recv the keymaster_message header, error code,
     * response data length, and response data. On subsequent iterations,
     * only recv the keymaster_message header and response data.
     */
    struct trusty_ipc_iovec resp_iovs[4] = {
            {.base = &header, .len = sizeof(header)},
            {.base = error, .len = sizeof(int32_t)},
            {.base = resp_data_len, .len = sizeof(uint32_t)},
            {.base = resp_data,
             .len = MIN(KEYMASTER_MAX_BUFFER_LENGTH, max_resp_len)}};

    rc = trusty_ipc_recv(&km_chan, resp_iovs, NELEMS(resp_iovs), true);
    rc = check_response_error(cmd, header, rc);
    if (rc < 0) {
        return rc;
    }
    /* resp_data_bytes does not include the error or response data length */
    resp_data_bytes += ((size_t)rc - sizeof(struct keymaster_message) -
                        2 * sizeof(uint32_t));
    if (header.cmd & KEYMASTER_STOP_BIT) {
        return TRUSTY_ERR_NONE;
    }

    /* Read the remaining response data */
    uint8_t* resp_data_start = resp_data + resp_data_bytes;
    size_t resp_data_remaining = *resp_data_len - resp_data_bytes;
    rc = km_read_raw_response(cmd, resp_data_start, resp_data_remaining);
    if (rc < 0) {
        return rc;
    }
    resp_data_bytes += rc;
    if (*resp_data_len != resp_data_bytes) {
        return TRUSTY_ERR_GENERIC;
    }
    return TRUSTY_ERR_NONE;
}

/**
 * Convenience method to send a request to the secure side, handle rpmb
 * operations, and receive the response. If |resp_data| is not NULL, the
 * caller expects an additional data buffer to be returned from the secure
 * side.
 */
static int km_do_tipc(uint32_t cmd,
                      void* req,
                      uint32_t req_len,
                      void* resp_data,
                      uint32_t* resp_data_len) {
    int rc = TRUSTY_ERR_GENERIC;
    struct km_no_response resp_header;

    rc = km_send_request(cmd, req, req_len);
    if (rc < 0) {
        trusty_error("%s: failed (%d) to send km request\n", __func__, rc);
        return rc;
    }

    if (!resp_data) {
        rc = km_read_raw_response(cmd, &resp_header, sizeof(resp_header));
    } else {
        rc = km_read_data_response(cmd, &resp_header.error, resp_data,
                                   resp_data_len);
    }

    if (rc < 0) {
        trusty_error("%s: failed (%d) to read km response\n", __func__, rc);
        return rc;
    }
    if (resp_header.error != KM_ERROR_OK) {
        trusty_error("%s: keymaster returned error (%d)\n", __func__,
                     resp_header.error);
        return TRUSTY_ERR_GENERIC;
    }
    return TRUSTY_ERR_NONE;
}

static int32_t MessageVersion(uint8_t major_ver,
                              uint8_t minor_ver,
                              uint8_t subminor_ver) {
    int32_t message_version = -1;
    switch (major_ver) {
    case 0:
        message_version = 0;
        break;
    case 1:
        switch (minor_ver) {
        case 0:
            message_version = 1;
            break;
        case 1:
            message_version = 2;
            break;
        }
        break;
    case 2:
        message_version = 3;
        break;
    }
    return message_version;
}

static int km_get_version(int32_t* version) {
    int rc = TRUSTY_ERR_GENERIC;
    struct km_get_version_resp resp;

    rc = km_send_request(KM_GET_VERSION, NULL, 0);
    if (rc < 0) {
        trusty_error("failed to send km version request", rc);
        return rc;
    }

    rc = km_read_raw_response(KM_GET_VERSION, &resp, sizeof(resp));
    if (rc < 0) {
        trusty_error("%s: failed (%d) to read km response\n", __func__, rc);
        return rc;
    }

    *version =
            MessageVersion(resp.major_ver, resp.minor_ver, resp.subminor_ver);
    return TRUSTY_ERR_NONE;
}

int km_tipc_init(struct trusty_ipc_dev* dev) {
    int rc = TRUSTY_ERR_GENERIC;

    trusty_assert(dev);

    trusty_ipc_chan_init(&km_chan, dev);
    trusty_debug("Connecting to Keymaster service\n");

    /* connect to km service and wait for connect to complete */
    rc = trusty_ipc_connect(&km_chan, KEYMASTER_PORT, true);
    if (rc < 0) {
        trusty_error("failed (%d) to connect to '%s'\n", rc, KEYMASTER_PORT);
        return rc;
    }
    initialized = true;

    int32_t version = -1;
    rc = km_get_version(&version);
    if (rc < 0) {
        trusty_error("failed (%d) to get keymaster version\n", rc);
        return rc;
    }
    if (version < trusty_km_version) {
        trusty_error("keymaster version mismatch. Expected %d, received %d\n",
                     trusty_km_version, version);
        return TRUSTY_ERR_GENERIC;
    }

    return TRUSTY_ERR_NONE;
}

void km_tipc_shutdown(void) {
    if (!initialized)
        return;
    /* close channel */
    trusty_ipc_close(&km_chan);

    initialized = false;
}

int trusty_set_boot_params(uint32_t os_version,
                           uint32_t os_patchlevel,
                           keymaster_verified_boot_t verified_boot_state,
                           bool device_locked,
                           const uint8_t* verified_boot_key_hash,
                           uint32_t verified_boot_key_hash_size,
                           const uint8_t* verified_boot_hash,
                           uint32_t verified_boot_hash_size) {
    struct km_boot_params params = {
            .os_version = os_version,
            .os_patchlevel = os_patchlevel,
            .device_locked = (uint32_t)device_locked,
            .verified_boot_state = (uint32_t)verified_boot_state,
            .verified_boot_key_hash_size = verified_boot_key_hash_size,
            .verified_boot_key_hash = verified_boot_key_hash,
            .verified_boot_hash_size = verified_boot_hash_size,
            .verified_boot_hash = verified_boot_hash};
    uint8_t* req = NULL;
    uint32_t req_size = 0;
    int rc = km_boot_params_serialize(&params, &req, &req_size);

    if (rc < 0) {
        trusty_error("failed (%d) to serialize request\n", rc);
        goto end;
    }
    rc = km_do_tipc(KM_SET_BOOT_PARAMS, req, req_size, NULL, NULL);

end:
    if (req) {
        trusty_free(req);
    }
    return rc;
}

static int trusty_send_attestation_data(uint32_t cmd,
                                        const uint8_t* data,
                                        uint32_t data_size,
                                        keymaster_algorithm_t algorithm) {
    struct km_attestation_data attestation_data = {
            .algorithm = (uint32_t)algorithm,
            .data_size = data_size,
            .data = data,
    };
    uint8_t* req = NULL;
    uint32_t req_size = 0;
    int rc = km_attestation_data_serialize(&attestation_data, &req, &req_size);

    if (rc < 0) {
        trusty_error("failed (%d) to serialize request\n", rc);
        goto end;
    }
    rc = km_do_tipc(cmd, req, req_size, NULL, NULL);

end:
    if (req) {
        trusty_free(req);
    }
    return rc;
}

static int trusty_send_raw_buffer(uint32_t cmd,
                                  const uint8_t* req_data,
                                  uint32_t req_data_size,
                                  uint8_t* resp_data,
                                  uint32_t* resp_data_size) {
    struct km_raw_buffer buf = {
            .data_size = req_data_size,
            .data = req_data,
    };
    uint8_t* req = NULL;
    uint32_t req_size = 0;
    int rc = km_raw_buffer_serialize(&buf, &req, &req_size);
    if (rc < 0) {
        trusty_error("failed (%d) to serialize request\n", rc);
        goto end;
    }
    rc = km_do_tipc(cmd, req, req_size, resp_data, resp_data_size);

end:
    if (req) {
        trusty_free(req);
    }
    return rc;
}

int trusty_set_attestation_key(const uint8_t* key,
                               uint32_t key_size,
                               keymaster_algorithm_t algorithm) {
    return trusty_send_attestation_data(KM_SET_ATTESTATION_KEY, key, key_size,
                                        algorithm);
}

int trusty_append_attestation_cert_chain(const uint8_t* cert,
                                         uint32_t cert_size,
                                         keymaster_algorithm_t algorithm) {
    return trusty_send_attestation_data(KM_APPEND_ATTESTATION_CERT_CHAIN, cert,
                                        cert_size, algorithm);
}

int trusty_atap_get_ca_request(const uint8_t* operation_start,
                               uint32_t operation_start_size,
                               uint8_t** ca_request_p,
                               uint32_t* ca_request_size_p) {
    *ca_request_p = trusty_calloc(1, kMaxCaRequestSize);
    if (!*ca_request_p) {
        return TRUSTY_ERR_NO_MEMORY;
    }
    *ca_request_size_p = kMaxCaRequestSize;
    int rc = trusty_send_raw_buffer(KM_ATAP_GET_CA_REQUEST, operation_start,
                                    operation_start_size, *ca_request_p,
                                    ca_request_size_p);
    if (rc != TRUSTY_ERR_NONE) {
        trusty_free(*ca_request_p);
    }
    return rc;
}

int trusty_atap_set_ca_response(const uint8_t* ca_response,
                                uint32_t ca_response_size) {
    struct km_set_ca_response_begin_req begin_req;
    int rc = TRUSTY_ERR_GENERIC;
    uint32_t bytes_sent = 0, send_size = 0;

    /* Tell the Trusty Keymaster TA the size of CA Response message */
    begin_req.ca_response_size = ca_response_size;
    rc = km_do_tipc(KM_ATAP_SET_CA_RESPONSE_BEGIN, &begin_req,
                    sizeof(begin_req), NULL, NULL);
    if (rc != TRUSTY_ERR_NONE) {
        return rc;
    }

    /* Send the CA Response message in chunks */
    while (bytes_sent < ca_response_size) {
        send_size = MIN(kMaxSendSize, ca_response_size - bytes_sent);
        rc = trusty_send_raw_buffer(KM_ATAP_SET_CA_RESPONSE_UPDATE,
                                    ca_response + bytes_sent, send_size, NULL,
                                    NULL);
        if (rc != TRUSTY_ERR_NONE) {
            return rc;
        }
        bytes_sent += send_size;
    }

    /* Tell Trusty Keymaster to parse the CA Response message */
    return km_do_tipc(KM_ATAP_SET_CA_RESPONSE_FINISH, NULL, 0, NULL, NULL);
}

int trusty_atap_read_uuid_str(char** uuid_p) {
    *uuid_p = (char*)trusty_calloc(1, kUuidSize + 1);
    *uuid_p[kUuidSize] = '\0';

    uint32_t response_size = kUuidSize;
    int rc = km_do_tipc(KM_ATAP_READ_UUID, NULL, 0, *uuid_p, &response_size);
    if (rc < 0) {
        trusty_error("failed to read uuid: %d\n", rc);
        trusty_free(*uuid_p);
        return rc;
    }
    if (response_size != kUuidSize) {
        trusty_error("keymaster returned wrong uuid size: %d\n", response_size);
        trusty_free(*uuid_p);
        rc = TRUSTY_ERR_GENERIC;
    }
    return rc;
}
