// Copyright 2015 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/policy_session_impl.h"

#include <iterator>
#include <map>
#include <string>
#include <vector>

#include <base/check.h>
#include <base/logging.h>
#include <base/macros.h>
#include <crypto/sha2.h>
#include <openssl/rand.h>

#include "trunks/error_codes.h"
#include "trunks/tpm_generated.h"

namespace {

// Returns a serialized representation of the unmodified handle. This is useful
// for predefined handle values, like TPM_RH_OWNER. For details on what types of
// handles use this name formula see Table 3 in the TPM 2.0 Library Spec Part 1
// (Section 16 - Names).
std::string NameFromHandle(trunks::TPM_HANDLE handle) {
  std::string name;
  trunks::Serialize_TPM_HANDLE(handle, &name);
  return name;
}

}  // namespace

namespace trunks {

PolicySessionImpl::PolicySessionImpl(const TrunksFactory& factory)
    : factory_(factory), session_type_(TPM_SE_POLICY) {
  session_manager_ = factory_.GetSessionManager();
}

PolicySessionImpl::PolicySessionImpl(const TrunksFactory& factory,
                                     TPM_SE session_type)
    : factory_(factory), session_type_(session_type) {
  session_manager_ = factory_.GetSessionManager();
}

PolicySessionImpl::~PolicySessionImpl() {
  session_manager_->CloseSession();
}

AuthorizationDelegate* PolicySessionImpl::GetDelegate() {
  if (session_manager_->GetSessionHandle() == kUninitializedHandle) {
    return nullptr;
  }
  return &hmac_delegate_;
}

TPM_RC PolicySessionImpl::StartBoundSession(
    TPMI_DH_ENTITY bind_entity,
    const std::string& bind_authorization_value,
    bool salted,
    bool enable_encryption) {
  hmac_delegate_.set_use_entity_authorization_for_encryption_only(true);
  if (session_type_ != TPM_SE_POLICY && session_type_ != TPM_SE_TRIAL) {
    LOG(ERROR) << "Cannot start a session of that type.";
    return SAPI_RC_INVALID_SESSIONS;
  }
  return session_manager_->StartSession(session_type_, bind_entity,
                                        bind_authorization_value, salted,
                                        enable_encryption, &hmac_delegate_);
}

TPM_RC PolicySessionImpl::StartUnboundSession(bool salted,
                                              bool enable_encryption) {
  // Just like a HmacAuthorizationSession, an unbound policy session is just
  // a session bound to TPM_RH_NULL.
  return StartBoundSession(TPM_RH_NULL, "", salted, enable_encryption);
}

TPM_RC PolicySessionImpl::GetDigest(std::string* digest) {
  CHECK(digest);
  TPM2B_DIGEST policy_digest;
  TPM_RC result = factory_.GetTpm()->PolicyGetDigestSync(
      session_manager_->GetSessionHandle(),
      "",  // No name is needed for this command, as it does no authorization.
      &policy_digest, nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
    return result;
  }
  *digest = StringFrom_TPM2B_DIGEST(policy_digest);
  return TPM_RC_SUCCESS;
}

TPM_RC PolicySessionImpl::PolicyOR(const std::vector<std::string>& digests) {
  TPML_DIGEST tpm_digests;
  if (digests.size() >= std::size(tpm_digests.digests)) {
    LOG(ERROR) << "TPM2.0 Spec only allows for up to 8 digests.";
    return SAPI_RC_BAD_PARAMETER;
  }
  tpm_digests.count = digests.size();
  for (size_t i = 0; i < digests.size(); i++) {
    tpm_digests.digests[i] = Make_TPM2B_DIGEST(digests[i]);
  }
  TPM_RC result = factory_.GetTpm()->PolicyORSync(
      session_manager_->GetSessionHandle(),
      "",  // No policy name is needed as we do no authorization checks.
      tpm_digests, nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicyOR: " << GetErrorString(result);
    return result;
  }

  return TPM_RC_SUCCESS;
}

TPM_RC PolicySessionImpl::PolicyPCR(
    const std::map<uint32_t, std::string>& pcr_map) {
  TPML_PCR_SELECTION pcr_select;
  memset(&pcr_select, 0, sizeof(TPML_PCR_SELECTION));
  // This process of selecting pcrs is highlighted in TPM 2.0 Library Spec
  // Part 2 (Section 10.5 - PCR structures).
  pcr_select.count = 1;
  pcr_select.pcr_selections[0].hash = TPM_ALG_SHA256;
  pcr_select.pcr_selections[0].sizeof_select = PCR_SELECT_MIN;
  TPM2B_DIGEST pcr_digest;
  std::string concatenated_pcr_values;

  bool map_contains_empty_value = false;
  for (const auto& map_pair : pcr_map) {
    uint32_t pcr_index = map_pair.first;
    const std::string& pcr_value = map_pair.second;
    if (pcr_value.empty()) {
      map_contains_empty_value = true;
    }
    uint8_t pcr_select_index = pcr_index / 8;
    uint8_t pcr_select_byte = 1 << (pcr_index % 8);
    if (pcr_select_index >= PCR_SELECT_MIN) {
      LOG(ERROR) << "Out of bounds pcr_index provided: " << pcr_index;
      return SAPI_RC_BAD_PARAMETER;
    }
    pcr_select.pcr_selections[0].pcr_select[pcr_select_index] |=
        pcr_select_byte;
    concatenated_pcr_values += pcr_value;
  }

  if (concatenated_pcr_values.empty()) {
    if (session_type_ == TPM_SE_TRIAL) {
      LOG(ERROR) << "Trial sessions have to define a PCR value.";
      return SAPI_RC_BAD_PARAMETER;
    }
    pcr_digest = Make_TPM2B_DIGEST("");
  } else {
    if (map_contains_empty_value) {
      LOG(ERROR) << "PCR map must not have both empty and non-empty values.";
      return SAPI_RC_BAD_PARAMETER;
    }
    pcr_digest =
        Make_TPM2B_DIGEST(crypto::SHA256HashString(concatenated_pcr_values));
  }

  TPM_RC result = factory_.GetTpm()->PolicyPCRSync(
      session_manager_->GetSessionHandle(),
      "",  // No policy name is needed as we do no authorization checks.
      pcr_digest, pcr_select, nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicyPCR: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC PolicySessionImpl::PolicyCommandCode(TPM_CC command_code) {
  TPM_RC result = factory_.GetTpm()->PolicyCommandCodeSync(
      session_manager_->GetSessionHandle(),
      "",  // No policy name is needed as we do no authorization checks.
      command_code, nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicyCommandCode: "
               << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC PolicySessionImpl::PolicySecret(TPMI_DH_ENTITY auth_entity,
                                       const std::string& auth_entity_name,
                                       const std::string& nonce,
                                       const std::string& cp_hash,
                                       const std::string& policy_ref,
                                       int32_t expiration,
                                       AuthorizationDelegate* delegate) {
  TPM2B_TIMEOUT timeout;
  TPMT_TK_AUTH policy_ticket;
  TPM_HANDLE policy_session_handle = session_manager_->GetSessionHandle();
  std::string policy_session_name;
  trunks::Serialize_TPM_HANDLE(policy_session_handle, &policy_session_name);

  TPM_RC result = factory_.GetTpm()->PolicySecretSync(
      auth_entity, auth_entity_name, policy_session_handle, policy_session_name,
      Make_TPM2B_DIGEST(nonce), Make_TPM2B_DIGEST(cp_hash),
      Make_TPM2B_DIGEST(policy_ref), expiration, &timeout, &policy_ticket,
      delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicySecret: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC PolicySessionImpl::PolicySigned(TPMI_DH_ENTITY auth_entity,
                                       const std::string& auth_entity_name,
                                       const std::string& nonce,
                                       const std::string& cp_hash,
                                       const std::string& policy_ref,
                                       int32_t expiration,
                                       const trunks::TPMT_SIGNATURE& signature,
                                       AuthorizationDelegate* delegate) {
  TPM2B_TIMEOUT timeout;
  TPMT_TK_AUTH policy_ticket;
  TPM_HANDLE policy_session_handle = session_manager_->GetSessionHandle();
  std::string policy_session_name;
  trunks::Serialize_TPM_HANDLE(policy_session_handle, &policy_session_name);

  TPM_RC result = factory_.GetTpm()->PolicySignedSync(
      auth_entity, auth_entity_name, policy_session_handle, policy_session_name,
      Make_TPM2B_DIGEST(nonce), Make_TPM2B_DIGEST(cp_hash),
      Make_TPM2B_DIGEST(policy_ref), expiration, signature, &timeout,
      &policy_ticket, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicySigned: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC PolicySessionImpl::PolicyAuthValue() {
  TPM_RC result = factory_.GetTpm()->PolicyAuthValueSync(
      session_manager_->GetSessionHandle(),
      "",  // No policy name is needed as we do no authorization checks.
      nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicyAuthValue: "
               << GetErrorString(result);
    return result;
  }
  hmac_delegate_.set_use_entity_authorization_for_encryption_only(false);
  return TPM_RC_SUCCESS;
}

TPM_RC PolicySessionImpl::PolicyRestart() {
  TPM_RC result = factory_.GetTpm()->PolicyAuthValueSync(
      session_manager_->GetSessionHandle(),
      "",  // No policy name is needed as we do no authorization checks.
      nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicyRestart: " << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

void PolicySessionImpl::SetEntityAuthorizationValue(const std::string& value) {
  hmac_delegate_.set_entity_authorization_value(value);
}

TPM_RC PolicySessionImpl::PolicyFidoSigned(
    TPMI_DH_ENTITY auth_entity,
    const std::string& auth_entity_name,
    const std::string& auth_data,
    const std::vector<FIDO_DATA_RANGE>& auth_data_descr,
    const TPMT_SIGNATURE& signature,
    AuthorizationDelegate* delegate) {
  TPM_HANDLE policy_session_handle = session_manager_->GetSessionHandle();
  std::string policy_session_name;
  Serialize_TPM_HANDLE(policy_session_handle, &policy_session_name);

  TPM_RC result = factory_.GetTpm()->PolicyFidoSignedSync(
      auth_entity, auth_entity_name, policy_session_handle, policy_session_name,
      auth_data, auth_data_descr, signature, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicyFidoSigned: "
               << GetErrorString(result);
    return result;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC PolicySessionImpl::PolicyNV(uint32_t index,
                                   uint32_t offset,
                                   bool using_owner_authorization,
                                   TPM2B_OPERAND operand,
                                   TPM_EO operation,
                                   AuthorizationDelegate* delegate) {
  TPM_RC result;
  std::string nv_name;
  result = factory_.GetTpmUtility()->GetNVSpaceName(index, &nv_name);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": Could not find space at " << index << " "
               << GetErrorString(result);
    return result;
  }
  uint32_t nv_index = NV_INDEX_FIRST + index;
  TPMI_RH_NV_AUTH auth_entity = nv_index;
  std::string auth_entity_name = nv_name;
  if (using_owner_authorization) {
    auth_entity = TPM_RH_OWNER;
    auth_entity_name = NameFromHandle(TPM_RH_OWNER);
  }

  TPM_HANDLE policy_session_handle = session_manager_->GetSessionHandle();
  std::string policy_session_name = NameFromHandle(policy_session_handle);

  result = factory_.GetTpm()->PolicyNVSync(
      auth_entity, auth_entity_name, nv_index, nv_name, policy_session_handle,
      policy_session_name, operand, offset, operation, delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error performing PolicyNV: " << GetErrorString(result);
  }
  return result;
}

}  // namespace trunks
