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

#include <memory>

#include <fbl/macros.h>
#include <gtest/gtest.h>

#include "lib/fpromise/result.h"
#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/connection.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_channel_test.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/fake_phase_listener.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/types.h"
#include "src/lib/fxl/memory/weak_ptr.h"

namespace bt::sm {
namespace {

struct Phase1Args {
  PairingRequestParams preq = PairingRequestParams();
  IOCapability io_capability = IOCapability::kNoInputNoOutput;
  BondableMode bondable_mode = BondableMode::Bondable;
  SecurityLevel level = SecurityLevel::kEncrypted;
  bool sc_supported = false;
};

class Phase1Test : public l2cap::testing::FakeChannelTest {
 public:
  Phase1Test() = default;
  ~Phase1Test() override = default;

 protected:
  void SetUp() override { NewPhase1(); }

  void TearDown() override { phase_1_ = nullptr; }

  void NewPhase1(Role role = Role::kInitiator, Phase1Args phase_args = Phase1Args(),
                 bt::LinkType ll_type = bt::LinkType::kLE) {
    l2cap::ChannelId cid =
        ll_type == bt::LinkType::kLE ? l2cap::kLESMPChannelId : l2cap::kSMPChannelId;
    uint16_t mtu = phase_args.sc_supported ? l2cap::kMaxMTU : kNoSecureConnectionsMtu;
    ChannelOptions options(cid, mtu);
    options.link_type = ll_type;

    listener_ = std::make_unique<FakeListener>();
    fake_chan_ = CreateFakeChannel(options);
    sm_chan_ = std::make_unique<PairingChannel>(fake_chan_);
    auto complete_cb = [this](PairingFeatures features, PairingRequestParams preq,
                              PairingResponseParams pres) {
      feature_exchange_count_++;
      features_ = features;
      last_pairing_req_ = util::NewPdu(sizeof(PairingRequestParams));
      last_pairing_res_ = util::NewPdu(sizeof(PairingResponseParams));
      PacketWriter preq_writer(kPairingRequest, last_pairing_req_.get());
      PacketWriter pres_writer(kPairingResponse, last_pairing_res_.get());
      *preq_writer.mutable_payload<PairingRequestParams>() = preq;
      *pres_writer.mutable_payload<PairingResponseParams>() = pres;
    };
    if (role == Role::kInitiator) {
      phase_1_ = Phase1::CreatePhase1Initiator(sm_chan_->GetWeakPtr(), listener_->as_weak_ptr(),
                                               phase_args.io_capability, phase_args.bondable_mode,
                                               phase_args.level, std::move(complete_cb));
    } else {
      phase_1_ = Phase1::CreatePhase1Responder(sm_chan_->GetWeakPtr(), listener_->as_weak_ptr(),
                                               phase_args.preq, phase_args.io_capability,
                                               phase_args.bondable_mode, phase_args.level,
                                               std::move(complete_cb));
    }
  }

  l2cap::testing::FakeChannel* fake_chan() const { return fake_chan_.get(); }
  Phase1* phase_1() { return phase_1_.get(); }
  FakeListener* listener() { return listener_.get(); }

  int feature_exchange_count() { return feature_exchange_count_; }
  PairingFeatures features() { return features_; }
  ByteBuffer* last_preq() { return last_pairing_req_.get(); }
  ByteBuffer* last_pres() { return last_pairing_res_.get(); }

 private:
  std::unique_ptr<FakeListener> listener_;
  fbl::RefPtr<l2cap::testing::FakeChannel> fake_chan_;
  std::unique_ptr<PairingChannel> sm_chan_;
  std::unique_ptr<Phase1> phase_1_;

  int feature_exchange_count_ = 0;
  PairingFeatures features_;
  MutableByteBufferPtr last_pairing_req_;
  MutableByteBufferPtr last_pairing_res_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Phase1Test);
};

TEST_F(Phase1Test, FeatureExchangeStartDefaultParams) {
  const StaticByteBuffer kRequest(0x01,  // code: "Pairing Request"
                                  0x03,  // IO cap.: NoInputNoOutput
                                  0x00,  // OOB: not present
                                  AuthReq::kBondingFlag | AuthReq::kCT2,
                                  0x10,                 // encr. key size: 16 (default max)
                                  KeyDistGen::kEncKey,  // initiator keys
                                  KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));
}

TEST_F(Phase1Test, FeatureExchangeStartCustomParams) {
  auto phase_args = Phase1Args{.io_capability = IOCapability::kDisplayYesNo,
                               .bondable_mode = BondableMode::NonBondable,
                               .level = SecurityLevel::kAuthenticated,
                               .sc_supported = true};
  NewPhase1(Role::kInitiator, phase_args);

  const StaticByteBuffer kRequest(0x01,  // code: "Pairing Request"
                                  0x01,  // IO cap.: DisplayYesNo
                                  0x00,  // OOB: not present
                                  AuthReq::kMITM | AuthReq::kSC | AuthReq::kCT2,
                                  0x10,  // encr. key size: 16 (default max)
                                  0x00,  // initiator keys: none - non-bondable mode
                                  0x00   // responder keys: none - non-bondable mode
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));
}

TEST_F(Phase1Test, FeatureExchangeInitiatorWithIdentityInfo) {
  listener()->set_identity_info(IdentityInfo());

  const StaticByteBuffer kRequest(0x01,  // code: "Pairing Request"
                                  0x03,  // IO cap.: NoInputNoOutput
                                  0x00,  // OOB: not present
                                  AuthReq::kBondingFlag | AuthReq::kCT2,
                                  0x10,  // encr. key size: 16 (default max)
                                  KeyDistGen::kEncKey | KeyDistGen::kIdKey,  // initiator keys
                                  KeyDistGen::kEncKey | KeyDistGen::kIdKey   // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  EXPECT_EQ(1, listener()->identity_info_count());
}

TEST_F(Phase1Test, FeatureExchangePairingFailed) {
  fake_chan()->Receive(StaticByteBuffer(0x05,  // code: Pairing Failed
                                        0x05   // reason: Pairing Not Supported
                                        ));
  RunLoopUntilIdle();

  EXPECT_EQ(Error(ErrorCode::kPairingNotSupported), listener()->last_error());
  EXPECT_EQ(1, listener()->pairing_error_count());
}

TEST_F(Phase1Test, FeatureExchangeLocalRejectsUnsupportedInitiatorKeys) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x03,  // IO cap.: NoInputNoOutput
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kCT2,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const auto kResponse =
      StaticByteBuffer(0x02,  // code: Pairing Response
                       0x00,  // IO cap.: DisplayOnly
                       0x00,  // OOB: not present
                       0x00,
                       0x07,                // encr. key size: 7 (default min)
                       KeyDistGen::kIdKey,  // initiator keys - not listed in kRequest
                       KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
      );
  const StaticByteBuffer kFailure(0x05,  // code: Pairing Failed
                                  0x0A   // reason: Invalid Parameters
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  // We should receive a pairing response and reply back with Pairing Failed.
  EXPECT_TRUE(ReceiveAndExpect(kResponse, kFailure));

  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kInvalidParameters), listener()->last_error());
  EXPECT_EQ(0, feature_exchange_count());
}

TEST_F(Phase1Test, FeatureExchangeLocalRejectsUnsupportedResponderKeys) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x03,  // IO cap.: NoInputNoOutput
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kCT2,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const auto kResponse =
      StaticByteBuffer(0x02,  // code: Pairing Response
                       0x00,  // IO cap.: DisplayOnly
                       0x00,  // OOB: not present
                       0x00,
                       0x07,                 // encr. key size: 7 (default min)
                       KeyDistGen::kEncKey,  // initiator keys
                       KeyDistGen::kSignKey  // responder keys - kSignKey not in kRequest
      );
  const StaticByteBuffer kFailure(0x05,  // code: Pairing Failed
                                  0x0A   // reason: Invalid Parameters
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  // We should receive a pairing response and reply back with Pairing Failed.
  EXPECT_TRUE(ReceiveAndExpect(kResponse, kFailure));

  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kInvalidParameters), listener()->last_error());
  EXPECT_EQ(0, feature_exchange_count());
}

// Pairing should fail if MITM is required but the I/O capabilities cannot provide it
TEST_F(Phase1Test, FeatureExchangeFailureAuthenticationRequirements) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x03,  // IO cap.: NoInputNoOutput
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kCT2,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x00,  // IO cap.: DisplayOnly
                                   0x00,  // OOB: not present
                                   AuthReq::kMITM,
                                   0x07,                // encr. key size: 7 (default min)
                                   0x00,                // initiator keys: none
                                   KeyDistGen::kEncKey  // responder keys: it's OK to
                                                        // use fewer keys than in
                                                        // kRequest
  );
  const StaticByteBuffer kFailure(0x05,  // code: Pairing Failed
                                  0x03   // reason: Authentication requirements
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  // We should receive a pairing response and reply back with Pairing Failed.
  EXPECT_TRUE(ReceiveAndExpect(kResponse, kFailure));

  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements), listener()->last_error());
  EXPECT_EQ(0, feature_exchange_count());
}

TEST_F(Phase1Test, FeatureExchangeFailureMalformedRequest) {
  const auto kMalformedResponse =
      StaticByteBuffer(0x02,                // code: Pairing Response
                       0x03,                // IO cap.: NoInputNoOutput
                       0x00,                // OOB: not present
                       0x00,                // AuthReq: empty
                       0x10,                // encr. key size: 16 (default max)
                       KeyDistGen::kEncKey  // initiator key dist.: encr. key only
                                            // Missing last byte, responder key dist.
      );
  const StaticByteBuffer kFailure(0x05,  // code: Pairing Failed
                                  0x0A   // reason: Invalid Parameters
  );

  EXPECT_TRUE(ReceiveAndExpect(kMalformedResponse, kFailure));
  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kInvalidParameters), listener()->last_error());
}

TEST_F(Phase1Test, FeatureExchangeBothSupportSCFeaturesHaveSC) {
  Phase1Args args;
  args.sc_supported = true;
  NewPhase1(Role::kInitiator, args);
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      0x03,  // IO cap.: NoInputNoOutput
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x00,  // IO cap.: DisplayOnly
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kSC,
                                   0x07,                // encr. key size: 7 (default min)
                                   0x00,                // initiator keys: none
                                   KeyDistGen::kEncKey  // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());

  EXPECT_TRUE(features().initiator);
  EXPECT_TRUE(features().secure_connections);
  ASSERT_TRUE(last_preq());
  ASSERT_TRUE(last_pres());
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
}

TEST_F(Phase1Test, FeatureExchangeScIgnoresEncKeyBit) {
  Phase1Args args;
  args.sc_supported = true;
  NewPhase1(Role::kInitiator, args);
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      0x03,  // IO cap.: NoInputNoOutput
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  const auto kResponse = StaticByteBuffer(0x02,  // code: Pairing Response
                                          0x00,  // IO cap.: DisplayOnly
                                          0x00,  // OOB: not present
                                          AuthReq::kBondingFlag | AuthReq::kSC,
                                          0x07,                // encr. key size: 7 (default min)
                                          0x00,                // initiator keys: none
                                          KeyDistGen::kEncKey  // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());

  EXPECT_TRUE(features().initiator);
  EXPECT_TRUE(features().secure_connections);
  // Even though both the pairing request and response had the EncKey bit set, because we
  // resolved the features to secure connections, we zero the bit out.
  EXPECT_FALSE(features().remote_key_distribution & KeyDistGen::kEncKey);
  EXPECT_FALSE(features().remote_key_distribution & KeyDistGen::kEncKey);
  ASSERT_TRUE(last_preq());
  ASSERT_TRUE(last_pres());
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
}

TEST_F(Phase1Test, FeatureExchangeLocalSCRemoteNoSCFeaturesNoSc) {
  Phase1Args args;
  args.sc_supported = true;
  NewPhase1(Role::kInitiator, args);
  const auto kRequest = StaticByteBuffer(
      0x01,  // code: Pairing Request
      0x03,  // IO cap.: NoInputNoOutput
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  const auto kResponse = StaticByteBuffer(0x02,  // code: Pairing Response
                                          0x00,  // IO cap.: DisplayOnly
                                          0x00,  // OOB: not present
                                          AuthReq::kBondingFlag,
                                          0x07,                // encr. key size: 7 (default min)
                                          0x00,                // initiator keys: none
                                          KeyDistGen::kEncKey  // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());

  EXPECT_TRUE(features().initiator);
  EXPECT_FALSE(features().secure_connections);
  ASSERT_TRUE(last_preq());
  ASSERT_TRUE(last_pres());
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
}

TEST_F(Phase1Test, FeatureExchangePairingResponseLegacyJustWorks) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x03,  // IO cap.: NoInputNoOutput
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kCT2,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x00,  // IO cap.: DisplayOnly
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag,
                                   0x07,                 // encr. key size: 7 (default min)
                                   KeyDistGen::kEncKey,  // initiator keys
                                   KeyDistGen::kEncKey   // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());

  EXPECT_TRUE(features().initiator);
  EXPECT_EQ(PairingMethod::kJustWorks, features().method);
  EXPECT_EQ(7, features().encryption_key_size);
  EXPECT_TRUE(KeyDistGen::kEncKey & features().local_key_distribution);
  EXPECT_TRUE(KeyDistGen::kEncKey & features().remote_key_distribution);
  ASSERT_TRUE(last_preq());
  ASSERT_TRUE(last_pres());
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
}

TEST_F(Phase1Test, FeatureExchangePairingResponseLegacyMITM) {
  auto phase_args = Phase1Args{.io_capability = IOCapability::kDisplayYesNo};
  NewPhase1(Role::kInitiator, phase_args);

  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x01,  // IO cap.: DisplayYesNo
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kCT2,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x02,  // IO cap.: KeyboardOnly
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kMITM,
                                   0x07,                // encr. key size: 7 (default min)
                                   0x00,                // initiator keys: none
                                   KeyDistGen::kEncKey  // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());

  EXPECT_TRUE(features().initiator);
  EXPECT_FALSE(features().secure_connections);
  EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay, features().method);
  EXPECT_EQ(7, features().encryption_key_size);
  EXPECT_FALSE(features().local_key_distribution);
  EXPECT_TRUE(KeyDistGen::kEncKey & features().remote_key_distribution);
  ASSERT_TRUE(last_preq() && last_pres());
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
}

TEST_F(Phase1Test, FeatureExchangeEncryptionKeySize) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x03,  // IO cap.: NoInputNoOutput
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kCT2,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x00,  // IO cap.: DisplayOnly
                                   0x00,  // OOB: not present
                                   AuthReq::kMITM,
                                   0x02,                 // encr. key size: 2 (too small)
                                   KeyDistGen::kEncKey,  // initiator keys
                                   KeyDistGen::kEncKey   // responder keys
  );
  const StaticByteBuffer kFailure(0x05,  // code: Pairing Failed
                                  0x06   // reason: Encryption Key Size
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  // We should receive a pairing response and reply back with Pairing Failed.
  EXPECT_TRUE(ReceiveAndExpect(kResponse, kFailure));

  EXPECT_EQ(0, feature_exchange_count());
  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kEncryptionKeySize), listener()->last_error());
}

TEST_F(Phase1Test, FeatureExchangeSecureAuthenticatedEncryptionKeySize) {
  auto phase_args = Phase1Args{.io_capability = IOCapability::kKeyboardDisplay,
                               .level = SecurityLevel::kSecureAuthenticated,
                               .sc_supported = true};
  NewPhase1(Role::kInitiator, phase_args);
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      0x04,  // IO cap.: KeyboardDisplay
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  const StaticByteBuffer kResponse(
      0x02,  // code: Pairing Response
      0x04,  // IO cap.: KeyboardDisplay
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC,
      0x0F,  // encr. key size: 15, i.e. one byte less than max possible encryption key size.
      KeyDistGen::kEncKey,  // initiator keys
      KeyDistGen::kEncKey   // responder keys
  );
  const StaticByteBuffer kFailure(kPairingFailed, ErrorCode::kEncryptionKeySize);

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  // We should receive a pairing response and reply back with Pairing Failed; we enforce that all
  // encryption keys are 16 bytes when `level` is set to SecureAuthenticated.
  EXPECT_TRUE(ReceiveAndExpect(kResponse, kFailure));

  EXPECT_EQ(0, feature_exchange_count());
  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kEncryptionKeySize), listener()->last_error());
}

TEST_F(Phase1Test, FeatureExchangeSecureConnectionsRequiredNotPresent) {
  auto phase_args = Phase1Args{.io_capability = IOCapability::kKeyboardDisplay,
                               .level = SecurityLevel::kSecureAuthenticated,
                               .sc_supported = true};
  NewPhase1(Role::kInitiator, phase_args);
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      0x04,  // IO cap.: KeyboardDisplay
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x04,  // IO cap.: KeyboardDisplay
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kMITM,
                                   0x10,                 // encr. key size: 16 (default max)
                                   KeyDistGen::kEncKey,  // initiator keys
                                   KeyDistGen::kEncKey   // responder keys
  );
  const auto kFailure = StaticByteBuffer(kPairingFailed, ErrorCode::kAuthenticationRequirements);

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  // We should receive a pairing response and reply back with Pairing Failed; we enforce that
  // Secure Connections is used when `level` is set to SecureAuthenticated.
  EXPECT_TRUE(ReceiveAndExpect(kResponse, kFailure));

  EXPECT_EQ(0, feature_exchange_count());
  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements), listener()->last_error());
}

TEST_F(Phase1Test, FeatureExchangeBothSupportScLinkKeyAndCt2GenerateH7CtKey) {
  auto phase_args = Phase1Args{.sc_supported = true};
  NewPhase1(Role::kInitiator, phase_args);
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      IOCapability::kNoInputNoOutput,
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  const auto kResponse = StaticByteBuffer(0x02,  // code: Pairing Response
                                          0x04,  // IO cap.: KeyboardDisplay
                                          0x00,  // OOB: not present
                                          AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
                                          0x10,                  // encr. key size: 16 (default max)
                                          KeyDistGen::kLinkKey,  // initiator keys
                                          KeyDistGen::kLinkKey   // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();
  EXPECT_EQ(1, feature_exchange_count());
  ASSERT_TRUE(features().generate_ct_key.has_value());
  EXPECT_EQ(CrossTransportKeyAlgo::kUseH7, features().generate_ct_key);
}

TEST_F(Phase1Test, FeatureExchangePeerDoesntSupportCt2GenerateH6CtKey) {
  auto phase_args = Phase1Args{.sc_supported = true};
  NewPhase1(Role::kInitiator, phase_args);
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      IOCapability::kNoInputNoOutput,
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x04,  // IO cap.: KeyboardDisplay
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kSC,
                                   0x10,                  // encr. key size: 16 (default max)
                                   KeyDistGen::kLinkKey,  // initiator keys
                                   KeyDistGen::kLinkKey   // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();
  EXPECT_EQ(1, feature_exchange_count());
  ASSERT_TRUE(features().generate_ct_key.has_value());
  EXPECT_EQ(CrossTransportKeyAlgo::kUseH6, features().generate_ct_key);
}

TEST_F(Phase1Test, FeatureExchangePeerDoesntSupportScDoNotGenerateCtKey) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         IOCapability::kNoInputNoOutput,
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kCT2,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  // Although the peer supports CTKG through the hci_spec::LinkKey field and SC, locally we do not
  // support SC, so CTKG is not allowed (v5.2 Vol. 3 Part H 3.6.1).
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x04,  // IO cap.: KeyboardDisplay
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kSC,
                                   0x10,                 // encr. key size: 16 (default max)
                                   KeyDistGen::kEncKey,  // initiator keys
                                   KeyDistGen::kEncKey   // responder keys
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();
  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().generate_ct_key.has_value());
}

TEST_F(Phase1Test, FeatureExchangePeerSupportsCt2ButNotLinkKeyDoNotGenerateCtKey) {
  auto phase_args = Phase1Args{.sc_supported = true};
  NewPhase1(Role::kInitiator, phase_args);
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      IOCapability::kNoInputNoOutput,
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  // The peer indicates support for the Link Key (CTKG) on only one of the Initiator/Responder
  // Key Dist./Gen. fields, as such we do not generate the CT key.
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x04,  // IO cap.: KeyboardDisplay
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kSC | kCT2,
                                   0x10,  // encr. key size: 16 (default max)
                                   0x00,  // initiator keys - none
                                   0x00   // responder keys - none
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();
  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().generate_ct_key.has_value());
}

TEST_F(Phase1Test, FeatureExchangePeerOnlyIndicatesOneLinkKeyDoNotGenerateCtKey) {
  auto phase_args = Phase1Args{.sc_supported = true};
  NewPhase1(Role::kInitiator, phase_args);
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      IOCapability::kNoInputNoOutput,
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  // The peer indicates support for the Link Key (CTKG) on only one of the Initiator/Responder
  // Key Dist./Gen. fields, as such we do not generate the CT key.
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x04,  // IO cap.: KeyboardDisplay
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kSC,
                                   0x10,                  // encr. key size: 16 (default max)
                                   KeyDistGen::kLinkKey,  // initiator keys
                                   0x00                   // responder keys - none
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();
  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().generate_ct_key.has_value());
}

TEST_F(Phase1Test, FeatureExchangeResponderErrorCentral) {
  const auto kRequest =
      StaticByteBuffer(0x01,                 // code: Pairing Request
                       0x03,                 // IO cap.: NoInputNoOutput
                       0x00,                 // OOB: not present
                       0x00,                 // AuthReq: no auth. request by default
                       0x10,                 // encr. key size: 16 (default max)
                       KeyDistGen::kEncKey,  // initiator key dist.: encr. key only
                       KeyDistGen::kEncKey   // responder key dist.: encr. key only
      );
  const StaticByteBuffer kFailure(0x05,  // code: Pairing Failed
                                  ErrorCode::kUnspecifiedReason);

  NewPhase1(Role::kInitiator);
  EXPECT_TRUE(ReceiveAndExpect(kRequest, kFailure));
  EXPECT_EQ(1, listener()->pairing_error_count());
}

// Verify that Pairing Requests are rejected by Phase1 - these are handled elsewhere in our stack.
TEST_F(Phase1Test, Phase1ResponderRejectsPairingRequest) {
  const auto kRequest =
      StaticByteBuffer(0x01,                 // code: Pairing Request
                       0x03,                 // IO cap.: NoInputNoOutput
                       0x00,                 // OOB: not present
                       0x00,                 // AuthReq: no auth. request by default
                       0x10,                 // encr. key size: 16 (default max)
                       KeyDistGen::kEncKey,  // initiator key dist.: encr. key only
                       KeyDistGen::kEncKey   // responder key dist.: encr. key only
      );
  const StaticByteBuffer kFailure(0x05,  // code: Pairing Failed
                                  ErrorCode::kUnspecifiedReason);

  NewPhase1(Role::kResponder);
  EXPECT_TRUE(ReceiveAndExpect(kRequest, kFailure));
  EXPECT_EQ(1, listener()->pairing_error_count());
}

TEST_F(Phase1Test, FeatureExchangeResponderBothSupportSCFeaturesHaveSC) {
  const auto kResponse = StaticByteBuffer(0x02,  // code: Pairing Response
                                          0x03,  // IO cap.: NoInputNoOutput
                                          0x00,  // OOB: not present
                                          AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
                                          0x10,                // encr. key size: 7 (default min)
                                          0x00,                // initiator keys: none
                                          KeyDistGen::kEncKey  // responder keys
  );

  Phase1Args args{.preq =
                      PairingRequestParams{
                          .io_capability = IOCapability::kNoInputNoOutput,
                          .auth_req = AuthReq::kBondingFlag | AuthReq::kSC,
                          .max_encryption_key_size = 0x10,  // 16, default max
                          .initiator_key_dist_gen = 0x00,
                          .responder_key_dist_gen = 0x01  // enc key
                      },
                  .sc_supported = true};
  NewPhase1(Role::kResponder, args);
  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  RunLoopUntilIdle();

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());

  EXPECT_FALSE(features().initiator);
  EXPECT_TRUE(features().secure_connections);
}

TEST_F(Phase1Test, FeatureExchangeResponderLocalSCRemoteNoSCFeaturesNoSC) {
  const auto kResponse = StaticByteBuffer(0x02,  // code: Pairing Response
                                          0x03,  // IO cap.: NoInputNoOutput
                                          0x00,  // OOB: not present
                                          AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
                                          0x10,                // encr. key size: 7 (default min)
                                          0x00,                // initiator keys: none
                                          KeyDistGen::kEncKey  // responder keys
  );

  Phase1Args args{.preq =
                      PairingRequestParams{
                          .io_capability = IOCapability::kNoInputNoOutput,
                          .auth_req = AuthReq::kBondingFlag,
                          .max_encryption_key_size = 0x10,  // 16, default max
                          .initiator_key_dist_gen = 0x00,
                          .responder_key_dist_gen = KeyDistGen::kEncKey  // enc key
                      },
                  .sc_supported = true};
  NewPhase1(Role::kResponder, args);
  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  RunLoopUntilIdle();

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());

  EXPECT_FALSE(features().initiator);
  EXPECT_FALSE(features().secure_connections);
}

// Tests that the local responder does not request keys that the initiator cannot distribute.
TEST_F(Phase1Test, FeatureExchangeLocalResponderDoesNotRequestUnsupportedKeys) {
  auto phase_args = Phase1Args{.preq = PairingRequestParams{
                                   .io_capability = IOCapability::kNoInputNoOutput,
                                   .auth_req = AuthReq::kBondingFlag,
                                   .max_encryption_key_size = 16,
                                   .initiator_key_dist_gen = 0x04,  // sign key only
                                   .responder_key_dist_gen = 0x00   // none
                               }};
  const StaticByteBuffer kResponse(
      0x02,  // code: Pairing Response
      0x03,  // IO cap.: NoInputNoOutput
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kCT2,
      0x10,  // encr. key size: 16 (default max)
      0x00,  // initiator keys: none - we shouldn't request the SignKey as we don't support it
      0x00   // responder keys: none
  );

  NewPhase1(Role::kResponder, phase_args);
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().initiator);
  EXPECT_FALSE(features().local_key_distribution);
  EXPECT_FALSE(features().remote_key_distribution);
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
}

// Tests that we (as the responder) request to distribute identity information if available.
TEST_F(Phase1Test, FeatureExchangeResponderDistributesIdKey) {
  auto phase_args =
      Phase1Args{.preq = PairingRequestParams{.io_capability = IOCapability::kNoInputNoOutput,
                                              .auth_req = 0x01,                 // bondable mode
                                              .max_encryption_key_size = 0x10,  // 16, default max
                                              .responder_key_dist_gen = KeyDistGen::kIdKey}};
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x03,  // IO cap.: NoInputNoOutput
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kCT2,
                                   0x10,               // encr. key size: 16 (default max)
                                   0x00,               // initiator keys: none
                                   KeyDistGen::kIdKey  // responder keys
  );

  NewPhase1(Role::kResponder, phase_args);
  listener()->set_identity_info(IdentityInfo());
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().initiator);
  EXPECT_TRUE(features().local_key_distribution & KeyDistGen::kIdKey);
  EXPECT_FALSE(features().remote_key_distribution);
}

// Tests that local responder doesn't respond with distribute ID info if available but not requested
// by the initiator.
TEST_F(Phase1Test, FeatureExchangeResponderRespectsInitiatorForIdKey) {
  auto phase_args =
      Phase1Args{.preq = PairingRequestParams{
                     .io_capability = IOCapability::kNoInputNoOutput,
                     .auth_req = 0x01,                 // bondable mode
                     .max_encryption_key_size = 0x10,  // 16, default max
                     .initiator_key_dist_gen = 0x00,
                     .responder_key_dist_gen = 0x00  // Initiator explicitly does not request ID key
                 }};
  const StaticByteBuffer kResponse(
      0x02,  // code: Pairing Response
      0x03,  // IO cap.: NoInputNoOutput
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kCT2,
      0x10,  // encr. key size: 16 (default max)
      0x00,  // initiator keys: none
      0x00   // responder keys: none - we shouldn't distribute IdKey even though we have it
  );

  NewPhase1(Role::kResponder, phase_args);
  listener()->set_identity_info(IdentityInfo());
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().initiator);
  EXPECT_FALSE(features().local_key_distribution);
  EXPECT_FALSE(features().remote_key_distribution);
}

// Pairing should fail if MITM is required but the pairing method cannot provide
// it (due to I/O capabilities).
TEST_F(Phase1Test, FeatureExchangeResponderFailedAuthenticationRequirements) {
  const auto kRequest =
      StaticByteBuffer(0x01,  // code: Pairing Response
                       0x00,  // IO cap.: DisplayOnly
                       0x00,  // OOB: not present
                       AuthReq::kMITM,
                       0x07,                 // encr. key size: 7 (default min)
                       KeyDistGen::kEncKey,  // initiator key dist.: encr. key only
                       KeyDistGen::kEncKey   // responder key dist.: encr. key only
      );
  const StaticByteBuffer kFailure(0x05,  // code: Pairing Failed
                                  0x03   // reason: Authentication requirements
  );
  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .io_capability = IOCapability::kNoInputNoOutput};
  NewPhase1(Role::kResponder, phase_args);

  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kFailure));
  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements), listener()->last_error());
}

TEST_F(Phase1Test, FeatureExchangeResponderJustWorks) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Response
                                         0x00,  // IO cap.: DisplayOnly
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag,
                                         0x07,                // encr. key size: 7 (default min)
                                         KeyDistGen::kIdKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x03,  // IO cap.: NoInputNoOutput
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kCT2,
                                   0x10,                // encr. key size: 16 (default max)
                                   KeyDistGen::kIdKey,  // initiator keys
                                   KeyDistGen::kEncKey  // responder keys
  );

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .io_capability = IOCapability::kNoInputNoOutput};

  NewPhase1(Role::kResponder, phase_args);
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().initiator);
  EXPECT_FALSE(features().secure_connections);
  EXPECT_EQ(PairingMethod::kJustWorks, features().method);
  EXPECT_EQ(7, features().encryption_key_size);
  ASSERT_TRUE(last_preq());
  ASSERT_TRUE(last_pres());
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));

  // We send the LTK when we are the responder.
  EXPECT_TRUE(KeyDistGen::kEncKey & features().local_key_distribution);

  // The remote should send us identity information since we requested it and it
  // promised it.
  EXPECT_TRUE(KeyDistGen::kIdKey & features().remote_key_distribution);
}

TEST_F(Phase1Test, FeatureExchangeResponderRequestInitiatorEncKey) {
  const StaticByteBuffer kRequest(0x01,  // code: Pairing Response
                                  0x00,  // IO cap.: DisplayOnly
                                  0x00,  // OOB: not present
                                  AuthReq::kBondingFlag,
                                  0x07,                 // encr. key size: 7 (default min)
                                  KeyDistGen::kEncKey,  // initiator keys
                                  0x03                  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x03,  // IO cap.: NoInputNoOutput
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kCT2,
                                   0x10,                 // encr. key size: 16 (default max)
                                   KeyDistGen::kEncKey,  // initiator keys
                                   KeyDistGen::kEncKey   // responder keys
  );

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .io_capability = IOCapability::kNoInputNoOutput};

  NewPhase1(Role::kResponder, phase_args);
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().initiator);
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));

  // We send the LTK as the initiator requested it. We also request the LTK from the initiator,
  // which indicated it was capable of distributing it.
  EXPECT_TRUE(KeyDistGen::kEncKey & features().local_key_distribution);
  EXPECT_TRUE(KeyDistGen::kEncKey & features().remote_key_distribution);
}

TEST_F(Phase1Test, FeatureExchangeResponderSendsOnlyRequestedKeys) {
  const StaticByteBuffer kRequest(0x01,  // code: Pairing Response
                                  0x00,  // IO cap.: DisplayOnly
                                  0x00,  // OOB: not present
                                  AuthReq::kBondingFlag,
                                  0x07,                // encr. key size: 7 (default min)
                                  KeyDistGen::kIdKey,  // initiator keys
                                  KeyDistGen::kIdKey   // responder keys - responder
                                                       // doesn't have ID info, so
                                                       // won't send it
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x03,  // IO cap.: NoInputNoOutput
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kCT2,
                                   0x10,                // encr. key size: 16 (default max)
                                   KeyDistGen::kIdKey,  // initiator keys
                                   0x00                 // responder keys: none
  );

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .io_capability = IOCapability::kNoInputNoOutput};
  NewPhase1(Role::kResponder, phase_args);
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });

  ASSERT_TRUE(Expect(kResponse));
  ASSERT_EQ(1, feature_exchange_count());
}

TEST_F(Phase1Test, FeatureExchangeResponderMITM) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x02,  // IO cap.: KeyboardOnly
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kMITM,
                                         0x07,                // encr. key size: 7 (default min)
                                         KeyDistGen::kIdKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   0x01,  // IO cap.: DisplayYesNo
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kCT2,
                                   0x10,                // encr. key size: 16 (default max)
                                   KeyDistGen::kIdKey,  // initiator keys
                                   KeyDistGen::kEncKey  // responder keys
  );

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .io_capability = IOCapability::kDisplayYesNo};
  NewPhase1(Role::kResponder, phase_args);

  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().initiator);
  EXPECT_FALSE(features().secure_connections);
  EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay, features().method);
  EXPECT_EQ(7, features().encryption_key_size);
  ASSERT_TRUE(last_preq());
  ASSERT_TRUE(last_pres());
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));

  // We send the LTK when we are the responder.
  EXPECT_TRUE(KeyDistGen::kEncKey & features().local_key_distribution);

  // The remote should send us identity information since we requested it and it
  // promised it.
  EXPECT_TRUE(KeyDistGen::kIdKey & features().remote_key_distribution);

  // We should have set bondable mode as both sides enabled it
  EXPECT_TRUE(features().will_bond);
}

TEST_F(Phase1Test, FeatureExchangeResponderRespectsDesiredLevel) {
  const StaticByteBuffer kRequest(0x01,  // code: Pairing Response
                                  0x01,  // IO cap.: KeyboardDisplay
                                  0x00,  // OOB: not present
                                  AuthReq::kBondingFlag | AuthReq::kSC,
                                  0x10,                // encr. key size: 16 (default max)
                                  0x00,                // initiator keys: none
                                  KeyDistGen::kEncKey  // responder keys
  );
  const auto kResponse =
      StaticByteBuffer(0x02,  // code: Pairing Response
                       0x01,  // IO cap.: KeyboardDisplay
                       0x00,  // OOB: not present
                       AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC | AuthReq::kCT2,
                       0x10,                // encr. key size: 16 (default max)
                       0x00,                // initiator keys: none
                       KeyDistGen::kEncKey  // responder keys
      );

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .io_capability = IOCapability::kDisplayYesNo,
                               .level = SecurityLevel::kAuthenticated,
                               .sc_supported = true};

  NewPhase1(Role::kResponder, phase_args);
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  EXPECT_EQ(0, listener()->pairing_error_count());
  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_TRUE(features().secure_connections);
  // We requested authenticated security, which led to Numeric Comparison as the pairing method.
  EXPECT_EQ(PairingMethod::kNumericComparison, features().method);
  ASSERT_TRUE(last_preq());
  ASSERT_TRUE(last_pres());
  EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
  EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
}

TEST_F(Phase1Test, FeatureExchangeResponderRejectsMethodOfInsufficientSecurity) {
  const StaticByteBuffer kRequest(0x01,  // code: Pairing Response
                                  0x01,  // IO cap.: DisplayYesNo
                                  0x00,  // OOB: not present
                                  AuthReq::kBondingFlag,
                                  0x10,                // encr. key size: 16 (default max)
                                  0x00,                // initiator keys: none
                                  KeyDistGen::kEncKey  // responder keys
  );
  const auto kFailure = StaticByteBuffer(kPairingFailed, ErrorCode::kAuthenticationRequirements);

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .io_capability = IOCapability::kDisplayYesNo,
                               .level = SecurityLevel::kAuthenticated,
                               .sc_supported = true};

  NewPhase1(Role::kResponder, phase_args);
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  // Both devices have DisplayYesNo IOCap, but the initiator does not support Secure Connections so
  // Numeric Comparison cannot be used. Neither device has a keyboard, so Passkey Entry cannot be
  // used. Thus authenticated pairing, the desired level, cannot be met and we fail.
  ASSERT_TRUE(Expect(kFailure));

  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements), listener()->last_error());
}

TEST_F(Phase1Test, FeatureExchangeResponderSecureAuthenticatedInitiatorNoInputNoOutput) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x03,  // IO cap.: NoInputNoOutput
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kSC,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const auto kFailure = StaticByteBuffer(kPairingFailed, ErrorCode::kAuthenticationRequirements);

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .io_capability = IOCapability::kDisplayYesNo,
                               .level = SecurityLevel::kSecureAuthenticated,
                               .sc_supported = true};
  NewPhase1(Role::kResponder, phase_args);
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });

  // Cannot perform SecureAuthenticated pairing with the peer's NoInputNoOutput IOCapabilities.
  ASSERT_TRUE(Expect(kFailure));

  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements), listener()->last_error());
}

TEST_F(Phase1Test, FeatureExchangeResponderDoesntSupportScDoNotGenerateCtKey) {
  const StaticByteBuffer kRequest(
      0x01,  // code: Pairing Request
      IOCapability::kNoInputNoOutput,
      0x00,  // OOB: not present
      AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
      0x10,                                        // encr. key size: 16 (default max)
      KeyDistGen::kEncKey | KeyDistGen::kLinkKey,  // initiator keys
      KeyDistGen::kEncKey | KeyDistGen::kIdKey | KeyDistGen::kLinkKey  // responder keys
  );
  // Although the peer supports CTKG through the hci_spec::LinkKey field and SC, locally we do not
  // support support SC, so CTKG is not allowed (v5.2 Vol. 3 Part H 3.6.1).
  const StaticByteBuffer kResponse(0x02,  // code: Pairing Response
                                   IOCapability::kNoInputNoOutput,
                                   0x00,  // OOB: not present
                                   AuthReq::kBondingFlag | AuthReq::kCT2,
                                   0x10,                 // encr. key size: 16 (default max)
                                   KeyDistGen::kEncKey,  // initiator keys
                                   KeyDistGen::kEncKey   // responder keys
  );

  auto reader = PacketReader(&kRequest);
  auto phase_args =
      Phase1Args{.preq = reader.payload<PairingRequestParams>(), .sc_supported = false};
  NewPhase1(Role::kResponder, phase_args);
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  EXPECT_TRUE(Expect(kResponse));

  EXPECT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().generate_ct_key.has_value());
}

TEST_F(Phase1Test, UnsupportedCommandDuringPairing) {
  phase_1()->Start();

  const StaticByteBuffer kExpected(0x05,  // code: Pairing Failed
                                   0x07   // reason: Command Not Supported
  );
  ReceiveAndExpect(StaticByteBuffer(0xFF), kExpected);
  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kCommandNotSupported), listener()->last_error());
}

TEST_F(Phase1Test, OnSecurityRequestWhilePairing) {
  phase_1()->Start();

  const StaticByteBuffer kSecurityRequest(0x0B,  // code: Security Request
                                          0x00   // auth_req
  );

  fake_chan()->Receive(kSecurityRequest);
  RunLoopUntilIdle();

  // The security request while pairing should cause pairing to fail.
  EXPECT_EQ(1, listener()->pairing_error_count());
}

// Tests whether a request from a device with bondable mode enabled to a peer with non-bondable
// mode enabled will return a PairingFeatures with non-bondable mode enabled, the desired result.
TEST_F(Phase1Test, FeatureExchangeInitiatorReqBondResNoBond) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x03,  // IO cap.: NoInputNoOutput
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag | AuthReq::kCT2,
                                         0x10,                 // encr. key size: 16 (default max)
                                         KeyDistGen::kEncKey,  // initiator keys
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const auto kResponse = StaticByteBuffer(0x02,  // code: Pairing Response
                                          0x00,  // IO cap.: DisplayOnly
                                          0x00,  // OOB: not present
                                          0x00,
                                          0x07,  // encr. key size: 7 (default min)
                                          0x00,  // initiator keys: none
                                          0x00   // responder keys: none due to non-bondable mode
  );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();

  // Should be in non-bondable mode even though the Initiator specifies bonding, as kResponse
  // indicated that the peer follower does not support bonding.
  EXPECT_FALSE(features().will_bond);
  EXPECT_EQ(features().local_key_distribution, 0u);
  EXPECT_EQ(features().remote_key_distribution, 0u);
}

TEST_F(Phase1Test, FeatureExchangeInitiatorReqNoBondResBond) {
  auto phase_args = Phase1Args{.bondable_mode = BondableMode::NonBondable};
  NewPhase1(Role::kInitiator, phase_args);
  const StaticByteBuffer kRequest(0x01,           // code: Pairing Request
                                  0x03,           // IO cap.: NoInputNoOutput
                                  0x00,           // OOB: not present
                                  AuthReq::kCT2,  // AuthReq: non-bondable
                                  0x10,           // encr. key size: 16 (default max)
                                  0x00,           // initiator keys: none
                                  0x00            // responder keys: none
  );
  const auto kResponse =
      StaticByteBuffer(0x02,  // code: Pairing Response
                       0x00,  // IO cap.: DisplayOnly
                       0x00,  // OOB: not present
                       AuthReq::kBondingFlag,
                       0x07,  // encr. key size: 7 (default min)
                       0x00,  // initiator keys: none - should not change request field
                       0x00   // responder keys: none - should not change request field
      );

  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kRequest));

  fake_chan()->Receive(kResponse);
  RunLoopUntilIdle();

  // Although kResponse is bondable, features should not bond as local device is non-bondable.
  ASSERT_EQ(1, feature_exchange_count());
  EXPECT_FALSE(features().will_bond);
  EXPECT_EQ(features().local_key_distribution, 0u);
  EXPECT_EQ(features().remote_key_distribution, 0u);
}

TEST_F(Phase1Test, FeatureExchangeResponderReqBondResNoBond) {
  const auto kRequest = StaticByteBuffer(0x01,  // code: Pairing Request
                                         0x03,  // IO cap.: NoInputNoOutput
                                         0x00,  // OOB: not present
                                         AuthReq::kBondingFlag,
                                         0x10,  // encr. key size: 16 (default max)
                                         0x00,  // initiator keys: none
                                         KeyDistGen::kEncKey | KeyDistGen::kIdKey  // responder keys
  );
  const auto kResponse =
      StaticByteBuffer(0x02,           // code: Pairing Response
                       0x03,           // IO cap.: NoInputNoOutput
                       0x00,           // OOB: not present
                       AuthReq::kCT2,  // AuthReq: non-bondable to match local mode,
                                       // even though kRequest was bondable
                       0x10,           // encr. key size: 16 (default max)
                       0x00,           // initiator keys: none - should not change request field
                       0x00            // responder keys: none - should not change request field
      );

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
                               .bondable_mode = BondableMode::NonBondable};
  NewPhase1(Role::kResponder, phase_args);
  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  // Should be in non-bondable mode even though the peer requested bondable, as the Bearer was
  // created in non-bondable mode.
  EXPECT_FALSE(features().will_bond);
  EXPECT_EQ(features().local_key_distribution, 0u);
  EXPECT_EQ(features().remote_key_distribution, 0u);
}

TEST_F(Phase1Test, FeatureExchangeResponderReqNoBondResNoBond) {
  const StaticByteBuffer kRequest(0x01,  // code: Pairing Request
                                  0x03,  // IO cap.: NoInputNoOutput
                                  0x00,  // OOB: not present
                                  0x00,  // AuthReq: non-bondable
                                  0x10,  // encr. key size: 16 (default max)
                                  0x00,  // initiator keys: none
                                  0x00   // responder keys: none
  );
  const auto kResponse =
      StaticByteBuffer(0x02,           // code: Pairing Response
                       0x03,           // IO cap.: NoInputNoOutput
                       0x00,           // OOB: not present
                       AuthReq::kCT2,  // AuthReq: non-bondable to match peer mode, even
                                       // though Phase1 is bondable.
                       0x10,           // encr. key size: 16 (default max)
                       0x00,           // initiator keys: none - should not change request field
                       0x00            // responder keys: none - should not change request field
      );

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{
      .preq = reader.payload<PairingRequestParams>(),
      .bondable_mode = BondableMode::Bondable,  // local mode is bondable, although peer is not
  };
  NewPhase1(Role::kResponder, phase_args);
  // Initiate the request in a loop task for Expect to detect it.
  async::PostTask(dispatcher(), [this] { phase_1()->Start(); });
  ASSERT_TRUE(Expect(kResponse));

  // Should be in non-bondable mode even though Bearer was created in bondable mode as
  // kRequest indicated that peer does not support bonding.
  EXPECT_FALSE(features().will_bond);
  EXPECT_EQ(features().local_key_distribution, 0u);
  EXPECT_EQ(features().remote_key_distribution, 0u);
}

TEST_F(Phase1Test, FeatureExchangeResponderReqNoBondWithKeys) {
  const auto kRequest =
      StaticByteBuffer(0x01,           // code: Pairing Request
                       0x03,           // IO cap.: NoInputNoOutput
                       0x00,           // OOB: not present
                       AuthReq::kCT2,  // AuthReq: non-bondable
                       0x10,           // encr. key size: 16 (default max)
                       KeyDistGen::kEncKey | KeyDistGen::kIdKey,  // initiator keys
                       KeyDistGen::kEncKey | KeyDistGen::kIdKey   // responder keys
      );

  auto reader = PacketReader(&kRequest);
  auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>()};
  NewPhase1(Role::kResponder, phase_args);
  // Initiate the request in a loop task for Expect to detect it.
  phase_1()->Start();
  RunLoopUntilIdle();

  // Check that we fail with invalid parameters when a peer requests nonbondable mode
  // with a non-zero KeyDistGen field
  EXPECT_EQ(1, listener()->pairing_error_count());
  EXPECT_EQ(Error(ErrorCode::kInvalidParameters), listener()->last_error());
}

}  // namespace
}  // namespace bt::sm
