// 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 "tpm_manager/server/local_data_migration.h"

#include <attestation/proto_bindings/attestation_ca.pb.h>
#include <base/check.h>
#include <base/files/file_path.h>
#include <brillo/secure_blob.h>
#include <crypto/scoped_openssl_types.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <libtpmcrypto/tpm.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <unordered_map>
#include <utility>

#include "tpm_manager/proto_bindings/tpm_manager.pb.h"
#include "tpm_manager/server/legacy_local_data.pb.h"

namespace {

constexpr size_t kAesKeySize = 32;
constexpr size_t kAesBlockSize = 16;
constexpr char kIVForTest[kAesBlockSize + 1] = "I'm your father.";
constexpr char kAesKeyForTest[kAesKeySize + 1] =
    "NOOOOOOOOOOOOOOO~!!!!!!!!!!!!!!!";
constexpr char kNonNullPointerCheckFailedRegex[] =
    R"(Check failed: ([a-z_]+ != nullptr))";

// The following few functions are simplied to minimum from
// "attestation/common/crypto_utility_impl.cc" so we can decrypt the encrypted
// database. So far it's okay to have duplicated utility functions as those in
// |local_data_migration.cc| because it's only for testing purpose and one day
// the shared code should be put in a common library.
//
// TODO(cylai): replace this with calls to commmon library once we have a
// library shared across all hwsec daemons.
unsigned char* SecureBlobAsSSLBuffer(const brillo::SecureBlob& blob) {
  return static_cast<unsigned char*>(
      const_cast<brillo::SecureBlob::value_type*>(blob.data()));
}

bool AesEncrypt(const EVP_CIPHER* cipher,
                const brillo::SecureBlob& data,
                const brillo::SecureBlob& key,
                const brillo::SecureBlob& iv,
                brillo::SecureBlob* encrypted_data) {
  if (key.size() != static_cast<size_t>(EVP_CIPHER_key_length(cipher)) ||
      iv.size() != kAesBlockSize) {
    return false;
  }
  if (data.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
    // EVP_EncryptUpdate takes a signed int.
    return false;
  }
  unsigned char* input_buffer = SecureBlobAsSSLBuffer(data);
  unsigned char* key_buffer = SecureBlobAsSSLBuffer(key);
  unsigned char* iv_buffer = SecureBlobAsSSLBuffer(iv);
  // Allocate enough space for the output (including padding).
  encrypted_data->resize(data.size() + kAesBlockSize);
  unsigned char* output_buffer = SecureBlobAsSSLBuffer(*encrypted_data);
  int output_size = 0;
  crypto::ScopedEVP_CIPHER_CTX encryption_context(EVP_CIPHER_CTX_new());
  if (!encryption_context) {
    return false;
  }
  if (!EVP_EncryptInit_ex(encryption_context.get(), cipher, nullptr, key_buffer,
                          iv_buffer)) {
    return false;
  }
  if (!EVP_EncryptUpdate(encryption_context.get(), output_buffer, &output_size,
                         input_buffer, data.size())) {
    return false;
  }
  size_t total_size = output_size;
  output_buffer += output_size;
  output_size = 0;
  if (!EVP_EncryptFinal_ex(encryption_context.get(), output_buffer,
                           &output_size)) {
    return false;
  }
  total_size += output_size;
  encrypted_data->resize(total_size);
  return true;
}

brillo::SecureBlob HmacSha512(const brillo::SecureBlob& key,
                              const brillo::SecureBlob& data) {
  brillo::SecureBlob mac;
  mac.resize(SHA512_DIGEST_LENGTH);
  HMAC(EVP_sha512(), SecureBlobAsSSLBuffer(key), key.size(),
       SecureBlobAsSSLBuffer(data), data.size(), mac.data(), nullptr);
  return mac;
}

bool EncryptLegacyAttestationDatabase(
    const tpm_manager::LegacyAttestationDatabase& database,
    tpmcrypto::Tpm* tpm,
    brillo::SecureBlob* serialized_encrypted_data) {
  std::string serialized_database = database.SerializeAsString();
  if (serialized_database.empty()) {
    return false;
  }
  attestation::EncryptedData encrypted_data;
  brillo::SecureBlob wrapped_key;
  if (!tpm->SealToPCR0(brillo::SecureBlob(std::string(kAesKeyForTest)),
                       &wrapped_key)) {
    return false;
  }
  encrypted_data.set_wrapped_key(wrapped_key.to_string());
  brillo::SecureBlob encrypted_output;
  if (!AesEncrypt(EVP_aes_256_cbc(), brillo::SecureBlob(serialized_database),
                  brillo::SecureBlob(std::string(kAesKeyForTest)),
                  brillo::SecureBlob(std::string(kIVForTest)),
                  &encrypted_output)) {
    return false;
  }
  encrypted_data.set_encrypted_data(encrypted_output.to_string());
  encrypted_data.set_iv(kIVForTest);
  encrypted_data.set_mac(
      HmacSha512(
          brillo::SecureBlob(std::string(kAesKeyForTest)),
          brillo::SecureBlob::Combine(
              brillo::SecureBlob(std::string(kIVForTest)), encrypted_output))
          .to_string());
  serialized_encrypted_data->resize(encrypted_data.ByteSizeLong());
  encrypted_data.SerializeWithCachedSizesToArray(
      serialized_encrypted_data->data());
  return true;
}

// A fake implementation of |Tpm| to emulate the behavior of sealing/unsealing
// operation by a real TPM object. The sealing and unsealing are emulated by
// reversing the content.
//
// TODO(cylai): implement a mock class in |tpmcrypto| project instead so the
// faking/mocking logic can be shared in a better way.
class FakeTpm : public tpmcrypto::Tpm {
 public:
  FakeTpm() = default;
  FakeTpm(const FakeTpm&) = delete;
  FakeTpm& operator=(const FakeTpm&) = delete;

  ~FakeTpm() override = default;

  bool SealToPCR0(const brillo::SecureBlob& value,
                  brillo::SecureBlob* sealed_value) override {
    CHECK(sealed_value);
    return Reverse(value, sealed_value);
  }

  bool Unseal(const brillo::SecureBlob& sealed_value,
              brillo::SecureBlob* value) override {
    CHECK(value);
    return !is_failure_mode_ && Reverse(sealed_value, value);
  }

  bool GetNVAttributes(uint32_t index, uint32_t* attributes) override {
    return true;
  }

  bool NVReadNoAuth(uint32_t index,
                    uint32_t offset,
                    size_t size,
                    std::string* data) override {
    return true;
  }

  // TODO(cylai): as the TODO above, determine if gmock is a more decent
  // choice.
  void SetIsFailureMode(bool flag) { is_failure_mode_ = flag; }

 private:
  bool Reverse(const brillo::SecureBlob& input, brillo::SecureBlob* output) {
    output->assign(input.rbegin(), input.rend());
    return true;
  }
  bool is_failure_mode_{false};
};

MATCHER_P(
    EqualsDelegate,
    d,
    "Compares |arg| against |d| regardless of their protobuf types as long as "
    "they have both have |blob|, |secret|, and |has_reset_lock_permissions| "
    "fields.") {
  return arg.blob() == d.blob() && arg.secret() == d.secret() &&
         arg.has_reset_lock_permissions() == d.has_reset_lock_permissions();
}

brillo::SecureBlob GenerateInvalidSerializedMessage() {
  return brillo::SecureBlob(128, 0);
}

std::string SealString(const std::string& s, tpmcrypto::Tpm* tpm) {
  brillo::SecureBlob output;
  CHECK(tpm->SealToPCR0(brillo::SecureBlob(s), &output));
  return output.to_string();
}

}  // namespace

namespace tpm_manager {

TEST(LocalDataMigrationTest, MigrateAuthDelegateDecrypt) {
  FakeTpm fake_tpm;
  LegacyAttestationDatabase expected_database;
  expected_database.mutable_delegate()->set_blob("blob");
  expected_database.mutable_delegate()->set_secret("secret");
  expected_database.mutable_delegate()->set_has_reset_lock_permissions(true);
  brillo::SecureBlob encrypted_database;
  ASSERT_TRUE(EncryptLegacyAttestationDatabase(expected_database, &fake_tpm,
                                               &encrypted_database));

  AuthDelegate result_delegate;
  EXPECT_TRUE(
      MigrateAuthDelegate(encrypted_database, &fake_tpm, &result_delegate));
  EXPECT_THAT(result_delegate, EqualsDelegate(expected_database.delegate()));

  fake_tpm.SetIsFailureMode(true);
  EXPECT_FALSE(
      MigrateAuthDelegate(encrypted_database, &fake_tpm, &result_delegate));
}

TEST(LocalDataMigrationTest, MigrateAuthDelegateInvalidParameter) {
  FakeTpm fake_tpm;
  AuthDelegate result_delegate;

  EXPECT_DEATH(
      MigrateAuthDelegate(brillo::SecureBlob{}, nullptr, &result_delegate),
      kNonNullPointerCheckFailedRegex);
  EXPECT_DEATH(MigrateAuthDelegate(brillo::SecureBlob{}, &fake_tpm, nullptr),
               kNonNullPointerCheckFailedRegex);

  brillo::SecureBlob invalid_encrypted_database =
      GenerateInvalidSerializedMessage();
  EXPECT_FALSE(MigrateAuthDelegate(invalid_encrypted_database, &fake_tpm,
                                   &result_delegate));
}

TEST(LocalDataMigrationTest, UnsealOwnerPasswordFromSerializedTpmStatus) {
  LegacyTpmStatus expected_tpm_status;
  FakeTpm fake_tpm;
  expected_tpm_status.set_owner_password(
      SealString("owner password", &fake_tpm));
  brillo::SecureBlob serialized_tpm_status(expected_tpm_status.ByteSizeLong());
  ASSERT_TRUE(expected_tpm_status.SerializeWithCachedSizesToArray(
      serialized_tpm_status.data()));
  brillo::SecureBlob owner_password;
  EXPECT_TRUE(UnsealOwnerPasswordFromSerializedTpmStatus(
      serialized_tpm_status, &fake_tpm, &owner_password));
  EXPECT_EQ(owner_password.to_string(), "owner password");

  fake_tpm.SetIsFailureMode(true);
  EXPECT_FALSE(UnsealOwnerPasswordFromSerializedTpmStatus(
      serialized_tpm_status, &fake_tpm, &owner_password));
  fake_tpm.SetIsFailureMode(false);

  EXPECT_DEATH(UnsealOwnerPasswordFromSerializedTpmStatus(brillo::SecureBlob{},
                                                          &fake_tpm, nullptr),
               kNonNullPointerCheckFailedRegex);
  EXPECT_DEATH(UnsealOwnerPasswordFromSerializedTpmStatus(
                   brillo::SecureBlob{}, nullptr, &owner_password),
               kNonNullPointerCheckFailedRegex);

  EXPECT_FALSE(UnsealOwnerPasswordFromSerializedTpmStatus(
      GenerateInvalidSerializedMessage(), &fake_tpm, &owner_password));
}

// A subclass of |LocalDataMigrator| with the file I/O faked with access of a
// hash table.
class LocalDataMigratorWithFakeFile : public LocalDataMigrator {
 public:
  using FileContentMap = std::unordered_map<std::string, std::string>;
  LocalDataMigratorWithFakeFile() = default;
  ~LocalDataMigratorWithFakeFile() override = default;

  // Updates the entry in |file_content_map_| with |path| as the key and
  // |content| as the value.
  void SetFakeFileContent(std::string path, std::string content) {
    auto result = file_content_map_.emplace(path, content);
    if (!result.second) {
      result.first->second = std::move(content);
    }
  }

  // Removes |path| from |file_content_map_|. Return |true| iff the entry is
  // erased.
  bool RemoveFakeFileContent(const std::string& path) {
    return file_content_map_.erase(path) > 0;
  }

  // Switches the behavior of the fake file reading operation. When
  // |is_failure_mode| is |false|, the content is read from |file_content_map_|;
  // when |is_failure_mode| is |true|, the file reading operation always fails.
  void SetIsFailureModeForRead(bool is_failure_mode) {
    is_failure_mode_ = is_failure_mode;
  }

 protected:
  FileContentMap file_content_map_;
  bool is_failure_mode_{false};

  bool PathExists(const base::FilePath& path) override {
    return file_content_map_.count(path.value()) > 0;
  }

  // Fake file reading operation; see |SetIsFailureModeForRead|.
  bool ReadFileToString(const base::FilePath& path,
                        std::string* content) override {
    if (is_failure_mode_) {
      return false;
    }
    auto result = file_content_map_.find(path.value());
    if (result == file_content_map_.end()) {
      return false;
    }
    *content = result->second;
    return true;
  }
};

TEST(LocalDataMigratorTest, MigrateAuthDelegateIfNeeded) {
  FakeTpm fake_tpm;
  LocalDataMigratorWithFakeFile migrator;
  LocalData local_data;

  const base::FilePath fake_path("fake path");
  const base::FilePath non_existent_path("non existent path");

  bool has_migrated;
  EXPECT_DEATH(migrator.MigrateAuthDelegateIfNeeded(non_existent_path, nullptr,
                                                    &local_data, &has_migrated),
               kNonNullPointerCheckFailedRegex);
  EXPECT_DEATH(migrator.MigrateAuthDelegateIfNeeded(
                   non_existent_path, &fake_tpm, nullptr, &has_migrated),
               kNonNullPointerCheckFailedRegex);
  EXPECT_DEATH(migrator.MigrateAuthDelegateIfNeeded(
                   non_existent_path, &fake_tpm, &local_data, nullptr),
               kNonNullPointerCheckFailedRegex);

  EXPECT_TRUE(migrator.MigrateAuthDelegateIfNeeded(non_existent_path, &fake_tpm,
                                                   &local_data, &has_migrated));
  EXPECT_FALSE(has_migrated);

  LegacyAttestationDatabase expected_database;
  expected_database.mutable_delegate()->set_blob("blob");
  expected_database.mutable_delegate()->set_secret("secret");
  expected_database.mutable_delegate()->set_has_reset_lock_permissions(true);
  brillo::SecureBlob encrypted_database;
  ASSERT_TRUE(EncryptLegacyAttestationDatabase(expected_database, &fake_tpm,
                                               &encrypted_database));
  migrator.SetFakeFileContent(fake_path.value(),
                              encrypted_database.to_string());

  fake_tpm.SetIsFailureMode(true);
  EXPECT_FALSE(migrator.MigrateAuthDelegateIfNeeded(
      fake_path, &fake_tpm, &local_data, &has_migrated));
  fake_tpm.SetIsFailureMode(false);

  migrator.SetIsFailureModeForRead(true);
  EXPECT_FALSE(migrator.MigrateAuthDelegateIfNeeded(
      fake_path, &fake_tpm, &local_data, &has_migrated));
  migrator.SetIsFailureModeForRead(false);

  EXPECT_TRUE(migrator.MigrateAuthDelegateIfNeeded(fake_path, &fake_tpm,
                                                   &local_data, &has_migrated));
  EXPECT_TRUE(has_migrated);
  EXPECT_THAT(local_data.owner_delegate(),
              EqualsDelegate(expected_database.delegate()));

  // Checks if the migration does no-ops if the data exist at both sides
  local_data.mutable_owner_delegate()->set_blob("another blob");
  local_data.mutable_owner_delegate()->set_secret("another secret");
  const LocalData local_data_before_migration_again = local_data;
  EXPECT_TRUE(migrator.MigrateAuthDelegateIfNeeded(fake_path, &fake_tpm,
                                                   &local_data, &has_migrated));
  EXPECT_FALSE(has_migrated);
  EXPECT_THAT(
      local_data.owner_delegate(),
      EqualsDelegate(local_data_before_migration_again.owner_delegate()));
}

TEST(LocalDataMigratorTest, MigrateOwnerPasswordIfNeeded) {
  LocalDataMigratorWithFakeFile migrator;
  LocalData local_data;
  FakeTpm fake_tpm;
  const base::FilePath fake_path("fake path");
  const base::FilePath non_existent_path("non existent path");
  bool has_migrated;

  EXPECT_DEATH(migrator.MigrateOwnerPasswordIfNeeded(
                   non_existent_path, &fake_tpm, nullptr, &has_migrated),
               kNonNullPointerCheckFailedRegex);
  EXPECT_DEATH(migrator.MigrateOwnerPasswordIfNeeded(
                   non_existent_path, &fake_tpm, &local_data, nullptr),
               kNonNullPointerCheckFailedRegex);
  EXPECT_TRUE(migrator.MigrateOwnerPasswordIfNeeded(
      non_existent_path, &fake_tpm, &local_data, &has_migrated));
  EXPECT_FALSE(has_migrated);

  LegacyTpmStatus expected_tpm_status;
  expected_tpm_status.set_owner_password(
      SealString("owner password", &fake_tpm));
  brillo::SecureBlob serialized_tpm_status(expected_tpm_status.ByteSizeLong());
  ASSERT_TRUE(expected_tpm_status.SerializeWithCachedSizesToArray(
      serialized_tpm_status.data()));

  migrator.SetFakeFileContent(fake_path.value(),
                              GenerateInvalidSerializedMessage().to_string());
  EXPECT_FALSE(migrator.MigrateOwnerPasswordIfNeeded(
      fake_path, &fake_tpm, &local_data, &has_migrated));

  migrator.SetFakeFileContent(fake_path.value(),
                              serialized_tpm_status.to_string());
  migrator.SetIsFailureModeForRead(true);
  EXPECT_FALSE(migrator.MigrateOwnerPasswordIfNeeded(
      fake_path, &fake_tpm, &local_data, &has_migrated));

  migrator.SetIsFailureModeForRead(false);
  EXPECT_TRUE(migrator.MigrateOwnerPasswordIfNeeded(
      fake_path, &fake_tpm, &local_data, &has_migrated));
  EXPECT_TRUE(has_migrated);
  EXPECT_EQ(local_data.owner_password(), "owner password");

  // Checks if the migration does no-ops if the data exist at both sides
  local_data.set_owner_password(
      SealString("another owner password", &fake_tpm));
  const LocalData local_data_before_migration_again = local_data;
  EXPECT_TRUE(migrator.MigrateOwnerPasswordIfNeeded(
      fake_path, &fake_tpm, &local_data, &has_migrated));
  EXPECT_FALSE(has_migrated);
  EXPECT_EQ(local_data.owner_password(),
            local_data_before_migration_again.owner_password());
}

}  //  namespace tpm_manager
