// Copyright (c) 2013 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 Lockbox.

#include "cryptohome/lockbox.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/cryptolib.h"
#include "cryptohome/mock_lockbox.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.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 Lockbox-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 LockboxTest : public ::testing::TestWithParam<Tpm::TpmVersion> {
 public:
  LockboxTest() : lockbox_(nullptr, 0xdeadbeef) {}
  ~LockboxTest() override = default;

  void SetUp() override {
    ON_CALL(tpm_, GetVersion()).WillByDefault(Return(GetParam()));

    // Create the OOBE data to reuse for post-boot tests.
    // This generates the expected NVRAM value and serialized file data.
    file_data_.assign(kFileData, kFileData + strlen(kFileData));
    lockbox_.set_tpm(&tpm_);
    lockbox_.set_process(&process_);
  }


  uint32_t GetExpectedNvramSpaceFlags() {
    switch (GetParam()) {
      case Tpm::TpmVersion::TPM_1_2:
        return Tpm::kTpmNvramWriteDefine | Tpm::kTpmNvramBindToPCR0;
      case Tpm::TpmVersion::TPM_2_0:
        return Tpm::kTpmNvramWriteDefine;
      case Tpm::TpmVersion::TPM_UNKNOWN:
        break;
    }
    NOTREACHED();
    return 0;
  }

  static const char* kFileData;
  Lockbox lockbox_;
  NiceMock<MockTpm> tpm_;
  NiceMock<brillo::ProcessMock> process_;
  brillo::Blob file_data_;

 private:
  DISALLOW_COPY_AND_ASSIGN(LockboxTest);
};

const char* LockboxTest::kFileData = "42";

TEST_P(LockboxTest, ResetTpmUnavailable) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(false));

  LockboxError error;
  EXPECT_FALSE(lockbox_.Reset(&error));
  EXPECT_EQ(error, LockboxError::kTpmUnavailable);
}

TEST_P(LockboxTest, ResetNoNvramSpace) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(false));

  LockboxError error;
  EXPECT_FALSE(lockbox_.Reset(&error));
  EXPECT_EQ(error, LockboxError::kNvramSpaceAbsent);
}

TEST_P(LockboxTest, ResetExistingSpaceUnlocked) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramLocked(0xdeadbeef)).WillOnce(Return(false));

  LockboxError error;
  EXPECT_TRUE(lockbox_.Reset(&error));
}

TEST_P(LockboxTest, ResetExistingSpaceLocked) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramLocked(0xdeadbeef)).WillOnce(Return(true));

  LockboxError error;
  EXPECT_FALSE(lockbox_.Reset(&error));
  EXPECT_EQ(error, LockboxError::kNvramInvalid);
}

TEST_P(LockboxTest, ResetCreateSpace) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));

  // Make the owner password available.
  static const char* kOwnerPassword = "sup";
  brillo::SecureBlob pw;
  pw.assign(kOwnerPassword, kOwnerPassword + strlen(kOwnerPassword));
  EXPECT_CALL(tpm_, GetOwnerPassword(_))
      .WillRepeatedly(DoAll(SetArgPointee<0>(pw), Return(true)));

  // No pre-existing space.
  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(false));

  // Create the new space.
  EXPECT_CALL(tpm_,
              DefineNvram(0xdeadbeef,
                          LockboxContents::GetNvramSize(NvramVersion::kDefault),
                          GetExpectedNvramSpaceFlags()))
      .WillOnce(Return(true));

  LockboxError error;
  EXPECT_TRUE(lockbox_.Reset(&error));
}

TEST_P(LockboxTest, ResetCreateSpacePreexisting) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));

  // Make the owner password available.
  static const char* kOwnerPassword = "sup";
  brillo::SecureBlob pw;
  pw.assign(kOwnerPassword, kOwnerPassword + strlen(kOwnerPassword));
  EXPECT_CALL(tpm_, GetOwnerPassword(_))
      .WillRepeatedly(DoAll(SetArgPointee<0>(pw), Return(true)));

  // Pre-existing space, expect the space to get destroyed.
  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(true));
  EXPECT_CALL(tpm_, DestroyNvram(0xdeadbeef)).WillOnce(Return(true));

  // Create the new space.
  EXPECT_CALL(tpm_,
              DefineNvram(0xdeadbeef,
                          LockboxContents::GetNvramSize(NvramVersion::kDefault),
                          GetExpectedNvramSpaceFlags()))
      .WillOnce(Return(true));

  LockboxError error;
  EXPECT_TRUE(lockbox_.Reset(&error));
}

TEST_P(LockboxTest, ResetNoOwnerAuth) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, GetOwnerPassword(_)).WillRepeatedly(Return(false));

  LockboxError error;
  EXPECT_FALSE(lockbox_.Reset(&error));
  EXPECT_EQ(error, LockboxError::kNvramSpaceAbsent);
}

TEST_P(LockboxTest, StoreOk) {
  brillo::SecureBlob key_material;
  switch (GetParam()) {
    case Tpm::TpmVersion::TPM_1_2:
      key_material.assign(static_cast<size_t>(NvramVersion::kDefault), 'A');
      break;
    case Tpm::TpmVersion::TPM_2_0:
      key_material.assign(static_cast<size_t>(NvramVersion::kDefault), 0);
      break;
    case Tpm::TpmVersion::TPM_UNKNOWN:
      NOTREACHED();
      break;
  }

  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));

  // Destroy calls with no file or existing NVRAM space.
  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(true));
  {
    InSequence s;
    EXPECT_CALL(tpm_, IsNvramLocked(0xdeadbeef)).WillOnce(Return(false));
    EXPECT_CALL(tpm_, GetNvramSize(0xdeadbeef))
        .WillOnce(
            Return(LockboxContents::GetNvramSize(NvramVersion::kDefault)));
    EXPECT_CALL(tpm_, GetRandomDataSecureBlob(key_material.size(), _))
        .WillRepeatedly(DoAll(SetArgPointee<1>(key_material), Return(true)));
    EXPECT_CALL(tpm_, WriteNvram(0xdeadbeef, _)).WillOnce(Return(true));
    EXPECT_CALL(tpm_, WriteLockNvram(0xdeadbeef)).WillRepeatedly(Return(true));
    EXPECT_CALL(tpm_, IsNvramLocked(0xdeadbeef)).WillOnce(Return(true));
  }
  EXPECT_CALL(process_, Reset(0)).Times(1);
  EXPECT_CALL(process_, AddArg("/usr/sbin/mount-encrypted")).Times(1);
  EXPECT_CALL(process_, AddArg("finalize")).Times(1);
  EXPECT_CALL(process_,
              AddArg(CryptoLib::SecureBlobToHex(
                         CryptoLib::Sha256(key_material))))
      .Times(1);
  EXPECT_CALL(process_, BindFd(_, 1)).Times(1);
  EXPECT_CALL(process_, BindFd(_, 2)).Times(1);
  EXPECT_CALL(process_, Run()).WillOnce(Return(0));

  LockboxError error;
  EXPECT_TRUE(lockbox_.Store(file_data_, &error));
}

TEST_P(LockboxTest, StoreLockedNvram) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramLocked(0xdeadbeef)).WillOnce(Return(true));

  LockboxError error;
  EXPECT_FALSE(lockbox_.Store(file_data_, &error));
  EXPECT_EQ(error, LockboxError::kNvramInvalid);
}

TEST_P(LockboxTest, StoreUnlockedNvramSizeBad) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));

  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(true));
  EXPECT_CALL(tpm_, IsNvramLocked(0xdeadbeef)).WillOnce(Return(false));
  EXPECT_CALL(tpm_, GetNvramSize(0xdeadbeef)).WillOnce(Return(0));

  LockboxError error;
  EXPECT_FALSE(lockbox_.Store(file_data_, &error));
  EXPECT_EQ(error, LockboxError::kNvramInvalid);
}

TEST_P(LockboxTest, StoreNoNvram) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(true));

  EXPECT_CALL(tpm_, IsNvramDefined(0xdeadbeef)).WillOnce(Return(false));

  LockboxError error;
  EXPECT_FALSE(lockbox_.Store(file_data_, &error));
  EXPECT_EQ(error, LockboxError::kNvramInvalid);
}

TEST_P(LockboxTest, StoreTpmNotReady) {
  EXPECT_CALL(tpm_, IsEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned()).WillRepeatedly(Return(false));

  LockboxError error;
  EXPECT_FALSE(lockbox_.Store(file_data_, &error));
  EXPECT_EQ(error, LockboxError::kNvramInvalid);
}

INSTANTIATE_TEST_CASE_P(LockboxTestTpm12,
                        LockboxTest,
                        testing::Values(Tpm::TpmVersion::TPM_1_2));
INSTANTIATE_TEST_CASE_P(LockboxTestTpm20,
                        LockboxTest,
                        testing::Values(Tpm::TpmVersion::TPM_2_0));

class LockboxContentsTest : public testing::Test {
 public:
  LockboxContentsTest() = default;

  void GenerateNvramData(NvramVersion version, brillo::SecureBlob* nvram_data) {
    std::unique_ptr<LockboxContents> contents =
        LockboxContents::New(LockboxContents::GetNvramSize(version));
    ASSERT_TRUE(contents);
    ASSERT_TRUE(contents->SetKeyMaterial(
        brillo::SecureBlob(contents->key_material_size(), 'A')));
    ASSERT_TRUE(contents->Protect({42}));
    ASSERT_TRUE(contents->Encode(nvram_data));
  }

  void LoadAndVerify(const brillo::SecureBlob& nvram_data,
                     const brillo::Blob& data,
                     LockboxContents::VerificationResult expected_result) {
    std::unique_ptr<LockboxContents> contents =
        LockboxContents::New(nvram_data.size());
    ASSERT_TRUE(contents);
    ASSERT_TRUE(contents->Decode(nvram_data));
    EXPECT_EQ(expected_result, contents->Verify(data));
  }
};

TEST_F(LockboxContentsTest, LoadAndVerifyOkTpmDefault) {
  brillo::SecureBlob nvram_data;
  ASSERT_NO_FATAL_FAILURE(
      GenerateNvramData(NvramVersion::kDefault, &nvram_data));
  LoadAndVerify(nvram_data, {42}, LockboxContents::VerificationResult::kValid);
}

TEST_F(LockboxContentsTest, LoadAndVerifyOkTpmV1) {
  brillo::SecureBlob nvram_data;
  ASSERT_NO_FATAL_FAILURE(
      GenerateNvramData(NvramVersion::kVersion1, &nvram_data));
  LoadAndVerify(nvram_data, {42}, LockboxContents::VerificationResult::kValid);
}

TEST_F(LockboxContentsTest, LoadAndVerifyOkTpmV2) {
  brillo::SecureBlob nvram_data;
  ASSERT_NO_FATAL_FAILURE(
      GenerateNvramData(NvramVersion::kVersion2, &nvram_data));
  LoadAndVerify(nvram_data, {42}, LockboxContents::VerificationResult::kValid);
}

TEST_F(LockboxContentsTest, LoadAndVerifyBadSize) {
  SecureBlob nvram_data;
  ASSERT_NO_FATAL_FAILURE(
      GenerateNvramData(NvramVersion::kVersion2, &nvram_data));

  // Change the expected file size to 0.
  nvram_data[0] = 0;
  nvram_data[1] = 0;
  nvram_data[2] = 0;
  nvram_data[3] = 0;

  LoadAndVerify(nvram_data, {42},
                LockboxContents::VerificationResult::kSizeMismatch);
}

TEST_F(LockboxContentsTest, LoadAndVerifyBadHash) {
  SecureBlob nvram_data;
  ASSERT_NO_FATAL_FAILURE(
      GenerateNvramData(NvramVersion::kVersion2, &nvram_data));

  // Invalidate the hash.
  nvram_data.back() ^= 0xff;

  LoadAndVerify(nvram_data, {42},
                LockboxContents::VerificationResult::kHashMismatch);
}

TEST_F(LockboxContentsTest, LoadAndVerifyBadData) {
  SecureBlob nvram_data;
  ASSERT_NO_FATAL_FAILURE(
      GenerateNvramData(NvramVersion::kVersion2, &nvram_data));
  LoadAndVerify(nvram_data, {17},
                LockboxContents::VerificationResult::kHashMismatch);
}

}  // namespace cryptohome
