// Copyright 2020 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_generated.h"

#include <base/bind.h>
#include <base/callback.h>
#include <base/logging.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <crypto/secure_hash.h>

#include "trunks/authorization_delegate.h"
#include "trunks/command_transceiver.h"
#include "trunks/error_codes.h"

namespace trunks {
// static
TPM_RC Tpm::SerializeCommand_PolicyFidoSigned(
    const TPMI_DH_OBJECT& auth_object,
    const std::string& auth_object_name,
    const TPMI_SH_POLICY& policy_session,
    const std::string& policy_session_name,
    const std::string& auth_data,
    const std::vector<FIDO_DATA_RANGE>& auth_data_descr,
    const TPMT_SIGNATURE& auth,
    std::string* serialized_command,
    AuthorizationDelegate* authorization_delegate) {
  VLOG(3) << __func__;
  TPM_RC rc = TPM_RC_SUCCESS;
  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
  UINT32 command_size = 10;  // Header size.
  std::string handle_section_bytes;
  std::string parameter_section_bytes;
  TPM_CC command_code = TPM_CCE_PolicyFidoSigned;
  bool is_command_parameter_encryption_possible = true;
  bool is_response_parameter_encryption_possible = true;

  // Serialize header
  std::string command_code_bytes;

  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  // Serialize handles
  std::string auth_object_bytes;

  rc = Serialize_TPMI_DH_OBJECT(auth_object, &auth_object_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  std::string policy_session_bytes;

  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  // Serialize Command parameters
  std::string auth_data_size_bytes;

  rc = Serialize_UINT16(auth_data.size(), &auth_data_size_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  std::string auth_data_bytes;

  for (const char& ch : auth_data) {
    rc = Serialize_BYTE(ch, &auth_data_bytes);
    if (rc != TPM_RC_SUCCESS)
      return rc;
  }

  // auth_data_descr is an array of tuples of (UINT16, UINT16).
  // auth_data_descr_count is the number of tuples in this array.

  std::string auth_data_descr_count_bytes;
  UINT16 auth_data_descr_count = auth_data_descr.size();

  rc = Serialize_UINT16(auth_data_descr_count, &auth_data_descr_count_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  std::string auth_data_descr_bytes;

  for (const auto& descr : auth_data_descr) {
    rc = Serialize_UINT16(descr.offset, &auth_data_descr_bytes);
    if (rc != TPM_RC_SUCCESS)
      return rc;

    rc = Serialize_UINT16(descr.size, &auth_data_descr_bytes);
    if (rc != TPM_RC_SUCCESS)
      return rc;
  }

  std::string auth_bytes;

  rc = Serialize_TPMT_SIGNATURE(auth, &auth_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  if (authorization_delegate) {
    // Encrypt just the auth_data, not the auth_data_size.
    if (!authorization_delegate->EncryptCommandParameter(&auth_data_bytes))
      return TRUNKS_RC_ENCRYPTION_FAILED;
  }

  // Get a hash and construct a command by concatenation parts
  std::unique_ptr<crypto::SecureHash> hash(
      crypto::SecureHash::Create(crypto::SecureHash::SHA256));

  // Construct the handle section
  hash->Update(command_code_bytes.data(), command_code_bytes.size());
  hash->Update(auth_object_name.data(), auth_object_name.size());
  handle_section_bytes += auth_object_bytes;
  command_size += auth_object_bytes.size();

  hash->Update(policy_session_name.data(), policy_session_name.size());
  handle_section_bytes += policy_session_bytes;
  command_size += policy_session_bytes.size();

  // Construct the parameter section
  // Hash on authenticator data
  hash->Update(auth_data_size_bytes.data(), auth_data_size_bytes.size());
  parameter_section_bytes += auth_data_size_bytes;
  command_size += auth_data_size_bytes.size();

  hash->Update(auth_data_bytes.data(), auth_data_bytes.size());
  parameter_section_bytes += auth_data_bytes;
  command_size += auth_data_bytes.size();

  // Hash on authenticator data descriptor
  hash->Update(auth_data_descr_count_bytes.data(),
               auth_data_descr_count_bytes.size());
  parameter_section_bytes += auth_data_descr_count_bytes;
  command_size += auth_data_descr_count_bytes.size();

  hash->Update(auth_data_descr_bytes.data(), auth_data_descr_bytes.size());
  parameter_section_bytes += auth_data_descr_bytes;
  command_size += auth_data_descr_bytes.size();

  // Hash on auth
  hash->Update(auth_bytes.data(), auth_bytes.size());
  parameter_section_bytes += auth_bytes;
  command_size += auth_bytes.size();

  std::string command_hash(32, 0);
  hash->Finish(base::data(command_hash), command_hash.size());

  // Construct the authorization section
  std::string authorization_section_bytes;
  std::string authorization_size_bytes;

  if (authorization_delegate) {
    if (!authorization_delegate->GetCommandAuthorization(
            command_hash, is_command_parameter_encryption_possible,
            is_response_parameter_encryption_possible,
            &authorization_section_bytes))
      return TRUNKS_RC_AUTHORIZATION_FAILED;

    if (!authorization_section_bytes.empty()) {
      tag = TPM_ST_SESSIONS;

      rc = Serialize_UINT32(authorization_section_bytes.size(),
                            &authorization_size_bytes);
      if (rc != TPM_RC_SUCCESS)
        return rc;

      command_size +=
          authorization_size_bytes.size() + authorization_section_bytes.size();
    }
  }

  // Construct the header section
  std::string tag_bytes;

  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  std::string command_size_bytes;

  rc = Serialize_UINT32(command_size, &command_size_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
                        handle_section_bytes + authorization_size_bytes +
                        authorization_section_bytes + parameter_section_bytes;
  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
  VLOG(2) << "Command: "
          << base::HexEncode(serialized_command->data(),
                             serialized_command->size());
  return TPM_RC_SUCCESS;
}

// static
TPM_RC Tpm::ParseResponse_PolicyFidoSigned(
    const std::string& response,
    AuthorizationDelegate* authorization_delegate) {
  VLOG(3) << __func__;
  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
  TPM_RC rc = TPM_RC_SUCCESS;
  std::string buffer(response);
  TPM_ST tag;
  std::string tag_bytes;

  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  UINT32 response_size;
  std::string response_size_bytes;

  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  TPM_RC response_code;
  std::string response_code_bytes;

  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;
  if (response_size != response.size())
    return TPM_RC_SIZE;
  if (response_code != TPM_RC_SUCCESS)
    return response_code;

  TPM_CC command_code = TPM_CCE_PolicyFidoSigned;
  std::string command_code_bytes;

  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
  if (rc != TPM_RC_SUCCESS)
    return rc;

  std::string authorization_section_bytes;

  if (tag == TPM_ST_SESSIONS) {
    UINT32 parameter_section_size = buffer.size();

    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
    if (rc != TPM_RC_SUCCESS)
      return rc;
    if (parameter_section_size > buffer.size())
      return TPM_RC_INSUFFICIENT;

    authorization_section_bytes = buffer.substr(parameter_section_size);
    // Keep the parameter section in |buffer|.
    buffer.erase(parameter_section_size);
  }
  std::unique_ptr<crypto::SecureHash> hash(
      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
  hash->Update(response_code_bytes.data(), response_code_bytes.size());
  hash->Update(command_code_bytes.data(), command_code_bytes.size());
  hash->Update(buffer.data(), buffer.size());
  std::string response_hash(32, 0);
  hash->Finish(base::data(response_hash), response_hash.size());
  if (tag == TPM_ST_SESSIONS) {
    CHECK(authorization_delegate) << "Authorization delegate missing!";
    if (!authorization_delegate->CheckResponseAuthorization(
            response_hash, authorization_section_bytes))
      return TRUNKS_RC_AUTHORIZATION_FAILED;
  }

  return TPM_RC_SUCCESS;
}

void PolicyFidoSignedErrorCallback(
    const Tpm::PolicyFidoSignedResponse& callback, TPM_RC response_code) {
  VLOG(1) << __func__;
  callback.Run(response_code);
}

void PolicyFidoSignedResponseParser(
    const Tpm::PolicyFidoSignedResponse& callback,
    AuthorizationDelegate* authorization_delegate,
    const std::string& response) {
  VLOG(1) << __func__;
  base::Callback<void(TPM_RC)> error_reporter =
      base::Bind(PolicyFidoSignedErrorCallback, callback);
  TPM_RC rc =
      Tpm::ParseResponse_PolicyFidoSigned(response, authorization_delegate);
  if (rc != TPM_RC_SUCCESS) {
    error_reporter.Run(rc);
    return;
  }
  callback.Run(rc);
}

void Tpm::PolicyFidoSigned(const TPMI_DH_OBJECT& auth_object,
                           const std::string& auth_object_name,
                           const TPMI_SH_POLICY& policy_session,
                           const std::string& policy_session_name,
                           const std::string& auth_data,
                           const std::vector<FIDO_DATA_RANGE>& auth_data_descr,
                           const TPMT_SIGNATURE& auth,
                           AuthorizationDelegate* authorization_delegate,
                           const PolicyFidoSignedResponse& callback) {
  VLOG(1) << __func__;
  base::Callback<void(TPM_RC)> error_reporter =
      base::Bind(PolicyFidoSignedErrorCallback, callback);
  base::Callback<void(const std::string&)> parser = base::Bind(
      PolicyFidoSignedResponseParser, callback, authorization_delegate);
  std::string command;
  TPM_RC rc = SerializeCommand_PolicyFidoSigned(
      auth_object, auth_object_name, policy_session, policy_session_name,
      auth_data, auth_data_descr, auth, &command, authorization_delegate);

  if (rc != TPM_RC_SUCCESS) {
    error_reporter.Run(rc);
    return;
  }
  transceiver_->SendCommand(command, parser);
}

TPM_RC Tpm::PolicyFidoSignedSync(
    const TPMI_DH_OBJECT& auth_object,
    const std::string& auth_object_name,
    const TPMI_SH_POLICY& policy_session,
    const std::string& policy_session_name,
    const std::string& auth_data,
    const std::vector<FIDO_DATA_RANGE>& auth_data_descr,
    const TPMT_SIGNATURE& auth,
    AuthorizationDelegate* authorization_delegate) {
  VLOG(1) << __func__;
  std::string command;
  TPM_RC rc = SerializeCommand_PolicyFidoSigned(
      auth_object, auth_object_name, policy_session, policy_session_name,
      auth_data, auth_data_descr, auth, &command, authorization_delegate);

  if (rc != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error from SerializeCommand_PolicyFidoSigned: "
               << GetErrorString(rc);
    return rc;
  }

  std::string response = transceiver_->SendCommandAndWait(command);

  rc = ParseResponse_PolicyFidoSigned(response, authorization_delegate);
  return rc;
}

}  // namespace trunks
