// Copyright 2021 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/csme/pinweaver_core_client.h"

#include <algorithm>
#include <string>

#include <base/check.h>
#include <base/logging.h>

#include "trunks/csme/pinweaver_client_utils.h"
#include "trunks/csme/pinweaver_csme_types.h"

namespace trunks {
namespace csme {

PinWeaverCoreClient::PinWeaverCoreClient(MeiClientFactory* mei_client_factory)
    : mei_client_factory_(mei_client_factory) {
  CHECK(mei_client_factory_);
}

bool PinWeaverCoreClient::ExtendPcr(uint32_t pcr_index,
                                    uint32_t hash_alg,
                                    const std::string& extension) {
  pw_pcr_extend_request req;
  BuildFixedSizedRequest(PW_PCR_EXTEND, seq_++, &req);
  req.pcr_index = pcr_index;
  req.hash_alg = hash_alg;
  // Only fixed-sized extension is supported.
  if (extension.size() != sizeof(req.buffer)) {
    LOG(ERROR) << __func__
               << ": Mismatched extension size: " << extension.size()
               << "; expecting " << sizeof(req.buffer) << ".";
    return false;
  }
  std::copy(extension.begin(), extension.end(), req.buffer);
  const std::string request = SerializeToString(req);
  std::string response;
  if (!GetMeiClient()->Send(request, /*wait_for_response_ready=*/true) ||
      !GetMeiClient()->Receive(&response)) {
    LOG(ERROR) << __func__ << ": Failed to send request.";
    return false;
  }

  if (!UnpackFromResponse(req.header, response)) {
    LOG(ERROR) << __func__ << ": failed to unpack response.";
    return false;
  }
  return true;
}
bool PinWeaverCoreClient::ReadPcr(uint32_t pcr_index_in,
                                  uint32_t hash_alg_in,
                                  uint32_t* pcr_index_out,
                                  uint32_t* hash_alg_out,
                                  std::string* pcr_value) {
  pw_pcr_read_request req;
  BuildFixedSizedRequest(PW_PCR_READ, seq_++, &req);
  req.pcr_index = pcr_index_in;
  req.hash_alg = hash_alg_in;
  const std::string request = SerializeToString(req);
  std::string response;
  if (!GetMeiClient()->Send(request, /*wait_for_response_ready=*/true) ||
      !GetMeiClient()->Receive(&response)) {
    LOG(ERROR) << __func__ << ": Failed to send request.";
    return false;
  }

  if (!UnpackFromResponse(req.header, response, pcr_index_out, hash_alg_out,
                          pcr_value)) {
    LOG(ERROR) << __func__ << ": failed to unpack response.";
    return false;
  }
  return true;
}

bool PinWeaverCoreClient::PinWeaverCommand(const std::string& pinweaver_request,
                                           std::string* pinweaver_response) {
  union {
    pw_core_pinweaver_command_request req;
    char req_serialized[sizeof(pw_core_pinweaver_command_request)];
  };
  req.header.pw_heci_cmd = pw_core_pinweaver_cmd_t::PW_CORE_PINWEAVER_CMD;
  req.header.pw_heci_seq = seq_++;
  req.header.total_length = pinweaver_request.size();
  std::copy(pinweaver_request.begin(), pinweaver_request.end(),
            req.pinweaver_request_blob);
  const std::string request(std::begin(req_serialized),
                            std::begin(req_serialized) +
                                sizeof(pw_heci_header_req) +
                                pinweaver_request.size());
  std::string response;
  if (!GetMeiClient()->Send(request, /*wait_for_response_ready=*/true) ||
      !GetMeiClient()->Receive(&response)) {
    LOG(ERROR) << __func__ << ": Failed to send request.";
    return false;
  }
  if (!UnpackStringFromResponse(req.header, response, pinweaver_response)) {
    LOG(ERROR) << __func__ << ": Failed to unpack response.";
  }
  return true;
}

MeiClient* PinWeaverCoreClient::GetMeiClient() {
  if (!mei_client_) {
    mei_client_ = mei_client_factory_->CreateMeiClientForPinWeaverCore();
  }
  return mei_client_.get();
}

bool PinWeaverCoreClient::UnpackStringFromResponse(
    const pw_heci_header_req& req_header,
    const std::string& response,
    std::string* payload) {
  struct __attribute__((packed)) PackedResponse {
    pw_heci_header_res header;
    char buffer[PW_MAX_HECI_PAYLOAD_SIZE];
  };
  if (response.size() > sizeof(PackedResponse)) {
    LOG(ERROR) << __func__
               << ": Unexpectedly large size of response: " << response.size()
               << "; expecting <" << sizeof(PackedResponse) << ".";
    return false;
  }
  const PackedResponse* resp =
      reinterpret_cast<const PackedResponse*>(response.data());

  // Perform rationality check.
  if (req_header.pw_heci_seq != resp->header.pw_heci_seq) {
    LOG(ERROR) << __func__ << ": Mismatched sequence: expected "
               << req_header.pw_heci_seq << " got " << resp->header.pw_heci_seq;
    return false;
  }
  if (req_header.pw_heci_cmd != resp->header.pw_heci_cmd) {
    LOG(ERROR) << __func__ << ": Mismatched command: expected "
               << req_header.pw_heci_cmd << " got " << resp->header.pw_heci_cmd;
    return false;
  }
  if (resp->header.pw_heci_rc) {
    LOG(ERROR) << __func__
               << ": CSME returns error: " << int(resp->header.pw_heci_rc);
    return false;
  }
  if (resp->header.total_length > PW_MAX_HECI_PAYLOAD_SIZE) {
    LOG(ERROR) << __func__ << ": Unexpectedly large payload length: "
               << resp->header.total_length;
    return false;
  }
  payload->assign(std::begin(resp->buffer),
                  std::begin(resp->buffer) + resp->header.total_length);
  return true;
}

}  // namespace csme
}  // namespace trunks
