// 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 "tpm_manager/server/tpm2_nvram_impl.h"

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

#include <base/logging.h>
#include <base/stl_util.h>
#include <trunks/authorization_delegate.h>
#include <trunks/error_codes.h>
#include <trunks/policy_session.h>
#include <trunks/scoped_global_session.h>
#include <trunks/tpm_constants.h>
#include <trunks/tpm_utility.h>
#include <trunks/tpm_utility_impl.h>

namespace tpm_manager {

using trunks::GetErrorString;
using trunks::TPM_RC;
using trunks::TPM_RC_SUCCESS;

namespace {

void MapAttributesFromTpm(trunks::TPMA_NV tpm_flags,
                          std::vector<NvramSpaceAttribute>* attributes) {
  if (tpm_flags & trunks::TPMA_NV_WRITEDEFINE)
    attributes->push_back(NVRAM_PERSISTENT_WRITE_LOCK);
  if (tpm_flags & trunks::TPMA_NV_WRITE_STCLEAR)
    attributes->push_back(NVRAM_BOOT_WRITE_LOCK);
  if (tpm_flags & trunks::TPMA_NV_READ_STCLEAR)
    attributes->push_back(NVRAM_BOOT_READ_LOCK);
  if (tpm_flags & (trunks::TPMA_NV_AUTHWRITE))
    attributes->push_back(NVRAM_WRITE_AUTHORIZATION);
  if (tpm_flags & (trunks::TPMA_NV_AUTHREAD))
    attributes->push_back(NVRAM_READ_AUTHORIZATION);
  if (tpm_flags & trunks::TPMA_NV_GLOBALLOCK)
    attributes->push_back(NVRAM_GLOBAL_LOCK);
  if (tpm_flags & trunks::TPMA_NV_PPWRITE)
    attributes->push_back(NVRAM_PLATFORM_WRITE);
  if (tpm_flags & trunks::TPMA_NV_OWNERWRITE)
    attributes->push_back(NVRAM_OWNER_WRITE);
  if (tpm_flags & trunks::TPMA_NV_OWNERREAD)
    attributes->push_back(NVRAM_OWNER_READ);
  if (tpm_flags & trunks::TPMA_NV_EXTEND)
    attributes->push_back(NVRAM_WRITE_EXTEND);
  if (tpm_flags & (trunks::TPMA_NV_PPREAD))
    attributes->push_back(NVRAM_PLATFORM_READ);
}

bool MapAttributesToTpm(
    const std::vector<NvramSpaceAttribute>& attributes,
    NvramSpacePolicy policy,
    trunks::TPMA_NV* tpm_flags,
    bool* world_read_allowed,
    bool* world_write_allowed) {
  if (policy == NVRAM_POLICY_NONE) {
    *tpm_flags = trunks::TPMA_NV_AUTHWRITE | trunks::TPMA_NV_AUTHREAD;
  } else {
    *tpm_flags = trunks::TPMA_NV_POLICYWRITE | trunks::TPMA_NV_POLICYREAD;
  }
  *world_read_allowed = true;
  *world_write_allowed = true;
  for (auto attribute : attributes) {
    switch (attribute) {
      case NVRAM_PERSISTENT_WRITE_LOCK:
        *tpm_flags |= trunks::TPMA_NV_WRITEDEFINE;
        break;
      case NVRAM_BOOT_WRITE_LOCK:
        *tpm_flags |= trunks::TPMA_NV_WRITE_STCLEAR;
        break;
      case NVRAM_BOOT_READ_LOCK:
        *tpm_flags |= trunks::TPMA_NV_READ_STCLEAR;
        break;
      case NVRAM_WRITE_AUTHORIZATION:
        *world_write_allowed = false;
        break;
      case NVRAM_READ_AUTHORIZATION:
        *world_read_allowed = false;
        break;
      case NVRAM_WRITE_EXTEND:
        *tpm_flags |= trunks::TPMA_NV_EXTEND;
        break;
      case NVRAM_PLATFORM_READ:
        *tpm_flags |= trunks::TPMA_NV_PPREAD;
        break;
      case NVRAM_GLOBAL_LOCK:
      case NVRAM_PLATFORM_WRITE:
      case NVRAM_OWNER_WRITE:
      case NVRAM_OWNER_READ:
        return false;
      default:
        break;
    }
  }
  return true;
}

NvramResult MapTpmError(TPM_RC tpm_error) {
  switch (trunks::GetFormatOneError(tpm_error)) {
    case trunks::TPM_RC_SUCCESS:
      return NVRAM_RESULT_SUCCESS;
    case trunks::TPM_RC_NV_RANGE:
    case trunks::TPM_RC_NV_SIZE:
    case trunks::TPM_RC_ATTRIBUTES:
      return NVRAM_RESULT_INVALID_PARAMETER;
    case trunks::TPM_RC_NV_LOCKED:
    case trunks::TPM_RC_NV_UNINITIALIZED:
      return NVRAM_RESULT_OPERATION_DISABLED;
    case trunks::TPM_RC_NV_AUTHORIZATION:
    case trunks::TPM_RC_BAD_AUTH:
    case trunks::TPM_RC_AUTH_FAIL:
    case trunks::TPM_RC_POLICY_FAIL:
      return NVRAM_RESULT_ACCESS_DENIED;
    case trunks::TPM_RC_NV_SPACE:
      return NVRAM_RESULT_INSUFFICIENT_SPACE;
    case trunks::TPM_RC_NV_DEFINED:
      return NVRAM_RESULT_SPACE_ALREADY_EXISTS;
    case trunks::TPM_RC_HANDLE:
      return NVRAM_RESULT_SPACE_DOES_NOT_EXIST;
  }
  return NVRAM_RESULT_DEVICE_ERROR;
}

}  // namespace

Tpm2NvramImpl::Tpm2NvramImpl(const trunks::TrunksFactory& factory,
                             LocalDataStore* local_data_store,
                             TpmStatus* tpm_status)
    : trunks_factory_(factory),
      local_data_store_(local_data_store),
      tpm_status_(tpm_status),
      initialized_(false),
#ifndef TRUNKS_USE_PER_OP_SESSIONS
      trunks_session_(trunks_factory_.GetHmacSession()),
#endif
      trunks_utility_(trunks_factory_.GetTpmUtility()) {}

NvramResult Tpm2NvramImpl::DefineSpace(
    uint32_t index,
    size_t size,
    const std::vector<NvramSpaceAttribute>& attributes,
    const std::string& authorization_value,
    NvramSpacePolicy policy) {
  if (!Initialize()) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }

  trunks::TPMA_NV attribute_flags = 0;
  bool world_read_allowed = false;
  bool world_write_allowed = false;
  if (!MapAttributesToTpm(attributes, policy,
                          &attribute_flags, &world_read_allowed,
                          &world_write_allowed)) {
    return NVRAM_RESULT_INVALID_PARAMETER;
  }
  NvramPolicyRecord policy_record;
  policy_record.set_index(index);
  policy_record.set_policy(policy);
  policy_record.set_world_read_allowed(world_read_allowed);
  policy_record.set_world_write_allowed(world_write_allowed);
  std::string policy_digest;
  if (!ComputePolicyDigest(&policy_record, &policy_digest)) {
    LOG(ERROR) << "Failed to compute policy digest.";
    return NVRAM_RESULT_DEVICE_ERROR;
  }

  NvIndexAuthenticator nvindex_auth(tpm_status_, &trunks_session_,
      trunks_factory_);
  trunks::AuthorizationDelegate* delegate =
      nvindex_auth.GetOwnerAuthDelegate(GetOwnerPassword());
  if (!delegate) {
    return NVRAM_RESULT_OPERATION_DISABLED;
  }

  TPM_RC result = trunks_utility_->DefineNVSpace(
      index, size, attribute_flags, authorization_value, policy_digest,
      delegate);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error defining nvram space: " << GetErrorString(result);
    return MapTpmError(result);
  }
  if (!SavePolicyRecord(policy_record)) {
    trunks_utility_->DestroyNVSpace(index, delegate);
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  return NVRAM_RESULT_SUCCESS;
}

NvramResult Tpm2NvramImpl::DestroySpace(uint32_t index) {
  if (!Initialize()) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  trunks::ScopedGlobalHmacSession session_scope(&trunks_factory_,
                                                kGlobalSessionSalted,
                                                kGlobalSessionEncryption,
                                                &trunks_session_);
  if (!trunks_session_) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  if (!SetupOwnerSession()) {
    return NVRAM_RESULT_OPERATION_DISABLED;
  }
  TPM_RC result =
      trunks_utility_->DestroyNVSpace(index, trunks_session_->GetDelegate());
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error destroying nvram space:" << GetErrorString(result);
    return MapTpmError(result);
  }
  DeletePolicyRecord(index);
  return NVRAM_RESULT_SUCCESS;
}

NvramResult Tpm2NvramImpl::WriteSpace(uint32_t index,
                                      const std::string& data,
                                      const std::string& authorization_value) {
  if (!Initialize()) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  trunks::TPMS_NV_PUBLIC nvram_public;
  TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error reading nvram space public area: "
               << GetErrorString(result);
    return MapTpmError(result);
  }
  if (nvram_public.attributes & trunks::TPMA_NV_WRITELOCKED) {
    return NVRAM_RESULT_OPERATION_DISABLED;
  }
  NvIndexAuthenticator nvindex_auth(tpm_status_, &trunks_session_,
      trunks_factory_);
  trunks::AuthorizationDelegate* authorization = nullptr;
  std::unique_ptr<trunks::PolicySession> policy_session =
      trunks_factory_.GetPolicySession();
  bool using_owner_authorization = false;
  bool extend = (nvram_public.attributes & trunks::TPMA_NV_EXTEND) != 0;
  if (nvram_public.attributes & trunks::TPMA_NV_POLICYWRITE) {
    NvramPolicyRecord policy_record;
    if (!GetPolicyRecord(index, &policy_record)) {
      LOG(ERROR) << "Policy record missing.";
      return NVRAM_RESULT_INVALID_PARAMETER;
    }
    if (!SetupPolicySession(
            policy_record, authorization_value,
            extend ? trunks::TPM_CC_NV_Extend : trunks::TPM_CC_NV_Write,
            policy_session.get())) {
      // This will fail if policy is not met, e.g. a PCR value is not the
      // required value.
      return NVRAM_RESULT_ACCESS_DENIED;
    }
    authorization = policy_session->GetDelegate();
  } else if (nvram_public.attributes & trunks::TPMA_NV_AUTHWRITE) {
    authorization = nvindex_auth.GetDirectAuthDelegate(authorization_value);
  } else if (nvram_public.attributes & trunks::TPMA_NV_OWNERWRITE) {
    using_owner_authorization = true;
    authorization = nvindex_auth.GetOwnerAuthDelegate(GetOwnerPassword());
  } else {
    // TPMA_NV_PPWRITE: Platform authorization is long gone.
    return NVRAM_RESULT_OPERATION_DISABLED;
  }
  if (!authorization) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  result = trunks_utility_->WriteNVSpace(index, 0 /* offset */, data,
                                         using_owner_authorization, extend,
                                         authorization);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error writing to nvram space: " << GetErrorString(result);
    return MapTpmError(result);
  }
  return NVRAM_RESULT_SUCCESS;
}

NvramResult Tpm2NvramImpl::ReadSpace(uint32_t index,
                                     std::string* data,
                                     const std::string& authorization_value) {
  CHECK(data);
  if (!Initialize()) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  trunks::TPMS_NV_PUBLIC nvram_public;
  TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error reading nvram space public area: "
               << GetErrorString(result);
    return MapTpmError(result);
  }
  if (nvram_public.attributes & trunks::TPMA_NV_READLOCKED) {
    return NVRAM_RESULT_OPERATION_DISABLED;
  }
  // Handle the case when the space has never been written to.
  if ((nvram_public.attributes & trunks::TPMA_NV_WRITTEN) == 0) {
    *data = std::string(nvram_public.data_size, 0);
    return NVRAM_RESULT_SUCCESS;
  }
  NvIndexAuthenticator nvindex_auth(tpm_status_, &trunks_session_,
      trunks_factory_);
  trunks::AuthorizationDelegate* authorization = nullptr;
  std::unique_ptr<trunks::PolicySession> policy_session =
      trunks_factory_.GetPolicySession();
  bool using_owner_authorization = false;
  if (nvram_public.attributes & trunks::TPMA_NV_POLICYREAD) {
    NvramPolicyRecord policy_record;
    if (!GetPolicyRecord(index, &policy_record)) {
      LOG(ERROR) << "Policy record missing.";
      return NVRAM_RESULT_INVALID_PARAMETER;
    }
    if (!SetupPolicySession(policy_record, authorization_value,
                            trunks::TPM_CC_NV_Read, policy_session.get())) {
      // This will fail if policy is not met, e.g. a PCR value is not the
      // required value.
      return NVRAM_RESULT_ACCESS_DENIED;
    }
    authorization = policy_session->GetDelegate();
  } else if (nvram_public.attributes & trunks::TPMA_NV_AUTHREAD) {
    authorization = nvindex_auth.GetDirectAuthDelegate(authorization_value);
  } else if (nvram_public.attributes & trunks::TPMA_NV_OWNERREAD) {
    using_owner_authorization = true;
    authorization = nvindex_auth.GetOwnerAuthDelegate(GetOwnerPassword());
  } else {
    // TPMA_NV_PPREAD: Platform authorization is long gone.
    return NVRAM_RESULT_OPERATION_DISABLED;
  }
  if (!authorization) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  result = trunks_utility_->ReadNVSpace(
      index, 0 /* offset */, nvram_public.data_size, using_owner_authorization,
      data, authorization);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error reading nvram space: " << GetErrorString(result);
    return MapTpmError(result);
  }
  return NVRAM_RESULT_SUCCESS;
}

NvramResult Tpm2NvramImpl::LockSpace(uint32_t index,
                                     bool lock_read,
                                     bool lock_write,
                                     const std::string& authorization_value) {
  if (!Initialize()) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  trunks::ScopedGlobalHmacSession session_scope(&trunks_factory_,
                                                kGlobalSessionSalted,
                                                kGlobalSessionEncryption,
                                                &trunks_session_);
  if (!trunks_session_) {
    return NVRAM_RESULT_DEVICE_ERROR;
  }
  trunks::TPMS_NV_PUBLIC nvram_public;
  TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error reading nvram space public area: "
               << GetErrorString(result);
    return MapTpmError(result);
  }
  bool is_read_locked =
      ((nvram_public.attributes & trunks::TPMA_NV_READLOCKED) != 0);
  bool is_write_locked =
      ((nvram_public.attributes & trunks::TPMA_NV_WRITELOCKED) != 0);
  if ((!lock_read || is_read_locked) && (!lock_write || is_write_locked)) {
    // Already locked.
    return NVRAM_RESULT_SUCCESS;
  }
  // Handle locking read and write separately because the authorization might be
  // different.
  if (lock_read && !is_read_locked) {
    trunks::AuthorizationDelegate* authorization = nullptr;
    std::unique_ptr<trunks::PolicySession> policy_session =
        trunks_factory_.GetPolicySession();
    bool using_owner_authorization = false;
    if (nvram_public.attributes & trunks::TPMA_NV_POLICYREAD) {
      NvramPolicyRecord policy_record;
      if (!GetPolicyRecord(index, &policy_record)) {
        LOG(ERROR) << "Policy record missing.";
        return NVRAM_RESULT_INVALID_PARAMETER;
      }
      if (!SetupPolicySession(policy_record, authorization_value,
                              trunks::TPM_CC_NV_ReadLock,
                              policy_session.get())) {
        // This will fail if policy is not met, e.g. a PCR value is not the
        // required value.
        return NVRAM_RESULT_ACCESS_DENIED;
      }
      authorization = policy_session->GetDelegate();
    } else if (nvram_public.attributes & trunks::TPMA_NV_AUTHREAD) {
      trunks_session_->SetEntityAuthorizationValue(authorization_value);
      authorization = trunks_session_->GetDelegate();
    } else if (nvram_public.attributes & trunks::TPMA_NV_OWNERREAD) {
      if (!SetupOwnerSession()) {
        // The owner password has been destroyed.
        return NVRAM_RESULT_OPERATION_DISABLED;
      }
      using_owner_authorization = true;
      authorization = trunks_session_->GetDelegate();
    } else {
      // TPMA_NV_PPREAD: Platform authorization is long gone.
      return NVRAM_RESULT_OPERATION_DISABLED;
    }
    result = trunks_utility_->LockNVSpace(
        index, true /* lock_read */, false /* lock_write */,
        using_owner_authorization, authorization);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << "Error locking nvram space: " << GetErrorString(result);
      return MapTpmError(result);
    }
  }
  if (lock_write && !is_write_locked) {
    trunks::AuthorizationDelegate* authorization = nullptr;
    std::unique_ptr<trunks::PolicySession> policy_session =
        trunks_factory_.GetPolicySession();
    bool using_owner_authorization = false;
    if (nvram_public.attributes & trunks::TPMA_NV_POLICYWRITE) {
      NvramPolicyRecord policy_record;
      if (!GetPolicyRecord(index, &policy_record)) {
        LOG(ERROR) << "Policy record missing.";
        return NVRAM_RESULT_INVALID_PARAMETER;
      }
      if (!SetupPolicySession(policy_record, authorization_value,
                              trunks::TPM_CC_NV_WriteLock,
                              policy_session.get())) {
        // This will fail if policy is not met, e.g. a PCR value is not the
        // required value.
        return NVRAM_RESULT_ACCESS_DENIED;
      }
      authorization = policy_session->GetDelegate();
    } else if (nvram_public.attributes & trunks::TPMA_NV_AUTHWRITE) {
      trunks_session_->SetEntityAuthorizationValue(authorization_value);
      authorization = trunks_session_->GetDelegate();
    } else if (nvram_public.attributes & trunks::TPMA_NV_OWNERWRITE) {
      if (!SetupOwnerSession()) {
        // The owner password has been destroyed.
        return NVRAM_RESULT_OPERATION_DISABLED;
      }
      using_owner_authorization = true;
      authorization = trunks_session_->GetDelegate();
    } else {
      // TPMA_NV_PPWRITE: Platform authorization is long gone.
      return NVRAM_RESULT_OPERATION_DISABLED;
    }
    result = trunks_utility_->LockNVSpace(
        index, false /* lock_read */, true /* lock_write */,
        using_owner_authorization, authorization);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << "Error locking nvram space: " << GetErrorString(result);
      return MapTpmError(result);
    }
  }
  return NVRAM_RESULT_SUCCESS;
}

NvramResult Tpm2NvramImpl::ListSpaces(std::vector<uint32_t>* index_list) {
  return MapTpmError(trunks_utility_->ListNVSpaces(index_list));
}

NvramResult Tpm2NvramImpl::GetSpaceInfo(
    uint32_t index,
    uint32_t* size,
    bool* is_read_locked,
    bool* is_write_locked,
    std::vector<NvramSpaceAttribute>* attributes,
    NvramSpacePolicy* policy) {
  trunks::TPMS_NV_PUBLIC nvram_public;
  TPM_RC result = trunks_utility_->GetNVSpacePublicArea(index, &nvram_public);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error reading NV space for index " << index
               << " with error: " << GetErrorString(result);
    return MapTpmError(result);
  }
  *size = nvram_public.data_size;
  *is_read_locked =
      ((nvram_public.attributes & trunks::TPMA_NV_READLOCKED) != 0);
  *is_write_locked =
      ((nvram_public.attributes & trunks::TPMA_NV_WRITELOCKED) != 0);
  MapAttributesFromTpm(nvram_public.attributes, attributes);
  *policy = NVRAM_POLICY_NONE;
  NvramPolicyRecord policy_record;
  if (GetPolicyRecord(index, &policy_record)) {
    *policy = policy_record.policy();
    if (!policy_record.world_read_allowed()) {
      attributes->push_back(NVRAM_READ_AUTHORIZATION);
    }
    if (!policy_record.world_write_allowed()) {
      attributes->push_back(NVRAM_WRITE_AUTHORIZATION);
    }
  }
  return NVRAM_RESULT_SUCCESS;
}

void Tpm2NvramImpl::PrunePolicies() {
  LocalData local_data;
  if (!local_data_store_->Read(&local_data)) {
    LOG(ERROR) << __func__ << ": failed to read local data.";
    return;
  }

  std::vector<uint32_t> nv_indices;
  if (ListSpaces(&nv_indices) != NVRAM_RESULT_SUCCESS) {
    LOG(ERROR) << __func__ << ": failed to list NV indices.";
    return;
  }

  // Keeps fresh NV policy records only. Local data may contain both stale and
  // fresh records because TPM 2.0 allows defining NV space before TPM is
  // owned.
  LocalData new_local_data;
  for (const auto& policy : local_data.nvram_policy()) {
    if (base::Contains(nv_indices, policy.index())) {
      *new_local_data.add_nvram_policy() = policy;
    }
  }
  *local_data.mutable_nvram_policy() = new_local_data.nvram_policy();

  if (!local_data_store_->Write(local_data)) {
    LOG(ERROR) << __func__ << ": failed to write local data.";
  }
}

bool Tpm2NvramImpl::Initialize() {
#ifndef TRUNKS_USE_PER_OP_SESSIONS
  if (initialized_) {
    return true;
  }
  TPM_RC result =
      trunks_session_->StartUnboundSession(true /* salted */,
                                           true /* enable_encryption */);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error starting a default authorization session: "
               << GetErrorString(result);
    return false;
  }
  initialized_ = true;
#endif
  return true;
}

std::string Tpm2NvramImpl::GetOwnerPassword() {
  LocalData local_data;
  if (local_data_store_ && local_data_store_->Read(&local_data)) {
    return local_data.owner_password();
  }
  LOG(ERROR) << "TPM owner password requested but not available.";
  return std::string();
}

bool Tpm2NvramImpl::SetupOwnerSession() {
  // TODO(menghuan): support Pre-Own password?
  std::string owner_password = GetOwnerPassword();
  if (owner_password.empty()) {
    LOG(ERROR) << "Owner authorization required but not available.";
    return false;
  }
  trunks_session_->SetEntityAuthorizationValue(owner_password);
  return true;
}

bool Tpm2NvramImpl::SetupPolicySession(
    const NvramPolicyRecord& policy_record,
    const std::string& authorization_value,
    trunks::TPM_CC command_code,
    trunks::PolicySession* session) {
  TPM_RC result = session->StartUnboundSession(true /* salted */,
                                               true /* enable_encryption */);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error starting a policy authorization session: "
               << GetErrorString(result);
    return false;
  }
  session->SetEntityAuthorizationValue(authorization_value);
  if (policy_record.policy() != NVRAM_POLICY_NONE) {
    if (!AddPoliciesForCommand(policy_record, command_code, session)) {
      return false;
    }
    if (!AddPolicyOR(policy_record, session)) {
      return false;
    }
  }
  return true;
}

bool Tpm2NvramImpl::AddPoliciesForCommand(
    const NvramPolicyRecord& policy_record,
    trunks::TPM_CC command_code,
    trunks::PolicySession* session) {
  TPM_RC result = session->PolicyCommandCode(command_code);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Failed to setup command code policy.";
    return false;
  }
  bool is_write_command = (command_code == trunks::TPM_CC_NV_Write ||
                           command_code == trunks::TPM_CC_NV_WriteLock ||
                           command_code == trunks::TPM_CC_NV_Extend);
  bool is_read_command = !is_write_command;
  // Check if this operation requires an authorization value.
  if ((is_read_command && !policy_record.world_read_allowed()) ||
      (is_write_command && !policy_record.world_write_allowed())) {
    result = session->PolicyAuthValue();
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << "Failed to setup auth policy.";
      return false;
    }
  }
  if (policy_record.policy() == NVRAM_POLICY_PCR0) {
    std::string current_pcr_value;
    result = trunks_utility_->ReadPCR(0, &current_pcr_value);
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << "Failed to read the current PCR value.";
      return false;
    }
    result = session->PolicyPCR(
        std::map<uint32_t, std::string>({{0, current_pcr_value}}));
    if (result != TPM_RC_SUCCESS) {
      LOG(ERROR) << "Failed to setup PCR policy.";
      return false;
    }
  }
  return true;
}

bool Tpm2NvramImpl::AddPolicyOR(
    const NvramPolicyRecord& policy_record,
    trunks::PolicySession* session) {
  std::vector<std::string> digests;
  for (int i = 0; i < policy_record.policy_digests_size(); ++i) {
    digests.push_back(policy_record.policy_digests(i));
  }
  TPM_RC result = session->PolicyOR(digests);
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Failed to setup OR policy.";
    return false;
  }
  return true;
}

bool Tpm2NvramImpl::ComputePolicyDigest(NvramPolicyRecord* policy_record,
                                        std::string* digest) {
  if (policy_record->policy() == NVRAM_POLICY_NONE) {
    digest->clear();
    return true;
  }
  // Compute a policy digest for each command then OR them all together. This
  // approach gives flexibility to have different requirements for read and
  // write operations, and the ability to support authorization values combined
  // with other policies.
  std::unique_ptr<trunks::PolicySession> trial_session;
  for (trunks::TPM_CC command_code :
       {trunks::TPM_CC_NV_Extend, trunks::TPM_CC_NV_Write,
        trunks::TPM_CC_NV_WriteLock, trunks::TPM_CC_NV_Read,
        trunks::TPM_CC_NV_ReadLock, trunks::TPM_CC_NV_Certify}) {
    trial_session = trunks_factory_.GetTrialSession();
    if (trial_session->StartUnboundSession(true /* salted */,
                                           false /* enable_encryption */) !=
        TPM_RC_SUCCESS) {
      return false;
    }
    if (!AddPoliciesForCommand(*policy_record, command_code,
                               trial_session.get())) {
      return false;
    }
    if (trial_session->GetDigest(digest) != TPM_RC_SUCCESS) {
      return false;
    }
    policy_record->add_policy_digests(*digest);
  }
  if (!AddPolicyOR(*policy_record, trial_session.get())) {
    return false;
  }
  if (trial_session->GetDigest(digest) != TPM_RC_SUCCESS) {
    return false;
  }
  return true;
}

bool Tpm2NvramImpl::GetPolicyRecord(uint32_t index, NvramPolicyRecord* record) {
  LocalData local_data;
  if (local_data_store_ && local_data_store_->Read(&local_data)) {
    for (int i = 0; i < local_data.nvram_policy_size(); ++i) {
      if (local_data.nvram_policy(i).index() == index) {
        *record = local_data.nvram_policy(i);
        return true;
      }
    }
  }
  return false;
}

bool Tpm2NvramImpl::SavePolicyRecord(const NvramPolicyRecord& record) {
  LocalData local_data;
  if (!local_data_store_ || !local_data_store_->Read(&local_data)) {
    LOG(ERROR) << "Failed to read local data.";
    return false;
  }
  LocalData new_local_data = local_data;
  new_local_data.clear_nvram_policy();
  for (int i = 0; i < local_data.nvram_policy_size(); ++i) {
    // Keep only the ones that don't match |record|.
    if (local_data.nvram_policy(i).index() != record.index()) {
      *new_local_data.add_nvram_policy() = local_data.nvram_policy(i);
    }
  }
  *new_local_data.add_nvram_policy() = record;
  if (!local_data_store_->Write(new_local_data)) {
    LOG(ERROR) << "Failed to write local data.";
    return false;
  }
  return true;
}

void Tpm2NvramImpl::DeletePolicyRecord(uint32_t index) {
  LocalData local_data;
  if (local_data_store_ && local_data_store_->Read(&local_data)) {
    LocalData new_local_data = local_data;
    new_local_data.clear_nvram_policy();
    for (int i = 0; i < local_data.nvram_policy_size(); ++i) {
      // Keep only the ones that don't match |index|.
      if (local_data.nvram_policy(i).index() != index) {
        *new_local_data.add_nvram_policy() = local_data.nvram_policy(i);
      }
    }
    local_data_store_->Write(new_local_data);
  }
}

}  // namespace tpm_manager
