// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "trunks/tpm_pinweaver.h"

#include <endian.h>

#include <algorithm>

#include <base/logging.h>

#include <trunks/cr50_headers/pinweaver_types.h>

namespace trunks {
namespace {

void Serialize(const void* value, size_t length, std::string* buffer) {
  const char* value_bytes = reinterpret_cast<const char*>(value);
  buffer->append(value_bytes, length);
}

void Serialize_pw_request_header_t(uint8_t message_type, uint16_t data_length,
                                   std::string* buffer) {
  struct pw_request_header_t header = {PW_PROTOCOL_VERSION, {message_type},
                                       htole16(data_length)};
  Serialize(&header, sizeof(header), buffer);
}

TPM_RC Parse_unimported_leaf_data_t(
    std::string::const_iterator begin, std::string::const_iterator end,
    std::string* cred_metadata, std::string* mac) {
  auto size = end - begin;
  if (size < sizeof(unimported_leaf_data_t))
    return SAPI_RC_BAD_SIZE;

  const struct unimported_leaf_data_t* unimported_leaf_data =
      reinterpret_cast<const struct unimported_leaf_data_t*>(&*begin);
  if (size != sizeof(unimported_leaf_data_t) +
      unimported_leaf_data->head.pub_len + unimported_leaf_data->head.sec_len) {
    return SAPI_RC_BAD_SIZE;
  }

  if (cred_metadata)
    cred_metadata->assign(begin, end);
  if (mac) {
    mac->assign(
        unimported_leaf_data->hmac, unimported_leaf_data->hmac +
            sizeof(unimported_leaf_data->hmac));
  }
  return TPM_RC_SUCCESS;
}

TPM_RC Validate_cred_metadata(const std::string& cred_metadata) {
  return Parse_unimported_leaf_data_t(cred_metadata.begin(),
                                      cred_metadata.end(), nullptr, nullptr);
}

}  // namespace

TPM_RC Serialize_pw_ping_t(std::string* buffer) {
  buffer->reserve(buffer->size() + sizeof(pw_request_header_t));

  Serialize_pw_request_header_t(PW_MT_INVALID, 0, buffer);
  return TPM_RC_SUCCESS;
}

TPM_RC Serialize_pw_reset_tree_t(uint8_t bits_per_level, uint8_t height,
                                 std::string* buffer) {
  struct pw_request_reset_tree_t data = {{bits_per_level}, {height}};
  buffer->reserve(buffer->size() + sizeof(pw_request_header_t) + sizeof(data));

  Serialize_pw_request_header_t(PW_RESET_TREE, sizeof(data), buffer);
  Serialize(&data, sizeof(data), buffer);
  return TPM_RC_SUCCESS;
}

TPM_RC Serialize_pw_insert_leaf_t(
    uint64_t label, const std::string& h_aux,
    const brillo::SecureBlob& le_secret, const brillo::SecureBlob& he_secret,
    const brillo::SecureBlob& reset_secret,
    const std::map<uint32_t, uint32_t>& delay_schedule, std::string* buffer) {
  if (h_aux.length() > PW_MAX_PATH_SIZE || le_secret.size() != PW_SECRET_SIZE ||
      he_secret.size() != PW_SECRET_SIZE ||
      reset_secret.size() != PW_SECRET_SIZE ||
      delay_schedule.size() > PW_SCHED_COUNT) {
    return SAPI_RC_BAD_PARAMETER;
  }

  struct pw_request_insert_leaf_t data = {};
  buffer->reserve(buffer->size() + sizeof(pw_request_header_t) + sizeof(data) +
                  h_aux.size());

  data.label = {htole64(label)};
  size_t x = 0;
  for (const auto& itr : delay_schedule) {
    data.delay_schedule[x].attempt_count = {htole32(itr.first)};
    data.delay_schedule[x].time_diff = {htole32(itr.second)};
    ++x;
  }
  std::copy(le_secret.begin(), le_secret.end(), data.low_entropy_secret);
  std::copy(he_secret.begin(), he_secret.end(), data.high_entropy_secret);
  std::copy(reset_secret.begin(), reset_secret.end(), data.reset_secret);

  Serialize_pw_request_header_t(PW_INSERT_LEAF, sizeof(data) + h_aux.size(),
                                buffer);
  Serialize(&data, sizeof(data), buffer);
  buffer->append(h_aux);
  return TPM_RC_SUCCESS;
}

TPM_RC Serialize_pw_remove_leaf_t(uint64_t label, const std::string& h_aux,
                                  const std::string& mac, std::string* buffer) {
  if (h_aux.length() > PW_MAX_PATH_SIZE || mac.size() != PW_HASH_SIZE) {
    return SAPI_RC_BAD_PARAMETER;
  }

  struct pw_request_remove_leaf_t data = {};
  buffer->reserve(buffer->size() + sizeof(pw_request_header_t) + sizeof(data) +
                  h_aux.size());

  data.leaf_location = {htole64(label)};
  std::copy(mac.begin(), mac.end(), data.leaf_hmac);

  Serialize_pw_request_header_t(PW_REMOVE_LEAF, sizeof(data) + h_aux.size(),
                                buffer);
  Serialize(&data, sizeof(data), buffer);
  buffer->append(h_aux);
  return TPM_RC_SUCCESS;
}

TPM_RC Serialize_pw_try_auth_t(
    const brillo::SecureBlob& le_secret, const std::string& h_aux,
    const std::string& cred_metadata, std::string* buffer) {
  if (le_secret.size() != PW_SECRET_SIZE || h_aux.length() > PW_MAX_PATH_SIZE ||
      Validate_cred_metadata(cred_metadata) != TPM_RC_SUCCESS) {
    return SAPI_RC_BAD_PARAMETER;
  }

  buffer->reserve(buffer->size() + sizeof(pw_request_header_t) +
      sizeof(pw_request_try_auth_t) +
      (cred_metadata.size() - sizeof(unimported_leaf_data_t)) + h_aux.size());

  Serialize_pw_request_header_t(
      PW_TRY_AUTH, le_secret.size() + cred_metadata.size() + h_aux.size(),
      buffer);

  buffer->append(le_secret.to_string());
  buffer->append(cred_metadata);
  buffer->append(h_aux);
  return TPM_RC_SUCCESS;
}

TPM_RC Serialize_pw_reset_auth_t(
    const brillo::SecureBlob& reset_secret, const std::string& h_aux,
    const std::string& cred_metadata, std::string* buffer) {
  if (reset_secret.size() != PW_SECRET_SIZE ||
      h_aux.length() > PW_MAX_PATH_SIZE ||
      Validate_cred_metadata(cred_metadata) != TPM_RC_SUCCESS) {
    return SAPI_RC_BAD_PARAMETER;
  }

  buffer->reserve(buffer->size() + sizeof(pw_request_header_t) +
      sizeof(pw_request_reset_auth_t) +
      (cred_metadata.size() - sizeof(unimported_leaf_data_t)) + h_aux.size());

  Serialize_pw_request_header_t(
      PW_RESET_AUTH, reset_secret.size() + cred_metadata.size() + h_aux.size(),
      buffer);

  buffer->append(reset_secret.to_string());
  buffer->append(cred_metadata);
  buffer->append(h_aux);
  return TPM_RC_SUCCESS;
}

TPM_RC Serialize_pw_get_log_t(
    const std::string& root, std::string* buffer) {
  if (root.size() != PW_HASH_SIZE) {
    return SAPI_RC_BAD_PARAMETER;
  }

  Serialize_pw_request_header_t(PW_GET_LOG,
                                sizeof(struct pw_request_get_log_t), buffer);
  buffer->append(root);
  return TPM_RC_SUCCESS;
}

TPM_RC Serialize_pw_log_replay_t(
    const std::string& log_root, const std::string& h_aux,
    const std::string& cred_metadata, std::string* buffer) {
  if (log_root.size() != PW_HASH_SIZE ||
      h_aux.length() > PW_MAX_PATH_SIZE ||
      Validate_cred_metadata(cred_metadata) != TPM_RC_SUCCESS) {
    return SAPI_RC_BAD_PARAMETER;
  }

  buffer->reserve(buffer->size() + sizeof(pw_request_header_t) +
      sizeof(pw_request_log_replay_t) +
      (cred_metadata.size() - sizeof(unimported_leaf_data_t)) +
      h_aux.size());

  Serialize_pw_request_header_t(PW_LOG_REPLAY, sizeof(pw_request_log_replay_t) -
                                    sizeof(struct unimported_leaf_data_t) +
                                    cred_metadata.size() + h_aux.size(),
                                buffer);
  buffer->append(log_root);
  buffer->append(cred_metadata);
  buffer->append(h_aux);
  return TPM_RC_SUCCESS;
}

TPM_RC Parse_pw_response_header_t(const std::string& buffer,
                                  uint32_t* result_code, std::string* root_hash,
                                  uint16_t* data_length) {
  *result_code = 0;
  if (root_hash)
    root_hash->clear();
  *data_length = 0;

  if (buffer.empty()) {
    return SAPI_RC_INSUFFICIENT_BUFFER;
  }

  uint8_t version = (uint8_t)buffer[0];
  if (version != PW_PROTOCOL_VERSION) {
    LOG(ERROR) << "Pinweaver protocol version mismatch: got "
               << static_cast<uint32_t>(version) << " expected "
               << PW_PROTOCOL_VERSION << ".";
    return SAPI_RC_ABI_MISMATCH;
  }

  if (buffer.size() < sizeof(struct pw_response_header_t)) {
    LOG(ERROR) << "Pinweaver response contained an unexpected number of bytes.";
    return SAPI_RC_INSUFFICIENT_BUFFER;
  }

  const struct pw_response_header_t* header =
      reinterpret_cast<const struct pw_response_header_t*>(buffer.data());
  *result_code = le32toh(header->result_code);
  if (root_hash)
    root_hash->assign(header->root, header->root + sizeof(header->root));
  *data_length = le16toh(header->data_length);

  if (buffer.size() != sizeof(struct pw_response_header_t) + *data_length) {
    LOG(ERROR) << "Pinweaver response contained " << buffer.size()
               << " instead of "
               << sizeof(struct pw_response_header_t) + *data_length
               << "bytes.";
    return SAPI_RC_BAD_SIZE;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC Parse_pw_short_message(const std::string& buffer, uint32_t* result_code,
                              std::string* root_hash) {
  uint16_t data_length;
  TPM_RC rc = Parse_pw_response_header_t(buffer, result_code, root_hash,
                                         &data_length);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  if (data_length != 0) {
    LOG(ERROR) << "Pinweaver error contained an unexpected number of bytes.";
    return SAPI_RC_BAD_SIZE;
  }

  return TPM_RC_SUCCESS;
}

TPM_RC Parse_pw_pong_t(const std::string& buffer) {
  uint32_t result_code;
  TPM_RC rc = Parse_pw_short_message(buffer, &result_code, nullptr);
  if (rc != TPM_RC_SUCCESS)
    return rc;
  if (result_code != PW_ERR_TYPE_INVALID)
    return SAPI_RC_ABI_MISMATCH;
  return TPM_RC_SUCCESS;
}

TPM_RC Parse_pw_insert_leaf_t(
    const std::string& buffer, uint32_t* result_code,
    std::string* root_hash, std::string* cred_metadata, std::string* mac) {
  cred_metadata->clear();
  mac->clear();

  uint16_t response_length;
  TPM_RC rc = Parse_pw_response_header_t(buffer, result_code, root_hash,
                                  &response_length);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  if (*result_code != 0) {
    return response_length == 0 ? TPM_RC_SUCCESS : SAPI_RC_BAD_SIZE;
  }

  return Parse_unimported_leaf_data_t(
      buffer.begin() + sizeof(pw_response_header_t), buffer.end(),
      cred_metadata, mac);
}

TPM_RC Parse_pw_try_auth_t(
    const std::string& buffer, uint32_t* result_code,
    std::string* root_hash, uint32_t* seconds_to_wait,
    brillo::SecureBlob* he_secret, std::string* cred_metadata_out,
    std::string* mac_out) {
  *seconds_to_wait = 0;
  he_secret->clear();
  cred_metadata_out->clear();
  mac_out->clear();

  uint16_t response_length;
  TPM_RC rc = Parse_pw_response_header_t(buffer, result_code, root_hash,
                                         &response_length);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  // For EC_SUCCESS, PW_ERR_RATE_LIMIT_REACHED, and PW_ERR_LOWENT_AUTH_FAILED
  // a full size response is sent. However, only particular fields are valid.
  if (*result_code != 0 && *result_code != PW_ERR_RATE_LIMIT_REACHED &&
      *result_code != PW_ERR_LOWENT_AUTH_FAILED) {
    return response_length == 0 ? TPM_RC_SUCCESS : SAPI_RC_BAD_SIZE;
  }

  if (response_length < sizeof(pw_response_try_auth_t))
    return SAPI_RC_BAD_SIZE;

  auto itr = buffer.begin() + sizeof(pw_response_header_t);
  // This field may not be aligned so it is retrieved in a way that will work
  // regardless of platform.
  *seconds_to_wait = (itr[0] << 24) | (itr[1] << 16) | (itr[2] << 8) | itr[3];
  itr += 4;

  // he_secret is only valid for EC_SUCCESS.
  if (*result_code == 0) {
    he_secret->assign(itr, itr + PW_SECRET_SIZE);
  }
  itr += PW_SECRET_SIZE;

  // For PW_ERR_RATE_LIMIT_REACHED the only valid result field is
  // seconds_to_wait.
  if (*result_code == PW_ERR_RATE_LIMIT_REACHED)
    return TPM_RC_SUCCESS;

  return Parse_unimported_leaf_data_t(itr, buffer.end(), cred_metadata_out,
                                      mac_out);
}

TPM_RC Parse_pw_reset_auth_t(
    const std::string& buffer, uint32_t* result_code,
    std::string* root_hash, brillo::SecureBlob* he_secret,
    std::string* cred_metadata_out, std::string* mac_out) {
  he_secret->clear();
  cred_metadata_out->clear();
  mac_out->clear();

  uint16_t response_length;
  TPM_RC rc = Parse_pw_response_header_t(buffer, result_code, root_hash,
                                         &response_length);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  if (*result_code != 0) {
    return response_length == 0 ? TPM_RC_SUCCESS : SAPI_RC_BAD_SIZE;
  }

  if (response_length < sizeof(pw_response_reset_auth_t)) {
    LOG(ERROR) << "Pinweaver pw_response_reset_auth contained an unexpected "
                  "number of bytes.";
    return SAPI_RC_BAD_SIZE;
  }

  auto itr = buffer.begin() + sizeof(pw_response_header_t);
  he_secret->assign(itr, itr + PW_SECRET_SIZE);
  itr += PW_SECRET_SIZE;

  return Parse_unimported_leaf_data_t(itr, buffer.end(), cred_metadata_out,
                                      mac_out);
}

TPM_RC Parse_pw_get_log_t(
    const std::string& buffer, uint32_t* result_code, std::string* root_hash,
    std::vector<trunks::PinWeaverLogEntry>* log) {
  log->clear();

  uint16_t response_length;
  TPM_RC rc = Parse_pw_response_header_t(buffer, result_code, root_hash,
                                         &response_length);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  if (*result_code != 0) {
    return response_length == 0 ? TPM_RC_SUCCESS : SAPI_RC_BAD_SIZE;
  }

  if (response_length % sizeof(struct pw_get_log_entry_t) != 0)
    return SAPI_RC_BAD_SIZE;

  log->resize(response_length / sizeof(struct pw_get_log_entry_t));
  TPM_RC ret = TPM_RC_SUCCESS;
  size_t x = 0;
  for (auto itr = buffer.begin() + sizeof(struct pw_response_header_t);
      itr < buffer.end(); itr += sizeof(struct pw_get_log_entry_t)) {
    const struct pw_get_log_entry_t* entry =
        reinterpret_cast<const struct pw_get_log_entry_t*>(&*itr);
    trunks::PinWeaverLogEntry* proto_entry = &(*log)[x];
    proto_entry->set_label(entry->label.v);
    proto_entry->set_root(entry->root, PW_HASH_SIZE);
    switch (entry->type.v) {
      case PW_INSERT_LEAF:
        proto_entry->mutable_insert_leaf()->set_hmac(entry->leaf_hmac,
                                                     PW_HASH_SIZE);
        break;
      case PW_REMOVE_LEAF:
        proto_entry->mutable_remove_leaf();
        break;
      case PW_TRY_AUTH: {
        auto* ptr = proto_entry->mutable_auth();
        ptr->mutable_timestamp()->set_boot_count(entry->timestamp.boot_count);
        ptr->mutable_timestamp()->set_timer_value(entry->timestamp.timer_value);
        ptr->set_return_code(entry->return_code);
      } break;
      case PW_RESET_TREE:
        proto_entry->mutable_reset_tree();
        break;
      default:
        ret = SAPI_RC_BAD_SEQUENCE;
    }
    ++x;
  }
  return ret;
}

TPM_RC Parse_pw_log_replay_t(
    const std::string& buffer, uint32_t* result_code,
    std::string* root_hash, std::string* cred_metadata_out,
    std::string* mac_out) {
  cred_metadata_out->clear();
  mac_out->clear();

  uint16_t response_length;
  TPM_RC rc = Parse_pw_response_header_t(buffer, result_code, root_hash,
                                         &response_length);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  if (*result_code != 0) {
    return response_length == 0 ? TPM_RC_SUCCESS : SAPI_RC_BAD_SIZE;
  }

  if (response_length < sizeof(struct pw_response_reset_auth_t))
    return SAPI_RC_BAD_SIZE;

  auto itr = buffer.begin() + sizeof(struct pw_response_header_t);

  return Parse_unimported_leaf_data_t(itr, buffer.end(), cred_metadata_out,
                                      mac_out);
}

}  // namespace trunks
