// Copyright 2020 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/tpm_initializer_impl.h"

#include <libhwsec/test_utils/tpm1/test_fixture.h>

#include "tpm_manager/common/typedefs.h"
#include "tpm_manager/server/mock_local_data_store.h"
#include "tpm_manager/server/mock_openssl_crypto_util.h"
#include "tpm_manager/server/mock_tpm_status.h"

namespace tpm_manager {

namespace {

using testing::_;
using testing::DoAll;
using testing::NiceMock;
using testing::Return;
using testing::SetArgPointee;

constexpr TSS_HCONTEXT kFakeContext = 99999;
constexpr TSS_HTPM kFakeTpm = 66666;

}  // namespace

class TpmInitializerTest : public ::hwsec::Tpm1HwsecTest {
 public:
  TpmInitializerTest()
      : tpm_initializer_(
            &mock_data_store_, &mock_tpm_status_, ownership_callback_),
        fake_local_data_(mock_data_store_.GetMutableFakeData()) {
    ON_CALL_OVERALLS(Ospi_Context_Create(_))
        .WillByDefault(
            DoAll(SetArgPointee<0>(kFakeContext), Return(TSS_SUCCESS)));
    ON_CALL_OVERALLS(Ospi_Context_GetTpmObject(_, _))
        .WillByDefault(DoAll(SetArgPointee<1>(kFakeTpm), Return(TSS_SUCCESS)));
  }
  ~TpmInitializerTest() override = default;

 protected:
  NiceMock<MockLocalDataStore> mock_data_store_;
  NiceMock<MockTpmStatus> mock_tpm_status_;
  OwnershipTakenCallBack ownership_callback_;
  TpmInitializerImpl tpm_initializer_;
  // Holds a reference of the internal |LocalData| of |mock_data_store_|.
  LocalData& fake_local_data_;
};

TEST_F(TpmInitializerTest, DAResetSuccess) {
  EXPECT_CALL(mock_tpm_status_, CheckAndNotifyIfTpmOwned(_))
      .WillOnce(DoAll(SetArgPointee<0>(TpmStatus::kTpmOwned), Return(true)));
  fake_local_data_.mutable_owner_delegate()->set_blob("blob");
  fake_local_data_.mutable_owner_delegate()->set_secret("secret");
  fake_local_data_.mutable_owner_delegate()->set_has_reset_lock_permissions(
      true);
  EXPECT_CALL_OVERALLS(Ospi_TPM_SetStatus(_, TSS_TPMSTATUS_RESETLOCK, _))
      .WillOnce(Return(TSS_SUCCESS));
  EXPECT_EQ(tpm_initializer_.ResetDictionaryAttackLock(),
            DictionaryAttackResetStatus::kResetAttemptSucceeded);
}

TEST_F(TpmInitializerTest, DAResetSuccessWithOwnerPassword) {
  EXPECT_CALL(mock_tpm_status_, CheckAndNotifyIfTpmOwned(_))
      .WillOnce(DoAll(SetArgPointee<0>(TpmStatus::kTpmOwned), Return(true)));
  fake_local_data_.set_owner_password("owner password");
  EXPECT_CALL_OVERALLS(Ospi_TPM_SetStatus(_, TSS_TPMSTATUS_RESETLOCK, _))
      .WillOnce(Return(TSS_SUCCESS));
  EXPECT_EQ(tpm_initializer_.ResetDictionaryAttackLock(),
            DictionaryAttackResetStatus::kResetAttemptSucceeded);
}

TEST_F(TpmInitializerTest, DAResetNoAuth) {
  EXPECT_CALL(mock_tpm_status_, CheckAndNotifyIfTpmOwned(_))
      .WillOnce(DoAll(SetArgPointee<0>(TpmStatus::kTpmOwned), Return(true)));
  EXPECT_EQ(tpm_initializer_.ResetDictionaryAttackLock(),
            DictionaryAttackResetStatus::kDelegateNotAvailable);
}

TEST_F(TpmInitializerTest, DAResetDelegateNoPermission) {
  EXPECT_CALL(mock_tpm_status_, CheckAndNotifyIfTpmOwned(_))
      .WillOnce(DoAll(SetArgPointee<0>(TpmStatus::kTpmOwned), Return(true)));
  fake_local_data_.mutable_owner_delegate()->set_blob("blob");
  fake_local_data_.mutable_owner_delegate()->set_secret("secret");
  fake_local_data_.mutable_owner_delegate()->set_has_reset_lock_permissions(
      false);
  EXPECT_EQ(tpm_initializer_.ResetDictionaryAttackLock(),
            DictionaryAttackResetStatus::kDelegateNotAllowed);
}

TEST_F(TpmInitializerTest, DAResetFailed) {
  EXPECT_CALL(mock_tpm_status_, CheckAndNotifyIfTpmOwned(_))
      .WillOnce(DoAll(SetArgPointee<0>(TpmStatus::kTpmOwned), Return(true)));
  fake_local_data_.mutable_owner_delegate()->set_blob("blob");
  fake_local_data_.mutable_owner_delegate()->set_secret("secret");
  fake_local_data_.mutable_owner_delegate()->set_has_reset_lock_permissions(
      true);
  EXPECT_CALL_OVERALLS(Ospi_TPM_SetStatus(_, TSS_TPMSTATUS_RESETLOCK, _))
      .WillOnce(Return(TPM_ERROR(TPM_E_BAD_PARAMETER)));
  EXPECT_EQ(tpm_initializer_.ResetDictionaryAttackLock(),
            DictionaryAttackResetStatus::kResetAttemptFailed);
}

TEST_F(TpmInitializerTest, DAResetFailedFailedAuthNoRepeat) {
  EXPECT_CALL(mock_tpm_status_, CheckAndNotifyIfTpmOwned(_))
      .WillOnce(DoAll(SetArgPointee<0>(TpmStatus::kTpmOwned), Return(true)));
  fake_local_data_.mutable_owner_delegate()->set_blob("blob");
  fake_local_data_.mutable_owner_delegate()->set_secret("secret");
  fake_local_data_.mutable_owner_delegate()->set_has_reset_lock_permissions(
      true);
  EXPECT_CALL_OVERALLS(Ospi_TPM_SetStatus(_, TSS_TPMSTATUS_RESETLOCK, _))
      .WillOnce(Return(TPM_ERROR(TPM_E_AUTHFAIL)));
  EXPECT_EQ(tpm_initializer_.ResetDictionaryAttackLock(),
            DictionaryAttackResetStatus::kResetAttemptFailed);
  // Makes sure the bad auth is flagged.
  EXPECT_CALL(mock_tpm_status_, CheckAndNotifyIfTpmOwned(_)).Times(0);
  EXPECT_EQ(tpm_initializer_.ResetDictionaryAttackLock(),
            DictionaryAttackResetStatus::kResetAttemptFailed);
}

TEST_F(TpmInitializerTest, DAResetFailedWrongPcr0) {
  EXPECT_CALL(mock_tpm_status_, CheckAndNotifyIfTpmOwned(_))
      .WillOnce(DoAll(SetArgPointee<0>(TpmStatus::kTpmOwned), Return(true)));
  fake_local_data_.mutable_owner_delegate()->set_blob("blob");
  fake_local_data_.mutable_owner_delegate()->set_secret("secret");
  fake_local_data_.mutable_owner_delegate()->set_has_reset_lock_permissions(
      true);
  EXPECT_CALL_OVERALLS(Ospi_TPM_SetStatus(_, TSS_TPMSTATUS_RESETLOCK, _))
      .WillOnce(Return(TPM_ERROR(TPM_E_WRONGPCRVAL)));
  EXPECT_EQ(tpm_initializer_.ResetDictionaryAttackLock(),
            DictionaryAttackResetStatus::kInvalidPcr0State);
}

}  // namespace tpm_manager
