// 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 "libtpmcrypto/tpm2_impl.h"

#include <base/logging.h>
#include <base/threading/platform_thread.h>
#include <brillo/secure_blob.h>
#include <trunks/error_codes.h>

using brillo::Blob;
using brillo::SecureBlob;
using trunks::AuthorizationDelegate;
using trunks::GetErrorString;
using trunks::HmacSession;
using trunks::PolicySession;
using trunks::TPM_RC;
using trunks::TPM_RC_SUCCESS;
using trunks::TPMS_NV_PUBLIC;
using trunks::TrunksFactoryImpl;

namespace tpmcrypto {

using PcrMap = std::map<uint32_t, std::string>;

Tpm2Impl::Tpm2Impl() = default;
Tpm2Impl::~Tpm2Impl() = default;

std::unique_ptr<Tpm> CreateTpmInstance() {
  return std::make_unique<Tpm2Impl>();
}

bool Tpm2Impl::SealToPCR0(const SecureBlob& value, SecureBlob* sealed_value) {
  CHECK(sealed_value);

  std::string policy_digest;
  std::unique_ptr<HmacSession> session;
  return EnsureInitialized() && CreatePcr0PolicyDigest(&policy_digest) &&
         CreateHmacSession(&session) &&
         SealData(session->GetDelegate(), policy_digest, value, sealed_value);
}

bool Tpm2Impl::Unseal(const SecureBlob& sealed_value, SecureBlob* value) {
  CHECK(value);

  std::unique_ptr<PolicySession> policy_session;
  return EnsureInitialized() && CreatePolicySessionForPCR0(&policy_session) &&
         UnsealData(policy_session->GetDelegate(), sealed_value, value);
}

bool Tpm2Impl::EnsureInitialized() {
  if (is_initialized_) {
    return true;
  }

  // Create and initialize trunks factory.
  factory_impl_ = std::make_unique<TrunksFactoryImpl>();
  if (!factory_impl_->Initialize()) {
    LOG(ERROR) << "Failed to initialize trunks factory.";
    factory_impl_.reset();
    return false;
  }

  // Create TPM utility using trunks factory.
  tpm_utility_ = factory_impl_->GetTpmUtility();
  if (!tpm_utility_) {
    return false;
  }

  is_initialized_ = true;
  return true;
}

bool Tpm2Impl::CreatePcr0PolicyDigest(std::string* policy_digest) {
  TPM_RC result = tpm_utility_->GetPolicyDigestForPcrValues(
      PcrMap({{0, ""}}), false /* use_auth_value */, policy_digest);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
    return false;
  }

  return true;
}

bool Tpm2Impl::CreateHmacSession(std::unique_ptr<HmacSession>* hmac_session) {
  std::unique_ptr<HmacSession> session = factory_impl_->GetHmacSession();
  if (tpm_utility_->StartSession(session.get()) != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error starting hmac session.";
    return false;
  }

  hmac_session->swap(session);
  return true;
}

bool Tpm2Impl::CreatePolicySessionForPCR0(
    std::unique_ptr<PolicySession>* policy_session) {
  std::unique_ptr<PolicySession> session = factory_impl_->GetPolicySession();
  TPM_RC result = session->StartUnboundSession(false /* salted */,
                                               false /* enable_encryption */);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
    return false;
  }

  result = session->PolicyPCR(PcrMap({{0, ""}}));
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error restricting policy to pcr 0: "
               << GetErrorString(result);
    return false;
  }

  policy_session->swap(session);
  return true;
}

bool Tpm2Impl::SealData(AuthorizationDelegate* session_delegate,
                        const std::string& policy_digest,
                        const SecureBlob& value,
                        SecureBlob* sealed_value) {
  const std::string data_to_seal(value.begin(), value.end());
  std::string sealed_data_str;
  TPM_RC result = tpm_utility_->SealData(data_to_seal, policy_digest, "",
                                         session_delegate, &sealed_data_str);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error creating sealed object: " << GetErrorString(result);
    return false;
  }

  sealed_value->assign(sealed_data_str.begin(), sealed_data_str.end());
  return true;
}

bool Tpm2Impl::UnsealData(AuthorizationDelegate* policy_delegate,
                          const SecureBlob& sealed_value,
                          SecureBlob* value) {
  const std::string sealed_data(sealed_value.begin(), sealed_value.end());
  std::string unsealed_data;
  TPM_RC result =
      tpm_utility_->UnsealData(sealed_data, policy_delegate, &unsealed_data);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error unsealing object: " << GetErrorString(result);
    return false;
  }

  value->assign(unsealed_data.begin(), unsealed_data.end());
  return true;
}

bool Tpm2Impl::GetNVAttributes(uint32_t index, uint32_t* attributes) {
  CHECK(attributes);
  if (!EnsureInitialized()) {
    return false;
  }
  TPMS_NV_PUBLIC space_info;
  TPM_RC result = tpm_utility_->GetNVSpacePublicArea(index, &space_info);
  if (result != trunks::TPM_RC_SUCCESS) {
    PLOG(ERROR) << "Failed to get the NVRAM space attributes";
    return false;
  }
  *attributes = space_info.attributes;
  return true;
}

bool Tpm2Impl::NVReadNoAuth(uint32_t index,
                            uint32_t offset,
                            size_t size,
                            std::string* data) {
  CHECK(data);
  if (!EnsureInitialized()) {
    return false;
  }
  const std::string kWellKnownPassword = "";
  auto pw_auth = factory_impl_->GetPasswordAuthorization(kWellKnownPassword);

  trunks::TPM_RC result = tpm_utility_->ReadNVSpace(
      index, offset, size, false /* using_owner_authorization */, data,
      pw_auth.get());
  if (result != trunks::TPM_RC_SUCCESS) {
    PLOG(ERROR) << "Failed to read TPM space index: " << index;
    return false;
  }
  return true;
}

}  // namespace tpmcrypto
