// Copyright 2018 The Fuchsia 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 "security_manager.h"

#include <cstdlib>

#include <fbl/macros.h>

#include "src/connectivity/bluetooth/core/bt-host/common/random.h"
#include "src/connectivity/bluetooth/core/bt-host/common/status.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/gap.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/connection.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/fake_connection.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/link_key.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/status.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_channel_test.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/ecdh_key.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/packet.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/smp.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/status.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/types.h"
#include "util.h"

namespace bt::sm {
namespace {

const DeviceAddress kLocalAddr(DeviceAddress::Type::kLEPublic,
                               {0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1});
const DeviceAddress kPeerAddr(DeviceAddress::Type::kLERandom, {0xB6, 0xB5, 0xB4, 0xB3, 0xB2, 0xB1});

const PairingRandomValue kHardCodedPairingRandom = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
                                                    0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};

class SMP_SecurityManagerTest : public l2cap::testing::FakeChannelTest, public sm::Delegate {
 public:
  SMP_SecurityManagerTest() : weak_ptr_factory_(this) {}
  ~SMP_SecurityManagerTest() override = default;

 protected:
  void TearDown() override {
    RunLoopUntilIdle();
    DestroySecurityManager();
  }

  void NewSecurityManager(Role role, IOCapability ioc, BondableMode bondable_mode) {
    // Setup fake SMP channel.
    ChannelOptions options(l2cap::kLESMPChannelId);
    fake_chan_ = CreateFakeChannel(options);
    fake_chan_->SetSendCallback(fit::bind_member(this, &SMP_SecurityManagerTest::OnDataReceived),
                                dispatcher());

    // Setup a fake logical link.
    auto link_role =
        role == Role::kInitiator ? hci::Connection::Role::kMaster : hci::Connection::Role::kSlave;
    fake_link_ = std::make_unique<hci::testing::FakeConnection>(1, hci::Connection::LinkType::kLE,
                                                                link_role, kLocalAddr, kPeerAddr);

    pairing_ = SecurityManager::Create(fake_link_->WeakPtr(), fake_chan_, ioc,
                                       weak_ptr_factory_.GetWeakPtr(), bondable_mode,
                                       gap::LeSecurityMode::Mode1);
  }

  void DestroySecurityManager() { pairing_ = nullptr; }

  // sm::Delegate override:
  void ConfirmPairing(ConfirmCallback confirm) override {
    if (confirm_delegate_) {
      confirm_delegate_(std::move(confirm));
    } else {
      confirm(true);
    }
  }

  // sm::Delegate override:
  void DisplayPasskey(uint32_t passkey, DisplayMethod method, ConfirmCallback confirm) override {
    if (display_delegate_) {
      display_delegate_(passkey, method, std::move(confirm));
    } else {
      ADD_FAILURE() << "No passkey display delegate set for " << util::DisplayMethodToString(method)
                    << " pairing";
    }
  }

  // sm::Delegate override:
  void RequestPasskey(PasskeyResponseCallback respond) override {
    if (request_passkey_delegate_) {
      request_passkey_delegate_(std::move(respond));
    } else {
      ADD_FAILURE() << "No passkey entry delegate set for passkey entry pairing";
    }
  }

  std::optional<IdentityInfo> OnIdentityInformationRequest() override {
    local_id_info_callback_count_++;
    return local_id_info_;
  }

  // Called by |pairing_| when the pairing procedure ends.
  void OnPairingComplete(Status status) override {
    pairing_complete_count_++;
    pairing_complete_status_ = status;
  }

  // Called by |pairing_| when a new LTK is obtained.
  void OnNewPairingData(const PairingData& pairing_data) override {
    pairing_data_callback_count_++;
    pairing_data_ = pairing_data;
  }

  // Called by |pairing_| when any encryption procedure fails.
  void OnAuthenticationFailure(hci::Status status) override {
    auth_failure_callback_count_++;
    auth_failure_status_ = status;
  }

  // Called by |pairing_| when the link security properties change.
  void OnNewSecurityProperties(const SecurityProperties& sec) override {
    new_sec_props_count_++;
    new_sec_props_ = sec;
  }

  void UpgradeSecurity(SecurityLevel level) {
    ZX_DEBUG_ASSERT(pairing_);
    pairing_->UpgradeSecurity(level, [this](auto status, const auto& props) {
      security_callback_count_++;
      security_status_ = status;
      sec_props_ = props;
    });
  }

  // Called when SMP sends a packet over the fake channel.
  void OnDataReceived(std::unique_ptr<const ByteBuffer> packet) {
    ZX_DEBUG_ASSERT(packet);

    PacketReader reader(packet.get());
    switch (reader.code()) {
      case kPairingFailed:
        pairing_failed_count_++;
        received_error_code_ = reader.payload<PairingFailedParams>();
        break;
      case kSecurityRequest:
        security_request_count_++;
        security_auth_req_ = reader.payload<AuthReqField>();
        break;
      case kPairingRequest:
        pairing_request_count_++;
        packet->Copy(&local_pairing_cmd_);
        break;
      case kPairingResponse:
        pairing_response_count_++;
        packet->Copy(&local_pairing_cmd_);
        break;
      case kPairingPublicKey:
        pairing_public_key_count_++;
        public_ecdh_key_ = EcdhKey::ParseFromPublicKey(reader.payload<PairingPublicKeyParams>());
        break;
      case kPairingConfirm:
        pairing_confirm_count_++;
        pairing_confirm_ = reader.payload<PairingConfirmValue>();
        break;
      case kPairingRandom:
        pairing_random_count_++;
        pairing_random_ = reader.payload<PairingRandomValue>();
        break;
      case kPairingDHKeyCheck:
        pairing_dhkey_check_count_++;
        pairing_dhkey_check_ = reader.payload<PairingDHKeyCheckValueE>();
        break;
      case kEncryptionInformation:
        enc_info_count_++;
        enc_info_ = reader.payload<EncryptionInformationParams>();
        break;
      case kMasterIdentification: {
        const auto& params = reader.payload<MasterIdentificationParams>();
        master_ident_count_++;
        ediv_ = le16toh(params.ediv);
        rand_ = le64toh(params.rand);
        break;
      }
      case kIdentityInformation:
        id_info_count_++;
        id_info_ = reader.payload<UInt128>();
        break;
      case kIdentityAddressInformation: {
        const auto& params = reader.payload<IdentityAddressInformationParams>();
        id_addr_info_count_++;
        id_addr_info_ = DeviceAddress(params.type == AddressType::kStaticRandom
                                          ? DeviceAddress::Type::kLERandom
                                          : DeviceAddress::Type::kLEPublic,
                                      params.bd_addr);
        break;
      }
      default:
        FAIL() << "Sent unsupported SMP command";
    }
  }

  // Emulates the receipt of pairing features (both as initiator and responder).
  void ReceivePairingFeatures(const PairingRequestParams& params, bool peer_initiator = false) {
    PacketWriter writer(peer_initiator ? kPairingRequest : kPairingResponse, &peer_pairing_cmd_);
    *writer.mutable_payload<PairingRequestParams>() = params;
    fake_chan()->Receive(peer_pairing_cmd_);
  }

  void ReceivePairingFeatures(IOCapability ioc = IOCapability::kNoInputNoOutput,
                              AuthReqField auth_req = 0,
                              uint8_t max_enc_key_size = kMaxEncryptionKeySize,
                              bool peer_initiator = false) {
    PairingRequestParams pairing_params;
    std::memset(&pairing_params, 0, sizeof(pairing_params));
    pairing_params.io_capability = ioc;
    pairing_params.auth_req = auth_req;
    pairing_params.max_encryption_key_size = max_enc_key_size;

    ReceivePairingFeatures(pairing_params, peer_initiator);
  }

  void ReceivePairingFailed(ErrorCode error_code) {
    StaticByteBuffer<sizeof(Header) + sizeof(ErrorCode)> buffer;
    PacketWriter writer(kPairingFailed, &buffer);
    *writer.mutable_payload<PairingFailedParams>() = error_code;
    fake_chan()->Receive(buffer);
  }

  void ReceivePairingPublicKey(const PairingPublicKeyParams& key) {
    StaticByteBuffer<util::PacketSize<PairingPublicKeyParams>()> buffer;
    PacketWriter writer(kPairingPublicKey, &buffer);
    std::memcpy(writer.mutable_payload_bytes(), &key, sizeof(PairingPublicKeyParams));
    fake_chan()->Receive(buffer);
  }

  void ReceivePairingConfirm(const UInt128& confirm) { Receive128BitCmd(kPairingConfirm, confirm); }

  void ReceivePairingRandom(const UInt128& random) { Receive128BitCmd(kPairingRandom, random); }

  void ReceivePairingDHKeyCheck(const UInt128& check) {
    Receive128BitCmd(kPairingDHKeyCheck, check);
  }

  void ReceiveEncryptionInformation(const UInt128& ltk) {
    Receive128BitCmd(kEncryptionInformation, ltk);
  }

  void ReceiveMasterIdentification(uint64_t random, uint16_t ediv) {
    StaticByteBuffer<sizeof(Header) + sizeof(MasterIdentificationParams)> buffer;
    PacketWriter writer(kMasterIdentification, &buffer);
    auto* params = writer.mutable_payload<MasterIdentificationParams>();
    params->ediv = htole16(ediv);
    params->rand = htole64(random);
    fake_chan()->Receive(buffer);
  }

  void ReceiveIdentityResolvingKey(const UInt128& irk) {
    Receive128BitCmd(kIdentityInformation, irk);
  }

  void ReceiveNonBondablePairingResponse() {
    // clang-format off
    const auto kResponse = CreateStaticByteBuffer(
      0x02,  // code: Pairing Response
      0x00,  // IO cap.: DisplayOnly
      0x00,  // OOB: not present
      0x00,  // AuthReq: no bonding, MITM not required
      0x07,  // encr. key size: 7 (default min)
      0x00,  // initiator keys: none
      0x00   // responder keys: none - nonbondable mode
    );
    // clang-format on
    fake_chan()->Receive(kResponse);
  }

  void ReceiveIdentityAddress(const DeviceAddress& address) {
    StaticByteBuffer<sizeof(Header) + sizeof(IdentityAddressInformationParams)> buffer;
    PacketWriter writer(kIdentityAddressInformation, &buffer);
    auto* params = writer.mutable_payload<IdentityAddressInformationParams>();
    params->type = address.type() == DeviceAddress::Type::kLEPublic ? AddressType::kPublic
                                                                    : AddressType::kStaticRandom;
    params->bd_addr = address.value();
    fake_chan()->Receive(buffer);
  }

  void ReceiveSecurityRequest(AuthReqField auth_req = 0u) {
    StaticByteBuffer<sizeof(Header) + sizeof(AuthReqField)> buffer;
    buffer[0] = kSecurityRequest;
    buffer[1] = auth_req;
    fake_chan()->Receive(buffer);
    RunLoopUntilIdle();
  }

  void GenerateLegacyConfirmValue(const UInt128& random, UInt128* out_value,
                                  bool peer_initiator = false, uint32_t tk = 0) {
    ZX_DEBUG_ASSERT(out_value);

    tk = htole32(tk);
    UInt128 tk128;
    tk128.fill(0);
    std::memcpy(tk128.data(), &tk, sizeof(tk));

    const ByteBuffer *preq, *pres;
    const DeviceAddress *init_addr, *rsp_addr;
    if (peer_initiator) {
      preq = &peer_pairing_cmd();
      pres = &local_pairing_cmd();
      init_addr = &kPeerAddr;
      rsp_addr = &kLocalAddr;
    } else {
      preq = &local_pairing_cmd();
      pres = &peer_pairing_cmd();
      init_addr = &kLocalAddr;
      rsp_addr = &kPeerAddr;
    }

    util::C1(tk128, random, *preq, *pres, *init_addr, *rsp_addr, out_value);
  }

  UInt128 GenerateScConfirmValue(const LocalEcdhKey& peer_key, const UInt128& random,
                                 Role local_role, bool gen_initiator_confirm, uint8_t r = 0) {
    ZX_ASSERT_MSG(public_ecdh_key_.has_value(), "cannot compute confirm, missing key!");
    UInt256 pka = public_ecdh_key_->GetPublicKeyX(), pkb = peer_key.GetPublicKeyX();
    if (local_role == Role::kResponder) {
      std::swap(pka, pkb);
    }
    return gen_initiator_confirm ? util::F4(pka, pkb, random, r).value()
                                 : util::F4(pkb, pka, random, r).value();
  }

  SecurityManager* pairing() const { return pairing_.get(); }
  l2cap::testing::FakeChannel* fake_chan() const { return fake_chan_.get(); }
  hci::testing::FakeConnection* fake_link() const { return fake_link_.get(); }

  int security_callback_count() const { return security_callback_count_; }
  ErrorCode received_error_code() const { return received_error_code_; }
  const Status& security_status() const { return security_status_; }
  const SecurityProperties& sec_props() const { return sec_props_; }

  int pairing_complete_count() const { return pairing_complete_count_; }
  const Status& pairing_complete_status() const { return pairing_complete_status_; }

  int pairing_data_callback_count() const { return pairing_data_callback_count_; }

  int auth_failure_callback_count() const { return auth_failure_callback_count_; }
  const hci::Status& auth_failure_status() const { return auth_failure_status_; }

  int local_id_info_callback_count() const { return local_id_info_callback_count_; }

  int new_sec_props_count() const { return new_sec_props_count_; }
  const SecurityProperties& new_sec_props() const { return new_sec_props_; }

  const std::optional<LTK>& peer_ltk() const { return pairing_data_.peer_ltk; }
  const std::optional<LTK>& local_ltk() const { return pairing_data_.local_ltk; }
  const std::optional<Key>& irk() const { return pairing_data_.irk; }
  const std::optional<DeviceAddress>& identity() const { return pairing_data_.identity_address; }
  const std::optional<Key>& csrk() const { return pairing_data_.csrk; }

  using ConfirmDelegate = fit::function<void(ConfirmCallback)>;
  void set_confirm_delegate(ConfirmDelegate delegate) { confirm_delegate_ = std::move(delegate); }

  using DisplayDelegate = fit::function<void(uint32_t, DisplayMethod, ConfirmCallback)>;
  void set_display_delegate(DisplayDelegate delegate) { display_delegate_ = std::move(delegate); }

  // sm::Delegate override:
  using RequestPasskeyDelegate = fit::function<void(PasskeyResponseCallback)>;
  void set_request_passkey_delegate(RequestPasskeyDelegate delegate) {
    request_passkey_delegate_ = std::move(delegate);
  }

  void set_local_id_info(std::optional<IdentityInfo> info) { local_id_info_ = info; }

  int security_request_count() const { return security_request_count_; }
  int pairing_failed_count() const { return pairing_failed_count_; }
  int pairing_request_count() const { return pairing_request_count_; }
  int pairing_response_count() const { return pairing_response_count_; }
  int pairing_public_key_count() const { return pairing_public_key_count_; }
  int pairing_confirm_count() const { return pairing_confirm_count_; }
  int pairing_random_count() const { return pairing_random_count_; }
  int pairing_dhkey_check_count() const { return pairing_dhkey_check_count_; }
  int enc_info_count() const { return enc_info_count_; }
  int id_info_count() const { return id_info_count_; }
  int id_addr_info_count() const { return id_addr_info_count_; }
  int master_ident_count() const { return master_ident_count_; }

  AuthReqField security_request_payload() const { return security_auth_req_; }
  const std::optional<EcdhKey>& public_ecdh_key() const { return public_ecdh_key_; }
  const UInt128& pairing_confirm() const { return pairing_confirm_; }
  const UInt128& pairing_random() const { return pairing_random_; }
  const UInt128& pairing_dhkey_check() const { return pairing_dhkey_check_; }
  const UInt128& enc_info() const { return enc_info_; }
  const UInt128& id_info() const { return id_info_; }
  const DeviceAddress& id_addr_info() const { return id_addr_info_; }
  uint16_t ediv() const { return ediv_; }
  uint64_t rand() const { return rand_; }
  const PairingData& pairing_data() const { return pairing_data_; }

  const ByteBuffer& local_pairing_cmd() const { return local_pairing_cmd_; }
  const ByteBuffer& peer_pairing_cmd() const { return peer_pairing_cmd_; }

 private:
  void Receive128BitCmd(Code cmd_code, const UInt128& value) {
    StaticByteBuffer<sizeof(Header) + sizeof(UInt128)> buffer;
    PacketWriter writer(cmd_code, &buffer);
    *writer.mutable_payload<UInt128>() = value;
    fake_chan()->Receive(buffer);
  }

  // We store the preq/pres values here to generate a valid confirm value for
  // the fake side.
  StaticByteBuffer<sizeof(Header) + sizeof(PairingRequestParams)> local_pairing_cmd_,
      peer_pairing_cmd_;

  // Number of times the security callback given to UpgradeSecurity has been
  // called and the most recent parameters that it was called with.
  int security_callback_count_ = 0;
  Status security_status_;
  SecurityProperties sec_props_;

  // Number of times the pairing data callback has been called and the most
  // recent value that it was called with.
  int pairing_data_callback_count_ = 0;
  PairingData pairing_data_;

  // Number of times the link security properties have been notified via
  // OnNewSecurityProperties().
  int new_sec_props_count_ = 0;
  SecurityProperties new_sec_props_;

  // State tracking the OnPairingComplete event.
  int pairing_complete_count_ = 0;
  Status pairing_complete_status_;

  // State tracking the OnAuthenticationFailure event.
  int auth_failure_callback_count_ = 0;
  hci::Status auth_failure_status_;

  // State tracking the OnIdentityInformationRequest event.
  int local_id_info_callback_count_ = 0;
  std::optional<IdentityInfo> local_id_info_;

  // Delegate functions used to respond to user input requests from the Security Manager.
  ConfirmDelegate confirm_delegate_;
  DisplayDelegate display_delegate_;
  RequestPasskeyDelegate request_passkey_delegate_;

  // Counts of commands that we have sent out to the peer.
  int security_request_count_ = 0;
  int pairing_failed_count_ = 0;
  int pairing_request_count_ = 0;
  int pairing_response_count_ = 0;
  int pairing_public_key_count_ = 0;
  int pairing_confirm_count_ = 0;
  int pairing_random_count_ = 0;
  int pairing_dhkey_check_count_ = 0;
  int enc_info_count_ = 0;
  int id_info_count_ = 0;
  int id_addr_info_count_ = 0;
  int master_ident_count_ = 0;

  // Values that have we have sent to the peer.
  AuthReqField security_auth_req_;
  std::optional<EcdhKey> public_ecdh_key_;
  UInt128 pairing_confirm_;
  UInt128 pairing_random_;
  UInt128 pairing_dhkey_check_;
  UInt128 enc_info_;
  UInt128 id_info_;
  DeviceAddress id_addr_info_;
  uint16_t ediv_;
  uint64_t rand_;

  ErrorCode received_error_code_ = ErrorCode::kNoError;

  fbl::RefPtr<l2cap::testing::FakeChannel> fake_chan_;
  std::unique_ptr<hci::testing::FakeConnection> fake_link_;
  std::unique_ptr<SecurityManager> pairing_;

  fxl::WeakPtrFactory<SMP_SecurityManagerTest> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(SMP_SecurityManagerTest);
};

class SMP_InitiatorPairingTest : public SMP_SecurityManagerTest {
 public:
  SMP_InitiatorPairingTest() = default;
  ~SMP_InitiatorPairingTest() override = default;

  void SetUp() override { SetUpSecurityManager(); }

  void SetUpSecurityManager(IOCapability ioc = IOCapability::kDisplayOnly,
                            BondableMode bondable_mode = BondableMode::Bondable) {
    NewSecurityManager(Role::kInitiator, ioc, bondable_mode);
  }

  void GenerateMatchingLegacyConfirmAndRandom(UInt128* out_confirm, UInt128* out_random,
                                              uint32_t tk = 0) {
    ZX_DEBUG_ASSERT(out_confirm);
    ZX_DEBUG_ASSERT(out_random);
    *out_random = kHardCodedPairingRandom;
    GenerateLegacyConfirmValue(*out_random, out_confirm, false /* peer_initiator */, tk);
  }

  struct MatchingPair {
    UInt128 confirm;
    UInt128 random;
  };
  MatchingPair GenerateMatchingScConfirmAndRandom(const LocalEcdhKey& peer_key, uint8_t r = 0) {
    MatchingPair pair;
    pair.random = kHardCodedPairingRandom;
    pair.confirm = GenerateScConfirmValue(peer_key, pair.random, Role::kInitiator, false, r);
    return pair;
  }
  // Emulate legacy pairing up until before encryption with STK. Returns the STK
  // that the initiator is expected to encrypt the link with in |out_stk|.
  //
  // This will not resolve the encryption request that is made by using the STK
  // before this function returns (this is to unit test encryption failure). Use
  // FastForwardToPhase3() to also emulate successful encryption.
  void FastForwardToSTK(UInt128* out_stk, SecurityLevel level = SecurityLevel::kEncrypted,
                        KeyDistGenField remote_keys = 0, KeyDistGenField local_keys = 0,
                        uint8_t max_key_size = kMaxEncryptionKeySize,
                        BondableMode bondable_mode = BondableMode::Bondable) {
    UpgradeSecurity(level);

    PairingRequestParams pairing_params;
    pairing_params.io_capability = IOCapability::kNoInputNoOutput;
    AuthReqField bondable = (bondable_mode == BondableMode::Bondable) ? AuthReq::kBondingFlag : 0,
                 mitm_protected = (level >= SecurityLevel::kAuthenticated) ? AuthReq::kMITM : 0;
    pairing_params.auth_req = mitm_protected | bondable;
    pairing_params.max_encryption_key_size = max_key_size;
    pairing_params.initiator_key_dist_gen = local_keys;
    pairing_params.responder_key_dist_gen = remote_keys;
    ReceivePairingFeatures(pairing_params);

    // Run the loop until the harness caches the feature exchange PDUs (preq &
    // pres) so that we can generate a valid confirm value.
    RunLoopUntilIdle();

    UInt128 sconfirm, srand;
    GenerateMatchingLegacyConfirmAndRandom(&sconfirm, &srand);
    ReceivePairingConfirm(sconfirm);
    ReceivePairingRandom(srand);
    RunLoopUntilIdle();

    EXPECT_EQ(1, pairing_confirm_count());
    EXPECT_EQ(1, pairing_random_count());
    EXPECT_EQ(0, pairing_failed_count());
    EXPECT_EQ(0, security_callback_count());

    ZX_DEBUG_ASSERT(out_stk);

    UInt128 tk;
    tk.fill(0);
    util::S1(tk, srand, pairing_random(), out_stk);
  }

  void FastForwardToPhase3(UInt128* out_encryption_key, bool secure_connections = false,
                           SecurityLevel level = SecurityLevel::kEncrypted,
                           KeyDistGenField remote_keys = 0, KeyDistGenField local_keys = 0,
                           uint8_t max_key_size = kMaxEncryptionKeySize,
                           BondableMode bondable_mode = BondableMode::Bondable) {
    if (secure_connections) {
      FastForwardToScLtk(out_encryption_key, level, remote_keys, local_keys, bondable_mode);
    } else {
      FastForwardToSTK(out_encryption_key, level, remote_keys, local_keys, max_key_size,
                       bondable_mode);
    }

    ASSERT_TRUE(fake_link()->ltk());
    EXPECT_EQ(1, fake_link()->start_encryption_count());

    // Resolve the encryption request.
    fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
    RunLoopUntilIdle();
    EXPECT_EQ(1, new_sec_props_count());
    EXPECT_EQ(level, new_sec_props().level());
  }

  void FastForwardToScLtk(UInt128* out_ltk, SecurityLevel level = SecurityLevel::kEncrypted,
                          KeyDistGenField peer_keys = 0, KeyDistGenField local_keys = 0,
                          BondableMode bondable = BondableMode::Bondable) {
    UpgradeSecurity(level);
    RunLoopUntilIdle();

    ASSERT_EQ(1, pairing_request_count());
    PairingRequestParams pres;
    pres.io_capability = IOCapability::kDisplayYesNo;
    AuthReqField bondable_flag = (bondable == BondableMode::Bondable) ? AuthReq::kBondingFlag : 0;
    AuthReqField mitm_flag = (level >= SecurityLevel::kAuthenticated) ? AuthReq::kMITM : 0;
    pres.auth_req = AuthReq::kSC | mitm_flag | bondable_flag;
    pres.max_encryption_key_size = kMaxEncryptionKeySize;
    pres.initiator_key_dist_gen = local_keys;
    pres.responder_key_dist_gen = peer_keys;
    ReceivePairingFeatures(pres);
    RunLoopUntilIdle();

    ASSERT_TRUE(public_ecdh_key().has_value());
    LocalEcdhKey peer_key = *LocalEcdhKey::Create();
    ReceivePairingPublicKey(peer_key.GetSerializedPublicKey());
    RunLoopUntilIdle();
    // We're in SC Numeric Comparison/Just Works, so as initiator we should not send a confirm.
    ASSERT_EQ(0, pairing_confirm_count());
    MatchingPair phase_2_vals = GenerateMatchingScConfirmAndRandom(peer_key);
    ReceivePairingConfirm(phase_2_vals.confirm);
    RunLoopUntilIdle();
    ASSERT_EQ(1, pairing_random_count());
    // If using MITM, we expect to be in Numeric Comparison
    ConfirmCallback display_cb = nullptr;
    if (mitm_flag != 0) {
      uint32_t kExpectedDisplayVal =
          *util::G2(public_ecdh_key()->GetPublicKeyX(), peer_key.GetPublicKeyX(), pairing_random(),
                    phase_2_vals.random) %
          1000000;
      set_display_delegate([kExpectedDisplayVal, &display_cb](uint32_t compare_value,
                                                              Delegate::DisplayMethod method,
                                                              ConfirmCallback cb) {
        ASSERT_TRUE(method == Delegate::DisplayMethod::kComparison);
        ASSERT_EQ(kExpectedDisplayVal, compare_value);
        display_cb = std::move(cb);
      });
    }
    ReceivePairingRandom(phase_2_vals.random);
    RunLoopUntilIdle();
    if (mitm_flag != 0) {
      ASSERT_TRUE(display_cb);
      display_cb(true);
    }  // Else we are content to use the default confirm delegate behavior to accept the pairing.

    util::F5Results f5 = *util::F5(peer_key.CalculateDhKey(*public_ecdh_key()), pairing_random(),
                                   phase_2_vals.random, kLocalAddr, kPeerAddr);

    UInt128 r_array{0};
    PacketReader reader(&local_pairing_cmd());
    PairingResponseParams preq = reader.payload<PairingRequestParams>();
    UInt128 dhkey_check_a =
        *util::F6(f5.mac_key, pairing_random(), phase_2_vals.random, r_array, preq.auth_req,
                  preq.oob_data_flag, preq.io_capability, kLocalAddr, kPeerAddr);
    UInt128 dhkey_check_b =
        *util::F6(f5.mac_key, phase_2_vals.random, pairing_random(), r_array, pres.auth_req,
                  pres.oob_data_flag, pres.io_capability, kPeerAddr, kLocalAddr);
    RunLoopUntilIdle();
    EXPECT_EQ(1, pairing_dhkey_check_count());
    ASSERT_EQ(dhkey_check_a, pairing_dhkey_check());
    ReceivePairingDHKeyCheck(dhkey_check_b);
    RunLoopUntilIdle();
    EXPECT_EQ(0, pairing_failed_count());
    EXPECT_EQ(0, security_callback_count());

    ASSERT_TRUE(out_ltk);
    *out_ltk = f5.ltk;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(SMP_InitiatorPairingTest);
};

class SMP_ResponderPairingTest : public SMP_SecurityManagerTest {
 public:
  SMP_ResponderPairingTest() = default;
  ~SMP_ResponderPairingTest() override = default;

  void SetUp() override { SetUpSecurityManager(); }

  void SetUpSecurityManager(IOCapability ioc = IOCapability::kDisplayOnly,
                            BondableMode bondable_mode = BondableMode::Bondable) {
    NewSecurityManager(Role::kResponder, ioc, bondable_mode);
  }

  void GenerateMatchingLegacyConfirmAndRandom(UInt128* out_confirm, UInt128* out_random,
                                              uint32_t tk = 0) {
    ZX_DEBUG_ASSERT(out_confirm);
    ZX_DEBUG_ASSERT(out_random);
    *out_random = kHardCodedPairingRandom;
    GenerateLegacyConfirmValue(*out_random, out_confirm, true /* peer_initiator */, tk);
  }
  struct MatchingPair {
    UInt128 confirm;
    UInt128 random;
  };
  MatchingPair GenerateMatchingScConfirmAndRandom(const LocalEcdhKey& peer_key, uint8_t r = 0) {
    MatchingPair pair;
    pair.random = kHardCodedPairingRandom;
    pair.confirm = GenerateScConfirmValue(peer_key, pair.random, Role::kResponder, true, r);
    return pair;
  }
  void ReceivePairingRequest(IOCapability ioc = IOCapability::kNoInputNoOutput,
                             AuthReqField auth_req = 0,
                             uint8_t max_enc_key_size = kMaxEncryptionKeySize) {
    ReceivePairingFeatures(ioc, auth_req, max_enc_key_size, true /* peer_initiator */);
  }

  void FastForwardToSTK(UInt128* out_stk, SecurityLevel level = SecurityLevel::kEncrypted,
                        KeyDistGenField remote_keys = 0, KeyDistGenField local_keys = 0,
                        uint8_t max_key_size = kMaxEncryptionKeySize,
                        BondableMode bondable_mode = BondableMode::Bondable) {
    PairingRequestParams pairing_params;
    pairing_params.io_capability = IOCapability::kNoInputNoOutput;
    AuthReqField bondable = (bondable_mode == BondableMode::Bondable) ? AuthReq::kBondingFlag : 0,
                 mitm_protected = (level >= SecurityLevel::kAuthenticated) ? AuthReq::kMITM : 0;
    pairing_params.auth_req = mitm_protected | bondable;
    pairing_params.max_encryption_key_size = max_key_size;
    pairing_params.initiator_key_dist_gen = remote_keys;
    pairing_params.responder_key_dist_gen = local_keys;
    ReceivePairingFeatures(pairing_params, true /* peer_initiator */);

    // Run the loop until the harness caches the feature exchange PDUs (preq &
    // pres) so that we can generate a valid confirm value.
    RunLoopUntilIdle();
    EXPECT_EQ(0, pairing_request_count());
    EXPECT_EQ(1, pairing_response_count());

    // The initiator should start the confirm/random exchange to generate the Phase 2 keys.
    EXPECT_EQ(0, pairing_confirm_count());
    EXPECT_EQ(0, pairing_random_count());

    UInt128 mconfirm, mrand;
    GenerateMatchingLegacyConfirmAndRandom(&mconfirm, &mrand);
    ReceivePairingConfirm(mconfirm);
    RunLoopUntilIdle();
    EXPECT_EQ(1, pairing_confirm_count());
    EXPECT_EQ(0, pairing_random_count());

    ReceivePairingRandom(mrand);
    RunLoopUntilIdle();
    EXPECT_EQ(1, pairing_confirm_count());
    EXPECT_EQ(1, pairing_random_count());
    EXPECT_EQ(0, pairing_failed_count());
    EXPECT_EQ(0, security_callback_count());

    ZX_DEBUG_ASSERT(out_stk);

    UInt128 tk;
    tk.fill(0);
    util::S1(tk, pairing_random(), mrand, out_stk);
  }

  void FastForwardToPhase3(UInt128* out_encryption_key, bool secure_connections = false,
                           SecurityLevel level = SecurityLevel::kEncrypted,
                           KeyDistGenField remote_keys = 0, KeyDistGenField local_keys = 0,
                           uint8_t max_key_size = kMaxEncryptionKeySize,
                           BondableMode bondable_mode = BondableMode::Bondable) {
    if (secure_connections) {
      FastForwardToScLtk(out_encryption_key, level, remote_keys, local_keys, bondable_mode);
    } else {
      FastForwardToSTK(out_encryption_key, level, remote_keys, local_keys, max_key_size,
                       bondable_mode);
    }

    ASSERT_TRUE(fake_link()->ltk());

    // No local start encryption request should be made.
    EXPECT_EQ(0, fake_link()->start_encryption_count());

    // Pretend that the initiator succeeded in encrypting the connection.
    fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
    RunLoopUntilIdle();
    EXPECT_EQ(1, new_sec_props_count());
    EXPECT_EQ(level, new_sec_props().level());
  }

  void FastForwardToScLtk(UInt128* out_ltk, SecurityLevel level = SecurityLevel::kEncrypted,
                          KeyDistGenField peer_keys = 0, KeyDistGenField local_keys = 0,
                          BondableMode bondable = BondableMode::Bondable) {
    PairingRequestParams preq;
    preq.io_capability = IOCapability::kDisplayYesNo;
    AuthReqField bondable_flag = (bondable == BondableMode::Bondable) ? AuthReq::kBondingFlag : 0;
    AuthReqField mitm_flag = (level >= SecurityLevel::kAuthenticated) ? AuthReq::kMITM : 0;
    preq.auth_req = AuthReq::kSC | mitm_flag | bondable_flag;
    preq.max_encryption_key_size = kMaxEncryptionKeySize;
    preq.initiator_key_dist_gen = local_keys;
    preq.responder_key_dist_gen = peer_keys;
    ReceivePairingFeatures(preq, true /* peer_initiator */);
    RunLoopUntilIdle();
    ASSERT_EQ(1, pairing_response_count());

    LocalEcdhKey peer_key = *LocalEcdhKey::Create();
    ReceivePairingPublicKey(peer_key.GetSerializedPublicKey());
    RunLoopUntilIdle();
    ASSERT_TRUE(public_ecdh_key().has_value());
    ASSERT_EQ(1, pairing_public_key_count());

    // We are in Just Works or Numeric Comparison based on IOCapabilities/MITM preferences, so we
    // expect the confirm value immediately after the public key.
    ASSERT_EQ(1, pairing_confirm_count());
    std::optional<uint32_t> display_val;
    if (mitm_flag != 0) {
      set_display_delegate(
          [&](uint32_t compare_value, Delegate::DisplayMethod method, ConfirmCallback cb) {
            ASSERT_TRUE(method == Delegate::DisplayMethod::kComparison);
            display_val = compare_value;
            cb(true);
          });
    }  // Else we are content to use the default confirm delegate behavior to accept the pairing.
    auto peer_rand = Random<PairingRandomValue>();
    ReceivePairingRandom(peer_rand);
    RunLoopUntilIdle();
    ASSERT_EQ(1, pairing_random_count());
    ASSERT_EQ(GenerateScConfirmValue(peer_key, pairing_random(), Role::kResponder, false),
              pairing_confirm());
    if (mitm_flag != 0) {
      ASSERT_TRUE(display_val.has_value());
      uint32_t kExpectedDisplayVal =
          *util::G2(peer_key.GetPublicKeyX(), public_ecdh_key()->GetPublicKeyX(), peer_rand,
                    pairing_random()) %
          1000000;

      EXPECT_EQ(kExpectedDisplayVal, display_val);
    }

    util::F5Results f5 = *util::F5(peer_key.CalculateDhKey(*public_ecdh_key()), peer_rand,
                                   pairing_random(), kPeerAddr, kLocalAddr);

    UInt128 r_array{0};
    PacketReader reader(&local_pairing_cmd());
    PairingResponseParams pres = reader.payload<PairingResponseParams>();
    UInt128 dhkey_check_a =
        *util::F6(f5.mac_key, peer_rand, pairing_random(), r_array, preq.auth_req,
                  preq.oob_data_flag, preq.io_capability, kPeerAddr, kLocalAddr);
    UInt128 dhkey_check_b =
        *util::F6(f5.mac_key, pairing_random(), peer_rand, r_array, pres.auth_req,
                  pres.oob_data_flag, pres.io_capability, kLocalAddr, kPeerAddr);
    ReceivePairingDHKeyCheck(dhkey_check_a);
    RunLoopUntilIdle();
    EXPECT_EQ(1, pairing_dhkey_check_count());
    ASSERT_EQ(dhkey_check_b, pairing_dhkey_check());
    EXPECT_EQ(0, pairing_failed_count());
    EXPECT_EQ(0, pairing_complete_count());

    ASSERT_TRUE(out_ltk);
    *out_ltk = f5.ltk;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(SMP_ResponderPairingTest);
};

// Calling `Abort` with no in-progress security upgrade should not cause a PairingComplete event.
TEST_F(SMP_InitiatorPairingTest, AbortNoSecurityUpgradeInProgress) {
  pairing()->Abort();
  RunLoopUntilIdle();
  EXPECT_EQ(0, pairing_complete_count());
}

// Disconnecting with no in-progress security upgrade should not cause a PairingComplete event.
TEST_F(SMP_InitiatorPairingTest, DisconnectNoSecurityUpgradeInProgress) {
  fake_chan()->Close();
  RunLoopUntilIdle();
  EXPECT_EQ(0, pairing_complete_count());
}

// Requesting pairing at the current security level should succeed immediately.
TEST_F(SMP_InitiatorPairingTest, UpgradeSecurityCurrentLevel) {
  UpgradeSecurity(SecurityLevel::kNoSecurity);
  RunLoopUntilIdle();

  // No pairing requests should have been made.
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Pairing should succeed.
  EXPECT_EQ(1, security_callback_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(SecurityLevel::kNoSecurity, sec_props().level());
  EXPECT_EQ(0u, sec_props().enc_key_size());
  EXPECT_FALSE(sec_props().secure_connections());
}

// Peer aborts during Phase 1.
TEST_F(SMP_InitiatorPairingTest, PairingFailedInPhase1) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Pairing not complete yet but we should be in Phase 1.
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(1, pairing_request_count());

  ReceivePairingFailed(ErrorCode::kPairingNotSupported);
  RunLoopUntilIdle();

  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_request_count());
  EXPECT_EQ(ErrorCode::kPairingNotSupported, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// Local aborts during Phase 1.
TEST_F(SMP_InitiatorPairingTest, PairingAbortedInPhase1) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Pairing not complete yet but we should be in Phase 1.
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(1, pairing_request_count());

  pairing()->Abort();
  RunLoopUntilIdle();

  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_request_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// Local resets I/O capabilities while pairing. This should abort any ongoing
// pairing and the new I/O capabilities should be used in following pairing
// requests.
TEST_F(SMP_InitiatorPairingTest, SecurityManagerResetDuringPairing) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Pairing not complete yet but we should be in Phase 1.
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(1, pairing_request_count());

  pairing()->Reset(IOCapability::kNoInputNoOutput);
  RunLoopUntilIdle();

  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_request_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());

  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Should have sent a new pairing request.
  EXPECT_EQ(2, pairing_request_count());

  // Make sure that the new request has the new I/O capabilities.
  const auto& params = local_pairing_cmd().view(1).As<PairingRequestParams>();
  EXPECT_EQ(IOCapability::kNoInputNoOutput, params.io_capability);
}

TEST_F(SMP_InitiatorPairingTest, ReceiveConfirmValueWhileNotPairing) {
  UInt128 confirm;
  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // Nothing should happen.
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
}

TEST_F(SMP_InitiatorPairingTest, ReceiveConfirmValueInPhase1) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  UInt128 confirm;
  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, RejectUnauthenticatedPairingInSecureConnectionsOnlyMode) {
  SetUpSecurityManager(IOCapability::kKeyboardDisplay);
  pairing()->set_security_mode(gap::LeSecurityMode::SecureConnectionsOnly);
  // In SC Only mode, SM should translate this "encrypted" request into a MITM requirement.
  UpgradeSecurity(SecurityLevel::kEncrypted);
  // The peer has NoInputNoOutput IOCapabilities, thus cannot perform authenticated pairing.
  ReceivePairingFeatures(IOCapability::kNoInputNoOutput, AuthReq::kBondingFlag | AuthReq::kSC);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kAuthenticationRequirements, security_status().protocol_error());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, RejectUnauthenticatedEncryptionInSecureConnectionsOnlyMode) {
  pairing()->set_security_mode(gap::LeSecurityMode::SecureConnectionsOnly);
  const LTK kUnauthenticatedLtk(SecurityProperties(true /*encrypted*/, false /*authenticated*/,
                                                   true /*SC*/, kMaxEncryptionKeySize),
                                hci::LinkKey());
  pairing()->AssignLongTermKey(kUnauthenticatedLtk);
  RunLoopUntilIdle();
  // After setting SC Only mode, assigning and encrypting with an unauthenticated LTK should cause
  // the channel to be disconnected with an authentication failure.
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true);
  RunLoopUntilIdle();

  EXPECT_EQ(1, auth_failure_callback_count());
  EXPECT_EQ(HostError::kInsufficientSecurity, auth_failure_status().error());
  EXPECT_TRUE(fake_chan()->link_error());
}

TEST_F(SMP_InitiatorPairingTest, AllowSecureAuthenticatedPairingInSecureConnectionsOnlyMode) {
  SetUpSecurityManager(IOCapability::kDisplayYesNo);
  pairing()->set_security_mode(gap::LeSecurityMode::SecureConnectionsOnly);
  UInt128 enc_key;
  FastForwardToPhase3(&enc_key, true, SecurityLevel::kSecureAuthenticated);
  RunLoopUntilIdle();
  // After setting SC Only mode, secure authenticated pairing should still complete successfully.
  EXPECT_EQ(1, pairing_data_callback_count());
  EXPECT_TRUE(peer_ltk().has_value());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  EXPECT_EQ(SecurityLevel::kSecureAuthenticated, sec_props().level());
}

// In Phase 2 but still waiting to receive TK.
TEST_F(SMP_InitiatorPairingTest, ReceiveConfirmValueWhileWaitingForUserInput) {
  bool tk_requested = false;
  set_confirm_delegate([&](ConfirmCallback) { tk_requested = true; });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  ReceivePairingFeatures();
  RunLoopUntilIdle();
  EXPECT_TRUE(tk_requested);

  UInt128 confirm;
  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// SecurityManager destroyed when waiting for Just Works user confirmation.
TEST_F(SMP_InitiatorPairingTest, SecurityManagerDestroyedStateWhileWaitingForUserInput) {
  ConfirmCallback respond;
  set_confirm_delegate([&](ConfirmCallback rsp) { respond = std::move(rsp); });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  ReceivePairingFeatures();
  RunLoopUntilIdle();
  EXPECT_TRUE(respond);

  DestroySecurityManager();

  // This should proceed safely.
  respond(true);
  RunLoopUntilIdle();
}

// Pairing no longer in progress when waiting for Just Works user confirmation.
TEST_F(SMP_InitiatorPairingTest, PairingAbortedWhileWaitingForUserInput) {
  ConfirmCallback respond;
  set_confirm_delegate([&](ConfirmCallback rsp) { respond = std::move(rsp); });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  ReceivePairingFeatures();
  RunLoopUntilIdle();
  EXPECT_TRUE(respond);

  ReceivePairingFailed(ErrorCode::kPairingNotSupported);
  RunLoopUntilIdle();
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kPairingNotSupported, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // This should have no effect.
  respond(true);
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_request_count());
  EXPECT_EQ(0, pairing_response_count());
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(0, pairing_data_callback_count());
}

// Pairing procedure stopped and restarted when TKResponse runs. The TKResponse
// does not belong to the current pairing.
TEST_F(SMP_InitiatorPairingTest, PairingRestartedWhileWaitingForTK) {
  ConfirmCallback respond;
  set_confirm_delegate([&](ConfirmCallback rsp) { respond = std::move(rsp); });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  ReceivePairingFeatures();
  RunLoopUntilIdle();
  EXPECT_TRUE(respond);

  // Stop pairing.
  ReceivePairingFailed(ErrorCode::kPairingNotSupported);
  RunLoopUntilIdle();
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kPairingNotSupported, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // Reset the delegate so that |respond| doesn't get overwritten by the second pairing.
  set_confirm_delegate(nullptr);

  UpgradeSecurity(SecurityLevel::kEncrypted);
  ReceivePairingFeatures();
  RunLoopUntilIdle();
  EXPECT_EQ(2, pairing_request_count());
  EXPECT_EQ(0, pairing_response_count());
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());

  // This should have no effect.
  respond(true);
  RunLoopUntilIdle();
  EXPECT_EQ(2, pairing_request_count());
  EXPECT_EQ(0, pairing_response_count());
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(0, pairing_data_callback_count());
}

TEST_F(SMP_InitiatorPairingTest, ReceiveRandomValueWhileNotPairing) {
  UInt128 random;
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  // Nothing should happen.
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
}

TEST_F(SMP_InitiatorPairingTest, ReceiveRandomValueInPhase1) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  UInt128 random;
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// In Phase 2 but still waiting to receive TK.
TEST_F(SMP_InitiatorPairingTest, ReceiveRandomValueWhileWaitingForTK) {
  bool confirmation_requested = false;
  set_confirm_delegate([&](ConfirmCallback) { confirmation_requested = true; });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  ReceivePairingFeatures();
  RunLoopUntilIdle();
  EXPECT_TRUE(confirmation_requested);

  UInt128 random;
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, LegacyPhase2SconfirmValueReceivedTwice) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  ReceivePairingFeatures();
  RunLoopUntilIdle();

  // Should have received Mconfirm.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  UInt128 confirm;
  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // Should have received Mrand.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Send Mconfirm again
  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, LegacyPhase2ReceiveRandomValueInWrongOrder) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  ReceivePairingFeatures();
  RunLoopUntilIdle();

  // Should have received Mconfirm.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  UInt128 random;
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  // Should have aborted pairing if Srand arrives before Srand.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, LegacyPhase2SconfirmValueInvalid) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Pick I/O capabilities and MITM flags that will result in Just Works
  // pairing.
  ReceivePairingFeatures();
  RunLoopUntilIdle();

  // Should have received Mconfirm.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Receive Sconfirm and Srand values that don't match.
  UInt128 confirm, random;
  confirm.fill(0);
  random.fill(1);

  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // Should have received Mrand.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Our Mconfirm/Mrand should be correct.
  UInt128 expected_confirm;
  GenerateLegacyConfirmValue(pairing_random(), &expected_confirm);
  EXPECT_EQ(expected_confirm, pairing_confirm());

  // Send the non-matching Srandom.
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kConfirmValueFailed, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, LegacyPhase2RandomValueReceivedTwice) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Pick I/O capabilities and MITM flags that will result in Just Works
  // pairing.
  ReceivePairingFeatures();
  RunLoopUntilIdle();

  // Should have received Mconfirm.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Receive Sconfirm and Srand values that match.
  UInt128 confirm, random;
  GenerateMatchingLegacyConfirmAndRandom(&confirm, &random);

  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // Should have received Mrand.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Our Mconfirm/Mrand should be correct.
  UInt128 expected_confirm;
  GenerateLegacyConfirmValue(pairing_random(), &expected_confirm);
  EXPECT_EQ(expected_confirm, pairing_confirm());

  // Send Srandom.
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());

  // Send Srandom again.
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());

  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, LegacyPhase2ConfirmValuesExchanged) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Pick I/O capabilities and MITM flags that will result in Just Works
  // pairing.
  ReceivePairingFeatures();
  RunLoopUntilIdle();

  // Should have received Mconfirm.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Receive Sconfirm and Srand values that match.
  UInt128 confirm, random;
  GenerateMatchingLegacyConfirmAndRandom(&confirm, &random);

  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // Should have received Mrand.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Our Mconfirm/Mrand should be correct.
  UInt128 expected_confirm;
  GenerateLegacyConfirmValue(pairing_random(), &expected_confirm);
  EXPECT_EQ(expected_confirm, pairing_confirm());

  // Send Srandom.
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
}

// TK delegate rejects pairing. When pairing method is "PasskeyEntryInput", this
// should result in a "Passkey Entry Failed" error.
TEST_F(SMP_InitiatorPairingTest, LegacyPhase2TKDelegateRejectsPasskeyInput) {
  SetUpSecurityManager(IOCapability::kKeyboardOnly);

  bool tk_requested = false;
  PasskeyResponseCallback respond;
  set_request_passkey_delegate([&](PasskeyResponseCallback cb_rsp) {
    tk_requested = true;
    respond = std::move(cb_rsp);
  });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Pick I/O capabilities and MITM flags that will result in Passkey Entry
  // pairing.
  ReceivePairingFeatures(IOCapability::kDisplayOnly, AuthReq::kMITM);
  RunLoopUntilIdle();
  ASSERT_TRUE(tk_requested);

  // Reject pairing.
  respond(-1);
  RunLoopUntilIdle();

  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kPasskeyEntryFailed, security_status().protocol_error());
}

// TK delegate rejects pairing.
TEST_F(SMP_InitiatorPairingTest, LegacyPhase2TKDelegateRejectsPairing) {
  bool tk_requested = false;
  ConfirmCallback respond;
  set_confirm_delegate([&](ConfirmCallback cb_rsp) {
    tk_requested = true;
    respond = std::move(cb_rsp);
  });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  ReceivePairingFeatures();
  RunLoopUntilIdle();
  ASSERT_TRUE(tk_requested);

  // Reject pairing.
  respond(false);
  RunLoopUntilIdle();

  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
}

TEST_F(SMP_InitiatorPairingTest, IgnoresExpiredConfirmRequestCallback) {
  ConfirmCallback respond = nullptr;
  set_confirm_delegate([&](ConfirmCallback rsp) { respond = std::move(rsp); });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  ReceivePairingFeatures();
  RunLoopUntilIdle();
  ASSERT_TRUE(respond);
  ConfirmCallback first_pairing_cb = std::move(respond);
  pairing()->Abort();
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_failed_count());

  // We reset the respond variable so we can "catch" the next PairingDelegate request in the same
  // variable (the `set_confirm_delegate` callback still has the reference to `respond`)
  respond = nullptr;

  // Start a separate pairing from the one captured in `first_pairing_cb`, which was `Abort`ed
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  ReceivePairingFeatures();
  RunLoopUntilIdle();
  first_pairing_cb(true);
  RunLoopUntilIdle();
  // The callback from the `Abort`ed pairing should be ignored, while calling `respond`, which is
  // associated with the active pairing, should cause the expected Pairing Confirm to be sent.
  EXPECT_EQ(0, pairing_confirm_count());
  ASSERT_TRUE(respond);
  respond(true);
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_confirm_count());
}

TEST_F(SMP_InitiatorPairingTest, IgnoresExpiredDisplayRequestCallback) {
  SetUpSecurityManager(IOCapability::kDisplayOnly);
  ConfirmCallback respond = nullptr;
  set_display_delegate([&](uint32_t /**/, Delegate::DisplayMethod method, ConfirmCallback rsp) {
    ASSERT_EQ(Delegate::DisplayMethod::kPeerEntry, method);
    respond = std::move(rsp);
  });

  // Must request MITM to test PasskeyEntryDisplay instead of JustWorks pairing
  UpgradeSecurity(SecurityLevel::kAuthenticated);
  RunLoopUntilIdle();

  ReceivePairingFeatures(IOCapability::kKeyboardOnly);
  RunLoopUntilIdle();
  ASSERT_TRUE(respond);
  ConfirmCallback first_pairing_cb = std::move(respond);
  pairing()->Abort();
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_failed_count());

  // We reset the respond variable so we can "catch" the next PairingDelegate request in the same
  // variable (the `set_display_delegate` callback still has the reference to `respond`)
  respond = nullptr;

  // Start a separate pairing from the one captured in `first_pairing_cb`, which was `Abort`ed
  UpgradeSecurity(SecurityLevel::kAuthenticated);
  RunLoopUntilIdle();

  ReceivePairingFeatures(IOCapability::kKeyboardOnly);
  RunLoopUntilIdle();
  first_pairing_cb(true);
  RunLoopUntilIdle();
  // The callback from the `Abort`ed pairing should be ignored, while calling `respond`, which is
  // associated with the active pairing, should cause the expected Pairing Confirm to be sent.
  EXPECT_EQ(0, pairing_confirm_count());
  ASSERT_TRUE(respond);
  respond(true);
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_confirm_count());
}

TEST_F(SMP_InitiatorPairingTest, IgnoresExpiredPasskeyEntryInputCallback) {
  SetUpSecurityManager(IOCapability::kKeyboardOnly);
  PasskeyResponseCallback passkey_cb = nullptr;
  set_request_passkey_delegate([&](PasskeyResponseCallback cb) { passkey_cb = std::move(cb); });

  // Must request MITM to test PasskeyEntryInput instead of JustWorks pairing
  UpgradeSecurity(SecurityLevel::kAuthenticated);
  RunLoopUntilIdle();

  ReceivePairingFeatures(IOCapability::kDisplayOnly);
  RunLoopUntilIdle();
  ASSERT_TRUE(passkey_cb);
  PasskeyResponseCallback first_pairing_cb = std::move(passkey_cb);
  pairing()->Abort();
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_failed_count());

  // We reset the respond variable so we can "catch" the next PairingDelegate request in the same
  // variable (the `set_display_delegate` callback still has the reference to `respond`)
  passkey_cb = nullptr;

  // Start a separate pairing from the one captured in `first_pairing_cb`, which was `Abort`ed
  UpgradeSecurity(SecurityLevel::kAuthenticated);
  RunLoopUntilIdle();

  ReceivePairingFeatures(IOCapability::kDisplayOnly);
  RunLoopUntilIdle();
  const int32_t kGenericPositive6DigitNumber = 123456;
  first_pairing_cb(kGenericPositive6DigitNumber);
  RunLoopUntilIdle();
  // The callback from the `Abort`ed pairing should be ignored, while calling `respond`, which is
  // associated with the active pairing, should cause the expected Pairing Confirm to be sent.
  EXPECT_EQ(0, pairing_confirm_count());
  ASSERT_TRUE(passkey_cb);
  passkey_cb(kGenericPositive6DigitNumber);
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_confirm_count());
}

// The TK delegate is called with the correct pairing method and the TK is
// factored into the confirm value generation.
TEST_F(SMP_InitiatorPairingTest, LegacyPhase2ConfirmValuesExchangedWithUserTK) {
  std::optional<uint32_t> tk = std::nullopt;
  auto method = Delegate::DisplayMethod::kComparison;
  ConfirmCallback respond;
  set_display_delegate(
      [&](uint32_t passkey, Delegate::DisplayMethod cb_method, ConfirmCallback cb_rsp) {
        tk = passkey;
        method = cb_method;
        respond = std::move(cb_rsp);
      });

  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();

  // Pick I/O capabilities and MITM flags that will result in Passkey Entry
  // pairing.
  ReceivePairingFeatures(IOCapability::kKeyboardOnly, AuthReq::kMITM);
  RunLoopUntilIdle();
  ASSERT_TRUE(tk.has_value());

  // DisplayMethod should be kPeerEntry, as Comparison is only for Secure Connections, not Legacy.
  ASSERT_EQ(Delegate::DisplayMethod::kPeerEntry, method);

  // Notify that TK was displayed.
  respond(true);
  RunLoopUntilIdle();

  // Should have received Mconfirm.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Receive Sconfirm and Srand values that match.
  UInt128 confirm, random;
  GenerateMatchingLegacyConfirmAndRandom(&confirm, &random, *tk);

  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // Should have received Mrand.
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, security_callback_count());

  // Our Mconfirm/Mrand should be correct.
  UInt128 expected_confirm;
  GenerateLegacyConfirmValue(pairing_random(), &expected_confirm, false /* peer_initiator */, *tk);
  EXPECT_EQ(expected_confirm, pairing_confirm());

  // Send Srandom.
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
}

// Peer aborts during Phase 2.
TEST_F(SMP_InitiatorPairingTest, PairingFailedInPhase2) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  ReceivePairingFeatures();
  RunLoopUntilIdle();

  UInt128 confirm, random;
  GenerateMatchingLegacyConfirmAndRandom(&confirm, &random);

  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());

  ReceivePairingFailed(ErrorCode::kConfirmValueFailed);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kConfirmValueFailed, security_status().protocol_error());
}

// Encryption with STK fails.
TEST_F(SMP_InitiatorPairingTest, EncryptionWithSTKFails) {
  UInt128 stk;
  FastForwardToSTK(&stk);

  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(stk, fake_link()->ltk()->value());
  EXPECT_EQ(0u, fake_link()->ltk()->ediv());
  EXPECT_EQ(0u, fake_link()->ltk()->rand());

  // The host should have requested encryption.
  EXPECT_EQ(SecurityProperties(), pairing()->security());
  EXPECT_EQ(1, fake_link()->start_encryption_count());

  fake_link()->TriggerEncryptionChangeCallback(hci::Status(hci::StatusCode::kPinOrKeyMissing),
                                               false /* enabled */);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, auth_failure_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(hci::StatusCode::kPinOrKeyMissing, auth_failure_status().protocol_error());

  // No security property update should have been sent since the security
  // properties have not changed.
  EXPECT_EQ(0, new_sec_props_count());
  EXPECT_EQ(SecurityProperties(), pairing()->security());
}

TEST_F(SMP_InitiatorPairingTest, EncryptionDisabledInPhase2) {
  UInt128 stk;
  FastForwardToSTK(&stk);

  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(stk, fake_link()->ltk()->value());
  EXPECT_EQ(0u, fake_link()->ltk()->ediv());
  EXPECT_EQ(0u, fake_link()->ltk()->rand());

  // The host should have requested encryption.
  EXPECT_EQ(1, fake_link()->start_encryption_count());
  EXPECT_EQ(SecurityProperties(), pairing()->security());

  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), false /* enabled */);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(0, auth_failure_callback_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());

  // No security property update should have been sent since the security
  // properties have not changed.
  EXPECT_EQ(0, new_sec_props_count());
  EXPECT_EQ(SecurityProperties(), pairing()->security());
}

// Tests that the STK is generated according to the max length provided
TEST_F(SMP_InitiatorPairingTest, StkLengthGeneration) {
  UInt128 stk;
  uint8_t max_key_size = 10;
  FastForwardToSTK(&stk, SecurityLevel::kEncrypted, 0, 0, max_key_size);

  // At this stage, the stk is stored here
  ASSERT_TRUE(fake_link()->ltk());

  // Ensure that most significant (16 - max_key_size) bytes are zero. The key
  // should be generated up to the max_key_size.
  for (auto i = max_key_size; i < fake_link()->ltk()->value().size(); i++) {
    EXPECT_TRUE(fake_link()->ltk()->value()[i] == 0);
  }
}

// Tests that the pairing procedure ends after encryption with the STK if there are no keys to
// distribute, and that no keys are notified for Legacy pairing in this case.
TEST_F(SMP_InitiatorPairingTest, LegacyPhase3CompleteWithoutKeyExchange) {
  UInt128 stk;
  FastForwardToSTK(&stk);

  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(stk, fake_link()->ltk()->value());
  EXPECT_EQ(0u, fake_link()->ltk()->ediv());
  EXPECT_EQ(0u, fake_link()->ltk()->rand());

  // The host should have requested encryption.
  EXPECT_EQ(1, fake_link()->start_encryption_count());

  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
  RunLoopUntilIdle();

  // Pairing should succeed without any pairing data.
  EXPECT_EQ(1, pairing_data_callback_count());
  EXPECT_FALSE(peer_ltk());
  EXPECT_FALSE(irk());
  EXPECT_FALSE(identity());
  EXPECT_FALSE(csrk());

  // Should have been called at least once to determine local identity
  // availability.
  EXPECT_NE(0, local_id_info_callback_count());

  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  EXPECT_EQ(SecurityLevel::kEncrypted, sec_props().level());
  EXPECT_EQ(16u, sec_props().enc_key_size());
  EXPECT_FALSE(sec_props().secure_connections());

  // The security properties should have been updated to match the STK.
  EXPECT_EQ(1, new_sec_props_count());
  EXPECT_EQ(sec_props(), pairing()->security());

  ASSERT_TRUE(fake_link()->ltk());
}

// Tests that for Secure Connections, the pairing procedure ends after encryption with the LTK if
// there are no keys to distribute, and that the LTK is notified.
TEST_F(SMP_InitiatorPairingTest, ScPhase3CompleteWithoutKeyExchange) {
  UInt128 ltk_bytes;
  const SecurityProperties kExpectedSecurity(SecurityLevel::kEncrypted, kMaxEncryptionKeySize,
                                             true /* secure connections */);
  FastForwardToPhase3(&ltk_bytes, true /*secure_connections*/, kExpectedSecurity.level(),
                      KeyDistGenField{0}, KeyDistGenField{0});

  const LTK kExpectedLtk(kExpectedSecurity, hci::LinkKey(ltk_bytes, 0, 0));
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kExpectedLtk.key(), fake_link()->ltk());

  // Pairing should succeed with the LTK as the SC pairing is bondable, even though no keys need to
  // be distributed in Phase 3.
  EXPECT_EQ(1, pairing_data_callback_count());
  EXPECT_TRUE(peer_ltk().has_value());
  EXPECT_EQ(kExpectedLtk, peer_ltk());
  EXPECT_EQ(peer_ltk(), local_ltk());
  EXPECT_FALSE(irk());
  EXPECT_FALSE(identity());
  EXPECT_FALSE(csrk());

  // Should have been called at least once to determine local identity  availability.
  EXPECT_NE(0, local_id_info_callback_count());

  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  EXPECT_EQ(kExpectedSecurity, sec_props());

  // The security properties should have been updated to match the LTK.
  EXPECT_EQ(1, new_sec_props_count());
  EXPECT_EQ(sec_props(), pairing()->security());

  ASSERT_TRUE(fake_link()->ltk());
}

// Tests that Secure Connections ignores the EncKey bit in the key distribution field.
TEST_F(SMP_InitiatorPairingTest, ScPhase3EncKeyBitSetNotDistributed) {
  UInt128 ltk_bytes;
  const SecurityProperties kExpectedSecurity(SecurityLevel::kEncrypted, kMaxEncryptionKeySize,
                                             true /* secure connections */);
  // We will request the EncKey from the peer and the peer will respond that it is capable of
  // sending it, but as this is SC pairing that should not occur.
  KeyDistGenField remote_keys{KeyDistGen::kEncKey}, local_keys{0};
  FastForwardToScLtk(&ltk_bytes, kExpectedSecurity.level(), remote_keys, local_keys,
                     BondableMode::Bondable);

  const LTK kExpectedLtk(kExpectedSecurity, hci::LinkKey(ltk_bytes, 0, 0));
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kExpectedLtk.key(), fake_link()->ltk());

  // The host should have requested encryption.
  EXPECT_EQ(1, fake_link()->start_encryption_count());

  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
  RunLoopUntilIdle();

  // Pairing should succeed without any messages being sent in "Phase 3". The LTK was generated in
  // SC Phase 2, and as the pairing is bondable, it is included in the callback.
  EXPECT_EQ(1, pairing_data_callback_count());
  EXPECT_TRUE(peer_ltk().has_value());
  EXPECT_EQ(kExpectedLtk, peer_ltk());
  EXPECT_FALSE(irk());
  EXPECT_FALSE(identity());
  EXPECT_FALSE(csrk());

  // Should have been called at least once to determine local identity  availability.
  EXPECT_NE(0, local_id_info_callback_count());

  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  EXPECT_EQ(kExpectedSecurity, sec_props());

  // The security properties should have been updated to match the LTK.
  EXPECT_EQ(1, new_sec_props_count());
  EXPECT_EQ(sec_props(), pairing()->security());

  ASSERT_TRUE(fake_link()->ltk());
}

// Tests that for Secure Connections non-bondable mode, the pairing procedure ends after encryption
// with the key generated in Phase 2, but the upper layers are not notified of that key as an LTK.
TEST_F(SMP_InitiatorPairingTest, ScPhase3NonBondableCompleteWithoutKeyExchange) {
  // Must have DisplayYesNo IOC to generate Authenticated security per kExpectedSecurity
  SetUpSecurityManager(IOCapability::kDisplayYesNo);
  const SecurityProperties kExpectedSecurity(SecurityLevel::kAuthenticated, kMaxEncryptionKeySize,
                                             true /* secure connections */);
  UInt128 ltk_bytes;
  FastForwardToScLtk(&ltk_bytes, kExpectedSecurity.level(), KeyDistGenField{0}, KeyDistGenField{0},
                     BondableMode::NonBondable);

  const hci::LinkKey kExpectedLinkKey(ltk_bytes, 0, 0);
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kExpectedLinkKey, fake_link()->ltk());

  // The host should have requested encryption.
  EXPECT_EQ(1, fake_link()->start_encryption_count());

  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
  RunLoopUntilIdle();

  // Pairing should succeed with the LTK as we are in SC, but as the pairing is non-bondable, no
  // LTK should be relayed up to the delegate.
  EXPECT_EQ(0, pairing_data_callback_count());

  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  EXPECT_EQ(kExpectedSecurity, sec_props());

  // The security properties should have been updated to match the LTK.
  EXPECT_EQ(1, new_sec_props_count());
  EXPECT_EQ(sec_props(), pairing()->security());

  ASSERT_TRUE(fake_link()->ltk());
}

TEST_F(SMP_InitiatorPairingTest, Phase3EncryptionInformationReceivedTwice) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey);

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());

  ReceiveEncryptionInformation(UInt128());
  RunLoopUntilIdle();

  // Waiting for EDIV and Rand
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());

  // Send the LTK twice. This should cause pairing to fail.
  ReceiveEncryptionInformation(UInt128());
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// The responder sends EDIV and Rand before LTK.
TEST_F(SMP_InitiatorPairingTest, Phase3MasterIdentificationReceivedInWrongOrder) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey);

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());

  // Send master identification before encryption information. This should cause
  // pairing to fail.
  ReceiveMasterIdentification(1, 2);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// The responder sends the sample LTK from the specification doc
TEST_F(SMP_InitiatorPairingTest, Phase3MasterIdentificationReceiveSampleLTK) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey);

  const UInt128 kLtkSample{{0xBF, 0x01, 0xFB, 0x9D, 0x4E, 0xF3, 0xBC, 0x36, 0xD8, 0x74, 0xF5, 0x39,
                            0x41, 0x38, 0x68, 0x4C}};

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());

  // Send a bad LTK, this should cause pairing to fail.
  ReceiveEncryptionInformation(kLtkSample);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// The responder sends the sample Rand from the specification doc
TEST_F(SMP_InitiatorPairingTest, Phase3MasterIdentificationReceiveExampleRand) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey);

  uint64_t kRandSample = 0xABCDEF1234567890;
  uint16_t kEDiv = 20;

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());

  // Send a bad Rand, this should cause pairing to fail.
  ReceiveEncryptionInformation(UInt128());
  ReceiveMasterIdentification(kRandSample, kEDiv);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// The responder sends an LTK that is longer than the max key size
TEST_F(SMP_InitiatorPairingTest, Phase3MasterIdentificationReceiveLongLTK) {
  UInt128 stk;
  auto max_key_size = 8;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey, 0, max_key_size);

  const UInt128 kLtk{{1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}};

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());

  // Send a long LTK, this should cause pairing to fail.
  ReceiveEncryptionInformation(kLtk);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kInvalidParameters, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kInvalidParameters, received_error_code());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, Phase3MasterIdentificationReceivedTwice) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey);

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());

  constexpr uint16_t kEdiv = 1;
  constexpr uint64_t kRand = 2;
  constexpr uint16_t kDupEdiv = 3;
  constexpr uint64_t kDupRand = 4;

  // Send duplicate master identification. Pairing should complete with the
  // first set of information. The second set should get ignored.
  ReceiveEncryptionInformation(UInt128());
  ReceiveMasterIdentification(kRand, kEdiv);
  ReceiveMasterIdentification(kDupRand, kDupEdiv);
  RunLoopUntilIdle();

  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(1, pairing_data_callback_count());
  EXPECT_TRUE(security_status().is_success());
  EXPECT_EQ(security_status(), pairing_complete_status());
  ASSERT_TRUE(pairing_data().peer_ltk.has_value());
  EXPECT_EQ(kEdiv, pairing_data().peer_ltk->key().ediv());
  EXPECT_EQ(kRand, pairing_data().peer_ltk->key().rand());
}

// Pairing completes after obtaining peer encryption information only.
TEST_F(SMP_InitiatorPairingTest, Phase3CompleteWithReceivingEncKey) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey);

  const UInt128 kLTK{{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0}};
  uint64_t kRand = 5;
  uint16_t kEDiv = 20;

  ReceiveEncryptionInformation(kLTK);
  ReceiveMasterIdentification(kRand, kEDiv);
  RunLoopUntilIdle();

  // Pairing should have succeeded.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // LTK should have been assigned to the link.
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kLTK, fake_link()->ltk()->value());
  EXPECT_EQ(kRand, fake_link()->ltk()->rand());
  EXPECT_EQ(kEDiv, fake_link()->ltk()->ediv());

  // We don't re-encrypt with the LTK while the link is already authenticated
  // with the STK.
  EXPECT_EQ(1, fake_link()->start_encryption_count());

  EXPECT_EQ(SecurityLevel::kEncrypted, sec_props().level());
  EXPECT_EQ(16u, sec_props().enc_key_size());
  EXPECT_FALSE(sec_props().secure_connections());

  // Should have been called at least once to determine local identity
  // availability.
  EXPECT_NE(0, local_id_info_callback_count());

  // Local identity information should not have been distributed by us since it
  // isn't available.
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());

  // Should have notified the LTK.
  EXPECT_EQ(1, pairing_data_callback_count());
  ASSERT_TRUE(peer_ltk());
  ASSERT_FALSE(irk());
  ASSERT_FALSE(identity());
  ASSERT_FALSE(csrk());
  EXPECT_EQ(sec_props(), peer_ltk()->security());
  EXPECT_EQ(kLTK, peer_ltk()->key().value());
  EXPECT_EQ(kRand, peer_ltk()->key().rand());
  EXPECT_EQ(kEDiv, peer_ltk()->key().ediv());

  // No security property update should have been sent for the LTK. This is
  // because the LTK and the STK are expected to have the same properties.
  EXPECT_EQ(1, new_sec_props_count());
}

TEST_F(SMP_InitiatorPairingTest, Phase3CompleteWithSendingEncKey) {
  UInt128 stk;
  KeyDistGenField remote_keys{0u}, local_keys{KeyDistGen::kEncKey};
  FastForwardToPhase3(&stk, false, SecurityLevel::kEncrypted, remote_keys, local_keys);
  RunLoopUntilIdle();

  // Pairing should have succeeded.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // Only the STK should be assigned to the link, as the distributed LTK was initiator-generated.
  // This means it can only be used to encrypt future connections where the roles are reversed.
  EXPECT_EQ(stk, fake_link()->ltk()->value());
  EXPECT_EQ(1, fake_link()->start_encryption_count());

  // Should have been called at least once to determine local identity availability.
  EXPECT_NE(0, local_id_info_callback_count());

  // Should have notified pairing data callback with the LTK.
  EXPECT_EQ(1, pairing_data_callback_count());
  ASSERT_TRUE(local_ltk());

  // LTK sent OTA should match what we notified the pairing data callback with.
  EXPECT_EQ(local_ltk()->key(), hci::LinkKey(enc_info(), rand(), ediv()));
}

// Pairing completes after obtaining short encryption information only.
TEST_F(SMP_InitiatorPairingTest, Phase3CompleteWithShortEncKey) {
  UInt128 stk;
  uint8_t max_key_size = 12;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey, 0u, max_key_size);

  // This LTK is within the max_key_size specified above.
  const UInt128 kLTK{{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 0, 0, 0, 0}};
  uint64_t kRand = 5;
  uint16_t kEDiv = 20;

  ReceiveEncryptionInformation(kLTK);
  ReceiveMasterIdentification(kRand, kEDiv);
  RunLoopUntilIdle();

  // Pairing should have succeeded.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // LTK should have been assigned to the link.
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kLTK, fake_link()->ltk()->value());
  EXPECT_EQ(kRand, fake_link()->ltk()->rand());
  EXPECT_EQ(kEDiv, fake_link()->ltk()->ediv());

  // We don't re-encrypt with the LTK while the link is already authenticated
  // with the STK.
  EXPECT_EQ(1, fake_link()->start_encryption_count());

  EXPECT_EQ(SecurityLevel::kEncrypted, sec_props().level());
  EXPECT_EQ(max_key_size, sec_props().enc_key_size());
  EXPECT_FALSE(sec_props().secure_connections());

  // Should have been called at least once to determine local identity
  // availability.
  EXPECT_NE(0, local_id_info_callback_count());

  // Local identity information should not have been distributed by us since it
  // isn't available.
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());

  // Should have notified the LTK.
  EXPECT_EQ(1, pairing_data_callback_count());
  ASSERT_TRUE(peer_ltk());
  ASSERT_FALSE(irk());
  ASSERT_FALSE(identity());
  ASSERT_FALSE(csrk());
  EXPECT_EQ(sec_props(), peer_ltk()->security());
  EXPECT_EQ(kLTK, peer_ltk()->key().value());
  EXPECT_EQ(kRand, peer_ltk()->key().rand());
  EXPECT_EQ(kEDiv, peer_ltk()->key().ediv());

  // No security property update should have been sent for the LTK. This is
  // because the LTK and the STK are expected to have the same properties.
  EXPECT_EQ(1, new_sec_props_count());
}

TEST_F(SMP_InitiatorPairingTest, Phase3WithLocalIdKey) {
  IdentityInfo local_id_info;
  local_id_info.irk = UInt128{{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0}};
  local_id_info.address = kLocalAddr;
  set_local_id_info(local_id_info);

  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      0,                    // remote keys
                      KeyDistGen::kIdKey);  // local keys

  // Local identity information should have been sent.
  EXPECT_EQ(1, id_info_count());
  EXPECT_EQ(local_id_info.irk, id_info());
  EXPECT_EQ(1, id_addr_info_count());
  EXPECT_EQ(local_id_info.address, id_addr_info());

  // Pairing should succeed without notifying any keys.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// Tests that pairing results in an error if a local ID key was initially
// negotiated but gets removed before the distribution phase.
TEST_F(SMP_InitiatorPairingTest, Phase3IsAbortedIfLocalIdKeyIsRemoved) {
  IdentityInfo local_id_info;
  local_id_info.irk = UInt128{{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0}};
  local_id_info.address = kLocalAddr;
  set_local_id_info(local_id_info);

  UInt128 stk;
  FastForwardToSTK(&stk, SecurityLevel::kEncrypted,
                   0,                    // remote keys
                   KeyDistGen::kIdKey);  // local keys

  // Local identity information should not have been sent yet.
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());

  // Pairing still in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Remove the local identity information.
  set_local_id_info(std::nullopt);

  // Encrypt with the STK to finish phase 2.
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
  RunLoopUntilIdle();

  // Pairing should have been aborted.
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_FALSE(security_status());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
}

TEST_F(SMP_InitiatorPairingTest, Phase3IRKReceivedTwice) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kIdKey);

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());

  ReceiveIdentityResolvingKey(UInt128());
  RunLoopUntilIdle();

  // Waiting for identity address.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Send an IRK again. This should cause pairing to fail.
  ReceiveIdentityResolvingKey(UInt128());
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// The responder sends its identity address before sending its IRK.
TEST_F(SMP_InitiatorPairingTest, Phase3IdentityAddressReceivedInWrongOrder) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kIdKey);

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Send identity address before the IRK. This should cause pairing to fail.
  ReceiveIdentityAddress(kPeerAddr);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_InitiatorPairingTest, Phase3IdentityAddressReceivedTwice) {
  UInt128 stk;
  // Request enc key to prevent pairing from completing after sending the first
  // identity address.
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey | KeyDistGen::kIdKey);

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  ReceiveIdentityResolvingKey(UInt128());
  ReceiveIdentityAddress(kPeerAddr);
  ReceiveIdentityAddress(kPeerAddr);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, security_status().protocol_error());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

// Pairing completes after obtaining identity information only.
TEST_F(SMP_InitiatorPairingTest, Phase3CompleteWithIdKey) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kIdKey);

  // Pairing should still be in progress.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_data_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  const UInt128 kIRK{{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0}};

  ReceiveIdentityResolvingKey(kIRK);
  ReceiveIdentityAddress(kPeerAddr);
  RunLoopUntilIdle();

  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // The link remains encrypted with the STK.
  EXPECT_EQ(SecurityLevel::kEncrypted, sec_props().level());
  EXPECT_EQ(16u, sec_props().enc_key_size());
  EXPECT_FALSE(sec_props().secure_connections());

  EXPECT_EQ(1, pairing_data_callback_count());
  ASSERT_FALSE(peer_ltk());
  ASSERT_TRUE(irk());
  ASSERT_TRUE(identity());
  ASSERT_FALSE(csrk());

  EXPECT_EQ(sec_props(), irk()->security());
  EXPECT_EQ(kIRK, irk()->value());
  EXPECT_EQ(kPeerAddr, *identity());
}

TEST_F(SMP_InitiatorPairingTest, Phase3CompleteWithAllKeys) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey | KeyDistGen::kIdKey);

  const UInt128 kLTK{{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0}};
  const UInt128 kIRK{{8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}};
  uint64_t kRand = 5;
  uint16_t kEDiv = 20;

  // The link should be assigned the STK as its link key.
  EXPECT_EQ(stk, fake_link()->ltk()->value());

  // Receive EncKey
  ReceiveEncryptionInformation(kLTK);
  ReceiveMasterIdentification(kRand, kEDiv);
  RunLoopUntilIdle();

  // Pairing still pending. SMP does not assign the LTK to the link until pairing completes.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Receive IdKey
  ReceiveIdentityResolvingKey(kIRK);
  ReceiveIdentityAddress(kPeerAddr);
  RunLoopUntilIdle();

  // Pairing should have succeeded
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // LTK should have been assigned to the link.
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kLTK, fake_link()->ltk()->value());
  EXPECT_EQ(kRand, fake_link()->ltk()->rand());
  EXPECT_EQ(kEDiv, fake_link()->ltk()->ediv());

  // We don't re-encrypt with the LTK while the link is already authenticated
  // with the STK.
  EXPECT_EQ(1, fake_link()->start_encryption_count());

  EXPECT_EQ(SecurityLevel::kEncrypted, sec_props().level());
  EXPECT_EQ(16u, sec_props().enc_key_size());
  EXPECT_FALSE(sec_props().secure_connections());

  // Should have notified the LTK.
  EXPECT_EQ(1, pairing_data_callback_count());
  ASSERT_TRUE(peer_ltk());
  ASSERT_TRUE(irk());
  ASSERT_TRUE(identity());
  ASSERT_FALSE(csrk());
  EXPECT_EQ(sec_props(), peer_ltk()->security());
  EXPECT_EQ(kLTK, peer_ltk()->key().value());
  EXPECT_EQ(kRand, peer_ltk()->key().rand());
  EXPECT_EQ(kEDiv, peer_ltk()->key().ediv());
  EXPECT_EQ(sec_props(), irk()->security());
  EXPECT_EQ(kIRK, irk()->value());
  EXPECT_EQ(kPeerAddr, *identity());
}

TEST_F(SMP_InitiatorPairingTest, GenerateCrossTransportLinkKey) {
  UInt128 stk;
  // Indicate support for SC and for link keys in both directions to enable CTKG.
  FastForwardToPhase3(&stk, true /*secure connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kLinkKey, KeyDistGen::kLinkKey);
  RunLoopUntilIdle();

  // Pairing should have succeeded
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // The PairingData should contain the CTKGenerated BR/EDR link key.
  EXPECT_TRUE(pairing_data().cross_transport_key.has_value());
}

TEST_F(SMP_InitiatorPairingTest, AssignLongTermKeyFailsDuringPairing) {
  UpgradeSecurity(SecurityLevel::kEncrypted);  // Initiate pairing.
  SecurityProperties sec_props(SecurityLevel::kAuthenticated, 16, false);
  EXPECT_FALSE(pairing()->AssignLongTermKey(LTK(sec_props, hci::LinkKey())));
  EXPECT_EQ(0, fake_link()->start_encryption_count());
  EXPECT_EQ(SecurityLevel::kNoSecurity, pairing()->security().level());
}

TEST_F(SMP_InitiatorPairingTest, AssignLongTermKey) {
  SecurityProperties sec_props(SecurityLevel::kAuthenticated, 16, false);
  LTK ltk(sec_props, hci::LinkKey());

  EXPECT_TRUE(pairing()->AssignLongTermKey(ltk));
  EXPECT_EQ(1, fake_link()->start_encryption_count());
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(ltk.key(), *fake_link()->ltk());

  // The link security level is not assigned until successful encryption.
  EXPECT_EQ(SecurityProperties(), pairing()->security());
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
  RunLoopUntilIdle();

  EXPECT_EQ(1, new_sec_props_count());
  EXPECT_EQ(sec_props, new_sec_props());
  EXPECT_EQ(sec_props, pairing()->security());
}

TEST_F(SMP_InitiatorPairingTest, ReceiveSecurityRequest) {
  ReceiveSecurityRequest(AuthReq::kMITM);
  RunLoopUntilIdle();

  // Should have requested pairing with MITM protection.
  EXPECT_EQ(1, pairing_request_count());
  const auto& params = local_pairing_cmd().view(1).As<PairingRequestParams>();
  EXPECT_TRUE(params.auth_req & AuthReq::kMITM);
}

TEST_F(SMP_InitiatorPairingTest, ReceiveSecurityRequestWhenPaired) {
  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kEncKey);
  EXPECT_EQ(stk, fake_link()->ltk()->value());
  EXPECT_EQ(1, pairing_request_count());

  // Receiving a security request now should have no effect since pairing is
  // still in progress.
  ReceiveSecurityRequest();
  EXPECT_EQ(1, pairing_request_count());

  // Receive EncKey and wait until the link is encrypted with the LTK.
  UInt128 kLTK{{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0}};
  uint64_t kRand = 5;
  uint16_t kEDiv = 20;
  ReceiveEncryptionInformation(kLTK);
  ReceiveMasterIdentification(kRand, kEDiv);
  RunLoopUntilIdle();
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
  RunLoopUntilIdle();
  ASSERT_EQ(1, pairing_complete_count());
  ASSERT_TRUE(security_status());
  ASSERT_TRUE(peer_ltk());
  ASSERT_EQ(SecurityLevel::kEncrypted, sec_props().level());
  ASSERT_EQ(1, fake_link()->start_encryption_count());  // Once for the STK
  ASSERT_EQ(1, pairing_request_count());

  // Receive a security request with the no MITM requirement. This should
  // trigger an encryption key refresh and no pairing request.
  ReceiveSecurityRequest();
  EXPECT_EQ(1, pairing_request_count());

  // Once for the STK and once again due to the locally initiated key refresh.
  ASSERT_EQ(2, fake_link()->start_encryption_count());

  // Receive a security request with a higher security requirement. This should
  // trigger a pairing request.
  ReceiveSecurityRequest(AuthReq::kMITM);
  EXPECT_EQ(2, pairing_request_count());
  const auto& params = local_pairing_cmd().view(1).As<PairingRequestParams>();
  EXPECT_TRUE(params.auth_req & AuthReq::kMITM);
}

TEST_F(SMP_InitiatorPairingTest, PairingTimeoutWorks) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();
  ASSERT_EQ(1, pairing_request_count());
  // Expiration of the pairing timeout should trigger the link error callback per v5.2 Vol. 3 Part H
  // 3.4. Link disconnection will generally cause channel closure, so this simulates that behavior
  // to validate that SM handles this safely.
  fake_chan()->SetLinkErrorCallback([chan = fake_chan()]() { chan->Close(); });
  RunLoopFor(kPairingTimeout);
  EXPECT_TRUE(fake_chan()->link_error());
  ASSERT_EQ(1, security_callback_count());
  EXPECT_EQ(HostError::kTimedOut, security_status().error());
  ASSERT_EQ(1, pairing_complete_count());
  EXPECT_EQ(HostError::kTimedOut, pairing_complete_status().error());
}

TEST_F(SMP_InitiatorPairingTest, NoTimeoutAfterSuccessfulPairing) {
  UInt128 out_stk;
  FastForwardToPhase3(&out_stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGenField{0}, KeyDistGenField{0});
  ASSERT_EQ(1, pairing_complete_count());
  ASSERT_EQ(1, security_callback_count());
  ASSERT_TRUE(security_status().is_success());
  ASSERT_TRUE(pairing_complete_status().is_success());
  // Verify that no timeout occurs after a successful pairing followed by a long interval.
  RunLoopFor(kPairingTimeout * 2);
  ASSERT_EQ(1, pairing_complete_count());
  ASSERT_EQ(1, security_callback_count());
  ASSERT_NE(HostError::kTimedOut, pairing_complete_status().error());
  ASSERT_NE(HostError::kTimedOut, security_status().error());
}

TEST_F(SMP_InitiatorPairingTest, AbortStopsPairingTimer) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();
  ASSERT_EQ(1, pairing_request_count());
  pairing()->Abort();
  // Calling Abort should stop the pairing procedure and the timer.
  ASSERT_EQ(1, pairing_complete_count());
  ASSERT_EQ(1, security_callback_count());
  // Run the loop for a time that would cause a timeout if a timer were active.
  RunLoopFor(kPairingTimeout * 2);
  ASSERT_EQ(1, pairing_complete_count());
  ASSERT_EQ(1, security_callback_count());
  ASSERT_NE(HostError::kTimedOut, pairing_complete_status().error());
  ASSERT_NE(HostError::kTimedOut, security_status().error());
}

TEST_F(SMP_InitiatorPairingTest, ResetStopsPairingTimer) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();
  ASSERT_EQ(1, pairing_request_count());
  pairing()->Reset(IOCapability::kDisplayYesNo);
  // Resetting the pairing aborts the current procedure.
  ASSERT_EQ(1, pairing_complete_count());
  ASSERT_EQ(1, security_callback_count());
  // Run the loop for a time that would cause a timeout if a timer were active.
  RunLoopFor(kPairingTimeout * 2);
  ASSERT_EQ(1, pairing_complete_count());
  ASSERT_EQ(1, security_callback_count());
  ASSERT_NE(HostError::kTimedOut, pairing_complete_status().error());
  ASSERT_NE(HostError::kTimedOut, security_status().error());
}

TEST_F(SMP_InitiatorPairingTest, SendingMessageRestartsTimer) {
  // SM will send the Pairing Request, which is special-cased to "reset and start" the pairing
  // timer (v5.2 Vol. 3 Part H 3.4), and thus not under test here.
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();
  ASSERT_EQ(1, pairing_request_count());
  // Run the loop until the pairing timeout has almost expired.
  RunLoopFor(kPairingTimeout - zx::duration(1));
  // Receive the not special-cased Pairing Response, which should trigger SM to send the also not
  // special-cased Pairing Confirm.
  ReceivePairingFeatures();
  // Run the loop for 1 more second, which would timeout if the timer had not been reset.
  RunLoopFor(zx::duration(1));
  // The timeout should not have triggered, so there should be no notification of pairing failure.
  ASSERT_EQ(0, pairing_complete_count());
  ASSERT_EQ(0, security_callback_count());
  // Verify that the timer is in fact still active; without receiving further messages, the timeout
  // should trigger.
  RunLoopFor(kPairingTimeout);
  ASSERT_EQ(1, pairing_complete_count());
  ASSERT_EQ(1, security_callback_count());
  ASSERT_EQ(HostError::kTimedOut, pairing_complete_status().error());
  ASSERT_EQ(HostError::kTimedOut, security_status().error());
}

TEST_F(SMP_InitiatorPairingTest, ModifyAssignedLinkLtkBeforeSecurityRequestCausesDisconnect) {
  SecurityProperties sec_props(SecurityLevel::kAuthenticated, 16, false);
  const LTK kOriginalLtk(sec_props, hci::LinkKey({1}, 2, 3));
  const hci::LinkKey kModifiedLtk(hci::LinkKey({4}, 5, 6));

  EXPECT_TRUE(pairing()->AssignLongTermKey(kOriginalLtk));
  fake_link()->set_le_ltk(kModifiedLtk);
  // When we receive the Security Request on a bonded (i.e. AssignLongTermKey has been called)
  // connection, we will refresh the encryption key. This checks that the link LTK = the SMP LTK
  // which is not the case.
  ReceiveSecurityRequest(AuthReqField{0});
  RunLoopUntilIdle();
  ASSERT_TRUE(fake_chan()->link_error());
  ASSERT_EQ(1, auth_failure_callback_count());
  ASSERT_EQ(hci::StatusCode::kPinOrKeyMissing, auth_failure_status().protocol_error());
}

TEST_F(SMP_ResponderPairingTest, SuccessfulPairAfterResetInProgressPairing) {
  ReceivePairingRequest();
  RunLoopUntilIdle();
  // At this point, we expect to have completed Phase 1, and pairing should still be in progress.
  EXPECT_EQ(1, pairing_response_count());

  pairing()->Abort();
  RunLoopUntilIdle();
  // Pairing should have failed and ended.
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, pairing_complete_count());

  // Verify that the next pairing request is properly handled
  ReceivePairingRequest();
  RunLoopUntilIdle();
  // At this point, we expect to have completed Phase 1, and pairing should still be in progress.
  EXPECT_EQ(2, pairing_response_count());
}

TEST_F(SMP_ResponderPairingTest, SecurityRequestCausesPairing) {
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();
  AuthReqField expected_auth_req = AuthReq::kBondingFlag;
  EXPECT_EQ(1, security_request_count());
  EXPECT_EQ(expected_auth_req, security_request_payload());
  UInt128 ltk_bytes;
  FastForwardToPhase3(&ltk_bytes, true /*secure_connections*/);
  // Pairing should have succeeded
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // LTK should have been assigned to the link.
  hci::LinkKey kExpectedLinkKey(ltk_bytes, 0, 0);
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kExpectedLinkKey, fake_link()->ltk());

  EXPECT_EQ(SecurityLevel::kEncrypted, sec_props().level());
  EXPECT_EQ(16u, sec_props().enc_key_size());
  EXPECT_TRUE(sec_props().secure_connections());

  // Should have notified the LTK.
  EXPECT_EQ(1, pairing_data_callback_count());
  ASSERT_TRUE(local_ltk());
  EXPECT_EQ(sec_props(), local_ltk()->security());
  EXPECT_EQ(kExpectedLinkKey, local_ltk()->key());
}

TEST_F(SMP_ResponderPairingTest, SecurityRequestWithExistingLtk) {
  const SecurityProperties kProps(SecurityLevel::kAuthenticated, kMaxEncryptionKeySize, true);
  const LTK kLtk(kProps, hci::LinkKey({1, 2, 3}, 0, 0));
  // This pretends that we have an already-bonded LTK.
  pairing()->AssignLongTermKey(kLtk);
  // LTK should have been assigned to the link.
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kLtk.key(), fake_link()->ltk());

  // Make the Security Upgrade request
  UpgradeSecurity(SecurityLevel::kAuthenticated);
  RunLoopUntilIdle();
  AuthReqField expected_auth_req = AuthReq::kBondingFlag | AuthReq::kMITM;
  EXPECT_EQ(1, security_request_count());
  EXPECT_EQ(expected_auth_req, security_request_payload());
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /*enabled*/);

  // Security should be upgraded.
  EXPECT_EQ(1, security_callback_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(kProps.level(), sec_props().level());
  EXPECT_EQ(16u, sec_props().enc_key_size());
  EXPECT_TRUE(sec_props().secure_connections());

  // No pairing should have taken place - we had an already-bonded LTK.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, pairing_complete_count());
  EXPECT_EQ(0, pairing_data_callback_count());
}

TEST_F(SMP_ResponderPairingTest, SecurityRequestInitiatorEncryptsWithInsufficientSecurityLtk) {
  const SecurityProperties kProps(SecurityLevel::kEncrypted, kMaxEncryptionKeySize, true);
  const LTK kLtk(kProps, hci::LinkKey({1, 2, 3}, 0, 0));
  // This pretends that we have an already-bonded LTK with kEncrypted security level.
  pairing()->AssignLongTermKey(kLtk);
  // LTK should have been assigned to the link.
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kLtk.key(), fake_link()->ltk());

  // Make a security request for authenticated security
  UpgradeSecurity(SecurityLevel::kAuthenticated);
  RunLoopUntilIdle();
  AuthReqField expected_auth_req = AuthReq::kBondingFlag | AuthReq::kMITM;
  EXPECT_EQ(1, security_request_count());
  EXPECT_EQ(expected_auth_req, security_request_payload());

  // Pretend the SMP initiator started encryption with the bonded LTK of SecurityLevel::kEncrypted.
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /*enabled*/);

  // If the peer responds to our MITM security request by encrypting with an unauthenticated key,
  // they stored the LTK/handle security request incorrectly - either way, disconnect the link.
  ASSERT_TRUE(fake_chan()->link_error());
}

TEST_F(SMP_ResponderPairingTest, AuthenticatedSecurityRequestWithInsufficientIoCapRejected) {
  SetUpSecurityManager(IOCapability::kNoInputNoOutput);
  // Make a security request for authenticated security
  UpgradeSecurity(SecurityLevel::kAuthenticated);
  RunLoopUntilIdle();
  // The security callback should have been rejected w/o sending any messages, as our IOCap cannot
  // perform authenticated pairing.
  EXPECT_EQ(0, security_request_count());
  EXPECT_EQ(1, security_callback_count());
  ASSERT_TRUE(security_status().is_protocol_error());
  EXPECT_EQ(ErrorCode::kAuthenticationRequirements, security_status().protocol_error());
  EXPECT_EQ(SecurityLevel::kNoSecurity, sec_props().level());
}

TEST_F(SMP_ResponderPairingTest, HandlesMultipleSecurityRequestsCorrectly) {
  // Make a security request for encrypted security
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();
  AuthReqField expected_auth_req = AuthReq::kBondingFlag;
  EXPECT_EQ(1, security_request_count());
  EXPECT_EQ(expected_auth_req, security_request_payload());

  // Making another security request, this time for authenticated security, while the first is
  // still pending should not cause another Security Request message to be sent.
  UpgradeSecurity(SecurityLevel::kAuthenticated);
  RunLoopUntilIdle();
  EXPECT_EQ(1, security_request_count());

  // Handle the first Security Request
  UInt128 ltk_bytes;
  FastForwardToPhase3(&ltk_bytes, true /*secure_connections*/, SecurityLevel::kEncrypted);
  // Pairing should have succeeded
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  EXPECT_EQ(SecurityLevel::kEncrypted, sec_props().level());

  // Should have notified the LTK.
  EXPECT_EQ(1, pairing_data_callback_count());
  ASSERT_TRUE(local_ltk());
  EXPECT_EQ(sec_props(), local_ltk()->security());
  EXPECT_EQ(ltk_bytes, local_ltk()->key().value());

  // After the first pairing satisfied the kEncrypted Security Request, the pending kAuthenticated
  // Security Request should have been sent immediately.
  EXPECT_EQ(2, security_request_count());
}

TEST_F(SMP_ResponderPairingTest, ReceiveSecondPairingRequestWhilePairing) {
  ReceivePairingRequest();
  RunLoopUntilIdle();

  // We should have sent a pairing response and should now be in Phase 2,
  // waiting for the peer to send us Mconfirm.
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // This should cause pairing to be aborted.
  ReceivePairingRequest();
  RunLoopUntilIdle();
  EXPECT_EQ(0, pairing_request_count());
  // We will abort the second pairing request without responding if we're already in progress
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(received_error_code(), pairing_complete_status().protocol_error());
}

TEST_F(SMP_ResponderPairingTest, ReceiveConfirmValueWhileWaitingForTK) {
  bool tk_requested = false;
  ConfirmCallback respond;
  set_confirm_delegate([&](ConfirmCallback cb) {
    tk_requested = true;
    respond = std::move(cb);
  });

  ReceivePairingRequest();
  RunLoopUntilIdle();
  ASSERT_TRUE(tk_requested);

  UInt128 confirm;
  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // Pairing should still be in progress without sending out any packets.
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Respond with the TK. This should cause us to send Sconfirm.
  respond(true);
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());
}

TEST_F(SMP_ResponderPairingTest, LegacyPhase2ReceivePairingRandomInWrongOrder) {
  ReceivePairingRequest();
  RunLoopUntilIdle();

  // We should have sent a pairing response and should now be in Phase 2,
  // waiting for the peer to send us Mconfirm.
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Peer sends Mrand before Mconfirm.
  UInt128 random;
  ReceivePairingRandom(random);
  RunLoopUntilIdle();
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, received_error_code());
  EXPECT_EQ(ErrorCode::kUnspecifiedReason, pairing_complete_status().protocol_error());
}

TEST_F(SMP_ResponderPairingTest, LegacyPhase2MconfirmValueInvalid) {
  ReceivePairingRequest();
  RunLoopUntilIdle();

  // We should have sent a pairing response and should now be in Phase 2,
  // waiting for the peer to send us Mconfirm.
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Set up values that don't match.
  UInt128 confirm, random;
  confirm.fill(0);
  random.fill(1);

  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // We should have sent Sconfirm.
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Peer sends Mrand that doesn't match. We should reject the pairing
  // without sending Srand.
  ReceivePairingRandom(random);
  RunLoopUntilIdle();
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kConfirmValueFailed, received_error_code());
  EXPECT_EQ(ErrorCode::kConfirmValueFailed, pairing_complete_status().protocol_error());
}

TEST_F(SMP_ResponderPairingTest, LegacyPhase2ConfirmValuesExchanged) {
  ReceivePairingRequest();
  RunLoopUntilIdle();

  // We should have sent a pairing response and should now be in Phase 2,
  // waiting for the peer to send us Mconfirm.
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(0, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Set up Sconfirm and Srand values that match.
  UInt128 confirm, random;
  GenerateMatchingLegacyConfirmAndRandom(&confirm, &random);

  // Peer sends Mconfirm.
  ReceivePairingConfirm(confirm);
  RunLoopUntilIdle();

  // We should have sent Sconfirm.
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(0, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Peer sends Mrand.
  ReceivePairingRandom(random);
  RunLoopUntilIdle();

  // We should have sent Srand.
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(1, pairing_response_count());
  EXPECT_EQ(1, pairing_confirm_count());
  EXPECT_EQ(1, pairing_random_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, pairing_complete_count());

  // Sconfirm/Srand values we sent should be correct.
  UInt128 expected_confirm;
  GenerateLegacyConfirmValue(pairing_random(), &expected_confirm, true /* peer_initiator */);
  EXPECT_EQ(expected_confirm, pairing_confirm());
}

TEST_F(SMP_ResponderPairingTest, LegacyPhase3LocalLTKDistributionNoRemoteKeys) {
  EXPECT_EQ(0, enc_info_count());
  EXPECT_EQ(0, master_ident_count());

  UInt128 stk;
  KeyDistGenField remote_keys{0}, local_keys{KeyDistGen::kEncKey};
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted, remote_keys,
                      local_keys);

  // Local LTK, EDiv, and Rand should be sent to the peer.
  EXPECT_EQ(1, enc_info_count());
  EXPECT_EQ(1, master_ident_count());
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(enc_info(), fake_link()->ltk()->value());
  EXPECT_EQ(ediv(), fake_link()->ltk()->ediv());
  EXPECT_EQ(rand(), fake_link()->ltk()->rand());

  // This LTK should be stored with the pairing data but the pairing callback
  // shouldn't be called because pairing wasn't initiated by UpgradeSecurity().
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());

  // Pairing is considered complete when all keys have been distributed even if
  // we're still encrypted with the STK. This is because the initiator may not
  // always re-encrypt the link with the LTK until a reconnection.
  EXPECT_EQ(1, pairing_data_callback_count());

  // Nonetheless the link should have been assigned the LTK.
  ASSERT_TRUE(pairing_data().local_ltk.has_value());
  EXPECT_EQ(fake_link()->ltk(), pairing_data().local_ltk->key());

  // Make sure that an encryption change has no effect.
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
  RunLoopUntilIdle();
  EXPECT_EQ(1, pairing_data_callback_count());

  // No additional security property update should have been sent since the STK
  // and LTK have the same properties.
  EXPECT_EQ(1, new_sec_props_count());
}

TEST_F(SMP_ResponderPairingTest, LegacyPhase3LocalLTKDistributionWithRemoteKeys) {
  EXPECT_EQ(0, enc_info_count());
  EXPECT_EQ(0, master_ident_count());

  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kIdKey,    // remote keys
                      KeyDistGen::kEncKey);  // local keys

  // Local LTK, EDiv, and Rand should be sent to the peer - we don't assign the new LTK to the link
  // until pairing is complete.
  EXPECT_EQ(1, enc_info_count());
  EXPECT_EQ(1, master_ident_count());

  // No local identity information should have been sent.
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());

  // This LTK should be stored with the pairing data but the pairing callback
  // shouldn't be called because pairing wasn't initiated by UpgradeSecurity().
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());

  // Still waiting for initiator's keys.
  EXPECT_EQ(0, pairing_data_callback_count());

  const auto kIrk = Random<UInt128>();
  ReceiveIdentityResolvingKey(kIrk);
  ReceiveIdentityAddress(kPeerAddr);
  RunLoopUntilIdle();

  // Pairing is considered complete when all keys have been distributed even if
  // we're still encrypted with the STK. This is because the initiator may not
  // always re-encrypt the link with the LTK until a reconnection.
  EXPECT_EQ(1, pairing_data_callback_count());

  // The peer should have sent us its identity information.
  ASSERT_TRUE(pairing_data().irk);
  EXPECT_EQ(kIrk, pairing_data().irk->value());
  ASSERT_TRUE(pairing_data().identity_address);
  EXPECT_EQ(kPeerAddr, *pairing_data().identity_address);

  // Nonetheless the link should have been assigned the LTK.
  ASSERT_TRUE(pairing_data().local_ltk.has_value());
  EXPECT_EQ(fake_link()->ltk(), pairing_data().local_ltk->key());
}

// Locally generated ltk length should match max key length specified
TEST_F(SMP_ResponderPairingTest, LegacyPhase3LocalLTKMaxLength) {
  EXPECT_EQ(0, enc_info_count());
  EXPECT_EQ(0, master_ident_count());

  UInt128 stk;
  uint16_t max_key_size = 7;

  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      0u,                   // remote keys
                      KeyDistGen::kEncKey,  // local keys
                      max_key_size);

  // Local LTK, EDiv, and Rand should be sent to the peer.
  EXPECT_EQ(1, enc_info_count());
  EXPECT_EQ(1, master_ident_count());
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(enc_info(), fake_link()->ltk()->value());
  EXPECT_EQ(ediv(), fake_link()->ltk()->ediv());
  EXPECT_EQ(rand(), fake_link()->ltk()->rand());

  // This LTK should be stored with the pairing data but the pairing callback
  // shouldn't be called because pairing wasn't initiated by UpgradeSecurity().
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(0, security_callback_count());

  // Pairing is considered complete when all keys have been distributed even if
  // we're still encrypted with the STK. This is because the initiator may not
  // always re-encrypt the link with the LTK until a reconnection.
  EXPECT_EQ(1, pairing_data_callback_count());

  // The link should have been assigned the LTK.
  ASSERT_TRUE(pairing_data().local_ltk.has_value());
  EXPECT_EQ(fake_link()->ltk(), pairing_data().local_ltk->key());

  // Ensure that most significant (16 - max_key_size) bytes are zero. The key
  // should be generated up to the max_key_size.
  auto ltk = pairing_data().local_ltk->key().value();
  for (auto i = max_key_size; i < ltk.size(); i++) {
    EXPECT_TRUE(ltk[i] == 0);
  }
}

TEST_F(SMP_ResponderPairingTest, LegacyPhase3ReceiveInitiatorEncKey) {
  UInt128 stk;
  KeyDistGenField remote_keys{KeyDistGen::kEncKey}, local_keys{0u};
  FastForwardToPhase3(&stk, false, SecurityLevel::kEncrypted, remote_keys, local_keys);

  const uint64_t kRand = 5;
  const uint16_t kEDiv = 20;
  const hci::LinkKey kLTK({1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0}, kRand, kEDiv);

  ReceiveEncryptionInformation(kLTK.value());
  ReceiveMasterIdentification(kRand, kEDiv);
  RunLoopUntilIdle();

  // Pairing should have succeeded.
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_TRUE(security_status());
  EXPECT_EQ(security_status(), pairing_complete_status());

  // No pairing callbacks needed as this is a peer-initiated pairing.
  EXPECT_EQ(0, security_callback_count());

  // Only the STK should be assigned to the link, as the distributed LTK was initiator-generated.
  // This means it can only be used to encrypt future connections where the roles are reversed.
  EXPECT_EQ(stk, fake_link()->ltk()->value());

  // Should have been called at least once to determine local identity availability.
  EXPECT_NE(0, local_id_info_callback_count());

  // Should have notified pairing data callback with the LTK.
  EXPECT_EQ(1, pairing_data_callback_count());
  ASSERT_TRUE(peer_ltk());

  // LTK received OTA should match what we notified the pairing data callback with.
  EXPECT_EQ(kLTK, peer_ltk()->key());
}

TEST_F(SMP_ResponderPairingTest, LegacyPhase3LocalIdKeyDistributionWithRemoteKeys) {
  IdentityInfo local_id_info;
  local_id_info.irk = UInt128{{1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0}};
  local_id_info.address = kLocalAddr;
  set_local_id_info(local_id_info);

  EXPECT_EQ(0, enc_info_count());
  EXPECT_EQ(0, master_ident_count());

  UInt128 stk;
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      KeyDistGen::kIdKey,   // remote keys
                      KeyDistGen::kIdKey);  // local keys

  // No local LTK, EDiv, and Rand should be sent to the peer.
  EXPECT_EQ(0, enc_info_count());
  EXPECT_EQ(0, master_ident_count());

  // Local identity information should have been sent.
  EXPECT_EQ(1, id_info_count());
  EXPECT_EQ(local_id_info.irk, id_info());
  EXPECT_EQ(1, id_addr_info_count());
  EXPECT_EQ(local_id_info.address, id_addr_info());

  // Still waiting for initiator's keys.
  EXPECT_EQ(0, pairing_data_callback_count());

  const auto kIrk = Random<UInt128>();
  ReceiveIdentityResolvingKey(kIrk);
  ReceiveIdentityAddress(kPeerAddr);
  RunLoopUntilIdle();

  // Pairing is considered complete when all keys have been distributed even if
  // we're still encrypted with the STK. This is because the initiator may not
  // always re-encrypt the link with the LTK until a reconnection.
  EXPECT_EQ(1, pairing_data_callback_count());

  // The peer should have sent us its identity information.
  ASSERT_TRUE(pairing_data().irk);
  EXPECT_EQ(kIrk, pairing_data().irk->value());
  ASSERT_TRUE(pairing_data().identity_address);
  EXPECT_EQ(kPeerAddr, *pairing_data().identity_address);
}

TEST_F(SMP_ResponderPairingTest, AssignLongTermKeyFailsDuringPairing) {
  ReceivePairingRequest();
  RunLoopUntilIdle();
  SecurityProperties sec_props(SecurityLevel::kAuthenticated, 16, false);
  EXPECT_FALSE(pairing()->AssignLongTermKey(LTK(sec_props, hci::LinkKey())));
  EXPECT_EQ(0, fake_link()->start_encryption_count());
  EXPECT_EQ(SecurityLevel::kNoSecurity, pairing()->security().level());
}

TEST_F(SMP_ResponderPairingTest, AssignLongTermKey) {
  SecurityProperties sec_props(SecurityLevel::kAuthenticated, 16, false);
  LTK ltk(sec_props, hci::LinkKey());

  EXPECT_TRUE(pairing()->AssignLongTermKey(ltk));
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(ltk.key(), *fake_link()->ltk());

  // No encryption request should have been made as the initiator is expected to
  // do it.
  EXPECT_EQ(0, fake_link()->start_encryption_count());

  // The link security level is not assigned until successful encryption.
  EXPECT_EQ(SecurityProperties(), pairing()->security());
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /* enabled */);
  RunLoopUntilIdle();

  EXPECT_EQ(1, new_sec_props_count());
  EXPECT_EQ(sec_props, new_sec_props());
  EXPECT_EQ(sec_props, pairing()->security());
}

TEST_F(SMP_ResponderPairingTest, EncryptWithLinkKeyModifiedOutsideSmDisconnects) {
  SecurityProperties sec_props(SecurityLevel::kAuthenticated, 16, false);
  const LTK kOriginalLtk(sec_props, hci::LinkKey({1}, 2, 3));
  const hci::LinkKey kModifiedLtk(hci::LinkKey({4}, 5, 6));

  EXPECT_TRUE(pairing()->AssignLongTermKey(kOriginalLtk));
  fake_link()->set_le_ltk(kModifiedLtk);
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /*enabled*/);
  RunLoopUntilIdle();
  ASSERT_TRUE(fake_chan()->link_error());
  ASSERT_EQ(1, auth_failure_callback_count());
  ASSERT_EQ(hci::StatusCode::kPinOrKeyMissing, auth_failure_status().protocol_error());
}

TEST_F(SMP_ResponderPairingTest, EncryptWithLinkKeyButNoSmLtkDisconnects) {
  // The LE link LTK should always be assigned through SM, so while encryption could succeed with
  // a link LTK but no SM LTK, this is a violation of bt-host assumptions and we will disconnect.
  fake_link()->set_le_ltk(hci::LinkKey({1}, 2, 3));
  fake_link()->TriggerEncryptionChangeCallback(hci::Status(), true /*enabled*/);
  RunLoopUntilIdle();
  ASSERT_TRUE(fake_chan()->link_error());
  ASSERT_EQ(1, auth_failure_callback_count());
  ASSERT_EQ(hci::StatusCode::kPinOrKeyMissing, auth_failure_status().protocol_error());
}

// As responder, we ignore security requests and don't send a Pairing Request or encrypt the link
// in response.
TEST_F(SMP_ResponderPairingTest, ReceiveSecurityRequest) {
  ReceiveSecurityRequest();
  EXPECT_EQ(0, pairing_request_count());
  EXPECT_EQ(0, fake_link()->start_encryption_count());
}

// Test that LTK is generated and passed up to SecurityManager when both sides request bonding
TEST_F(SMP_ResponderPairingTest, BothSidesRequestBondingLTKCreated) {
  UInt128 stk;
  SetUpSecurityManager(IOCapability::kDisplayOnly);
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      0u,                   // remote keys
                      KeyDistGen::kEncKey,  // local keys
                      kMaxEncryptionKeySize, BondableMode::Bondable);

  // The link should have been assigned the LTK.
  EXPECT_TRUE(pairing_data().local_ltk.has_value());
}

// Test that LTK is not passed up to SecurityManager when local side requests non-bondable mode and
// peer requests bondable mode.
TEST_F(SMP_ResponderPairingTest, LocalRequestsNonBondableNoLTKCreated) {
  UInt128 stk;
  SetUpSecurityManager(IOCapability::kDisplayOnly, BondableMode::NonBondable);
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      0u,                   // remote keys
                      KeyDistGen::kEncKey,  // local keys
                      kMaxEncryptionKeySize, BondableMode::Bondable);

  // The link should not have been assigned the LTK.
  EXPECT_FALSE(pairing_data().local_ltk.has_value() || pairing_data().peer_ltk.has_value());
}

// Test that LTK is not passed up to SecurityManager when local side requests bondable mode and peer
// requests non-bondable mode.
TEST_F(SMP_ResponderPairingTest, PeerRequestsNonBondableNoLTKCreated) {
  UInt128 stk;
  SetUpSecurityManager(IOCapability::kDisplayOnly, BondableMode::Bondable);
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      0u,  // remote keys
                      0u,  // local keys
                      kMaxEncryptionKeySize, BondableMode::NonBondable);

  // The link should not have been assigned the LTK.
  EXPECT_FALSE(pairing_data().local_ltk.has_value() || pairing_data().peer_ltk.has_value());
}

// Test that LTK is not generated and passed up to SecurityManager when both sides request
// non-bondable mode.
TEST_F(SMP_ResponderPairingTest, BothSidesRequestNonBondableNoLTKCreated) {
  UInt128 stk;
  SetUpSecurityManager(IOCapability::kDisplayOnly, BondableMode::NonBondable);
  FastForwardToPhase3(&stk, false /*secure_connections*/, SecurityLevel::kEncrypted,
                      0u,  // remote keys
                      0u,  // local keys
                      kMaxEncryptionKeySize, BondableMode::NonBondable);

  // The link should not have been assigned the LTK.
  EXPECT_FALSE(pairing_data().local_ltk.has_value() || pairing_data().peer_ltk.has_value());
}

TEST_F(SMP_ResponderPairingTest, PairingRequestStartsPairingTimer) {
  ReceivePairingRequest();
  RunLoopFor(kPairingTimeout);
  EXPECT_TRUE(fake_chan()->link_error());
  // Pairing should fail, but no callbacks should be notified because the pairing was initiated
  // remotely, not through UpgradeSecurity locally
  ASSERT_EQ(1, pairing_complete_count());
  EXPECT_EQ(HostError::kTimedOut, pairing_complete_status().error());
  EXPECT_EQ(0, security_callback_count());
}

TEST_F(SMP_ResponderPairingTest, RejectUnauthenticatedPairingInSecureConnectionsOnlyMode) {
  SetUpSecurityManager(IOCapability::kKeyboardDisplay);
  pairing()->set_security_mode(gap::LeSecurityMode::SecureConnectionsOnly);
  // In SC Only mode, SM should translate this "encrypted" request into a MITM requirement.
  UpgradeSecurity(SecurityLevel::kEncrypted);
  RunLoopUntilIdle();
  EXPECT_EQ(1, security_request_count());
  EXPECT_EQ(AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC, security_request_payload());
  // The peer has NoInputNoOutput IOCapabilities, thus cannot perform authenticated pairing.
  ReceivePairingRequest(IOCapability::kNoInputNoOutput, AuthReq::kBondingFlag | AuthReq::kSC);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, security_callback_count());
  EXPECT_EQ(ErrorCode::kAuthenticationRequirements, security_status().protocol_error());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(security_status(), pairing_complete_status());
}

TEST_F(SMP_ResponderPairingTest, RejectInsufficientKeySizeRequestInSecureConnectionsOnlyMode) {
  SetUpSecurityManager(IOCapability::kKeyboardDisplay);
  pairing()->set_security_mode(gap::LeSecurityMode::SecureConnectionsOnly);
  // The peer encryption key size is not kMaxEncryptionKeySize, thus does not meet the Secure
  // Connections Only requirements.
  ReceivePairingRequest(IOCapability::kDisplayYesNo, AuthReq::kBondingFlag | AuthReq::kSC,
                        kMaxEncryptionKeySize - 1);
  RunLoopUntilIdle();

  EXPECT_EQ(1, pairing_failed_count());
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(ErrorCode::kEncryptionKeySize, pairing_complete_status().protocol_error());
}

// Tests that Secure Connections works as responder
TEST_F(SMP_ResponderPairingTest, SecureConnectionsWorks) {
  // Must have DisplayYesNo IOC to generate Authenticated security per kExpectedSecurity
  SetUpSecurityManager(IOCapability::kDisplayYesNo);
  UInt128 ltk_bytes;
  const SecurityProperties kExpectedSecurity(SecurityLevel::kAuthenticated, kMaxEncryptionKeySize,
                                             true /* secure connections */);
  FastForwardToPhase3(&ltk_bytes, true /*secure_connections*/, kExpectedSecurity.level());

  const LTK kExpectedLtk(kExpectedSecurity, hci::LinkKey(ltk_bytes, 0, 0));
  ASSERT_TRUE(fake_link()->ltk());
  EXPECT_EQ(kExpectedLtk.key(), fake_link()->ltk());

  // Pairing should succeed with the LTK as the SC pairing is bondable, even though no keys need to
  // be distributed in Phase 3.
  EXPECT_EQ(1, pairing_data_callback_count());
  EXPECT_TRUE(local_ltk().has_value());
  EXPECT_EQ(kExpectedLtk, local_ltk());
  EXPECT_EQ(local_ltk(), peer_ltk());
  EXPECT_FALSE(irk());
  EXPECT_FALSE(identity());
  EXPECT_FALSE(csrk());

  // Should have been called at least once to determine local identity  availability.
  EXPECT_NE(0, local_id_info_callback_count());
  // Pairing should complete successfully
  EXPECT_EQ(1, pairing_complete_count());
  EXPECT_EQ(0, pairing_failed_count());
  EXPECT_TRUE(pairing_complete_status());

  // No callbacks are notified as the peer started this pairing, not a call to UpgradeSecurity.
  EXPECT_EQ(0, security_callback_count());
  EXPECT_EQ(0, id_info_count());
  EXPECT_EQ(0, id_addr_info_count());

  EXPECT_EQ(kExpectedSecurity, pairing()->security());

  // The security properties should have been updated to match the LTK.
  EXPECT_EQ(1, new_sec_props_count());
  EXPECT_EQ(pairing()->security(), new_sec_props());

  ASSERT_TRUE(fake_link()->ltk());
}
}  // namespace
}  // namespace bt::sm
