// 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/check.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;

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, "",
                                         /*require_admin_with_policy=*/true,
                                         session_delegate, &sealed_data_str);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error sealing data: " << 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 data: " << 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
