//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "trunks/policy_session_impl.h"

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

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

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

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) {
  if (digests.size() >= arraysize(TPML_DIGEST::digests)) {
    LOG(ERROR) << "TPM2.0 Spec only allows for up to 8 digests.";
    return SAPI_RC_BAD_PARAMETER;
  }
  TPML_DIGEST tpm_digests;
  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);
}

}  // namespace trunks
