// Copyright 2016 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.
//
// Unit tests for FirmwareManagementParameters.

#include "cryptohome/firmware_management_parameters.h"

#include <base/files/file_util.h>
#include <base/logging.h>
#include <brillo/process/process_mock.h>
#include <brillo/secure_blob.h>
#include <gtest/gtest.h>

#include "cryptohome/mock_firmware_management_parameters.h"
#include "cryptohome/mock_fwmp_checker.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"

extern "C" {
#include "cryptohome/crc8.h"
}

namespace cryptohome {
using brillo::SecureBlob;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;

// Provides a test fixture for ensuring Firmware Management Parameters
// flows work as expected.
//
// Multiple helpers are included to ensure tests are starting from the same
// baseline for difference scenarios, such as first boot or all-other-normal
// boots.
template <
    FirmwareManagementParameters::ResetMethod reset_method,
    FirmwareManagementParameters::WriteProtectionMethod write_protection_method>
class FirmwareManagementParametersTestBase : public ::testing::Test {
 public:
  FirmwareManagementParametersTestBase()
      : fwmp_checker_(new MockFwmpChecker()),
        fwmp_(reset_method,
              write_protection_method,
              &tpm_,
              std::unique_ptr<FwmpChecker>(fwmp_checker_)) {}
  FirmwareManagementParametersTestBase(
      const FirmwareManagementParametersTestBase&) = delete;
  FirmwareManagementParametersTestBase& operator=(
      const FirmwareManagementParametersTestBase&) = delete;

  virtual ~FirmwareManagementParametersTestBase() {}

  virtual void SetUp() {
    // Create the OOBE data to reuse for post-boot tests.
    fwmp_flags_ = 0x1234;
    fwmp_hash_.assign(kHashData, kHashData + strlen(kHashData));
    fwmp_hash_ptr_ = &fwmp_hash_;
  }

  // Sets the expectations for `FirmwareManagementParameters::Store()` according
  // to the configurations.
  void SetExpectationForStore(SecureBlob* nvram_data) {
    // Ensure an enabled, owned TPM.
    EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
    EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));

    InSequence s;
    EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
        .WillOnce(Return(true));
    EXPECT_CALL(tpm_, IsNvramLocked(FirmwareManagementParameters::kNvramIndex))
        .WillOnce(Return(false));
    EXPECT_CALL(tpm_, GetNvramSize(FirmwareManagementParameters::kNvramIndex))
        .WillOnce(Return(FirmwareManagementParameters::kNvramBytes));
    EXPECT_CALL(*fwmp_checker_,
                IsValidForWrite(FirmwareManagementParameters::kNvramIndex))
        .WillOnce(Return(true));

    // Save blob that was written
    if (write_protection_method ==
        FirmwareManagementParameters::WriteProtectionMethod::
            kOwnerAuthorization) {
      EXPECT_CALL(tpm_,
                  OwnerWriteNvram(FirmwareManagementParameters::kNvramIndex, _))
          .WillOnce(DoAll(SaveArg<1>(nvram_data), Return(true)));
    } else {
      EXPECT_CALL(tpm_,
                  WriteNvram(FirmwareManagementParameters::kNvramIndex, _))
          .WillOnce(DoAll(SaveArg<1>(nvram_data), Return(true)));
    }

    if (write_protection_method ==
        FirmwareManagementParameters::WriteProtectionMethod::kWriteLock) {
      EXPECT_CALL(tpm_,
                  WriteLockNvram(FirmwareManagementParameters::kNvramIndex))
          .WillOnce(Return(true));
      EXPECT_CALL(tpm_,
                  IsNvramLocked(FirmwareManagementParameters::kNvramIndex))
          .WillOnce(Return(true));
    }
  }

  const char* kHashData = "AxxxxxxxBxxxxxxxCxxxxxxxDxxxxxxE";
  const brillo::SecureBlob kContentsWithHash = {
      // clang-format off
    0xd2,
    0x28,
    0x10,
    0x00,
    0x34, 0x12, 0x00, 0x00,
    'A', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
    'B', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
    'C', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
    'D', 'x', 'x', 'x', 'x', 'x', 'x', 'E'
      // clang-format on
  };
  const brillo::SecureBlob kContentsNoHash = {
      // clang-format off
    0x6c,
    0x28,
    0x10,
    0x00,
    0x34, 0x12, 0x00, 0x00,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
      // clang-format on
  };
  MockFwmpChecker* fwmp_checker_;
  FirmwareManagementParameters fwmp_;
  NiceMock<MockTpm> tpm_;
  uint32_t fwmp_flags_;
  brillo::Blob fwmp_hash_;
  brillo::Blob* fwmp_hash_ptr_;
};

class FirmwareManagementParametersTest
    : public FirmwareManagementParametersTestBase<
          FirmwareManagementParameters::ResetMethod::kRecreateSpace,
          FirmwareManagementParameters::WriteProtectionMethod::kWriteLock> {};

// Create a new space
TEST_F(FirmwareManagementParametersTest, CreateNew) {
  // HasAuthorization() checks for Create() and Destroy()
  EXPECT_CALL(tpm_, IsEnabled()).Times(2).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).Times(2).WillRepeatedly(Return(true));
  brillo::SecureBlob pw("sup");
  EXPECT_CALL(tpm_, GetOwnerPassword(_))
      .Times(2)
      .WillRepeatedly(DoAll(SetArgPointee<0>(pw), Return(true)));

  // Destroy() doesn't find an existing space
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));

  // Create the new space
  EXPECT_CALL(tpm_, DefineNvram(FirmwareManagementParameters::kNvramIndex,
                                FirmwareManagementParameters::kNvramBytes,
                                Tpm::kTpmNvramWriteDefine |
                                    Tpm::kTpmNvramFirmwareReadable))
      .WillOnce(Return(true));
  EXPECT_TRUE(fwmp_.Create());
}

// Create on top of an existing space
TEST_F(FirmwareManagementParametersTest, CreateOverExisting) {
  // HasAuthorization() checks for Create() and Destroy()
  ON_CALL(tpm_, IsEnabled()).WillByDefault(Return(true));
  ON_CALL(tpm_, IsOwned()).WillByDefault(Return(true));
  brillo::SecureBlob pw("sup");
  ON_CALL(tpm_, GetOwnerPassword(_))
      .WillByDefault(DoAll(SetArgPointee<0>(pw), Return(true)));

  // Destroy() the existing space
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, DestroyNvram(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));

  // Create the new space
  EXPECT_CALL(tpm_, DefineNvram(FirmwareManagementParameters::kNvramIndex,
                                FirmwareManagementParameters::kNvramBytes,
                                Tpm::kTpmNvramWriteDefine |
                                    Tpm::kTpmNvramFirmwareReadable))
      .WillOnce(Return(true));
  EXPECT_TRUE(fwmp_.Create());
}

// Create fails without auth
TEST_F(FirmwareManagementParametersTest, CreateWithNoAuth) {
  // Enabled and owned succeed
  ON_CALL(tpm_, IsEnabled()).WillByDefault(Return(true));
  ON_CALL(tpm_, IsOwned()).WillByDefault(Return(true));

  // No password for you
  EXPECT_CALL(tpm_, GetOwnerPassword(_)).WillOnce(Return(false));
  EXPECT_FALSE(fwmp_.Create());
}

// Create fails on define error
TEST_F(FirmwareManagementParametersTest, CreateDefineError) {
  // HasAuthorization() checks for Create() and Destroy()
  ON_CALL(tpm_, IsEnabled()).WillByDefault(Return(true));
  ON_CALL(tpm_, IsOwned()).WillByDefault(Return(true));
  brillo::SecureBlob pw("sup");
  ON_CALL(tpm_, GetOwnerPassword(_))
      .WillByDefault(DoAll(SetArgPointee<0>(pw), Return(true)));

  // Destroy() doesn't find an existing space
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));

  // Create the new space fails
  EXPECT_CALL(tpm_, DefineNvram(FirmwareManagementParameters::kNvramIndex,
                                FirmwareManagementParameters::kNvramBytes,
                                Tpm::kTpmNvramWriteDefine |
                                    Tpm::kTpmNvramFirmwareReadable))
      .WillOnce(Return(false));
  EXPECT_FALSE(fwmp_.Create());
}

// Destroy existing space
TEST_F(FirmwareManagementParametersTest, DestroyExisting) {
  // HasAuthorization() checks for Destroy()
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));
  brillo::SecureBlob pw("sup");
  EXPECT_CALL(tpm_, GetOwnerPassword(_))
      .WillOnce(DoAll(SetArgPointee<0>(pw), Return(true)));

  // Destroy() the existing space
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, DestroyNvram(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));

  EXPECT_TRUE(fwmp_.Destroy());
}

// Destroy non-existing space
TEST_F(FirmwareManagementParametersTest, DestroyNonExisting) {
  // HasAuthorization() checks for Destroy()
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));
  brillo::SecureBlob pw("sup");
  EXPECT_CALL(tpm_, GetOwnerPassword(_))
      .WillOnce(DoAll(SetArgPointee<0>(pw), Return(true)));

  // Destroy() non-existing space is fine
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));

  EXPECT_TRUE(fwmp_.Destroy());
}

// Destroy fails without auth
TEST_F(FirmwareManagementParametersTest, DestroyWithNoAuth) {
  // Enabled and owned succeed
  ON_CALL(tpm_, IsEnabled()).WillByDefault(Return(true));
  ON_CALL(tpm_, IsOwned()).WillByDefault(Return(true));

  // No password for you
  EXPECT_CALL(tpm_, GetOwnerPassword(_)).WillOnce(Return(false));
  EXPECT_FALSE(fwmp_.Destroy());
}

// Destroy failure
TEST_F(FirmwareManagementParametersTest, DestroyFailure) {
  // HasAuthorization() checks for Destroy()
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));
  brillo::SecureBlob pw("sup");
  EXPECT_CALL(tpm_, GetOwnerPassword(_))
      .WillOnce(DoAll(SetArgPointee<0>(pw), Return(true)));

  // Destroy() the existing space
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, DestroyNvram(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));

  EXPECT_FALSE(fwmp_.Destroy());
}

// Store flags and hash
TEST_F(FirmwareManagementParametersTest, StoreFlagsAndHash) {
  SecureBlob nvram_data;
  SetExpectationForStore(&nvram_data);
  EXPECT_TRUE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data, kContentsWithHash);
}

// Store flags only
TEST_F(FirmwareManagementParametersTest, StoreFlagsOnly) {
  SecureBlob nvram_data;
  fwmp_hash_ptr_ = NULL;
  SetExpectationForStore(&nvram_data);
  EXPECT_TRUE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data, kContentsNoHash);
}

// Store fails if TPM isn't ready
TEST_F(FirmwareManagementParametersTest, StoreNotReady) {
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(false));
  EXPECT_FALSE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
}

// Store fails if space doesn't exist
TEST_F(FirmwareManagementParametersTest, StoreNoNvram) {
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));
  EXPECT_FALSE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
}

// Store fails if space is locked
TEST_F(FirmwareManagementParametersTest, StoreLockedNvram) {
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramLocked(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_FALSE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
}

// Store fails if space is wrong size
TEST_F(FirmwareManagementParametersTest, StoreNvramSizeBad) {
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramLocked(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));

  // Return a bad NVRAM size.
  EXPECT_CALL(tpm_, GetNvramSize(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(4));
  EXPECT_FALSE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
}

// Store fails if the space is not valid for write operation.
TEST_F(FirmwareManagementParametersTest, StoreNvramNotValidForWrite) {
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramLocked(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));

  // Return a bad NVRAM size.
  EXPECT_CALL(tpm_, GetNvramSize(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(FirmwareManagementParameters::kNvramBytes));
  EXPECT_CALL(*fwmp_checker_,
              IsValidForWrite(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));
  EXPECT_FALSE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
}

// Store fails if hash is wrong size
TEST_F(FirmwareManagementParametersTest, StoreHashSizeBad) {
  EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramLocked(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(false));
  EXPECT_CALL(tpm_, GetNvramSize(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(FirmwareManagementParameters::kNvramBytes));

  // Return a bad NVRAM size.
  brillo::Blob bad_hash = brillo::BlobFromString("wrong-size");
  EXPECT_FALSE(fwmp_.Store(fwmp_flags_, &bad_hash));
  EXPECT_FALSE(fwmp_.IsLoaded());
}

// Load existing data
TEST_F(FirmwareManagementParametersTest, LoadExisting) {
  uint32_t flags;
  brillo::Blob hash;
  SecureBlob nvram_data(kContentsWithHash);

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(DoAll(SetArgPointee<1>(nvram_data), Return(true)));

  // Load succeeds
  EXPECT_FALSE(fwmp_.IsLoaded());
  EXPECT_TRUE(fwmp_.Load());
  EXPECT_TRUE(fwmp_.IsLoaded());

  // And really loaded things
  EXPECT_TRUE(fwmp_.GetFlags(&flags));
  EXPECT_EQ(flags, fwmp_flags_);
  EXPECT_TRUE(fwmp_.GetDeveloperKeyHash(&hash));
  EXPECT_EQ(fwmp_hash_, hash);
}

// GetFlags automatically loads
TEST_F(FirmwareManagementParametersTest, GetFlags) {
  uint32_t flags;
  brillo::Blob hash;
  SecureBlob nvram_data(kContentsWithHash);

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(DoAll(SetArgPointee<1>(nvram_data), Return(true)));

  EXPECT_FALSE(fwmp_.IsLoaded());
  EXPECT_TRUE(fwmp_.GetFlags(&flags));
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(flags, fwmp_flags_);
}

// GetDeveloperKeyHash automatically loads
TEST_F(FirmwareManagementParametersTest, GetDeveloperKeyHash) {
  brillo::Blob hash;
  SecureBlob nvram_data(kContentsWithHash);

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(DoAll(SetArgPointee<1>(nvram_data), Return(true)));

  EXPECT_FALSE(fwmp_.IsLoaded());
  EXPECT_TRUE(fwmp_.GetDeveloperKeyHash(&hash));
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(fwmp_hash_, hash);
}

// Load and Get fail if space doesn't exist
TEST_F(FirmwareManagementParametersTest, LoadNoNvram) {
  uint32_t flags;
  brillo::Blob hash;

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .Times(3)
      .WillRepeatedly(Return(false));

  EXPECT_FALSE(fwmp_.Load());
  EXPECT_FALSE(fwmp_.IsLoaded());

  EXPECT_FALSE(fwmp_.GetFlags(&flags));
  EXPECT_FALSE(fwmp_.IsLoaded());

  EXPECT_FALSE(fwmp_.GetDeveloperKeyHash(&hash));
  EXPECT_FALSE(fwmp_.IsLoaded());
}

// Load fails on read error
TEST_F(FirmwareManagementParametersTest, LoadReadError) {
  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(Return(false));
  EXPECT_FALSE(fwmp_.Load());
}

// Load fails on space too small
TEST_F(FirmwareManagementParametersTest, LoadNvramTooSmall) {
  SecureBlob nvram_data(kContentsWithHash);

  nvram_data.erase(nvram_data.begin(), nvram_data.begin() + 1);

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(DoAll(SetArgPointee<1>(nvram_data), Return(true)));
  EXPECT_FALSE(fwmp_.Load());
}

// Load fails on bad struct size
TEST_F(FirmwareManagementParametersTest, LoadBadStructSize) {
  SecureBlob nvram_data(kContentsWithHash);

  // Alter struct size
  nvram_data[1]++;

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(DoAll(SetArgPointee<1>(nvram_data), Return(true)));
  EXPECT_FALSE(fwmp_.Load());
}

// Load fails on bad CRC
TEST_F(FirmwareManagementParametersTest, LoadBadCrc) {
  SecureBlob nvram_data(kContentsWithHash);

  // Alter CRC
  nvram_data[0] ^= 0x42;

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(DoAll(SetArgPointee<1>(nvram_data), Return(true)));
  EXPECT_FALSE(fwmp_.Load());
}

// Load allows different minor version
TEST_F(FirmwareManagementParametersTest, LoadMinorVersion) {
  SecureBlob nvram_data(kContentsWithHash);

  // Alter minor version
  nvram_data[2] += 1;

  // Recalculate CRC
  nvram_data[0] =
      crc8(nvram_data.data() + FirmwareManagementParameters::kCrcDataOffset,
           nvram_data.size() - FirmwareManagementParameters::kCrcDataOffset);

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(DoAll(SetArgPointee<1>(nvram_data), Return(true)));
  EXPECT_TRUE(fwmp_.Load());
}

// Load fails on different major version
TEST_F(FirmwareManagementParametersTest, LoadMajorVersion) {
  SecureBlob nvram_data(kContentsWithHash);

  // Alter major version
  nvram_data[2] += 0x10;

  // Recalculate CRC
  nvram_data[0] =
      crc8(nvram_data.data() + FirmwareManagementParameters::kCrcDataOffset,
           nvram_data.size() - FirmwareManagementParameters::kCrcDataOffset);

  EXPECT_CALL(tpm_, IsNvramDefined(FirmwareManagementParameters::kNvramIndex))
      .WillOnce(Return(true));
  EXPECT_CALL(tpm_, ReadNvram(FirmwareManagementParameters::kNvramIndex, _))
      .Times(1)
      .WillOnce(DoAll(SetArgPointee<1>(nvram_data), Return(true)));
  EXPECT_FALSE(fwmp_.Load());
}

class FirmwareManagementParametersPlatformIndexTest
    : public FirmwareManagementParametersTestBase<
          FirmwareManagementParameters::ResetMethod::kStoreDefaultFlags,
          FirmwareManagementParameters::WriteProtectionMethod::
              kOwnerAuthorization> {};

// Store flags and hash
TEST_F(FirmwareManagementParametersPlatformIndexTest, StoreFlagsAndHash) {
  SecureBlob nvram_data;
  SetExpectationForStore(&nvram_data);
  EXPECT_TRUE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data, kContentsWithHash);
}

// Store flags only
TEST_F(FirmwareManagementParametersPlatformIndexTest, StoreFlagsOnly) {
  SecureBlob nvram_data;
  fwmp_hash_ptr_ = nullptr;
  SetExpectationForStore(&nvram_data);
  EXPECT_TRUE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data, kContentsNoHash);
}

TEST_F(FirmwareManagementParametersPlatformIndexTest, CreateSetsDefaultFlags) {
  SecureBlob default_nvram_data;
  SetExpectationForStore(&default_nvram_data);
  EXPECT_TRUE(fwmp_.Store(/*flags=*/0, /*developer_key_hash=*/nullptr));
  EXPECT_TRUE(fwmp_.IsLoaded());

  // Modify the content of FWMP.
  SecureBlob nvram_data;
  SetExpectationForStore(&nvram_data);
  EXPECT_TRUE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data, kContentsWithHash);

  // `Create()` is supposed to write the default content.
  SetExpectationForStore(&nvram_data);
  EXPECT_TRUE(fwmp_.Create());
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data.to_string(), default_nvram_data.to_string());

  // Modify the content of FWMP again.
  SetExpectationForStore(&nvram_data);
  EXPECT_TRUE(fwmp_.Store(fwmp_flags_, fwmp_hash_ptr_));
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data, kContentsWithHash);

  // `Destroy()` is supposed to write the default content.
  SetExpectationForStore(&nvram_data);
  EXPECT_TRUE(fwmp_.Destroy());
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data.to_string(), default_nvram_data.to_string());
}

}  // namespace cryptohome
