// 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-spec/link_key.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/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
