// Copyright 2019 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 <string>

#include <base/logging.h>
#include <base/test/task_environment.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <tpm_manager/proto_bindings/tpm_manager.pb.h>
#include <tpm_manager-client-test/tpm_manager/dbus-proxy-mocks.h>
#include <trunks/mock_authorization_delegate.h>
#include <trunks/mock_policy_session.h>
#include <trunks/mock_tpm.h>
#include <trunks/mock_tpm_utility.h>
#include <trunks/trunks_factory_for_test.h>

#include "sealed_storage/sealed_storage.h"

using testing::_;
using testing::AtLeast;
using testing::Expectation;
using testing::ExpectationSet;
using testing::InSequence;
using testing::Invoke;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::WithArgs;

constexpr uint8_t kRandomByte = 0x12;
constexpr uint16_t kExpectedIVSize = 16; /* AES IV size */
constexpr uint8_t kDftPolicyFill = 0x23;
constexpr uint8_t kWrongPolicyFill = 0x45;
constexpr size_t kPolicyDigestSize = 32; /* SHA-256 digest */
constexpr size_t kPcrValueSize = 32;     /* SHA-256 digest */

bool operator==(const trunks::TPM2B_ECC_PARAMETER& rh,
                const trunks::TPM2B_ECC_PARAMETER& lh) {
  return rh.size == lh.size && memcmp(rh.buffer, lh.buffer, rh.size) == 0;
}
bool operator==(const trunks::TPMS_ECC_POINT& rh,
                const trunks::TPMS_ECC_POINT& lh) {
  return rh.x == lh.x && rh.y == lh.y;
}
bool operator==(const trunks::TPM2B_ECC_POINT& rh,
                const trunks::TPM2B_ECC_POINT& lh) {
  return rh.size == lh.size && rh.point == lh.point;
}

MATCHER_P(Equals, value, "") {
  return arg == value;
}

namespace sealed_storage {

class SealedStorageTest : public ::testing::Test {
 public:
  SealedStorageTest() = default;
  SealedStorageTest(const SealedStorageTest&) = delete;
  SealedStorageTest& operator=(const SealedStorageTest&) = delete;

  virtual ~SealedStorageTest() = default;

  static SecretData DftDataToSeal() { return SecretData("testdata"); }

  static std::string DftPolicyDigest() {
    return std::string(kPolicyDigestSize, kDftPolicyFill);
  }

  static std::string WrongPolicyDigest() {
    return std::string(kPolicyDigestSize, kWrongPolicyFill);
  }

  static trunks::TPM2B_ECC_POINT GetECPointWithFilledXY(uint8_t x_fill,
                                                        uint8_t y_fill) {
    const trunks::TPMS_ECC_POINT point = {
        trunks::Make_TPM2B_ECC_PARAMETER(
            std::string(MAX_ECC_KEY_BYTES, x_fill)),
        trunks::Make_TPM2B_ECC_PARAMETER(
            std::string(MAX_ECC_KEY_BYTES, y_fill))};
    return trunks::Make_TPM2B_ECC_POINT(point);
  }

  static trunks::TPM2B_ECC_POINT DftPubPoint() {
    return GetECPointWithFilledXY(0x11, 0x22);
  }

  static trunks::TPM2B_ECC_POINT DftZPoint() {
    return GetECPointWithFilledXY(0x33, 0x44);
  }

  static trunks::TPM2B_ECC_POINT WrongZPoint() {
    return GetECPointWithFilledXY(0x55, 0x66);
  }

  static Policy ConstructEmptyPolicy() { return {}; }

  static Policy ConstructPcrBoundPolicy() {
    Policy::PcrMap pcr_map;

    for (uint8_t pcr = 0; pcr < 10; pcr++) {
      pcr_map.emplace(pcr, ConstructPcrValue(pcr));
    }

    return {pcr_map};
  }

  static std::string ConstructPcrValue(uint8_t pcr) {
    return std::string(kPcrValueSize, pcr ^ 0xFF);
  }

  static Policy ConstructSecretBoundPolicy(std::string secret) {
    return {{}, SecretData(secret)};
  }

  static Policy ConstructSecretAndPcrBoundPolicy(std::string secret) {
    Policy pcr_bound_policy = ConstructPcrBoundPolicy();
    return {pcr_bound_policy.pcr_map, SecretData(secret)};
  }

  // Convert the sealed data blob of the default version produced by Seal()
  // into V1 blob.
  static void ConvertToV1(Data* sealed_data) {
    constexpr size_t kAdditionalV2DataSize =
        /* plain size */ sizeof(uint16_t) +
        /* policy digest */ sizeof(uint16_t) + kPolicyDigestSize;
    (*sealed_data)[0] = 0x01;
    sealed_data->erase(sealed_data->cbegin() + 1,
                       sealed_data->cbegin() + 1 + kAdditionalV2DataSize);
  }

  // Sets up a pair of ZPoints returned from KeyGen and ZGen with the following
  // properties: if you encrypt a particular data_to_seal with the first ZPoint
  // (returned from KeyGen) and then decrypt it with the second ZPoint (returned
  // from ZGen), decryption returns success as it produces valid padding (but
  // not the same data, of course).
  // Returns data_to_sign to be used with the setup ZPoints.
  const SecretData SetupWrongZPointWithGarbageData() {
    z_point_ = GetECPointWithFilledXY(0x11, 0x11);          // KeyGen
    z_gen_out_point_ = GetECPointWithFilledXY(0x0F, 0x00);  // ZGen
    return SecretData("testdata");
  }

  void SetUp() override {
    trunks_factory_.set_tpm(&tpm_);
    trunks_factory_.set_tpm_utility(&tpm_utility_);
    trunks_factory_.set_policy_session(&policy_session_);
    trunks_factory_.set_trial_session(&policy_session_);

    ON_CALL(tpm_ownership_, GetTpmStatus(_, _, _, _))
        .WillByDefault(
            Invoke([this](const tpm_manager::GetTpmStatusRequest& request,
                          tpm_manager::GetTpmStatusReply* reply,
                          brillo::ErrorPtr*, int) {
              reply->set_status(tpm_manager_result_);
              reply->mutable_local_data()->set_endorsement_password(
                  endorsement_password_);
              return true;
            }));

    ON_CALL(tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
        .WillByDefault(
            Invoke(this, &SealedStorageTest::CreatePrimarySyncShort));
    ON_CALL(tpm_, ECDH_KeyGenSync(_, _, _, _, _))
        .WillByDefault(Invoke(this, &SealedStorageTest::ECDH_KeyGenSync));
    ON_CALL(tpm_, ECDH_ZGenSync(_, _, _, _, _))
        .WillByDefault(Invoke(this, &SealedStorageTest::ECDH_ZGenSync));
    ON_CALL(tpm_, GetRandomSync(_, _, _))
        .WillByDefault(Invoke(this, &SealedStorageTest::GetRandomSync));
    ON_CALL(tpm_utility_, GetPolicyDigestForPcrValues(_, _, _))
        .WillByDefault(
            Invoke(this, &SealedStorageTest::GetPolicyDigestForPcrValues));
    ON_CALL(policy_session_, PolicyPCR(_))
        .WillByDefault(Invoke(this, &SealedStorageTest::PolicyPCR));
    ON_CALL(policy_session_, GetDelegate())
        .WillByDefault(Return(&auth_delegate_));
    ON_CALL(policy_session_, GetDigest(_))
        .WillByDefault(Invoke(this, &SealedStorageTest::GetDigest));
    ON_CALL(policy_session_, PolicyOR(_))
        .WillByDefault(Return(policy_or_result_));
    ON_CALL(policy_session_, StartUnboundSession(_, _))
        .WillByDefault(Return(start_session_result_));
  }

  trunks::TPM_RC CreatePrimarySyncShort(
      const trunks::TPMI_RH_HIERARCHY& primary_handle,
      const trunks::TPM2B_PUBLIC& in_public,
      const trunks::TPML_PCR_SELECTION& creation_pcr,
      trunks::TPM_HANDLE* object_handle,
      trunks::TPM2B_PUBLIC* out_public,
      trunks::TPM2B_CREATION_DATA* creation_data,
      trunks::TPM2B_DIGEST* creation_hash,
      trunks::TPMT_TK_CREATION* creation_ticket,
      trunks::TPM2B_NAME* name,
      trunks::AuthorizationDelegate* authorization_delegate) {
    create_primary_public_area_ = in_public;
    *object_handle = sealing_key_handle_;
    return create_primary_result_;
  }

  trunks::TPM_RC ECDH_KeyGenSync(
      const trunks::TPMI_DH_OBJECT& key_handle,
      const std::string& key_handle_name,
      trunks::TPM2B_ECC_POINT* z_point,
      trunks::TPM2B_ECC_POINT* pub_point,
      trunks::AuthorizationDelegate* authorization_delegate) {
    *z_point = z_point_;
    *pub_point = pub_point_;
    return key_gen_result_;
  }

  trunks::TPM_RC ECDH_ZGenSync(
      const trunks::TPMI_DH_OBJECT& key_handle,
      const std::string& key_handle_name,
      const trunks::TPM2B_ECC_POINT& in_point,
      trunks::TPM2B_ECC_POINT* out_point,
      trunks::AuthorizationDelegate* authorization_delegate) {
    *out_point = z_gen_out_point_;
    z_gen_in_point_ = in_point;
    return z_gen_result_;
  }

  trunks::TPM_RC GetPolicyDigestForPcrValues(
      const std::map<uint32_t, std::string>& pcr_map,
      bool use_auth_value,
      std::string* policy_digest) {
    *policy_digest = policy_digest_;
    return get_policy_digest_result_;
  }

  trunks::TPM_RC GetRandomSync(
      const trunks::UINT16& bytes_requested,
      trunks::TPM2B_DIGEST* random_bytes,
      trunks::AuthorizationDelegate* authorization_delegate) {
    if (random_.has_value()) {
      *random_bytes = trunks::Make_TPM2B_DIGEST(random_.value());
    } else {
      random_bytes->size = bytes_requested;
      memset(random_bytes->buffer, kRandomByte, bytes_requested);
    }
    return get_random_result_;
  }

  trunks::TPM_RC PolicyPCR(const std::map<uint32_t, std::string>& pcr_map) {
    return policy_pcr_result_;
  }

  trunks::TPM_RC GetDigest(std::string* policy_digest) {
    *policy_digest = policy_digest_;
    return get_policy_digest_result_;
  }

  void ExpectCommandSequence(bool do_seal = true, bool do_unseal = true) {
    bool use_empty_policy = policy_.pcr_map.empty();
    ExpectationSet seal_commands;

    /* Seal: Create policy digest */
    if (use_empty_policy) {
      EXPECT_CALL(tpm_utility_, GetPolicyDigestForPcrValues(_, _, _)).Times(0);
    } else {
      EXPECT_CALL(tpm_utility_,
                  GetPolicyDigestForPcrValues(policy_.pcr_map, _, _))
          .Times(AtLeast(1));
    }

    if (do_seal) {
      /* Seal: Create sealing key */
      Expectation status1 =
          EXPECT_CALL(tpm_ownership_, GetTpmStatus(_, _, _, _));
      seal_commands += status1;
      if (tpm_manager_result_ != tpm_manager::STATUS_SUCCESS) {
        /* In case of GetTpmStatus error... */
        EXPECT_CALL(tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
            .Times(0);
        return;
      }

      Expectation create_primary1 =
          EXPECT_CALL(tpm_, CreatePrimarySyncShort(trunks::TPM_RH_ENDORSEMENT,
                                                   _, _, _, _, _, _, _, _, _))
              .After(status1);
      seal_commands += create_primary1;
      if (create_primary_result_ != trunks::TPM_RC_SUCCESS) {
        /* In case of CreatePrimary error... */
        EXPECT_CALL(tpm_, ECDH_KeyGenSync(_, _, _, _, _)).Times(0);
        return;
      }

      /* Seal: Generate seeds */
      Expectation key_gen =
          EXPECT_CALL(tpm_, ECDH_KeyGenSync(sealing_key_handle_, _, _, _, _))
              .After(create_primary1);
      seal_commands += key_gen;
      Expectation get_random =
          EXPECT_CALL(tpm_, GetRandomSync(kExpectedIVSize, _, _));
      seal_commands += get_random;
    }

    if (do_unseal) {
      /* Unseal: Create sealing key */
      Expectation status2 =
          EXPECT_CALL(tpm_ownership_, GetTpmStatus(_, _, _, _))
              .After(seal_commands);
      if (tpm_manager_result_ != tpm_manager::STATUS_SUCCESS) {
        /* In case of GetTpmStatus error... */
        EXPECT_CALL(tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
            .Times(0);
        return;
      }

      Expectation create_primary2 =
          EXPECT_CALL(tpm_, CreatePrimarySyncShort(trunks::TPM_RH_ENDORSEMENT,
                                                   _, _, _, _, _, _, _, _, _))
              .After(status2);
      if (create_primary_result_ != trunks::TPM_RC_SUCCESS) {
        /* In case of CreatePrimary error... */
        EXPECT_CALL(tpm_, ECDH_ZGenSync(_, _, _, _, _)).Times(0);
        return;
      }

      /* Unseal: Restore seeds */
      Expectation start_session =
          EXPECT_CALL(policy_session_, StartUnboundSession(_, _))
              .Times(AtLeast(1));
      if (use_empty_policy) {
        EXPECT_CALL(policy_session_, PolicyPCR(_)).Times(0);
      } else {
        EXPECT_CALL(policy_session_, PolicyPCR(policy_.pcr_map))
            .After(start_session);
        if (policy_pcr_result_ != trunks::TPM_RC_SUCCESS) {
          /* In case of CreatePrimary error... */
          EXPECT_CALL(tpm_, ECDH_ZGenSync(_, _, _, _, _)).Times(0);
          return;
        }
      }
      Expectation get_delegate =
          EXPECT_CALL(policy_session_, GetDelegate()).After(start_session);
      EXPECT_CALL(tpm_, ECDH_ZGenSync(sealing_key_handle_, _,
                                      Equals(pub_point_), _, &auth_delegate_))
          .After(create_primary2, get_delegate);
    }
  }

  void ResetMocks() {
    Mock::VerifyAndClearExpectations(&tpm_ownership_);
    Mock::VerifyAndClearExpectations(&tpm_utility_);
    Mock::VerifyAndClearExpectations(&tpm_);
    Mock::VerifyAndClearExpectations(&policy_session_);
  }

  void SealUnseal(bool expect_seal_success,
                  bool expect_unseal_success,
                  const SecretData& data_to_seal) {
    sealed_storage_.reset_policy(policy_);
    auto sealed_data = sealed_storage_.Seal(data_to_seal);
    EXPECT_EQ(sealed_data.has_value(), expect_seal_success);
    if (!sealed_data.has_value()) {
      return;
    }

    auto result = sealed_storage_.Unseal(sealed_data.value());
    EXPECT_EQ(result.has_value(), expect_unseal_success);
    if (expect_unseal_success && result.has_value()) {
      EXPECT_EQ(result.value(), data_to_seal);
    }
  }

 protected:
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
      base::test::TaskEnvironment::MainThreadType::IO};
  Policy policy_;
  trunks::MockTpm tpm_;
  trunks::MockTpmUtility tpm_utility_;
  trunks::MockAuthorizationDelegate auth_delegate_;
  NiceMock<trunks::MockPolicySession> policy_session_;
  trunks::TrunksFactoryForTest trunks_factory_;
  testing::StrictMock<org::chromium::TpmManagerProxyMock> tpm_ownership_;
  SealedStorage sealed_storage_{policy_, &trunks_factory_, &tpm_ownership_};

  tpm_manager::TpmManagerStatus tpm_manager_result_ =
      tpm_manager::STATUS_SUCCESS;
  std::string endorsement_password_ = "endorsement_password";

  trunks::TPM_RC create_primary_result_ = trunks::TPM_RC_SUCCESS;
  trunks::TPM_HANDLE sealing_key_handle_ = trunks::TRANSIENT_FIRST;
  trunks::TPM2B_PUBLIC create_primary_public_area_ = {};

  trunks::TPM_RC key_gen_result_ = trunks::TPM_RC_SUCCESS;
  trunks::TPM2B_ECC_POINT z_point_ = DftZPoint();
  trunks::TPM2B_ECC_POINT pub_point_ = DftPubPoint();

  trunks::TPM_RC z_gen_result_ = trunks::TPM_RC_SUCCESS;
  trunks::TPM2B_ECC_POINT z_gen_out_point_ = DftZPoint();
  trunks::TPM2B_ECC_POINT z_gen_in_point_ = {};

  trunks::TPM_RC get_random_result_ = trunks::TPM_RC_SUCCESS;
  base::Optional<std::string> random_ = {};

  trunks::TPM_RC get_policy_digest_result_ = trunks::TPM_RC_SUCCESS;
  std::string policy_digest_ = DftPolicyDigest();

  trunks::TPM_RC policy_pcr_result_ = trunks::TPM_RC_SUCCESS;

  trunks::TPM_RC policy_or_result_ = trunks::TPM_RC_SUCCESS;

  trunks::TPM_RC start_session_result_ = trunks::TPM_RC_SUCCESS;
};

TEST_F(SealedStorageTest, TrivialPolicySuccess) {
  ExpectCommandSequence();
  SealUnseal(true, true, DftDataToSeal());
}

TEST_F(SealedStorageTest, VariousPlaintextSizesSuccess) {
  for (size_t data_size = 0; data_size <= 65; data_size++) {
    std::string data(data_size, 'x');
    ExpectCommandSequence();
    SealUnseal(true, true, SecretData(data));
    ResetMocks();
  }
}

TEST_F(SealedStorageTest, PcrBoundPolicySuccess) {
  policy_ = ConstructPcrBoundPolicy();
  ExpectCommandSequence();
  SealUnseal(true, true, DftDataToSeal());
}

TEST_F(SealedStorageTest, SecretBoundPolicySuccess) {
  policy_ = ConstructSecretBoundPolicy("secret");
  ExpectCommandSequence();
  SealUnseal(true, true, DftDataToSeal());
}

TEST_F(SealedStorageTest, SecretAndPcrBoundPolicySuccess) {
  policy_ = ConstructSecretAndPcrBoundPolicy("secret");
  ExpectCommandSequence();
  SealUnseal(true, true, DftDataToSeal());
}

TEST_F(SealedStorageTest, WrongRestoredZPointError) {
  z_gen_out_point_ = WrongZPoint();
  ExpectCommandSequence();
  SealUnseal(true, false, DftDataToSeal());
}

TEST_F(SealedStorageTest, WrongDeviceStateError) {
  policy_ = ConstructPcrBoundPolicy();
  policy_pcr_result_ = trunks::TPM_RC_VALUE;
  ExpectCommandSequence();
  SealUnseal(true, false, DftDataToSeal());
}

TEST_F(SealedStorageTest, WrongRestoredZPointGarbage) {
  const auto data_to_seal = SetupWrongZPointWithGarbageData();
  policy_ = ConstructPcrBoundPolicy();
  ExpectCommandSequence();
  SealUnseal(true, false, data_to_seal);
}

TEST_F(SealedStorageTest, WrongPolicy) {
  const auto data_to_seal = SetupWrongZPointWithGarbageData();
  policy_ = ConstructPcrBoundPolicy();
  sealed_storage_.reset_policy(policy_);

  // Set up sealed_data with some initial policy digest.
  policy_digest_ = DftPolicyDigest();
  ExpectCommandSequence(true, false);
  auto sealed_data = sealed_storage_.Seal(data_to_seal);
  EXPECT_TRUE(sealed_data.has_value());
  ResetMocks();

  // Try unsealing with a different policy, resulting in a different digest.
  policy_digest_ = WrongPolicyDigest();
  EXPECT_CALL(tpm_ownership_, GetTpmStatus(_, _, _, _)).Times(AtLeast(0));
  EXPECT_CALL(tpm_utility_, GetPolicyDigestForPcrValues(_, _, _)).Times(1);
  EXPECT_CALL(tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
      .Times(0);
  EXPECT_CALL(tpm_, ECDH_ZGenSync(_, _, _, _, _)).Times(0);
  auto result = sealed_storage_.Unseal(sealed_data.value());
  EXPECT_FALSE(result.has_value());
}

TEST_F(SealedStorageTest, NonEmptySealEmptyUnsealPolicy) {
  const auto data_to_seal = SetupWrongZPointWithGarbageData();
  policy_ = ConstructPcrBoundPolicy();
  sealed_storage_.reset_policy(policy_);

  // Set up sealed_data with some initial non-empty policy digest.
  policy_digest_ = DftPolicyDigest();
  ExpectCommandSequence(true, false);
  auto sealed_data = sealed_storage_.Seal(data_to_seal);
  EXPECT_TRUE(sealed_data.has_value());
  ResetMocks();

  // Try unsealing with an empty policy.
  policy_ = ConstructEmptyPolicy();
  sealed_storage_.reset_policy(policy_);
  EXPECT_CALL(tpm_ownership_, GetTpmStatus(_, _, _, _)).Times(AtLeast(0));
  EXPECT_CALL(tpm_utility_, GetPolicyDigestForPcrValues(_, _, _)).Times(0);
  EXPECT_CALL(tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
      .Times(0);
  EXPECT_CALL(tpm_, ECDH_ZGenSync(_, _, _, _, _)).Times(0);
  auto result = sealed_storage_.Unseal(sealed_data.value());
  EXPECT_FALSE(result.has_value());
}

TEST_F(SealedStorageTest, EmptySealNonEmptyUnsealPolicy) {
  const auto data_to_seal = SetupWrongZPointWithGarbageData();
  policy_ = ConstructEmptyPolicy();
  sealed_storage_.reset_policy(policy_);

  // Set up sealed_data with initial empty policy.
  ExpectCommandSequence(true, false);
  auto sealed_data = sealed_storage_.Seal(data_to_seal);
  EXPECT_TRUE(sealed_data.has_value());
  ResetMocks();

  // Try unsealing with some non-empty policy.
  policy_ = ConstructPcrBoundPolicy();
  sealed_storage_.reset_policy(policy_);
  EXPECT_CALL(tpm_ownership_, GetTpmStatus(_, _, _, _)).Times(AtLeast(0));
  EXPECT_CALL(tpm_utility_, GetPolicyDigestForPcrValues(_, _, _)).Times(1);
  EXPECT_CALL(tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
      .Times(0);
  EXPECT_CALL(tpm_, ECDH_ZGenSync(_, _, _, _, _)).Times(0);
  auto result = sealed_storage_.Unseal(sealed_data.value());
  EXPECT_FALSE(result.has_value());
}

TEST_F(SealedStorageTest, CanUnsealV1) {
  const auto data_to_seal = DftDataToSeal();
  policy_ = ConstructPcrBoundPolicy();
  sealed_storage_.reset_policy(policy_);
  ExpectCommandSequence();

  auto sealed_data = sealed_storage_.Seal(data_to_seal);
  ASSERT_TRUE(sealed_data.has_value());
  ConvertToV1(&sealed_data.value());

  // Now set the correct expected plaintext size and unseal the V1 blob.
  sealed_storage_.set_plain_size_for_v1(data_to_seal.size());
  auto result = sealed_storage_.Unseal(sealed_data.value());
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ(result.value(), data_to_seal);
}

TEST_F(SealedStorageTest, WrongSizeForV1) {
  const auto data_to_seal = DftDataToSeal();
  policy_ = ConstructPcrBoundPolicy();
  sealed_storage_.reset_policy(policy_);
  ExpectCommandSequence();

  auto sealed_data = sealed_storage_.Seal(data_to_seal);
  ASSERT_TRUE(sealed_data.has_value());
  ConvertToV1(&sealed_data.value());

  // Now set a wrong expected plaintext size and try unsealing the V1 blob.
  sealed_storage_.set_plain_size_for_v1(data_to_seal.size() + 10);
  auto result = sealed_storage_.Unseal(sealed_data.value());
  ASSERT_FALSE(result.has_value());
}

TEST_F(SealedStorageTest, WrongPolicySecret) {
  const auto data_to_seal = SetupWrongZPointWithGarbageData();
  policy_ = ConstructSecretBoundPolicy("correct secret");
  sealed_storage_.reset_policy(policy_);

  ExpectCommandSequence(true, false);
  auto sealed_data = sealed_storage_.Seal(data_to_seal);
  EXPECT_TRUE(sealed_data.has_value());
  ResetMocks();

  policy_ = ConstructSecretBoundPolicy("wrong secret");
  sealed_storage_.reset_policy(policy_);
  // A different secret leads to a wrong policy digest.
  policy_digest_ = WrongPolicyDigest();
  EXPECT_CALL(tpm_ownership_, GetTpmStatus(_, _, _, _)).Times(AtLeast(0));
  auto result = sealed_storage_.Unseal(sealed_data.value());
  EXPECT_FALSE(result.has_value());
}

TEST_F(SealedStorageTest, PcrAndSecretWrongDeviceStateCorrectSecret) {
  policy_ = ConstructSecretAndPcrBoundPolicy("secret");
  policy_pcr_result_ = trunks::TPM_RC_VALUE;
  ExpectCommandSequence();
  SealUnseal(true, false, DftDataToSeal());
}

TEST_F(SealedStorageTest, PcrAndSecretCorrectDeviceStateWrongSecret) {
  const auto data_to_seal = SetupWrongZPointWithGarbageData();
  policy_ = ConstructSecretAndPcrBoundPolicy("correct secret");
  sealed_storage_.reset_policy(policy_);

  ExpectCommandSequence(true, false);
  auto sealed_data = sealed_storage_.Seal(data_to_seal);
  EXPECT_TRUE(sealed_data.has_value());
  ResetMocks();

  policy_ = ConstructSecretBoundPolicy("wrong secret");
  sealed_storage_.reset_policy(policy_);
  // A different secret leads to a wrong policy digest.
  policy_digest_ = WrongPolicyDigest();
  EXPECT_CALL(tpm_ownership_, GetTpmStatus(_, _, _, _)).Times(AtLeast(0));
  auto result = sealed_storage_.Unseal(sealed_data.value());
  EXPECT_FALSE(result.has_value());
}

}  // namespace sealed_storage
