/*
 * 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_serializable.h>

uint8_t* append_to_buf(uint8_t* buf, const void* data, size_t data_len) {
    if (data && data_len) {
        trusty_memcpy(buf, data, data_len);
    }
    return buf + data_len;
}

uint8_t* append_uint32_to_buf(uint8_t* buf, uint32_t val) {
    return append_to_buf(buf, &val, sizeof(val));
}

uint8_t* append_sized_buf_to_buf(uint8_t* buf,
                                 const uint8_t* data,
                                 uint32_t data_len) {
    buf = append_uint32_to_buf(buf, data_len);
    return append_to_buf(buf, data, data_len);
}

int km_boot_params_serialize(const struct km_boot_params* params,
                             uint8_t** out,
                             uint32_t* out_size) {
    uint8_t* tmp;

    if (!out || !params || !out_size) {
        return TRUSTY_ERR_INVALID_ARGS;
    }
    *out_size = (sizeof(params->os_version) + sizeof(params->os_patchlevel) +
                 sizeof(params->device_locked) +
                 sizeof(params->verified_boot_state) +
                 sizeof(params->verified_boot_key_hash_size) +
                 sizeof(params->verified_boot_hash_size) +
                 params->verified_boot_key_hash_size +
                 params->verified_boot_hash_size);
    *out = trusty_calloc(*out_size, 1);
    if (!*out) {
        return TRUSTY_ERR_NO_MEMORY;
    }

    tmp = append_uint32_to_buf(*out, params->os_version);
    tmp = append_uint32_to_buf(tmp, params->os_patchlevel);
    tmp = append_uint32_to_buf(tmp, params->device_locked);
    tmp = append_uint32_to_buf(tmp, params->verified_boot_state);
    tmp = append_sized_buf_to_buf(tmp, params->verified_boot_key_hash,
                                  params->verified_boot_key_hash_size);
    tmp = append_sized_buf_to_buf(tmp, params->verified_boot_hash,
                                  params->verified_boot_hash_size);

    return TRUSTY_ERR_NONE;
}

int km_attestation_data_serialize(const struct km_attestation_data* data,
                                  uint8_t** out,
                                  uint32_t* out_size) {
    uint8_t* tmp;

    if (!out || !data || !out_size) {
        return TRUSTY_ERR_INVALID_ARGS;
    }
    *out_size = (sizeof(data->algorithm) + sizeof(data->data_size) +
                 data->data_size);
    *out = trusty_calloc(*out_size, 1);
    if (!*out) {
        return TRUSTY_ERR_NO_MEMORY;
    }

    tmp = append_uint32_to_buf(*out, data->algorithm);
    tmp = append_sized_buf_to_buf(tmp, data->data, data->data_size);

    return TRUSTY_ERR_NONE;
}

int km_raw_buffer_serialize(const struct km_raw_buffer* buf,
                            uint8_t** out,
                            uint32_t* out_size) {
    if (!out || !buf || !out_size) {
        return TRUSTY_ERR_INVALID_ARGS;
    }
    *out_size = sizeof(buf->data_size) + buf->data_size;
    *out = trusty_calloc(*out_size, 1);
    if (!*out) {
        return TRUSTY_ERR_NO_MEMORY;
    }
    append_sized_buf_to_buf(*out, buf->data, buf->data_size);

    return TRUSTY_ERR_NONE;
}
