// 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
