1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 // inclusive-language: disable
16
17 #include "pw_bluetooth_sapphire/internal/host/sm/phase_1.h"
18
19 #include <memory>
20
21 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
22 #include "pw_bluetooth_sapphire/internal/host/common/macros.h"
23 #include "pw_bluetooth_sapphire/internal/host/hci/connection.h"
24 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
25 #include "pw_bluetooth_sapphire/internal/host/l2cap/mock_channel_test.h"
26 #include "pw_bluetooth_sapphire/internal/host/sm/fake_phase_listener.h"
27 #include "pw_bluetooth_sapphire/internal/host/sm/packet.h"
28 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
29 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
30 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
31 #include "pw_unit_test/framework.h"
32
33 namespace bt::sm {
34 namespace {
35
36 struct Phase1Args {
37 PairingRequestParams preq = PairingRequestParams();
38 IOCapability io_capability = IOCapability::kNoInputNoOutput;
39 BondableMode bondable_mode = BondableMode::Bondable;
40 SecurityLevel level = SecurityLevel::kEncrypted;
41 bool sc_supported = false;
42 };
43
44 class Phase1Test : public l2cap::testing::MockChannelTest {
45 public:
46 Phase1Test() = default;
47 ~Phase1Test() override = default;
48
49 protected:
SetUp()50 void SetUp() override { NewPhase1(); }
51
TearDown()52 void TearDown() override { phase_1_ = nullptr; }
53
NewPhase1(Role role=Role::kInitiator,Phase1Args phase_args=Phase1Args (),bt::LinkType ll_type=bt::LinkType::kLE)54 void NewPhase1(Role role = Role::kInitiator,
55 Phase1Args phase_args = Phase1Args(),
56 bt::LinkType ll_type = bt::LinkType::kLE) {
57 l2cap::ChannelId cid = ll_type == bt::LinkType::kLE ? l2cap::kLESMPChannelId
58 : l2cap::kSMPChannelId;
59 uint16_t mtu =
60 phase_args.sc_supported ? l2cap::kMaxMTU : kNoSecureConnectionsMtu;
61 ChannelOptions options(cid, mtu);
62 options.link_type = ll_type;
63
64 listener_ = std::make_unique<FakeListener>();
65 l2cap::testing::FakeChannel::WeakPtr fake_chan = CreateFakeChannel(options);
66 sm_chan_ = std::make_unique<PairingChannel>(fake_chan->GetWeakPtr());
67 auto complete_cb = [this](PairingFeatures features,
68 PairingRequestParams preq,
69 PairingResponseParams pres) {
70 feature_exchange_count_++;
71 features_ = features;
72 last_pairing_req_ = util::NewPdu(sizeof(PairingRequestParams));
73 last_pairing_res_ = util::NewPdu(sizeof(PairingResponseParams));
74 PacketWriter preq_writer(kPairingRequest, last_pairing_req_.get());
75 PacketWriter pres_writer(kPairingResponse, last_pairing_res_.get());
76 *preq_writer.mutable_payload<PairingRequestParams>() = preq;
77 *pres_writer.mutable_payload<PairingResponseParams>() = pres;
78 };
79 if (role == Role::kInitiator) {
80 phase_1_ = Phase1::CreatePhase1Initiator(sm_chan_->GetWeakPtr(),
81 listener_->as_weak_ptr(),
82 phase_args.io_capability,
83 phase_args.bondable_mode,
84 phase_args.level,
85 std::move(complete_cb));
86 } else {
87 phase_1_ = Phase1::CreatePhase1Responder(sm_chan_->GetWeakPtr(),
88 listener_->as_weak_ptr(),
89 phase_args.preq,
90 phase_args.io_capability,
91 phase_args.bondable_mode,
92 phase_args.level,
93 std::move(complete_cb));
94 }
95 }
96
phase_1()97 Phase1* phase_1() { return phase_1_.get(); }
listener()98 FakeListener* listener() { return listener_.get(); }
99
feature_exchange_count()100 int feature_exchange_count() { return feature_exchange_count_; }
features()101 PairingFeatures features() { return features_; }
last_preq()102 ByteBuffer* last_preq() { return last_pairing_req_.get(); }
last_pres()103 ByteBuffer* last_pres() { return last_pairing_res_.get(); }
104
105 private:
106 std::unique_ptr<FakeListener> listener_;
107 std::unique_ptr<PairingChannel> sm_chan_;
108 std::unique_ptr<Phase1> phase_1_;
109
110 int feature_exchange_count_ = 0;
111 PairingFeatures features_;
112 MutableByteBufferPtr last_pairing_req_;
113 MutableByteBufferPtr last_pairing_res_;
114
115 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Phase1Test);
116 };
117
TEST_F(Phase1Test,FeatureExchangeStartDefaultParams)118 TEST_F(Phase1Test, FeatureExchangeStartDefaultParams) {
119 const StaticByteBuffer kRequest(
120 0x01, // code: "Pairing Request"
121 0x03, // IO cap.: NoInputNoOutput
122 0x00, // OOB: not present
123 AuthReq::kBondingFlag | AuthReq::kCT2,
124 0x10, // encr. key size: 16 (default max)
125 KeyDistGen::kEncKey, // initiator keys
126 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
127 );
128 EXPECT_PACKET_OUT(kRequest);
129 phase_1()->Start();
130 }
131
TEST_F(Phase1Test,FeatureExchangeStartCustomParams)132 TEST_F(Phase1Test, FeatureExchangeStartCustomParams) {
133 auto phase_args = Phase1Args{.io_capability = IOCapability::kDisplayYesNo,
134 .bondable_mode = BondableMode::NonBondable,
135 .level = SecurityLevel::kAuthenticated,
136 .sc_supported = true};
137 NewPhase1(Role::kInitiator, phase_args);
138
139 const StaticByteBuffer kRequest(
140 0x01, // code: "Pairing Request"
141 0x01, // IO cap.: DisplayYesNo
142 0x00, // OOB: not present
143 AuthReq::kMITM | AuthReq::kSC | AuthReq::kCT2,
144 0x10, // encr. key size: 16 (default max)
145 0x00, // initiator keys: none - non-bondable mode
146 0x00 // responder keys: none - non-bondable mode
147 );
148 EXPECT_PACKET_OUT(kRequest);
149 phase_1()->Start();
150 }
151
TEST_F(Phase1Test,FeatureExchangeInitiatorWithIdentityInfo)152 TEST_F(Phase1Test, FeatureExchangeInitiatorWithIdentityInfo) {
153 listener()->set_identity_info(IdentityInfo());
154
155 const StaticByteBuffer kRequest(
156 0x01, // code: "Pairing Request"
157 0x03, // IO cap.: NoInputNoOutput
158 0x00, // OOB: not present
159 AuthReq::kBondingFlag | AuthReq::kCT2,
160 0x10, // encr. key size: 16 (default max)
161 KeyDistGen::kEncKey | KeyDistGen::kIdKey, // initiator keys
162 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
163 );
164
165 EXPECT_PACKET_OUT(kRequest);
166 phase_1()->Start();
167 EXPECT_EQ(1, listener()->identity_info_count());
168 }
169
TEST_F(Phase1Test,FeatureExchangePairingFailed)170 TEST_F(Phase1Test, FeatureExchangePairingFailed) {
171 fake_chan()->Receive(StaticByteBuffer(0x05, // code: Pairing Failed
172 0x05 // reason: Pairing Not Supported
173 ));
174 RunUntilIdle();
175
176 EXPECT_EQ(Error(ErrorCode::kPairingNotSupported), listener()->last_error());
177 EXPECT_EQ(1, listener()->pairing_error_count());
178 }
179
TEST_F(Phase1Test,FeatureExchangeLocalRejectsUnsupportedInitiatorKeys)180 TEST_F(Phase1Test, FeatureExchangeLocalRejectsUnsupportedInitiatorKeys) {
181 const auto kRequest = StaticByteBuffer(
182 0x01, // code: Pairing Request
183 0x03, // IO cap.: NoInputNoOutput
184 0x00, // OOB: not present
185 AuthReq::kBondingFlag | AuthReq::kCT2,
186 0x10, // encr. key size: 16 (default max)
187 KeyDistGen::kEncKey, // initiator keys
188 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
189 );
190 const auto kResponse = StaticByteBuffer(
191 0x02, // code: Pairing Response
192 0x00, // IO cap.: DisplayOnly
193 0x00, // OOB: not present
194 0x00,
195 0x07, // encr. key size: 7 (default min)
196 KeyDistGen::kIdKey, // initiator keys - not listed in kRequest
197 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
198 );
199 const StaticByteBuffer kFailure(0x05, // code: Pairing Failed
200 0x0A // reason: Invalid Parameters
201 );
202 EXPECT_PACKET_OUT(kRequest);
203 phase_1()->Start();
204
205 // We should receive a pairing response and reply back with Pairing Failed.
206 EXPECT_PACKET_OUT(kFailure);
207 fake_chan()->Receive(kResponse);
208 RunUntilIdle();
209 EXPECT_TRUE(AllExpectedPacketsSent());
210
211 EXPECT_EQ(1, listener()->pairing_error_count());
212 EXPECT_EQ(Error(ErrorCode::kInvalidParameters), listener()->last_error());
213 EXPECT_EQ(0, feature_exchange_count());
214 }
215
TEST_F(Phase1Test,FeatureExchangeLocalRejectsUnsupportedResponderKeys)216 TEST_F(Phase1Test, FeatureExchangeLocalRejectsUnsupportedResponderKeys) {
217 const auto kRequest = StaticByteBuffer(
218 0x01, // code: Pairing Request
219 0x03, // IO cap.: NoInputNoOutput
220 0x00, // OOB: not present
221 AuthReq::kBondingFlag | AuthReq::kCT2,
222 0x10, // encr. key size: 16 (default max)
223 KeyDistGen::kEncKey, // initiator keys
224 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
225 );
226 const auto kResponse = StaticByteBuffer(
227 0x02, // code: Pairing Response
228 0x00, // IO cap.: DisplayOnly
229 0x00, // OOB: not present
230 0x00,
231 0x07, // encr. key size: 7 (default min)
232 KeyDistGen::kEncKey, // initiator keys
233 KeyDistGen::kSignKey // responder keys - kSignKey not in kRequest
234 );
235 const StaticByteBuffer kFailure(0x05, // code: Pairing Failed
236 0x0A // reason: Invalid Parameters
237 );
238
239 EXPECT_PACKET_OUT(kRequest);
240 phase_1()->Start();
241 RunUntilIdle();
242 ASSERT_TRUE(AllExpectedPacketsSent());
243
244 // We should receive a pairing response and reply back with Pairing Failed.
245 EXPECT_PACKET_OUT(kFailure);
246 fake_chan()->Receive(kResponse);
247 RunUntilIdle();
248 ASSERT_TRUE(AllExpectedPacketsSent());
249
250 EXPECT_EQ(1, listener()->pairing_error_count());
251 EXPECT_EQ(Error(ErrorCode::kInvalidParameters), listener()->last_error());
252 EXPECT_EQ(0, feature_exchange_count());
253 }
254
255 // Pairing should fail if MITM is required but the I/O capabilities cannot
256 // provide it
TEST_F(Phase1Test,FeatureExchangeFailureAuthenticationRequirements)257 TEST_F(Phase1Test, FeatureExchangeFailureAuthenticationRequirements) {
258 const auto kRequest = StaticByteBuffer(
259 0x01, // code: Pairing Request
260 0x03, // IO cap.: NoInputNoOutput
261 0x00, // OOB: not present
262 AuthReq::kBondingFlag | AuthReq::kCT2,
263 0x10, // encr. key size: 16 (default max)
264 KeyDistGen::kEncKey, // initiator keys
265 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
266 );
267 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
268 0x00, // IO cap.: DisplayOnly
269 0x00, // OOB: not present
270 AuthReq::kMITM,
271 0x07, // encr. key size: 7 (default min)
272 0x00, // initiator keys: none
273 KeyDistGen::kEncKey // responder keys: it's
274 // OK to use fewer keys
275 // than in kRequest
276 );
277 const StaticByteBuffer kFailure(0x05, // code: Pairing Failed
278 0x03 // reason: Authentication requirements
279 );
280
281 EXPECT_PACKET_OUT(kRequest);
282 phase_1()->Start();
283 ASSERT_TRUE(AllExpectedPacketsSent());
284
285 // We should receive a pairing response and reply back with Pairing Failed.
286 EXPECT_PACKET_OUT(kFailure);
287 fake_chan()->Receive(kResponse);
288 RunUntilIdle();
289 EXPECT_TRUE(AllExpectedPacketsSent());
290
291 EXPECT_EQ(1, listener()->pairing_error_count());
292 EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements),
293 listener()->last_error());
294 EXPECT_EQ(0, feature_exchange_count());
295 }
296
TEST_F(Phase1Test,FeatureExchangeFailureMalformedRequest)297 TEST_F(Phase1Test, FeatureExchangeFailureMalformedRequest) {
298 const auto kMalformedResponse = StaticByteBuffer(
299 0x02, // code: Pairing Response
300 0x03, // IO cap.: NoInputNoOutput
301 0x00, // OOB: not present
302 0x00, // AuthReq: empty
303 0x10, // encr. key size: 16 (default max)
304 KeyDistGen::kEncKey // initiator key dist.: encr. key only
305 // Missing last byte, responder key dist.
306 );
307 const StaticByteBuffer kFailure(0x05, // code: Pairing Failed
308 0x0A // reason: Invalid Parameters
309 );
310
311 EXPECT_PACKET_OUT(kFailure);
312 fake_chan()->Receive(kMalformedResponse);
313 RunUntilIdle();
314 EXPECT_TRUE(AllExpectedPacketsSent());
315
316 EXPECT_EQ(1, listener()->pairing_error_count());
317 EXPECT_EQ(Error(ErrorCode::kInvalidParameters), listener()->last_error());
318 }
319
TEST_F(Phase1Test,FeatureExchangeBothSupportSCFeaturesHaveSC)320 TEST_F(Phase1Test, FeatureExchangeBothSupportSCFeaturesHaveSC) {
321 Phase1Args args;
322 args.sc_supported = true;
323 NewPhase1(Role::kInitiator, args);
324 const StaticByteBuffer kRequest(
325 0x01, // code: Pairing Request
326 0x03, // IO cap.: NoInputNoOutput
327 0x00, // OOB: not present
328 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
329 0x10, // encr. key size: 16 (default max)
330 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
331 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
332 KeyDistGen::kLinkKey // responder keys
333 );
334 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
335 0x00, // IO cap.: DisplayOnly
336 0x00, // OOB: not present
337 AuthReq::kBondingFlag | AuthReq::kSC,
338 0x07, // encr. key size: 7 (default min)
339 0x00, // initiator keys: none
340 KeyDistGen::kEncKey // responder keys
341 );
342
343 EXPECT_PACKET_OUT(kRequest);
344 phase_1()->Start();
345 ASSERT_TRUE(AllExpectedPacketsSent());
346
347 fake_chan()->Receive(kResponse);
348 RunUntilIdle();
349
350 EXPECT_EQ(0, listener()->pairing_error_count());
351 EXPECT_EQ(1, feature_exchange_count());
352
353 EXPECT_TRUE(features().initiator);
354 EXPECT_TRUE(features().secure_connections);
355 ASSERT_TRUE(last_preq());
356 ASSERT_TRUE(last_pres());
357 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
358 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
359 }
360
TEST_F(Phase1Test,FeatureExchangeScIgnoresEncKeyBit)361 TEST_F(Phase1Test, FeatureExchangeScIgnoresEncKeyBit) {
362 Phase1Args args;
363 args.sc_supported = true;
364 NewPhase1(Role::kInitiator, args);
365 const StaticByteBuffer kRequest(
366 0x01, // code: Pairing Request
367 0x03, // IO cap.: NoInputNoOutput
368 0x00, // OOB: not present
369 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
370 0x10, // encr. key size: 16 (default max)
371 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
372 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
373 KeyDistGen::kLinkKey // responder keys
374 );
375 const auto kResponse =
376 StaticByteBuffer(0x02, // code: Pairing Response
377 0x00, // IO cap.: DisplayOnly
378 0x00, // OOB: not present
379 AuthReq::kBondingFlag | AuthReq::kSC,
380 0x07, // encr. key size: 7 (default min)
381 0x00, // initiator keys: none
382 KeyDistGen::kEncKey // responder keys
383 );
384
385 EXPECT_PACKET_OUT(kRequest);
386 phase_1()->Start();
387 ASSERT_TRUE(AllExpectedPacketsSent());
388
389 fake_chan()->Receive(kResponse);
390 RunUntilIdle();
391
392 EXPECT_EQ(0, listener()->pairing_error_count());
393 EXPECT_EQ(1, feature_exchange_count());
394
395 EXPECT_TRUE(features().initiator);
396 EXPECT_TRUE(features().secure_connections);
397 // Even though both the pairing request and response had the EncKey bit set,
398 // because we resolved the features to secure connections, we zero the bit
399 // out.
400 EXPECT_FALSE(features().remote_key_distribution & KeyDistGen::kEncKey);
401 EXPECT_FALSE(features().remote_key_distribution & KeyDistGen::kEncKey);
402 ASSERT_TRUE(last_preq());
403 ASSERT_TRUE(last_pres());
404 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
405 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
406 }
407
TEST_F(Phase1Test,FeatureExchangeLocalSCRemoteNoSCFeaturesNoSc)408 TEST_F(Phase1Test, FeatureExchangeLocalSCRemoteNoSCFeaturesNoSc) {
409 Phase1Args args;
410 args.sc_supported = true;
411 NewPhase1(Role::kInitiator, args);
412 const auto kRequest = StaticByteBuffer(
413 0x01, // code: Pairing Request
414 0x03, // IO cap.: NoInputNoOutput
415 0x00, // OOB: not present
416 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
417 0x10, // encr. key size: 16 (default max)
418 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
419 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
420 KeyDistGen::kLinkKey // responder keys
421 );
422 const auto kResponse =
423 StaticByteBuffer(0x02, // code: Pairing Response
424 0x00, // IO cap.: DisplayOnly
425 0x00, // OOB: not present
426 AuthReq::kBondingFlag,
427 0x07, // encr. key size: 7 (default min)
428 0x00, // initiator keys: none
429 KeyDistGen::kEncKey // responder keys
430 );
431
432 EXPECT_PACKET_OUT(kRequest);
433 phase_1()->Start();
434 ASSERT_TRUE(AllExpectedPacketsSent());
435
436 fake_chan()->Receive(kResponse);
437 RunUntilIdle();
438
439 EXPECT_EQ(0, listener()->pairing_error_count());
440 EXPECT_EQ(1, feature_exchange_count());
441
442 EXPECT_TRUE(features().initiator);
443 EXPECT_FALSE(features().secure_connections);
444 ASSERT_TRUE(last_preq());
445 ASSERT_TRUE(last_pres());
446 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
447 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
448 }
449
TEST_F(Phase1Test,FeatureExchangePairingResponseLegacyJustWorks)450 TEST_F(Phase1Test, FeatureExchangePairingResponseLegacyJustWorks) {
451 const auto kRequest = StaticByteBuffer(
452 0x01, // code: Pairing Request
453 0x03, // IO cap.: NoInputNoOutput
454 0x00, // OOB: not present
455 AuthReq::kBondingFlag | AuthReq::kCT2,
456 0x10, // encr. key size: 16 (default max)
457 KeyDistGen::kEncKey, // initiator keys
458 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
459 );
460 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
461 0x00, // IO cap.: DisplayOnly
462 0x00, // OOB: not present
463 AuthReq::kBondingFlag,
464 0x07, // encr. key size: 7 (default min)
465 KeyDistGen::kEncKey, // initiator keys
466 KeyDistGen::kEncKey // responder keys
467 );
468
469 EXPECT_PACKET_OUT(kRequest);
470 phase_1()->Start();
471 ASSERT_TRUE(AllExpectedPacketsSent());
472
473 fake_chan()->Receive(kResponse);
474 RunUntilIdle();
475
476 EXPECT_EQ(0, listener()->pairing_error_count());
477 EXPECT_EQ(1, feature_exchange_count());
478
479 EXPECT_TRUE(features().initiator);
480 EXPECT_EQ(PairingMethod::kJustWorks, features().method);
481 EXPECT_EQ(7, features().encryption_key_size);
482 EXPECT_TRUE(KeyDistGen::kEncKey & features().local_key_distribution);
483 EXPECT_TRUE(KeyDistGen::kEncKey & features().remote_key_distribution);
484 ASSERT_TRUE(last_preq());
485 ASSERT_TRUE(last_pres());
486 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
487 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
488 }
489
TEST_F(Phase1Test,FeatureExchangePairingResponseLegacyMITM)490 TEST_F(Phase1Test, FeatureExchangePairingResponseLegacyMITM) {
491 auto phase_args = Phase1Args{.io_capability = IOCapability::kDisplayYesNo};
492 NewPhase1(Role::kInitiator, phase_args);
493
494 const auto kRequest = StaticByteBuffer(
495 0x01, // code: Pairing Request
496 0x01, // IO cap.: DisplayYesNo
497 0x00, // OOB: not present
498 AuthReq::kBondingFlag | AuthReq::kCT2,
499 0x10, // encr. key size: 16 (default max)
500 KeyDistGen::kEncKey, // initiator keys
501 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
502 );
503 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
504 0x02, // IO cap.: KeyboardOnly
505 0x00, // OOB: not present
506 AuthReq::kBondingFlag | AuthReq::kMITM,
507 0x07, // encr. key size: 7 (default min)
508 0x00, // initiator keys: none
509 KeyDistGen::kEncKey // responder keys
510 );
511
512 EXPECT_PACKET_OUT(kRequest);
513 phase_1()->Start();
514 ASSERT_TRUE(AllExpectedPacketsSent());
515
516 fake_chan()->Receive(kResponse);
517 RunUntilIdle();
518
519 EXPECT_EQ(0, listener()->pairing_error_count());
520 EXPECT_EQ(1, feature_exchange_count());
521
522 EXPECT_TRUE(features().initiator);
523 EXPECT_FALSE(features().secure_connections);
524 EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay, features().method);
525 EXPECT_EQ(7, features().encryption_key_size);
526 EXPECT_FALSE(features().local_key_distribution);
527 EXPECT_TRUE(KeyDistGen::kEncKey & features().remote_key_distribution);
528 ASSERT_TRUE(last_preq() && last_pres());
529 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
530 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
531 }
532
TEST_F(Phase1Test,FeatureExchangeEncryptionKeySize)533 TEST_F(Phase1Test, FeatureExchangeEncryptionKeySize) {
534 const auto kRequest = StaticByteBuffer(
535 0x01, // code: Pairing Request
536 0x03, // IO cap.: NoInputNoOutput
537 0x00, // OOB: not present
538 AuthReq::kBondingFlag | AuthReq::kCT2,
539 0x10, // encr. key size: 16 (default max)
540 KeyDistGen::kEncKey, // initiator keys
541 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
542 );
543 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
544 0x00, // IO cap.: DisplayOnly
545 0x00, // OOB: not present
546 AuthReq::kMITM,
547 0x02, // encr. key size: 2 (too small)
548 KeyDistGen::kEncKey, // initiator keys
549 KeyDistGen::kEncKey // responder keys
550 );
551 const StaticByteBuffer kFailure(0x05, // code: Pairing Failed
552 0x06 // reason: Encryption Key Size
553 );
554
555 EXPECT_PACKET_OUT(kRequest);
556 phase_1()->Start();
557 ASSERT_TRUE(AllExpectedPacketsSent());
558
559 EXPECT_PACKET_OUT(kFailure);
560 fake_chan()->Receive(kResponse);
561 RunUntilIdle();
562 ASSERT_TRUE(AllExpectedPacketsSent());
563
564 EXPECT_EQ(0, feature_exchange_count());
565 EXPECT_EQ(1, listener()->pairing_error_count());
566 EXPECT_EQ(Error(ErrorCode::kEncryptionKeySize), listener()->last_error());
567 }
568
TEST_F(Phase1Test,FeatureExchangeSecureAuthenticatedEncryptionKeySize)569 TEST_F(Phase1Test, FeatureExchangeSecureAuthenticatedEncryptionKeySize) {
570 auto phase_args = Phase1Args{.io_capability = IOCapability::kKeyboardDisplay,
571 .level = SecurityLevel::kSecureAuthenticated,
572 .sc_supported = true};
573 NewPhase1(Role::kInitiator, phase_args);
574 const StaticByteBuffer kRequest(
575 0x01, // code: Pairing Request
576 0x04, // IO cap.: KeyboardDisplay
577 0x00, // OOB: not present
578 AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC | AuthReq::kCT2,
579 0x10, // encr. key size: 16 (default max)
580 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
581 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
582 KeyDistGen::kLinkKey // responder keys
583 );
584 const StaticByteBuffer kResponse(
585 0x02, // code: Pairing Response
586 0x04, // IO cap.: KeyboardDisplay
587 0x00, // OOB: not present
588 AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC,
589 0x0F, // encr. key size: 15, i.e. one byte less than max
590 // possible encryption key size.
591 KeyDistGen::kEncKey, // initiator keys
592 KeyDistGen::kEncKey // responder keys
593 );
594 const StaticByteBuffer kFailure(kPairingFailed,
595 ErrorCode::kEncryptionKeySize);
596
597 EXPECT_PACKET_OUT(kRequest);
598 phase_1()->Start();
599 ASSERT_TRUE(AllExpectedPacketsSent());
600
601 // We should receive a pairing response and reply back with Pairing Failed; we
602 // enforce that all encryption keys are 16 bytes when `level` is set to
603 // SecureAuthenticated.
604 EXPECT_PACKET_OUT(kFailure);
605 fake_chan()->Receive(kResponse);
606 RunUntilIdle();
607 ASSERT_TRUE(AllExpectedPacketsSent());
608
609 EXPECT_EQ(0, feature_exchange_count());
610 EXPECT_EQ(1, listener()->pairing_error_count());
611 EXPECT_EQ(Error(ErrorCode::kEncryptionKeySize), listener()->last_error());
612 }
613
TEST_F(Phase1Test,FeatureExchangeSecureConnectionsRequiredNotPresent)614 TEST_F(Phase1Test, FeatureExchangeSecureConnectionsRequiredNotPresent) {
615 auto phase_args = Phase1Args{.io_capability = IOCapability::kKeyboardDisplay,
616 .level = SecurityLevel::kSecureAuthenticated,
617 .sc_supported = true};
618 NewPhase1(Role::kInitiator, phase_args);
619 const StaticByteBuffer kRequest(
620 0x01, // code: Pairing Request
621 0x04, // IO cap.: KeyboardDisplay
622 0x00, // OOB: not present
623 AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC | AuthReq::kCT2,
624 0x10, // encr. key size: 16 (default max)
625 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
626 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
627 KeyDistGen::kLinkKey // responder keys
628 );
629 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
630 0x04, // IO cap.: KeyboardDisplay
631 0x00, // OOB: not present
632 AuthReq::kBondingFlag | AuthReq::kMITM,
633 0x10, // encr. key size: 16 (default max)
634 KeyDistGen::kEncKey, // initiator keys
635 KeyDistGen::kEncKey // responder keys
636 );
637 const auto kFailure =
638 StaticByteBuffer(kPairingFailed, ErrorCode::kAuthenticationRequirements);
639
640 EXPECT_PACKET_OUT(kRequest);
641 phase_1()->Start();
642 ASSERT_TRUE(AllExpectedPacketsSent());
643
644 // We should receive a pairing response and reply back with Pairing Failed; we
645 // enforce that Secure Connections is used when `level` is set to
646 // SecureAuthenticated.
647 EXPECT_PACKET_OUT(kFailure);
648 fake_chan()->Receive(kResponse);
649 RunUntilIdle();
650 ASSERT_TRUE(AllExpectedPacketsSent());
651
652 EXPECT_EQ(0, feature_exchange_count());
653 EXPECT_EQ(1, listener()->pairing_error_count());
654 EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements),
655 listener()->last_error());
656 }
657
TEST_F(Phase1Test,FeatureExchangeBothSupportScLinkKeyAndCt2GenerateH7CtKey)658 TEST_F(Phase1Test, FeatureExchangeBothSupportScLinkKeyAndCt2GenerateH7CtKey) {
659 auto phase_args = Phase1Args{.sc_supported = true};
660 NewPhase1(Role::kInitiator, phase_args);
661 const StaticByteBuffer kRequest(
662 0x01, // code: Pairing Request
663 IOCapability::kNoInputNoOutput,
664 0x00, // OOB: not present
665 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
666 0x10, // encr. key size: 16 (default max)
667 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
668 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
669 KeyDistGen::kLinkKey // responder keys
670 );
671 const auto kResponse =
672 StaticByteBuffer(0x02, // code: Pairing Response
673 0x04, // IO cap.: KeyboardDisplay
674 0x00, // OOB: not present
675 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
676 0x10, // encr. key size: 16 (default max)
677 KeyDistGen::kLinkKey, // initiator keys
678 KeyDistGen::kLinkKey // responder keys
679 );
680
681 EXPECT_PACKET_OUT(kRequest);
682 phase_1()->Start();
683 ASSERT_TRUE(AllExpectedPacketsSent());
684
685 fake_chan()->Receive(kResponse);
686 RunUntilIdle();
687 EXPECT_EQ(1, feature_exchange_count());
688 ASSERT_TRUE(features().generate_ct_key.has_value());
689 EXPECT_EQ(CrossTransportKeyAlgo::kUseH7, features().generate_ct_key);
690 }
691
TEST_F(Phase1Test,FeatureExchangePeerDoesntSupportCt2GenerateH6CtKey)692 TEST_F(Phase1Test, FeatureExchangePeerDoesntSupportCt2GenerateH6CtKey) {
693 auto phase_args = Phase1Args{.sc_supported = true};
694 NewPhase1(Role::kInitiator, phase_args);
695 const StaticByteBuffer kRequest(
696 0x01, // code: Pairing Request
697 IOCapability::kNoInputNoOutput,
698 0x00, // OOB: not present
699 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
700 0x10, // encr. key size: 16 (default max)
701 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
702 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
703 KeyDistGen::kLinkKey // responder keys
704 );
705 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
706 0x04, // IO cap.: KeyboardDisplay
707 0x00, // OOB: not present
708 AuthReq::kBondingFlag | AuthReq::kSC,
709 0x10, // encr. key size: 16 (default max)
710 KeyDistGen::kLinkKey, // initiator keys
711 KeyDistGen::kLinkKey // responder keys
712 );
713
714 EXPECT_PACKET_OUT(kRequest);
715 phase_1()->Start();
716 ASSERT_TRUE(AllExpectedPacketsSent());
717
718 fake_chan()->Receive(kResponse);
719 RunUntilIdle();
720 EXPECT_EQ(1, feature_exchange_count());
721 ASSERT_TRUE(features().generate_ct_key.has_value());
722 EXPECT_EQ(CrossTransportKeyAlgo::kUseH6, features().generate_ct_key);
723 }
724
TEST_F(Phase1Test,FeatureExchangePeerDoesntSupportScDoNotGenerateCtKey)725 TEST_F(Phase1Test, FeatureExchangePeerDoesntSupportScDoNotGenerateCtKey) {
726 const auto kRequest = StaticByteBuffer(
727 0x01, // code: Pairing Request
728 IOCapability::kNoInputNoOutput,
729 0x00, // OOB: not present
730 AuthReq::kBondingFlag | AuthReq::kCT2,
731 0x10, // encr. key size: 16 (default max)
732 KeyDistGen::kEncKey, // initiator keys
733 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
734 );
735 // Although the peer supports CTKG through the hci_spec::LinkKey field and SC,
736 // locally we do not support SC, so CTKG is not allowed (v5.2 Vol. 3 Part
737 // H 3.6.1).
738 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
739 0x04, // IO cap.: KeyboardDisplay
740 0x00, // OOB: not present
741 AuthReq::kBondingFlag | AuthReq::kSC,
742 0x10, // encr. key size: 16 (default max)
743 KeyDistGen::kEncKey, // initiator keys
744 KeyDistGen::kEncKey // responder keys
745 );
746
747 EXPECT_PACKET_OUT(kRequest);
748 phase_1()->Start();
749 ASSERT_TRUE(AllExpectedPacketsSent());
750
751 fake_chan()->Receive(kResponse);
752 RunUntilIdle();
753 EXPECT_EQ(1, feature_exchange_count());
754 EXPECT_FALSE(features().generate_ct_key.has_value());
755 }
756
TEST_F(Phase1Test,FeatureExchangePeerSupportsCt2ButNotLinkKeyDoNotGenerateCtKey)757 TEST_F(Phase1Test,
758 FeatureExchangePeerSupportsCt2ButNotLinkKeyDoNotGenerateCtKey) {
759 auto phase_args = Phase1Args{.sc_supported = true};
760 NewPhase1(Role::kInitiator, phase_args);
761 const StaticByteBuffer kRequest(
762 0x01, // code: Pairing Request
763 IOCapability::kNoInputNoOutput,
764 0x00, // OOB: not present
765 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
766 0x10, // encr. key size: 16 (default max)
767 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
768 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
769 KeyDistGen::kLinkKey // responder keys
770 );
771 // The peer indicates support for the Link Key (CTKG) on only one of the
772 // Initiator/Responder Key Dist./Gen. fields, as such we do not generate the
773 // CT key.
774 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
775 0x04, // IO cap.: KeyboardDisplay
776 0x00, // OOB: not present
777 AuthReq::kBondingFlag | AuthReq::kSC | kCT2,
778 0x10, // encr. key size: 16 (default max)
779 0x00, // initiator keys - none
780 0x00 // responder keys - none
781 );
782
783 EXPECT_PACKET_OUT(kRequest);
784 phase_1()->Start();
785 ASSERT_TRUE(AllExpectedPacketsSent());
786
787 fake_chan()->Receive(kResponse);
788 RunUntilIdle();
789 EXPECT_EQ(1, feature_exchange_count());
790 EXPECT_FALSE(features().generate_ct_key.has_value());
791 }
792
TEST_F(Phase1Test,FeatureExchangePeerOnlyIndicatesOneLinkKeyDoNotGenerateCtKey)793 TEST_F(Phase1Test,
794 FeatureExchangePeerOnlyIndicatesOneLinkKeyDoNotGenerateCtKey) {
795 auto phase_args = Phase1Args{.sc_supported = true};
796 NewPhase1(Role::kInitiator, phase_args);
797 const StaticByteBuffer kRequest(
798 0x01, // code: Pairing Request
799 IOCapability::kNoInputNoOutput,
800 0x00, // OOB: not present
801 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
802 0x10, // encr. key size: 16 (default max)
803 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
804 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
805 KeyDistGen::kLinkKey // responder keys
806 );
807 // The peer indicates support for the Link Key (CTKG) on only one of the
808 // Initiator/Responder Key Dist./Gen. fields, as such we do not generate the
809 // CT key.
810 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
811 0x04, // IO cap.: KeyboardDisplay
812 0x00, // OOB: not present
813 AuthReq::kBondingFlag | AuthReq::kSC,
814 0x10, // encr. key size: 16 (default max)
815 KeyDistGen::kLinkKey, // initiator keys
816 0x00 // responder keys - none
817 );
818
819 EXPECT_PACKET_OUT(kRequest);
820 phase_1()->Start();
821 ASSERT_TRUE(AllExpectedPacketsSent());
822
823 fake_chan()->Receive(kResponse);
824 RunUntilIdle();
825 EXPECT_EQ(1, feature_exchange_count());
826 EXPECT_FALSE(features().generate_ct_key.has_value());
827 }
828
TEST_F(Phase1Test,FeatureExchangeResponderErrorCentral)829 TEST_F(Phase1Test, FeatureExchangeResponderErrorCentral) {
830 const auto kRequest = StaticByteBuffer(
831 0x01, // code: Pairing Request
832 0x03, // IO cap.: NoInputNoOutput
833 0x00, // OOB: not present
834 0x00, // AuthReq: no auth. request by default
835 0x10, // encr. key size: 16 (default max)
836 KeyDistGen::kEncKey, // initiator key dist.: encr. key only
837 KeyDistGen::kEncKey // responder key dist.: encr. key only
838 );
839 const StaticByteBuffer kFailure(0x05, // code: Pairing Failed
840 ErrorCode::kUnspecifiedReason);
841
842 NewPhase1(Role::kInitiator);
843 EXPECT_PACKET_OUT(kFailure);
844 fake_chan()->Receive(kRequest);
845 RunUntilIdle();
846 ASSERT_TRUE(AllExpectedPacketsSent());
847 EXPECT_EQ(1, listener()->pairing_error_count());
848 }
849
850 // Verify that Pairing Requests are rejected by Phase1 - these are handled
851 // elsewhere in our stack.
TEST_F(Phase1Test,Phase1ResponderRejectsPairingRequest)852 TEST_F(Phase1Test, Phase1ResponderRejectsPairingRequest) {
853 const auto kRequest = StaticByteBuffer(
854 0x01, // code: Pairing Request
855 0x03, // IO cap.: NoInputNoOutput
856 0x00, // OOB: not present
857 0x00, // AuthReq: no auth. request by default
858 0x10, // encr. key size: 16 (default max)
859 KeyDistGen::kEncKey, // initiator key dist.: encr. key only
860 KeyDistGen::kEncKey // responder key dist.: encr. key only
861 );
862 const StaticByteBuffer kFailure(0x05, // code: Pairing Failed
863 ErrorCode::kUnspecifiedReason);
864
865 NewPhase1(Role::kResponder);
866 EXPECT_PACKET_OUT(kFailure);
867 fake_chan()->Receive(kRequest);
868 RunUntilIdle();
869 ASSERT_TRUE(AllExpectedPacketsSent());
870 EXPECT_EQ(1, listener()->pairing_error_count());
871 }
872
TEST_F(Phase1Test,FeatureExchangeResponderBothSupportSCFeaturesHaveSC)873 TEST_F(Phase1Test, FeatureExchangeResponderBothSupportSCFeaturesHaveSC) {
874 const auto kResponse =
875 StaticByteBuffer(0x02, // code: Pairing Response
876 0x03, // IO cap.: NoInputNoOutput
877 0x00, // OOB: not present
878 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
879 0x10, // encr. key size: 7 (default min)
880 0x00, // initiator keys: none
881 KeyDistGen::kEncKey // responder keys
882 );
883
884 Phase1Args args{.preq =
885 PairingRequestParams{
886 .io_capability = IOCapability::kNoInputNoOutput,
887 .oob_data_flag = OOBDataFlag::kNotPresent,
888 .auth_req = AuthReq::kBondingFlag | AuthReq::kSC,
889 .max_encryption_key_size = 0x10, // 16, default max
890 .initiator_key_dist_gen = 0x00,
891 .responder_key_dist_gen = 0x01 // enc key
892 },
893 .sc_supported = true};
894 NewPhase1(Role::kResponder, args);
895 EXPECT_PACKET_OUT(kResponse);
896 phase_1()->Start();
897 ASSERT_TRUE(AllExpectedPacketsSent());
898
899 RunUntilIdle();
900
901 EXPECT_EQ(0, listener()->pairing_error_count());
902 EXPECT_EQ(1, feature_exchange_count());
903
904 EXPECT_FALSE(features().initiator);
905 EXPECT_TRUE(features().secure_connections);
906 }
907
TEST_F(Phase1Test,FeatureExchangeResponderLocalSCRemoteNoSCFeaturesNoSC)908 TEST_F(Phase1Test, FeatureExchangeResponderLocalSCRemoteNoSCFeaturesNoSC) {
909 const auto kResponse =
910 StaticByteBuffer(0x02, // code: Pairing Response
911 0x03, // IO cap.: NoInputNoOutput
912 0x00, // OOB: not present
913 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
914 0x10, // encr. key size: 7 (default min)
915 0x00, // initiator keys: none
916 KeyDistGen::kEncKey // responder keys
917 );
918
919 Phase1Args args{
920 .preq =
921 PairingRequestParams{
922 .io_capability = IOCapability::kNoInputNoOutput,
923 .oob_data_flag = OOBDataFlag::kNotPresent,
924 .auth_req = AuthReq::kBondingFlag,
925 .max_encryption_key_size = 0x10, // 16, default max
926 .initiator_key_dist_gen = 0x00,
927 .responder_key_dist_gen = KeyDistGen::kEncKey // enc key
928 },
929 .sc_supported = true};
930 NewPhase1(Role::kResponder, args);
931 EXPECT_PACKET_OUT(kResponse);
932 phase_1()->Start();
933 ASSERT_TRUE(AllExpectedPacketsSent());
934
935 RunUntilIdle();
936
937 EXPECT_EQ(0, listener()->pairing_error_count());
938 EXPECT_EQ(1, feature_exchange_count());
939
940 EXPECT_FALSE(features().initiator);
941 EXPECT_FALSE(features().secure_connections);
942 }
943
944 // Tests that the local responder does not request keys that the initiator
945 // cannot distribute.
TEST_F(Phase1Test,FeatureExchangeLocalResponderDoesNotRequestUnsupportedKeys)946 TEST_F(Phase1Test, FeatureExchangeLocalResponderDoesNotRequestUnsupportedKeys) {
947 auto phase_args =
948 Phase1Args{.preq = PairingRequestParams{
949 .io_capability = IOCapability::kNoInputNoOutput,
950 .oob_data_flag = OOBDataFlag::kNotPresent,
951 .auth_req = AuthReq::kBondingFlag,
952 .max_encryption_key_size = 16,
953 .initiator_key_dist_gen = 0x04, // sign key only
954 .responder_key_dist_gen = 0x00 // none
955 }};
956 const StaticByteBuffer kResponse(
957 0x02, // code: Pairing Response
958 0x03, // IO cap.: NoInputNoOutput
959 0x00, // OOB: not present
960 AuthReq::kBondingFlag | AuthReq::kCT2,
961 0x10, // encr. key size: 16 (default max)
962 0x00, // initiator keys: none - we shouldn't request the SignKey
963 // as we don't support it
964 0x00 // responder keys: none
965 );
966
967 NewPhase1(Role::kResponder, phase_args);
968 EXPECT_PACKET_OUT(kResponse);
969 phase_1()->Start();
970 ASSERT_TRUE(AllExpectedPacketsSent());
971
972 EXPECT_EQ(1, feature_exchange_count());
973 EXPECT_FALSE(features().initiator);
974 EXPECT_FALSE(features().local_key_distribution);
975 EXPECT_FALSE(features().remote_key_distribution);
976 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
977 }
978
979 // Tests that we (as the responder) request to distribute identity information
980 // if available.
TEST_F(Phase1Test,FeatureExchangeResponderDistributesIdKey)981 TEST_F(Phase1Test, FeatureExchangeResponderDistributesIdKey) {
982 auto phase_args =
983 Phase1Args{.preq = PairingRequestParams{
984 .io_capability = IOCapability::kNoInputNoOutput,
985 .oob_data_flag = OOBDataFlag::kNotPresent,
986 .auth_req = 0x01, // bondable mode
987 .max_encryption_key_size = 0x10, // 16, default max
988 .initiator_key_dist_gen = 0x00,
989 .responder_key_dist_gen = KeyDistGen::kIdKey}};
990 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
991 0x03, // IO cap.: NoInputNoOutput
992 0x00, // OOB: not present
993 AuthReq::kBondingFlag | AuthReq::kCT2,
994 0x10, // encr. key size: 16 (default max)
995 0x00, // initiator keys: none
996 KeyDistGen::kIdKey // responder keys
997 );
998
999 NewPhase1(Role::kResponder, phase_args);
1000 listener()->set_identity_info(IdentityInfo());
1001 EXPECT_PACKET_OUT(kResponse);
1002 phase_1()->Start();
1003 ASSERT_TRUE(AllExpectedPacketsSent());
1004
1005 EXPECT_EQ(1, feature_exchange_count());
1006 EXPECT_FALSE(features().initiator);
1007 EXPECT_TRUE(features().local_key_distribution & KeyDistGen::kIdKey);
1008 EXPECT_FALSE(features().remote_key_distribution);
1009 }
1010
1011 // Tests that local responder doesn't respond with distribute ID info if
1012 // available but not requested by the initiator.
TEST_F(Phase1Test,FeatureExchangeResponderRespectsInitiatorForIdKey)1013 TEST_F(Phase1Test, FeatureExchangeResponderRespectsInitiatorForIdKey) {
1014 auto phase_args =
1015 Phase1Args{.preq = PairingRequestParams{
1016 .io_capability = IOCapability::kNoInputNoOutput,
1017 .oob_data_flag = OOBDataFlag::kNotPresent,
1018 .auth_req = 0x01, // bondable mode
1019 .max_encryption_key_size = 0x10, // 16, default max
1020 .initiator_key_dist_gen = 0x00,
1021 .responder_key_dist_gen =
1022 0x00 // Initiator explicitly does not request ID key
1023 }};
1024 const StaticByteBuffer kResponse(
1025 0x02, // code: Pairing Response
1026 0x03, // IO cap.: NoInputNoOutput
1027 0x00, // OOB: not present
1028 AuthReq::kBondingFlag | AuthReq::kCT2,
1029 0x10, // encr. key size: 16 (default max)
1030 0x00, // initiator keys: none
1031 0x00 // responder keys: none - we shouldn't distribute IdKey
1032 // even though we have it
1033 );
1034
1035 NewPhase1(Role::kResponder, phase_args);
1036 listener()->set_identity_info(IdentityInfo());
1037 EXPECT_PACKET_OUT(kResponse);
1038 phase_1()->Start();
1039 ASSERT_TRUE(AllExpectedPacketsSent());
1040
1041 EXPECT_EQ(1, feature_exchange_count());
1042 EXPECT_FALSE(features().initiator);
1043 EXPECT_FALSE(features().local_key_distribution);
1044 EXPECT_FALSE(features().remote_key_distribution);
1045 }
1046
1047 // Pairing should fail if MITM is required but the pairing method cannot provide
1048 // it (due to I/O capabilities).
TEST_F(Phase1Test,FeatureExchangeResponderFailedAuthenticationRequirements)1049 TEST_F(Phase1Test, FeatureExchangeResponderFailedAuthenticationRequirements) {
1050 const auto kRequest = StaticByteBuffer(
1051 0x01, // code: Pairing Response
1052 0x00, // IO cap.: DisplayOnly
1053 0x00, // OOB: not present
1054 AuthReq::kMITM,
1055 0x07, // encr. key size: 7 (default min)
1056 KeyDistGen::kEncKey, // initiator key dist.: encr. key only
1057 KeyDistGen::kEncKey // responder key dist.: encr. key only
1058 );
1059 const StaticByteBuffer kFailure(0x05, // code: Pairing Failed
1060 0x03 // reason: Authentication requirements
1061 );
1062 auto reader = PacketReader(&kRequest);
1063 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1064 .io_capability = IOCapability::kNoInputNoOutput};
1065 NewPhase1(Role::kResponder, phase_args);
1066
1067 EXPECT_PACKET_OUT(kFailure);
1068 phase_1()->Start();
1069 ASSERT_TRUE(AllExpectedPacketsSent());
1070 EXPECT_EQ(1, listener()->pairing_error_count());
1071 EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements),
1072 listener()->last_error());
1073 }
1074
TEST_F(Phase1Test,FeatureExchangeResponderJustWorks)1075 TEST_F(Phase1Test, FeatureExchangeResponderJustWorks) {
1076 const auto kRequest = StaticByteBuffer(
1077 0x01, // code: Pairing Response
1078 0x00, // IO cap.: DisplayOnly
1079 0x00, // OOB: not present
1080 AuthReq::kBondingFlag,
1081 0x07, // encr. key size: 7 (default min)
1082 KeyDistGen::kIdKey, // initiator keys
1083 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
1084 );
1085 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
1086 0x03, // IO cap.: NoInputNoOutput
1087 0x00, // OOB: not present
1088 AuthReq::kBondingFlag | AuthReq::kCT2,
1089 0x10, // encr. key size: 16 (default max)
1090 KeyDistGen::kIdKey, // initiator keys
1091 KeyDistGen::kEncKey // responder keys
1092 );
1093
1094 auto reader = PacketReader(&kRequest);
1095 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1096 .io_capability = IOCapability::kNoInputNoOutput};
1097
1098 NewPhase1(Role::kResponder, phase_args);
1099 EXPECT_PACKET_OUT(kResponse);
1100 phase_1()->Start();
1101 ASSERT_TRUE(AllExpectedPacketsSent());
1102
1103 EXPECT_EQ(0, listener()->pairing_error_count());
1104 EXPECT_EQ(1, feature_exchange_count());
1105 EXPECT_FALSE(features().initiator);
1106 EXPECT_FALSE(features().secure_connections);
1107 EXPECT_EQ(PairingMethod::kJustWorks, features().method);
1108 EXPECT_EQ(7, features().encryption_key_size);
1109 ASSERT_TRUE(last_preq());
1110 ASSERT_TRUE(last_pres());
1111 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
1112 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
1113
1114 // We send the LTK when we are the responder.
1115 EXPECT_TRUE(KeyDistGen::kEncKey & features().local_key_distribution);
1116
1117 // The remote should send us identity information since we requested it and it
1118 // promised it.
1119 EXPECT_TRUE(KeyDistGen::kIdKey & features().remote_key_distribution);
1120 }
1121
TEST_F(Phase1Test,FeatureExchangeResponderRequestInitiatorEncKey)1122 TEST_F(Phase1Test, FeatureExchangeResponderRequestInitiatorEncKey) {
1123 const StaticByteBuffer kRequest(0x01, // code: Pairing Response
1124 0x00, // IO cap.: DisplayOnly
1125 0x00, // OOB: not present
1126 AuthReq::kBondingFlag,
1127 0x07, // encr. key size: 7 (default min)
1128 KeyDistGen::kEncKey, // initiator keys
1129 0x03 // responder keys
1130 );
1131 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
1132 0x03, // IO cap.: NoInputNoOutput
1133 0x00, // OOB: not present
1134 AuthReq::kBondingFlag | AuthReq::kCT2,
1135 0x10, // encr. key size: 16 (default max)
1136 KeyDistGen::kEncKey, // initiator keys
1137 KeyDistGen::kEncKey // responder keys
1138 );
1139
1140 auto reader = PacketReader(&kRequest);
1141 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1142 .io_capability = IOCapability::kNoInputNoOutput};
1143
1144 NewPhase1(Role::kResponder, phase_args);
1145 EXPECT_PACKET_OUT(kResponse);
1146 phase_1()->Start();
1147 ASSERT_TRUE(AllExpectedPacketsSent());
1148
1149 EXPECT_EQ(0, listener()->pairing_error_count());
1150 EXPECT_EQ(1, feature_exchange_count());
1151 EXPECT_FALSE(features().initiator);
1152 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
1153 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
1154
1155 // We send the LTK as the initiator requested it. We also request the LTK from
1156 // the initiator, which indicated it was capable of distributing it.
1157 EXPECT_TRUE(KeyDistGen::kEncKey & features().local_key_distribution);
1158 EXPECT_TRUE(KeyDistGen::kEncKey & features().remote_key_distribution);
1159 }
1160
TEST_F(Phase1Test,FeatureExchangeResponderSendsOnlyRequestedKeys)1161 TEST_F(Phase1Test, FeatureExchangeResponderSendsOnlyRequestedKeys) {
1162 const StaticByteBuffer kRequest(
1163 0x01, // code: Pairing Response
1164 0x00, // IO cap.: DisplayOnly
1165 0x00, // OOB: not present
1166 AuthReq::kBondingFlag,
1167 0x07, // encr. key size: 7 (default min)
1168 KeyDistGen::kIdKey, // initiator keys
1169 KeyDistGen::kIdKey // responder keys - responder
1170 // doesn't have ID info, so
1171 // won't send it
1172 );
1173 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
1174 0x03, // IO cap.: NoInputNoOutput
1175 0x00, // OOB: not present
1176 AuthReq::kBondingFlag | AuthReq::kCT2,
1177 0x10, // encr. key size: 16 (default max)
1178 KeyDistGen::kIdKey, // initiator keys
1179 0x00 // responder keys: none
1180 );
1181
1182 auto reader = PacketReader(&kRequest);
1183 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1184 .io_capability = IOCapability::kNoInputNoOutput};
1185 NewPhase1(Role::kResponder, phase_args);
1186 EXPECT_PACKET_OUT(kResponse);
1187 phase_1()->Start();
1188 ASSERT_TRUE(AllExpectedPacketsSent());
1189 ASSERT_EQ(1, feature_exchange_count());
1190 }
1191
TEST_F(Phase1Test,FeatureExchangeResponderMITM)1192 TEST_F(Phase1Test, FeatureExchangeResponderMITM) {
1193 const auto kRequest = StaticByteBuffer(
1194 0x01, // code: Pairing Request
1195 0x02, // IO cap.: KeyboardOnly
1196 0x00, // OOB: not present
1197 AuthReq::kBondingFlag | AuthReq::kMITM,
1198 0x07, // encr. key size: 7 (default min)
1199 KeyDistGen::kIdKey, // initiator keys
1200 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
1201 );
1202 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
1203 0x01, // IO cap.: DisplayYesNo
1204 0x00, // OOB: not present
1205 AuthReq::kBondingFlag | AuthReq::kCT2,
1206 0x10, // encr. key size: 16 (default max)
1207 KeyDistGen::kIdKey, // initiator keys
1208 KeyDistGen::kEncKey // responder keys
1209 );
1210
1211 auto reader = PacketReader(&kRequest);
1212 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1213 .io_capability = IOCapability::kDisplayYesNo};
1214 NewPhase1(Role::kResponder, phase_args);
1215
1216 EXPECT_PACKET_OUT(kResponse);
1217 phase_1()->Start();
1218 ASSERT_TRUE(AllExpectedPacketsSent());
1219
1220 EXPECT_EQ(0, listener()->pairing_error_count());
1221 EXPECT_EQ(1, feature_exchange_count());
1222 EXPECT_FALSE(features().initiator);
1223 EXPECT_FALSE(features().secure_connections);
1224 EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay, features().method);
1225 EXPECT_EQ(7, features().encryption_key_size);
1226 ASSERT_TRUE(last_preq());
1227 ASSERT_TRUE(last_pres());
1228 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
1229 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
1230
1231 // We send the LTK when we are the responder.
1232 EXPECT_TRUE(KeyDistGen::kEncKey & features().local_key_distribution);
1233
1234 // The remote should send us identity information since we requested it and it
1235 // promised it.
1236 EXPECT_TRUE(KeyDistGen::kIdKey & features().remote_key_distribution);
1237
1238 // We should have set bondable mode as both sides enabled it
1239 EXPECT_TRUE(features().will_bond);
1240 }
1241
TEST_F(Phase1Test,FeatureExchangeResponderRespectsDesiredLevel)1242 TEST_F(Phase1Test, FeatureExchangeResponderRespectsDesiredLevel) {
1243 const StaticByteBuffer kRequest(0x01, // code: Pairing Response
1244 0x01, // IO cap.: KeyboardDisplay
1245 0x00, // OOB: not present
1246 AuthReq::kBondingFlag | AuthReq::kSC,
1247 0x10, // encr. key size: 16 (default max)
1248 0x00, // initiator keys: none
1249 KeyDistGen::kEncKey // responder keys
1250 );
1251 const auto kResponse = StaticByteBuffer(
1252 0x02, // code: Pairing Response
1253 0x01, // IO cap.: KeyboardDisplay
1254 0x00, // OOB: not present
1255 AuthReq::kBondingFlag | AuthReq::kMITM | AuthReq::kSC | AuthReq::kCT2,
1256 0x10, // encr. key size: 16 (default max)
1257 0x00, // initiator keys: none
1258 KeyDistGen::kEncKey // responder keys
1259 );
1260
1261 auto reader = PacketReader(&kRequest);
1262 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1263 .io_capability = IOCapability::kDisplayYesNo,
1264 .level = SecurityLevel::kAuthenticated,
1265 .sc_supported = true};
1266
1267 NewPhase1(Role::kResponder, phase_args);
1268 EXPECT_PACKET_OUT(kResponse);
1269 phase_1()->Start();
1270 ASSERT_TRUE(AllExpectedPacketsSent());
1271
1272 EXPECT_EQ(0, listener()->pairing_error_count());
1273 EXPECT_EQ(1, feature_exchange_count());
1274 EXPECT_TRUE(features().secure_connections);
1275 // We requested authenticated security, which led to Numeric Comparison as the
1276 // pairing method.
1277 EXPECT_EQ(PairingMethod::kNumericComparison, features().method);
1278 ASSERT_TRUE(last_preq());
1279 ASSERT_TRUE(last_pres());
1280 EXPECT_TRUE(ContainersEqual(kRequest, *last_preq()));
1281 EXPECT_TRUE(ContainersEqual(kResponse, *last_pres()));
1282 }
1283
TEST_F(Phase1Test,FeatureExchangeResponderRejectsMethodOfInsufficientSecurity)1284 TEST_F(Phase1Test,
1285 FeatureExchangeResponderRejectsMethodOfInsufficientSecurity) {
1286 const StaticByteBuffer kRequest(0x01, // code: Pairing Response
1287 0x01, // IO cap.: DisplayYesNo
1288 0x00, // OOB: not present
1289 AuthReq::kBondingFlag,
1290 0x10, // encr. key size: 16 (default max)
1291 0x00, // initiator keys: none
1292 KeyDistGen::kEncKey // responder keys
1293 );
1294 const auto kFailure =
1295 StaticByteBuffer(kPairingFailed, ErrorCode::kAuthenticationRequirements);
1296
1297 auto reader = PacketReader(&kRequest);
1298 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1299 .io_capability = IOCapability::kDisplayYesNo,
1300 .level = SecurityLevel::kAuthenticated,
1301 .sc_supported = true};
1302
1303 NewPhase1(Role::kResponder, phase_args);
1304 // Both devices have DisplayYesNo IOCap, but the initiator does not support
1305 // Secure Connections so Numeric Comparison cannot be used. Neither device has
1306 // a keyboard, so Passkey Entry cannot be used. Thus authenticated pairing,
1307 // the desired level, cannot be met and we fail.
1308 EXPECT_PACKET_OUT(kFailure);
1309 phase_1()->Start();
1310 ASSERT_TRUE(AllExpectedPacketsSent());
1311
1312 EXPECT_EQ(1, listener()->pairing_error_count());
1313 EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements),
1314 listener()->last_error());
1315 }
1316
TEST_F(Phase1Test,FeatureExchangeResponderSecureAuthenticatedInitiatorNoInputNoOutput)1317 TEST_F(Phase1Test,
1318 FeatureExchangeResponderSecureAuthenticatedInitiatorNoInputNoOutput) {
1319 const auto kRequest = StaticByteBuffer(
1320 0x01, // code: Pairing Request
1321 0x03, // IO cap.: NoInputNoOutput
1322 0x00, // OOB: not present
1323 AuthReq::kBondingFlag | AuthReq::kSC,
1324 0x10, // encr. key size: 16 (default max)
1325 KeyDistGen::kEncKey, // initiator keys
1326 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
1327 );
1328 const auto kFailure =
1329 StaticByteBuffer(kPairingFailed, ErrorCode::kAuthenticationRequirements);
1330
1331 auto reader = PacketReader(&kRequest);
1332 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1333 .io_capability = IOCapability::kDisplayYesNo,
1334 .level = SecurityLevel::kSecureAuthenticated,
1335 .sc_supported = true};
1336 NewPhase1(Role::kResponder, phase_args);
1337
1338 // Cannot perform SecureAuthenticated pairing with the peer's NoInputNoOutput
1339 // IOCapabilities.
1340 EXPECT_PACKET_OUT(kFailure);
1341 phase_1()->Start();
1342 ASSERT_TRUE(AllExpectedPacketsSent());
1343
1344 EXPECT_EQ(1, listener()->pairing_error_count());
1345 EXPECT_EQ(Error(ErrorCode::kAuthenticationRequirements),
1346 listener()->last_error());
1347 }
1348
TEST_F(Phase1Test,FeatureExchangeResponderDoesntSupportScDoNotGenerateCtKey)1349 TEST_F(Phase1Test, FeatureExchangeResponderDoesntSupportScDoNotGenerateCtKey) {
1350 const StaticByteBuffer kRequest(
1351 0x01, // code: Pairing Request
1352 IOCapability::kNoInputNoOutput,
1353 0x00, // OOB: not present
1354 AuthReq::kBondingFlag | AuthReq::kSC | AuthReq::kCT2,
1355 0x10, // encr. key size: 16 (default max)
1356 KeyDistGen::kEncKey | KeyDistGen::kLinkKey, // initiator keys
1357 KeyDistGen::kEncKey | KeyDistGen::kIdKey |
1358 KeyDistGen::kLinkKey // responder keys
1359 );
1360 // Although the peer supports CTKG through the hci_spec::LinkKey field and SC,
1361 // locally we do not support support SC, so CTKG is not allowed (v5.2 Vol. 3
1362 // Part H 3.6.1).
1363 const StaticByteBuffer kResponse(0x02, // code: Pairing Response
1364 IOCapability::kNoInputNoOutput,
1365 0x00, // OOB: not present
1366 AuthReq::kBondingFlag | AuthReq::kCT2,
1367 0x10, // encr. key size: 16 (default max)
1368 KeyDistGen::kEncKey, // initiator keys
1369 KeyDistGen::kEncKey // responder keys
1370 );
1371
1372 auto reader = PacketReader(&kRequest);
1373 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1374 .sc_supported = false};
1375 NewPhase1(Role::kResponder, phase_args);
1376 EXPECT_PACKET_OUT(kResponse);
1377 phase_1()->Start();
1378 ASSERT_TRUE(AllExpectedPacketsSent());
1379
1380 EXPECT_EQ(1, feature_exchange_count());
1381 EXPECT_FALSE(features().generate_ct_key.has_value());
1382 }
1383
TEST_F(Phase1Test,UnsupportedCommandDuringPairing)1384 TEST_F(Phase1Test, UnsupportedCommandDuringPairing) {
1385 const StaticByteBuffer kRequest(
1386 0x01, // code: "Pairing Request"
1387 0x03, // IO cap.: NoInputNoOutput
1388 0x00, // OOB: not present
1389 AuthReq::kBondingFlag | AuthReq::kCT2,
1390 0x10, // encr. key size: 16 (default max)
1391 KeyDistGen::kEncKey, // initiator keys
1392 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
1393 );
1394 EXPECT_PACKET_OUT(kRequest);
1395 phase_1()->Start();
1396
1397 const StaticByteBuffer kFailed(0x05, // code: Pairing Failed
1398 0x07 // reason: Command Not Supported
1399 );
1400 EXPECT_PACKET_OUT(kFailed);
1401 fake_chan()->Receive(StaticByteBuffer(0xFF));
1402 RunUntilIdle();
1403 ASSERT_TRUE(AllExpectedPacketsSent());
1404
1405 EXPECT_EQ(1, listener()->pairing_error_count());
1406 EXPECT_EQ(Error(ErrorCode::kCommandNotSupported), listener()->last_error());
1407 }
1408
TEST_F(Phase1Test,OnSecurityRequestWhilePairing)1409 TEST_F(Phase1Test, OnSecurityRequestWhilePairing) {
1410 const StaticByteBuffer kPairingRequest(
1411 0x01, // code: "Pairing Request"
1412 0x03, // IO cap.: NoInputNoOutput
1413 0x00, // OOB: not present
1414 AuthReq::kBondingFlag | AuthReq::kCT2,
1415 0x10, // encr. key size: 16 (default max)
1416 KeyDistGen::kEncKey, // initiator keys
1417 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
1418 );
1419 EXPECT_PACKET_OUT(kPairingRequest);
1420 phase_1()->Start();
1421
1422 const StaticByteBuffer kSecurityRequest(0x0B, // code: Security Request
1423 0x00 // auth_req
1424 );
1425
1426 const StaticByteBuffer kFailed(0x05, // code: Pairing Failed
1427 0x08 // reason: unspecified reason
1428 );
1429 EXPECT_PACKET_OUT(kFailed);
1430 fake_chan()->Receive(kSecurityRequest);
1431 RunUntilIdle();
1432
1433 // The security request while pairing should cause pairing to fail.
1434 EXPECT_EQ(1, listener()->pairing_error_count());
1435 }
1436
1437 // Tests whether a request from a device with bondable mode enabled to a peer
1438 // with non-bondable mode enabled will return a PairingFeatures with
1439 // non-bondable mode enabled, the desired result.
TEST_F(Phase1Test,FeatureExchangeInitiatorReqBondResNoBond)1440 TEST_F(Phase1Test, FeatureExchangeInitiatorReqBondResNoBond) {
1441 const auto kRequest = StaticByteBuffer(
1442 0x01, // code: Pairing Request
1443 0x03, // IO cap.: NoInputNoOutput
1444 0x00, // OOB: not present
1445 AuthReq::kBondingFlag | AuthReq::kCT2,
1446 0x10, // encr. key size: 16 (default max)
1447 KeyDistGen::kEncKey, // initiator keys
1448 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
1449 );
1450 const auto kResponse =
1451 StaticByteBuffer(0x02, // code: Pairing Response
1452 0x00, // IO cap.: DisplayOnly
1453 0x00, // OOB: not present
1454 0x00,
1455 0x07, // encr. key size: 7 (default min)
1456 0x00, // initiator keys: none
1457 0x00 // responder keys: none due to non-bondable mode
1458 );
1459
1460 EXPECT_PACKET_OUT(kRequest);
1461 phase_1()->Start();
1462 ASSERT_TRUE(AllExpectedPacketsSent());
1463
1464 fake_chan()->Receive(kResponse);
1465 RunUntilIdle();
1466
1467 // Should be in non-bondable mode even though the Initiator specifies bonding,
1468 // as kResponse indicated that the peer follower does not support bonding.
1469 EXPECT_FALSE(features().will_bond);
1470 EXPECT_EQ(features().local_key_distribution, 0u);
1471 EXPECT_EQ(features().remote_key_distribution, 0u);
1472 }
1473
TEST_F(Phase1Test,FeatureExchangeInitiatorReqNoBondResBond)1474 TEST_F(Phase1Test, FeatureExchangeInitiatorReqNoBondResBond) {
1475 auto phase_args = Phase1Args{.bondable_mode = BondableMode::NonBondable};
1476 NewPhase1(Role::kInitiator, phase_args);
1477 const StaticByteBuffer kRequest(0x01, // code: Pairing Request
1478 0x03, // IO cap.: NoInputNoOutput
1479 0x00, // OOB: not present
1480 AuthReq::kCT2, // AuthReq: non-bondable
1481 0x10, // encr. key size: 16 (default max)
1482 0x00, // initiator keys: none
1483 0x00 // responder keys: none
1484 );
1485 const auto kResponse = StaticByteBuffer(
1486 0x02, // code: Pairing Response
1487 0x00, // IO cap.: DisplayOnly
1488 0x00, // OOB: not present
1489 AuthReq::kBondingFlag,
1490 0x07, // encr. key size: 7 (default min)
1491 0x00, // initiator keys: none - should not change request field
1492 0x00 // responder keys: none - should not change request field
1493 );
1494
1495 EXPECT_PACKET_OUT(kRequest);
1496 phase_1()->Start();
1497 ASSERT_TRUE(AllExpectedPacketsSent());
1498
1499 fake_chan()->Receive(kResponse);
1500 RunUntilIdle();
1501
1502 // Although kResponse is bondable, features should not bond as local device is
1503 // non-bondable.
1504 ASSERT_EQ(1, feature_exchange_count());
1505 EXPECT_FALSE(features().will_bond);
1506 EXPECT_EQ(features().local_key_distribution, 0u);
1507 EXPECT_EQ(features().remote_key_distribution, 0u);
1508 }
1509
TEST_F(Phase1Test,FeatureExchangeResponderReqBondResNoBond)1510 TEST_F(Phase1Test, FeatureExchangeResponderReqBondResNoBond) {
1511 const auto kRequest = StaticByteBuffer(
1512 0x01, // code: Pairing Request
1513 0x03, // IO cap.: NoInputNoOutput
1514 0x00, // OOB: not present
1515 AuthReq::kBondingFlag,
1516 0x10, // encr. key size: 16 (default max)
1517 0x00, // initiator keys: none
1518 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
1519 );
1520 const auto kResponse = StaticByteBuffer(
1521 0x02, // code: Pairing Response
1522 0x03, // IO cap.: NoInputNoOutput
1523 0x00, // OOB: not present
1524 AuthReq::kCT2, // AuthReq: non-bondable to match local mode,
1525 // even though kRequest was bondable
1526 0x10, // encr. key size: 16 (default max)
1527 0x00, // initiator keys: none - should not change request field
1528 0x00 // responder keys: none - should not change request field
1529 );
1530
1531 auto reader = PacketReader(&kRequest);
1532 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>(),
1533 .bondable_mode = BondableMode::NonBondable};
1534 NewPhase1(Role::kResponder, phase_args);
1535 EXPECT_PACKET_OUT(kResponse);
1536 phase_1()->Start();
1537 ASSERT_TRUE(AllExpectedPacketsSent());
1538
1539 // Should be in non-bondable mode even though the peer requested bondable, as
1540 // the Bearer was created in non-bondable mode.
1541 EXPECT_FALSE(features().will_bond);
1542 EXPECT_EQ(features().local_key_distribution, 0u);
1543 EXPECT_EQ(features().remote_key_distribution, 0u);
1544 }
1545
TEST_F(Phase1Test,FeatureExchangeResponderReqNoBondResNoBond)1546 TEST_F(Phase1Test, FeatureExchangeResponderReqNoBondResNoBond) {
1547 const StaticByteBuffer kRequest(0x01, // code: Pairing Request
1548 0x03, // IO cap.: NoInputNoOutput
1549 0x00, // OOB: not present
1550 0x00, // AuthReq: non-bondable
1551 0x10, // encr. key size: 16 (default max)
1552 0x00, // initiator keys: none
1553 0x00 // responder keys: none
1554 );
1555 const auto kResponse = StaticByteBuffer(
1556 0x02, // code: Pairing Response
1557 0x03, // IO cap.: NoInputNoOutput
1558 0x00, // OOB: not present
1559 AuthReq::kCT2, // AuthReq: non-bondable to match peer mode, even
1560 // though Phase1 is bondable.
1561 0x10, // encr. key size: 16 (default max)
1562 0x00, // initiator keys: none - should not change request field
1563 0x00 // responder keys: none - should not change request field
1564 );
1565
1566 auto reader = PacketReader(&kRequest);
1567 auto phase_args = Phase1Args{
1568 .preq = reader.payload<PairingRequestParams>(),
1569 .bondable_mode = BondableMode::Bondable, // local mode is bondable,
1570 // although peer is not
1571 };
1572 NewPhase1(Role::kResponder, phase_args);
1573 EXPECT_PACKET_OUT(kResponse);
1574 phase_1()->Start();
1575 ASSERT_TRUE(AllExpectedPacketsSent());
1576
1577 // Should be in non-bondable mode even though Bearer was created in bondable
1578 // mode as kRequest indicated that peer does not support bonding.
1579 EXPECT_FALSE(features().will_bond);
1580 EXPECT_EQ(features().local_key_distribution, 0u);
1581 EXPECT_EQ(features().remote_key_distribution, 0u);
1582 }
1583
TEST_F(Phase1Test,FeatureExchangeResponderReqNoBondWithKeys)1584 TEST_F(Phase1Test, FeatureExchangeResponderReqNoBondWithKeys) {
1585 const auto kRequest = StaticByteBuffer(
1586 0x01, // code: Pairing Request
1587 0x03, // IO cap.: NoInputNoOutput
1588 0x00, // OOB: not present
1589 AuthReq::kCT2, // AuthReq: non-bondable
1590 0x10, // encr. key size: 16 (default max)
1591 KeyDistGen::kEncKey | KeyDistGen::kIdKey, // initiator keys
1592 KeyDistGen::kEncKey | KeyDistGen::kIdKey // responder keys
1593 );
1594
1595 auto reader = PacketReader(&kRequest);
1596 auto phase_args = Phase1Args{.preq = reader.payload<PairingRequestParams>()};
1597 NewPhase1(Role::kResponder, phase_args);
1598
1599 const StaticByteBuffer kFailed(0x05, // code: Pairing Failed
1600 0x0A // reason: invalid parameters
1601 );
1602 EXPECT_PACKET_OUT(kFailed);
1603 phase_1()->Start();
1604 RunUntilIdle();
1605
1606 // Check that we fail with invalid parameters when a peer requests nonbondable
1607 // mode with a non-zero KeyDistGen field
1608 EXPECT_EQ(1, listener()->pairing_error_count());
1609 EXPECT_EQ(Error(ErrorCode::kInvalidParameters), listener()->last_error());
1610 }
1611
1612 } // namespace
1613 } // namespace bt::sm
1614