// 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 "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/sm/phase_1.h"

#include <memory>

#include <gtest/gtest.h>

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/macros.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci/connection.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/l2cap/mock_channel_test.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/sm/fake_phase_listener.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/sm/packet.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/sm/smp.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/sm/types.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/test_helpers.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::MockChannelTest {
 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>();
    l2cap::testing::FakeChannel::WeakPtr fake_chan = CreateFakeChannel(options);
    sm_chan_ = std::make_unique<PairingChannel>(fake_chan->GetWeakPtr());
    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));
    }
  }

  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_;
  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_;

  BT_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
  );
  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
}

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
  );
  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
}

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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  EXPECT_EQ(1, listener()->identity_info_count());
}

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

  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
  );
  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();

  // We should receive a pairing response and reply back with Pairing Failed.
  EXPECT_PACKET_OUT(kFailure);
  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  EXPECT_TRUE(AllExpectedPacketsSent());

  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  RunUntilIdle();
  ASSERT_TRUE(AllExpectedPacketsSent());

  // We should receive a pairing response and reply back with Pairing Failed.
  EXPECT_PACKET_OUT(kFailure);
  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  // We should receive a pairing response and reply back with Pairing Failed.
  EXPECT_PACKET_OUT(kFailure);
  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  EXPECT_TRUE(AllExpectedPacketsSent());

  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_PACKET_OUT(kFailure);
  fake_chan()->Receive(kMalformedResponse);
  RunUntilIdle();
  EXPECT_TRUE(AllExpectedPacketsSent());

  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

  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
      );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

  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
      );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  EXPECT_PACKET_OUT(kFailure);
  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  // 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_PACKET_OUT(kFailure);
  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  // 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_PACKET_OUT(kFailure);
  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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
      );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  fake_chan()->Receive(kResponse);
  RunUntilIdle();
  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_PACKET_OUT(kFailure);
  fake_chan()->Receive(kRequest);
  RunUntilIdle();
  ASSERT_TRUE(AllExpectedPacketsSent());
  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_PACKET_OUT(kFailure);
  fake_chan()->Receive(kRequest);
  RunUntilIdle();
  ASSERT_TRUE(AllExpectedPacketsSent());
  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,
                          .oob_data_flag = OOBDataFlag::kNotPresent,
                          .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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  RunUntilIdle();

  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,
              .oob_data_flag = OOBDataFlag::kNotPresent,
              .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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  RunUntilIdle();

  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,
                     .oob_data_flag = OOBDataFlag::kNotPresent,
                     .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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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,
                     .oob_data_flag = OOBDataFlag::kNotPresent,
                     .auth_req = 0x01,                 // bondable mode
                     .max_encryption_key_size = 0x10,  // 16, default max
                     .initiator_key_dist_gen = 0x00,
                     .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());
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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,
                     .oob_data_flag = OOBDataFlag::kNotPresent,
                     .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());
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);

  EXPECT_PACKET_OUT(kFailure);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());
  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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());
  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);

  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);
  // 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.
  EXPECT_PACKET_OUT(kFailure);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);

  // Cannot perform SecureAuthenticated pairing with the peer's NoInputNoOutput
  // IOCapabilities.
  EXPECT_PACKET_OUT(kFailure);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

TEST_F(Phase1Test, UnsupportedCommandDuringPairing) {
  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
  );
  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();

  const StaticByteBuffer kFailed(0x05,  // code: Pairing Failed
                                 0x07   // reason: Command Not Supported
  );
  EXPECT_PACKET_OUT(kFailed);
  fake_chan()->Receive(StaticByteBuffer(0xFF));
  RunUntilIdle();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

TEST_F(Phase1Test, OnSecurityRequestWhilePairing) {
  const StaticByteBuffer kPairingRequest(
      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
  );
  EXPECT_PACKET_OUT(kPairingRequest);
  phase_1()->Start();

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

  const StaticByteBuffer kFailed(0x05,  // code: Pairing Failed
                                 0x08   // reason: unspecified reason
  );
  EXPECT_PACKET_OUT(kFailed);
  fake_chan()->Receive(kSecurityRequest);
  RunUntilIdle();

  // 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
      );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

  // 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
  );

  EXPECT_PACKET_OUT(kRequest);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

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

  // 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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  // 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);
  EXPECT_PACKET_OUT(kResponse);
  phase_1()->Start();
  ASSERT_TRUE(AllExpectedPacketsSent());

  // 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);

  const StaticByteBuffer kFailed(0x05,  // code: Pairing Failed
                                 0x0A   // reason: invalid parameters
  );
  EXPECT_PACKET_OUT(kFailed);
  phase_1()->Start();
  RunUntilIdle();

  // 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
