// 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_mock.h>
#include <brillo/secure_blob.h>
#include <gtest/gtest.h>

#include "cryptohome/mock_firmware_management_parameters.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.
class FirmwareManagementParametersTest : public ::testing::Test {
 public:
  FirmwareManagementParametersTest() :
    fwmp_(&tpm_) { }
  virtual ~FirmwareManagementParametersTest() { }

  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_;
  }

  virtual void TearDown() { }

  // Perform an NVRAM store.
  // fwmp: FirmwareManagementParameters object to operate on.
  // nvram_data: destination for blob saved to NVRAM
  void DoStore(FirmwareManagementParameters* fwmp, 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));

      // Save blob that was written
      EXPECT_CALL(tpm_,
                  WriteNvram(FirmwareManagementParameters::kNvramIndex, _))
        .Times(1)
        .WillOnce(DoAll(SaveArg<1>(nvram_data), Return(true)));

      EXPECT_CALL(tpm_,
                  WriteLockNvram(FirmwareManagementParameters::kNvramIndex))
        .WillOnce(Return(true));
      EXPECT_CALL(tpm_,
                  IsNvramLocked(FirmwareManagementParameters::kNvramIndex))
        .WillOnce(Return(true));
    }
    EXPECT_TRUE(fwmp->Store(fwmp_flags_, fwmp_hash_ptr_));
  }

  // Populate the mock NVRAM with valid data.
  void GenerateNvramData(SecureBlob* nvram) {
    FirmwareManagementParameters throwaway_fwmp(NULL);
    DoStore(&throwaway_fwmp, nvram);
    Mock::VerifyAndClearExpectations(&tpm_);
  }

  static const char* kHashData;
  static brillo::SecureBlob kContentsWithHash;
  static brillo::SecureBlob kContentsNoHash;
  FirmwareManagementParameters fwmp_;
  NiceMock<MockTpm> tpm_;
  uint32_t fwmp_flags_;
  brillo::Blob fwmp_hash_;
  brillo::Blob* fwmp_hash_ptr_;

 private:
  DISALLOW_COPY_AND_ASSIGN(FirmwareManagementParametersTest);
};
const char* FirmwareManagementParametersTest::kHashData =
  "AxxxxxxxBxxxxxxxCxxxxxxxDxxxxxxE";
brillo::SecureBlob FirmwareManagementParametersTest::kContentsWithHash(
  {
    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'
  });
brillo::SecureBlob FirmwareManagementParametersTest::kContentsNoHash(
  {
    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
  });

//
// The actual tests!
//

// 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;
  DoStore(&fwmp_, &nvram_data);
  EXPECT_TRUE(fwmp_.IsLoaded());
  EXPECT_EQ(nvram_data, kContentsWithHash);
}

// Store flags only
TEST_F(FirmwareManagementParametersTest, StoreFlagsOnly) {
  SecureBlob nvram_data;
  fwmp_hash_ptr_ = NULL;
  DoStore(&fwmp_, &nvram_data);
  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 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::SecureBlob bad_hash("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());
}

}  // namespace cryptohome
