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 #include "pw_bluetooth_sapphire/internal/host/gap/secure_simple_pairing_state.h"
16
17 #include <inttypes.h>
18 #include <pw_assert/check.h>
19
20 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
21 #include "pw_bluetooth_sapphire/internal/host/gap/bredr_connection_manager.h"
22 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
23 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
24
25 namespace bt::gap {
26
27 using pw::bluetooth::emboss::AuthenticationRequirements;
28 using pw::bluetooth::emboss::IoCapability;
29
30 namespace {
31
32 const char* const kInspectEncryptionStatusPropertyName = "encryption_status";
33 const char* const kInspectSecurityPropertiesPropertyName =
34 "security_properties";
35
36 } // namespace
37
SecureSimplePairingState(Peer::WeakPtr peer,PairingDelegate::WeakPtr pairing_delegate,WeakPtr<hci::BrEdrConnection> link,bool outgoing_connection,fit::closure auth_cb,StatusCallback status_cb,hci::LocalAddressDelegate * low_energy_address_delegate,bool controller_remote_public_key_validation_supported,sm::BrEdrSecurityManagerFactory security_manager_factory,pw::async::Dispatcher & dispatcher)38 SecureSimplePairingState::SecureSimplePairingState(
39 Peer::WeakPtr peer,
40 PairingDelegate::WeakPtr pairing_delegate,
41 WeakPtr<hci::BrEdrConnection> link,
42 bool outgoing_connection,
43 fit::closure auth_cb,
44 StatusCallback status_cb,
45 hci::LocalAddressDelegate* low_energy_address_delegate,
46 bool controller_remote_public_key_validation_supported,
47 sm::BrEdrSecurityManagerFactory security_manager_factory,
48 pw::async::Dispatcher& dispatcher)
49 : peer_id_(peer->identifier()),
50 peer_(std::move(peer)),
51 link_(std::move(link)),
52 outgoing_connection_(outgoing_connection),
53 peer_missing_key_(false),
54 low_energy_address_delegate_(std::move(low_energy_address_delegate)),
55 pairing_delegate_(std::move(pairing_delegate)),
56 state_(State::kIdle),
57 send_auth_request_callback_(std::move(auth_cb)),
58 status_callback_(std::move(status_cb)),
59 controller_remote_public_key_validation_supported_(
60 controller_remote_public_key_validation_supported),
61 security_manager_factory_(std::move(security_manager_factory)),
62 dispatcher_(dispatcher) {
63 PW_CHECK(link_.is_alive());
64 PW_CHECK(send_auth_request_callback_);
65 PW_CHECK(status_callback_);
66 link_->set_encryption_change_callback(
67 fit::bind_member<&SecureSimplePairingState::OnEncryptionChange>(this));
68 cleanup_cb_ = [](SecureSimplePairingState* self) {
69 self->link_->set_encryption_change_callback(nullptr);
70 auto callbacks_to_signal =
71 self->CompletePairingRequests(ToResult(HostError::kLinkDisconnected));
72
73 bt_log(TRACE,
74 "gap-bredr",
75 "Signaling %zu unresolved pairing listeners for %#.4x",
76 callbacks_to_signal.size(),
77 self->handle());
78
79 for (auto& cb : callbacks_to_signal) {
80 cb();
81 }
82 };
83 }
84
~SecureSimplePairingState()85 SecureSimplePairingState::~SecureSimplePairingState() {
86 if (cleanup_cb_) {
87 cleanup_cb_(this);
88 }
89 }
90
InitiatePairing(BrEdrSecurityRequirements security_requirements,StatusCallback status_cb)91 void SecureSimplePairingState::InitiatePairing(
92 BrEdrSecurityRequirements security_requirements, StatusCallback status_cb) {
93 // TODO(fxbug.dev/42082728): Reject pairing if peer/local device don't support
94 // Secure Connections and SC is required
95 if (state() == State::kIdle ||
96 state() == State::kInitiatorWaitLEPairingComplete) {
97 PW_CHECK(!is_pairing());
98
99 // If the current link key already meets the security requirements, skip
100 // pairing and report success.
101 if (link_->ltk_type() && SecurityPropertiesMeetRequirements(
102 sm::SecurityProperties(*link_->ltk_type()),
103 security_requirements)) {
104 status_cb(handle(), fit::ok());
105 return;
106 }
107 // TODO(fxbug.dev/42118593): If there is no pairing delegate set AND the
108 // current peer does not have a bonded link key, there is no way to upgrade
109 // the link security, so we don't need to bother calling
110 // `send_auth_request`.
111 //
112 // TODO(fxbug.dev/42133435): If current IO capabilities would make meeting
113 // security requirements impossible, skip pairing and report failure
114 // immediately.
115
116 PairingRequest request{.security_requirements = security_requirements,
117 .status_callback = std::move(status_cb)};
118 request_queue_.push_back(std::move(request));
119
120 if (state() == State::kInitiatorWaitLEPairingComplete) {
121 return;
122 }
123
124 InitiateNextPairingRequest();
125 return;
126 }
127
128 // More than one consumer may wish to initiate pairing (e.g. concurrent
129 // outbound L2CAP channels), but each should wait for the results of any
130 // ongoing pairing procedure instead of sending their own Authentication
131 // Request.
132 if (is_pairing()) {
133 PW_CHECK(state() != State::kIdle);
134 bt_log(INFO,
135 "gap-bredr",
136 "Already pairing %#.4x (id: %s); blocking callback on completion",
137 handle(),
138 bt_str(peer_id()));
139 PairingRequest request{.security_requirements = security_requirements,
140 .status_callback = std::move(status_cb)};
141 request_queue_.push_back(std::move(request));
142 } else {
143 // In the error state, we should expect no pairing to be created and cancel
144 // this particular request immediately.
145 PW_CHECK(state() == State::kFailed);
146 status_cb(handle(), ToResult(HostError::kCanceled));
147 }
148 }
149
InitiateNextPairingRequest()150 void SecureSimplePairingState::InitiateNextPairingRequest() {
151 PW_CHECK(state() == State::kIdle);
152 PW_CHECK(!is_pairing());
153
154 if (request_queue_.empty()) {
155 return;
156 }
157
158 // "If a BR/EDR/LE device supports LE Secure Connections, then it shall
159 // initiate pairing on only one transport at a time to the same remote
160 // device." (v6.0, Vol 3, Part C, Sec. 14.2)
161 if (peer_->le() && peer_->le()->is_pairing()) {
162 bt_log(INFO,
163 "gap-bredr",
164 "Waiting for LE pairing to complete on %#.4x (id %s)",
165 handle(),
166 bt_str(peer_id()));
167 state_ = State::kInitiatorWaitLEPairingComplete;
168 peer_->MutLe().add_pairing_completion_callback(
169 [self = weak_self_.GetWeakPtr()]() {
170 if (!self.is_alive() ||
171 self->state_ != State::kInitiatorWaitLEPairingComplete) {
172 return;
173 }
174 self->state_ = State::kIdle;
175 self->InitiateNextPairingRequest();
176 });
177 return;
178 }
179
180 PairingRequest& request = request_queue_.front();
181
182 current_pairing_ =
183 Pairing::MakeInitiator(request.security_requirements,
184 outgoing_connection_,
185 peer_->MutBrEdr().RegisterPairing());
186
187 bt_log(DEBUG,
188 "gap-bredr",
189 "Initiating queued pairing on %#.4x (id %s)",
190 handle(),
191 bt_str(peer_id()));
192 state_ = State::kInitiatorWaitLinkKeyRequest;
193 send_auth_request_callback_();
194 }
195
OnIoCapabilityRequest()196 std::optional<IoCapability> SecureSimplePairingState::OnIoCapabilityRequest() {
197 if (state() != State::kInitiatorWaitIoCapRequest &&
198 state() != State::kResponderWaitIoCapRequest) {
199 FailWithUnexpectedEvent(__func__);
200 return std::nullopt;
201 }
202
203 // Log an error and return std::nullopt if we can't respond to a pairing
204 // request because there's no pairing delegate. This corresponds to the
205 // non-bondable state as outlined in spec v5.2 Vol. 3 Part C 4.3.1.
206 if (!pairing_delegate().is_alive()) {
207 bt_log(WARN,
208 "gap-bredr",
209 "No pairing delegate set; not pairing link %#.4x (peer: %s)",
210 handle(),
211 bt_str(peer_id()));
212 // We set the state_ to Idle instead of Failed because it is possible that a
213 // PairingDelegate will be set before the next pairing attempt, allowing it
214 // to succeed.
215 state_ = State::kIdle;
216 SignalStatus(ToResult(HostError::kNotReady), __func__);
217 return std::nullopt;
218 }
219
220 current_pairing_->local_iocap =
221 sm::util::IOCapabilityForHci(pairing_delegate()->io_capability());
222 if (state() == State::kInitiatorWaitIoCapRequest) {
223 PW_CHECK(initiator());
224 state_ = State::kInitiatorWaitIoCapResponse;
225 } else {
226 PW_CHECK(is_pairing());
227 PW_CHECK(!initiator());
228 current_pairing_->ComputePairingData();
229
230 state_ = GetStateForPairingEvent(current_pairing_->expected_event);
231 }
232
233 return current_pairing_->local_iocap;
234 }
235
OnIoCapabilityResponse(IoCapability peer_iocap)236 void SecureSimplePairingState::OnIoCapabilityResponse(IoCapability peer_iocap) {
237 // If we previously provided a key for peer to pair, but that didn't work,
238 // they may try to re-pair. Cancel the previous pairing if they try to
239 // restart.
240 if (state() == State::kWaitEncryption) {
241 PW_CHECK(is_pairing());
242 current_pairing_ = nullptr;
243 state_ = State::kIdle;
244 }
245 if (state() == State::kIdle ||
246 state() == State::kInitiatorWaitLEPairingComplete) {
247 PW_CHECK(!is_pairing());
248 current_pairing_ = Pairing::MakeResponder(
249 peer_iocap, outgoing_connection_, peer_->MutBrEdr().RegisterPairing());
250
251 // Defer gathering local IO Capability until OnIoCapabilityRequest, where
252 // the pairing can be rejected if there's no pairing delegate.
253 state_ = State::kResponderWaitIoCapRequest;
254 } else if (state() == State::kInitiatorWaitIoCapResponse) {
255 PW_CHECK(initiator());
256
257 current_pairing_->peer_iocap = peer_iocap;
258 current_pairing_->ComputePairingData();
259
260 state_ = GetStateForPairingEvent(current_pairing_->expected_event);
261 } else {
262 FailWithUnexpectedEvent(__func__);
263 }
264 }
265
OnUserConfirmationRequest(uint32_t numeric_value,UserConfirmationCallback cb)266 void SecureSimplePairingState::OnUserConfirmationRequest(
267 uint32_t numeric_value, UserConfirmationCallback cb) {
268 if (state() != State::kWaitUserConfirmationRequest) {
269 FailWithUnexpectedEvent(__func__);
270 cb(false);
271 return;
272 }
273 PW_CHECK(is_pairing());
274
275 // TODO(fxbug.dev/42113087): Reject pairing if pairing delegate went away.
276 PW_CHECK(pairing_delegate().is_alive());
277 state_ = State::kWaitPairingComplete;
278
279 if (current_pairing_->action == PairingAction::kAutomatic) {
280 if (!outgoing_connection_) {
281 bt_log(ERROR,
282 "gap-bredr",
283 "automatically rejecting incoming link pairing (peer: %s, handle: "
284 "%#.4x)",
285 bt_str(peer_id()),
286 handle());
287 } else {
288 bt_log(DEBUG,
289 "gap-bredr",
290 "automatically confirming outgoing link pairing (peer: %s, "
291 "handle: %#.4x)",
292 bt_str(peer_id()),
293 handle());
294 }
295 cb(outgoing_connection_);
296 return;
297 }
298 auto confirm_cb = [callback = std::move(cb),
299 pairing = current_pairing_->GetWeakPtr(),
300 peer_id = peer_id(),
301 handle = handle()](bool confirm) mutable {
302 if (!pairing.is_alive()) {
303 return;
304 }
305 bt_log(DEBUG,
306 "gap-bredr",
307 "%sing User Confirmation Request (peer: %s, handle: %#.4x)",
308 confirm ? "Confirm" : "Cancel",
309 bt_str(peer_id),
310 handle);
311 callback(confirm);
312 };
313 // PairingAction::kDisplayPasskey indicates that this device has a display and
314 // performs "Numeric Comparison with automatic confirmation" but
315 // auto-confirmation is delegated to PairingDelegate.
316 if (current_pairing_->action == PairingAction::kDisplayPasskey ||
317 current_pairing_->action == PairingAction::kComparePasskey) {
318 pairing_delegate()->DisplayPasskey(
319 peer_id(),
320 numeric_value,
321 PairingDelegate::DisplayMethod::kComparison,
322 std::move(confirm_cb));
323 } else if (current_pairing_->action == PairingAction::kGetConsent) {
324 pairing_delegate()->ConfirmPairing(peer_id(), std::move(confirm_cb));
325 } else {
326 PW_CRASH("%#.4x (id: %s): unexpected action %d",
327 handle(),
328 bt_str(peer_id()),
329 static_cast<int>(current_pairing_->action));
330 }
331 }
332
OnUserPasskeyRequest(UserPasskeyCallback cb)333 void SecureSimplePairingState::OnUserPasskeyRequest(UserPasskeyCallback cb) {
334 if (state() != State::kWaitUserPasskeyRequest) {
335 FailWithUnexpectedEvent(__func__);
336 cb(std::nullopt);
337 return;
338 }
339 PW_CHECK(is_pairing());
340
341 // TODO(fxbug.dev/42113087): Reject pairing if pairing delegate went away.
342 PW_CHECK(pairing_delegate().is_alive());
343 state_ = State::kWaitPairingComplete;
344
345 PW_CHECK(current_pairing_->action == PairingAction::kRequestPasskey,
346 "%#.4x (id: %s): unexpected action %d",
347 handle(),
348 bt_str(peer_id()),
349 static_cast<int>(current_pairing_->action));
350 auto pairing = current_pairing_->GetWeakPtr();
351 auto passkey_cb =
352 [this, callback = std::move(cb), pairing](int64_t passkey) mutable {
353 if (!pairing.is_alive()) {
354 return;
355 }
356 bt_log(DEBUG,
357 "gap-bredr",
358 "%#.4x (id: %s): Replying %" PRId64 " to User Passkey Request",
359 handle(),
360 bt_str(peer_id()),
361 passkey);
362 if (passkey >= 0) {
363 callback(static_cast<uint32_t>(passkey));
364 } else {
365 callback(std::nullopt);
366 }
367 };
368 pairing_delegate()->RequestPasskey(peer_id(), std::move(passkey_cb));
369 }
370
OnUserPasskeyNotification(uint32_t numeric_value)371 void SecureSimplePairingState::OnUserPasskeyNotification(
372 uint32_t numeric_value) {
373 if (state() != State::kWaitUserPasskeyNotification) {
374 FailWithUnexpectedEvent(__func__);
375 return;
376 }
377 PW_CHECK(is_pairing());
378
379 // TODO(fxbug.dev/42113087): Reject pairing if pairing delegate went away.
380 PW_CHECK(pairing_delegate().is_alive());
381 state_ = State::kWaitPairingComplete;
382
383 auto pairing = current_pairing_->GetWeakPtr();
384 auto confirm_cb = [this, pairing](bool confirm) {
385 if (!pairing.is_alive()) {
386 return;
387 }
388 bt_log(DEBUG,
389 "gap-bredr",
390 "%#.4x (id: %s): Can't %s pairing from Passkey Notification side",
391 handle(),
392 bt_str(peer_id()),
393 confirm ? "confirm" : "cancel");
394 };
395 pairing_delegate()->DisplayPasskey(peer_id(),
396 numeric_value,
397 PairingDelegate::DisplayMethod::kPeerEntry,
398 std::move(confirm_cb));
399 }
400
OnSimplePairingComplete(pw::bluetooth::emboss::StatusCode status_code)401 void SecureSimplePairingState::OnSimplePairingComplete(
402 pw::bluetooth::emboss::StatusCode status_code) {
403 // The pairing process may fail early, which the controller will deliver as an
404 // Simple Pairing Complete with a non-success status. Log and proxy the error
405 // code.
406 if (const fit::result result = ToResult(status_code);
407 is_pairing() && bt_is_error(result,
408 INFO,
409 "gap-bredr",
410 "Pairing failed on link %#.4x (id: %s)",
411 handle(),
412 bt_str(peer_id()))) {
413 // TODO(fxbug.dev/42113087): Checking pairing_delegate() for reset like this
414 // isn't thread safe.
415 if (pairing_delegate().is_alive()) {
416 pairing_delegate()->CompletePairing(peer_id(),
417 ToResult(HostError::kFailed));
418 }
419 state_ = State::kFailed;
420 SignalStatus(result, __func__);
421 return;
422 }
423 // Handle successful Authentication Complete events that are not expected.
424 if (state() != State::kWaitPairingComplete) {
425 FailWithUnexpectedEvent(__func__);
426 return;
427 }
428 PW_CHECK(is_pairing());
429
430 pairing_delegate()->CompletePairing(peer_id(), fit::ok());
431 state_ = State::kWaitLinkKey;
432 }
433
OnLinkKeyRequest()434 std::optional<hci_spec::LinkKey> SecureSimplePairingState::OnLinkKeyRequest() {
435 if (state() != State::kIdle &&
436 state() != State::kInitiatorWaitLinkKeyRequest &&
437 state() != State::kInitiatorWaitLEPairingComplete) {
438 FailWithUnexpectedEvent(__func__);
439 return std::nullopt;
440 }
441
442 PW_CHECK(peer_.is_alive());
443
444 std::optional<sm::LTK> link_key;
445
446 if (peer_missing_key_) {
447 bt_log(INFO,
448 "gap-bredr",
449 "peer %s missing key, ignoring our key",
450 bt_str(peer_->identifier()));
451 } else if (peer_->bredr() && peer_->bredr()->bonded()) {
452 bt_log(INFO,
453 "gap-bredr",
454 "recalling link key for bonded peer %s",
455 bt_str(peer_->identifier()));
456
457 PW_CHECK(peer_->bredr()->link_key().has_value());
458 link_key = peer_->bredr()->link_key();
459 PW_CHECK(link_key->security().enc_key_size() ==
460 hci_spec::kBrEdrLinkKeySize);
461
462 const auto link_key_type = link_key->security().GetLinkKeyType();
463 link_->set_link_key(link_key->key(), link_key_type);
464 } else {
465 bt_log(
466 INFO, "gap-bredr", "peer %s not bonded", bt_str(peer_->identifier()));
467 }
468
469 // The link key request may be received outside of Simple Pairing (e.g. when
470 // the peer initiates the authentication procedure).
471 if (!is_pairing()) {
472 if (link_key.has_value()) {
473 current_pairing_ =
474 Pairing::MakeResponderForBonded(peer_->MutBrEdr().RegisterPairing());
475 state_ = State::kWaitEncryption;
476 return link_key->key();
477 }
478 return std::optional<hci_spec::LinkKey>();
479 }
480 PW_CHECK(is_pairing());
481
482 if (link_key.has_value() &&
483 SecurityPropertiesMeetRequirements(
484 link_key->security(), current_pairing_->preferred_security)) {
485 // Skip Simple Pairing and just perform authentication with existing key.
486 state_ = State::kInitiatorWaitAuthComplete;
487 return link_key->key();
488 }
489
490 // Request that the controller perform Simple Pairing to generate a new key.
491 state_ = State::kInitiatorWaitIoCapRequest;
492 return std::nullopt;
493 }
494
OnLinkKeyNotification(const UInt128 & link_key,hci_spec::LinkKeyType key_type,bool local_secure_connections_supported)495 void SecureSimplePairingState::OnLinkKeyNotification(
496 const UInt128& link_key,
497 hci_spec::LinkKeyType key_type,
498 bool local_secure_connections_supported) {
499 // TODO(fxbug.dev/42111880): We assume the controller is never in pairing
500 // debug mode because it's a security hazard to pair and bond using Debug
501 // Combination link keys.
502 PW_CHECK(key_type != hci_spec::LinkKeyType::kDebugCombination,
503 "Pairing on link %#.4x (id: %s) resulted in insecure Debug "
504 "Combination link key",
505 handle(),
506 bt_str(peer_id()));
507
508 // When not pairing, only connection link key changes are allowed.
509 if (!is_pairing() && key_type == hci_spec::LinkKeyType::kChangedCombination) {
510 if (!link_->ltk()) {
511 bt_log(WARN,
512 "gap-bredr",
513 "Got Changed Combination key but link %#.4x (id: %s) has no "
514 "current key",
515 handle(),
516 bt_str(peer_id()));
517 state_ = State::kFailed;
518 SignalStatus(ToResult(HostError::kInsufficientSecurity),
519 "OnLinkKeyNotification with no current key");
520 return;
521 }
522
523 bt_log(DEBUG,
524 "gap-bredr",
525 "Changing link key on %#.4x (id: %s)",
526 handle(),
527 bt_str(peer_id()));
528 link_->set_link_key(hci_spec::LinkKey(link_key, 0, 0), key_type);
529 return;
530 }
531
532 if (state() != State::kWaitLinkKey) {
533 FailWithUnexpectedEvent(__func__);
534 return;
535 }
536
537 // The association model and resulting link security properties are computed
538 // by both the Link Manager (controller) and the host subsystem, so check that
539 // they agree.
540 PW_CHECK(is_pairing());
541 sm::SecurityProperties sec_props = sm::SecurityProperties(key_type);
542 current_pairing_->received_link_key_security_properties = sec_props;
543
544 // Link keys resulting from legacy pairing are assigned lowest security level
545 // and we reject them.
546 if (sec_props.level() == sm::SecurityLevel::kNoSecurity) {
547 bt_log(WARN,
548 "gap-bredr",
549 "Link key (type %hhu) for %#.4x (id: %s) has insufficient security",
550 static_cast<unsigned char>(key_type),
551 handle(),
552 bt_str(peer_id()));
553 state_ = State::kFailed;
554 SignalStatus(ToResult(HostError::kInsufficientSecurity),
555 "OnLinkKeyNotification with insufficient security");
556 return;
557 }
558
559 // inclusive-language: ignore
560 // If we performed an association procedure for MITM protection then expect
561 // the controller to produce a corresponding "authenticated" link key.
562 // Inversely, do not accept a link key reported as authenticated if we haven't
563 // performed the corresponding association procedure because it may provide a
564 // false high expectation of security to the user or application.
565 if (sec_props.authenticated() != current_pairing_->authenticated) {
566 bt_log(WARN,
567 "gap-bredr",
568 "Expected %sauthenticated link key for %#.4x (id: %s), got %hhu",
569 current_pairing_->authenticated ? "" : "un",
570 handle(),
571 bt_str(peer_id()),
572 static_cast<unsigned char>(key_type));
573 state_ = State::kFailed;
574 SignalStatus(ToResult(HostError::kInsufficientSecurity),
575 "OnLinkKeyNotification with incorrect link authorization");
576 return;
577 }
578
579 // Set Security Properties for this BR/EDR connection
580 bredr_security_ = sec_props;
581
582 // TODO(fxbug.dev/42082735): When in SC Only mode, all services require
583 // security mode 4, level 4
584 if (security_mode_ == BrEdrSecurityMode::SecureConnectionsOnly &&
585 security_properties().level() !=
586 sm::SecurityLevel::kSecureAuthenticated) {
587 bt_log(WARN,
588 "gap-bredr",
589 "BR/EDR link key has insufficient security for Secure Connections "
590 "Only mode");
591 state_ = State::kFailed;
592 SignalStatus(ToResult(HostError::kInsufficientSecurity),
593 "OnLinkKeyNotification requires Secure Connections");
594 return;
595 }
596
597 // If peer and local Secure Connections support are present, the pairing logic
598 // needs to verify that the Link Key Type received in the Link Key
599 // Notification event is one of the Secure Connections types (0x07 and 0x08).
600 //
601 // Core Spec v5.2 Vol 4, Part E, 7.7.24: The values 0x07 and 0x08 shall only
602 // be used when the Host has indicated support for Secure Connections in the
603 // Secure_Connections_Host_Support parameter.
604 if (IsPeerSecureConnectionsSupported() &&
605 local_secure_connections_supported) {
606 if (!security_properties().secure_connections()) {
607 bt_log(WARN,
608 "gap-bredr",
609 "Link Key Type must be a Secure Connections key type;"
610 " Received type: %hhu (handle: %#.4x, id: %s)",
611 static_cast<unsigned char>(key_type),
612 handle(),
613 bt_str(peer_id()));
614 state_ = State::kFailed;
615 SignalStatus(ToResult(HostError::kInsufficientSecurity),
616 "OnLinkKeyNotification requires Secure Connections");
617 return;
618 }
619 link_->set_use_secure_connections(true);
620 }
621
622 link_->set_link_key(hci_spec::LinkKey(link_key, 0, 0), key_type);
623 if (initiator()) {
624 state_ = State::kInitiatorWaitAuthComplete;
625 } else {
626 EnableEncryption();
627 }
628 }
629
OnAuthenticationComplete(pw::bluetooth::emboss::StatusCode status_code)630 void SecureSimplePairingState::OnAuthenticationComplete(
631 pw::bluetooth::emboss::StatusCode status_code) {
632 if (is_pairing() && peer_->bredr() && peer_->bredr()->bonded() &&
633 status_code == pw::bluetooth::emboss::StatusCode::PIN_OR_KEY_MISSING) {
634 // We have provided our link key, but the remote side says they don't have a
635 // key. Pretend we don't have a link key, then start the pairing over. We
636 // will get consent even if we are otherwise kAutomatic
637 bt_log(
638 INFO,
639 "gap-bredr",
640 "Re-initiating pairing on %#.4x (id %s) as remote side reports no key.",
641 handle(),
642 bt_str(peer_id()));
643 peer_missing_key_ = true;
644 current_pairing_->allow_automatic = false;
645 state_ = State::kInitiatorWaitLinkKeyRequest;
646 send_auth_request_callback_();
647 return;
648 }
649 // The pairing process may fail early, which the controller will deliver as an
650 // Authentication Complete with a non-success status. Log and proxy the error
651 // code.
652 if (const fit::result result = ToResult(status_code);
653 bt_is_error(result,
654 INFO,
655 "gap-bredr",
656 "Authentication failed on link %#.4x (id: %s)",
657 handle(),
658 bt_str(peer_id()))) {
659 state_ = State::kFailed;
660 SignalStatus(result, __func__);
661 return;
662 }
663
664 // Handle successful Authentication Complete events that are not expected.
665 if (state() != State::kInitiatorWaitAuthComplete) {
666 FailWithUnexpectedEvent(__func__);
667 return;
668 }
669 PW_CHECK(initiator());
670 EnableEncryption();
671 }
672
OnEncryptionChange(hci::Result<bool> result)673 void SecureSimplePairingState::OnEncryptionChange(hci::Result<bool> result) {
674 // Update inspect properties
675 pw::bluetooth::emboss::EncryptionStatus encryption_status =
676 link_->encryption_status();
677 inspect_properties_.encryption_status.Set(
678 EncryptionStatusToString(encryption_status));
679
680 if (state() != State::kWaitEncryption) {
681 // Ignore encryption changes when not expecting them because they may be
682 // triggered by the peer at any time (v5.0 Vol 2, Part F, Sec 4.4).
683 bt_log(TRACE,
684 "gap-bredr",
685 "%#.4x (id: %s): %s(%s, %s) in state \"%s\"; taking no action",
686 handle(),
687 bt_str(peer_id()),
688 __func__,
689 bt_str(result),
690 result.is_ok() ? (result.value() ? "true" : "false") : "?",
691 ToString(state()));
692 return;
693 }
694
695 if (result.is_ok() && !result.value()) {
696 // With Secure Connections, encryption should never be disabled (v5.0 Vol 2,
697 // Part E, Sec 7.1.16) at all.
698 bt_log(WARN,
699 "gap-bredr",
700 "Pairing failed due to encryption disable on link %#.4x (id: %s)",
701 handle(),
702 bt_str(peer_id()));
703 result = fit::error(Error(HostError::kFailed));
704 }
705
706 if (!result.is_ok()) {
707 state_ = State::kFailed;
708 SignalStatus(result.take_error(), __func__);
709 return;
710 }
711
712 if (!current_pairing_->received_link_key_security_properties) {
713 bt_log(
714 DEBUG,
715 "gap-bredr",
716 "skipping BR/EDR cross-transport key derivation (previously paired)");
717 } else if (link_->role() != pw::bluetooth::emboss::ConnectionRole::CENTRAL) {
718 // Only the central can initiate cross-transport key derivation.
719 bt_log(DEBUG,
720 "gap-bredr",
721 "skipping BR/EDR cross-transport key derivation as peripheral");
722 } else if (!security_manager_) {
723 bt_log(INFO,
724 "gap-bredr",
725 "skipping BR/EDR cross-transport key derivation because SMP "
726 "channel not set");
727 } else {
728 state_ = State::kWaitCrossTransportKeyDerivation;
729 security_manager_->InitiateBrEdrCrossTransportKeyDerivation(
730 fit::bind_member<
731 &SecureSimplePairingState::OnCrossTransportKeyDerivationComplete>(
732 this));
733 return;
734 }
735
736 state_ = State::kIdle;
737 SignalStatus(hci::Result<>(fit::ok()), __func__);
738 }
739
740 std::unique_ptr<SecureSimplePairingState::Pairing>
MakeInitiator(BrEdrSecurityRequirements security_requirements,bool outgoing_connection,Peer::PairingToken && token)741 SecureSimplePairingState::Pairing::MakeInitiator(
742 BrEdrSecurityRequirements security_requirements,
743 bool outgoing_connection,
744 Peer::PairingToken&& token) {
745 // Private ctor is inaccessible to std::make_unique.
746 std::unique_ptr<Pairing> pairing(
747 new Pairing(outgoing_connection, std::move(token)));
748 pairing->initiator = true;
749 pairing->preferred_security = security_requirements;
750 return pairing;
751 }
752
753 std::unique_ptr<SecureSimplePairingState::Pairing>
MakeResponder(pw::bluetooth::emboss::IoCapability peer_iocap,bool outgoing_connection,Peer::PairingToken && token)754 SecureSimplePairingState::Pairing::MakeResponder(
755 pw::bluetooth::emboss::IoCapability peer_iocap,
756 bool outgoing_connection,
757 Peer::PairingToken&& token) {
758 // Private ctor is inaccessible to std::make_unique.
759 std::unique_ptr<Pairing> pairing(
760 new Pairing(outgoing_connection, std::move(token)));
761 pairing->initiator = false;
762 pairing->peer_iocap = peer_iocap;
763 // Don't try to upgrade security as responder.
764 pairing->preferred_security = {.authentication = false,
765 .secure_connections = false};
766 return pairing;
767 }
768
769 std::unique_ptr<SecureSimplePairingState::Pairing>
MakeResponderForBonded(Peer::PairingToken && token)770 SecureSimplePairingState::Pairing::MakeResponderForBonded(
771 Peer::PairingToken&& token) {
772 std::unique_ptr<Pairing> pairing(
773 new Pairing(/* link initiated */ false, std::move(token)));
774 pairing->initiator = false;
775 // Don't try to upgrade security as responder.
776 pairing->preferred_security = {.authentication = false,
777 .secure_connections = false};
778 return pairing;
779 }
780
ComputePairingData()781 void SecureSimplePairingState::Pairing::ComputePairingData() {
782 if (initiator) {
783 action = GetInitiatorPairingAction(local_iocap, peer_iocap);
784 } else {
785 action = GetResponderPairingAction(peer_iocap, local_iocap);
786 }
787 if (!allow_automatic && action == PairingAction::kAutomatic) {
788 action = PairingAction::kGetConsent;
789 }
790 expected_event = GetExpectedEvent(local_iocap, peer_iocap);
791 PW_DCHECK(GetStateForPairingEvent(expected_event) != State::kFailed);
792 authenticated = IsPairingAuthenticated(local_iocap, peer_iocap);
793 bt_log(DEBUG,
794 "gap-bredr",
795 "As %s with local %hhu/peer %hhu capabilities, expecting an "
796 "%sauthenticated %u pairing "
797 "using %#x%s",
798 initiator ? "initiator" : "responder",
799 static_cast<unsigned char>(local_iocap),
800 static_cast<unsigned char>(peer_iocap),
801 authenticated ? "" : "un",
802 static_cast<unsigned int>(action),
803 expected_event,
804 allow_automatic ? "" : " (auto not allowed)");
805 }
806
ToString(SecureSimplePairingState::State state)807 const char* SecureSimplePairingState::ToString(
808 SecureSimplePairingState::State state) {
809 switch (state) {
810 case State::kIdle:
811 return "Idle";
812 case State::kInitiatorWaitLEPairingComplete:
813 return "InitiatorWaitLEPairingComplete";
814 case State::kInitiatorWaitLinkKeyRequest:
815 return "InitiatorWaitLinkKeyRequest";
816 case State::kInitiatorWaitIoCapRequest:
817 return "InitiatorWaitIoCapRequest";
818 case State::kInitiatorWaitIoCapResponse:
819 return "InitiatorWaitIoCapResponse";
820 case State::kResponderWaitIoCapRequest:
821 return "ResponderWaitIoCapRequest";
822 case State::kWaitUserConfirmationRequest:
823 return "WaitUserConfirmationRequest";
824 case State::kWaitUserPasskeyRequest:
825 return "WaitUserPasskeyRequest";
826 case State::kWaitUserPasskeyNotification:
827 return "WaitUserPasskeyNotification";
828 case State::kWaitPairingComplete:
829 return "WaitPairingComplete";
830 case State::kWaitLinkKey:
831 return "WaitLinkKey";
832 case State::kInitiatorWaitAuthComplete:
833 return "InitiatorWaitAuthComplete";
834 case State::kWaitEncryption:
835 return "WaitEncryption";
836 case State::kWaitCrossTransportKeyDerivation:
837 return "WaitCrossTransportKeyDerivation";
838 case State::kFailed:
839 return "Failed";
840 default:
841 break;
842 }
843 return "";
844 }
845
846 SecureSimplePairingState::State
GetStateForPairingEvent(hci_spec::EventCode event_code)847 SecureSimplePairingState::GetStateForPairingEvent(
848 hci_spec::EventCode event_code) {
849 switch (event_code) {
850 case hci_spec::kUserConfirmationRequestEventCode:
851 return State::kWaitUserConfirmationRequest;
852 case hci_spec::kUserPasskeyRequestEventCode:
853 return State::kWaitUserPasskeyRequest;
854 case hci_spec::kUserPasskeyNotificationEventCode:
855 return State::kWaitUserPasskeyNotification;
856 default:
857 break;
858 }
859 return State::kFailed;
860 }
861
SignalStatus(hci::Result<> status,const char * caller)862 void SecureSimplePairingState::SignalStatus(hci::Result<> status,
863 const char* caller) {
864 bt_log(INFO,
865 "gap-bredr",
866 "Signaling pairing listeners for %#.4x (id: %s) from %s with %s",
867 handle(),
868 bt_str(peer_id()),
869 caller,
870 bt_str(status));
871
872 // Collect the callbacks before invoking them so that
873 // CompletePairingRequests() can safely access members.
874 auto callbacks_to_signal = CompletePairingRequests(status);
875
876 // This SecureSimplePairingState may be destroyed by these callbacks (e.g. if
877 // signaling an error causes a disconnection), so care must be taken not to
878 // access any members.
879 status_callback_(handle(), status);
880 for (auto& cb : callbacks_to_signal) {
881 cb();
882 }
883 }
884
CompletePairingRequests(hci::Result<> status)885 std::vector<fit::closure> SecureSimplePairingState::CompletePairingRequests(
886 hci::Result<> status) {
887 std::vector<fit::closure> callbacks_to_signal;
888
889 if (!is_pairing()) {
890 PW_CHECK(request_queue_.empty());
891 return callbacks_to_signal;
892 }
893
894 if (status.is_error()) {
895 // On pairing failure, signal all requests.
896 for (auto& request : request_queue_) {
897 callbacks_to_signal.push_back(
898 [handle = handle(),
899 status,
900 cb = std::move(request.status_callback)]() { cb(handle, status); });
901 }
902 request_queue_.clear();
903 current_pairing_ = nullptr;
904 return callbacks_to_signal;
905 }
906
907 PW_CHECK(state_ == State::kIdle);
908 PW_CHECK(link_->ltk_type().has_value());
909
910 auto security_properties = sm::SecurityProperties(link_->ltk_type().value());
911
912 // If a new link key was received, notify all callbacks because we always
913 // negotiate the best security possible. Even though pairing succeeded, send
914 // an error status if the individual request security requirements are not
915 // satisfied.
916 // TODO(fxbug.dev/42075714): Only notify failure to callbacks of requests that
917 // inclusive-language: ignore
918 // have the same (or none) MITM requirements as the current pairing.
919 bool link_key_received =
920 current_pairing_->received_link_key_security_properties.has_value();
921 if (link_key_received) {
922 for (auto& request : request_queue_) {
923 auto sec_props_satisfied = SecurityPropertiesMeetRequirements(
924 security_properties, request.security_requirements);
925 auto request_status = sec_props_satisfied
926 ? status
927 : ToResult(HostError::kInsufficientSecurity);
928
929 callbacks_to_signal.push_back(
930 [handle = handle(),
931 request_status,
932 cb = std::move(request.status_callback)]() {
933 cb(handle, request_status);
934 });
935 }
936 request_queue_.clear();
937 } else {
938 // If no new link key was received, then only authentication with an old key
939 // was performed (Simple Pairing was not required), and unsatisfied requests
940 // should initiate a new pairing rather than failing. If any pairing
941 // requests are satisfied by the existing key, notify them.
942 auto it = request_queue_.begin();
943 while (it != request_queue_.end()) {
944 if (!SecurityPropertiesMeetRequirements(security_properties,
945 it->security_requirements)) {
946 it++;
947 continue;
948 }
949
950 callbacks_to_signal.push_back(
951 [handle = handle(), status, cb = std::move(it->status_callback)]() {
952 cb(handle, status);
953 });
954 it = request_queue_.erase(it);
955 }
956 }
957 current_pairing_ = nullptr;
958 InitiateNextPairingRequest();
959
960 return callbacks_to_signal;
961 }
962
EnableEncryption()963 void SecureSimplePairingState::EnableEncryption() {
964 if (!link_->StartEncryption()) {
965 bt_log(ERROR,
966 "gap-bredr",
967 "%#.4x (id: %s): Failed to enable encryption (state \"%s\")",
968 handle(),
969 bt_str(peer_id()),
970 ToString(state()));
971 status_callback_(link_->handle(), ToResult(HostError::kFailed));
972 state_ = State::kFailed;
973 return;
974 }
975 state_ = State::kWaitEncryption;
976 }
977
FailWithUnexpectedEvent(const char * handler_name)978 void SecureSimplePairingState::FailWithUnexpectedEvent(
979 const char* handler_name) {
980 bt_log(ERROR,
981 "gap-bredr",
982 "%#.4x (id: %s): Unexpected event %s while in state \"%s\"",
983 handle(),
984 bt_str(peer_id()),
985 handler_name,
986 ToString(state()));
987 state_ = State::kFailed;
988 SignalStatus(ToResult(HostError::kNotSupported), __func__);
989 }
990
IsPeerSecureConnectionsSupported() const991 bool SecureSimplePairingState::IsPeerSecureConnectionsSupported() const {
992 return peer_->features().HasBit(
993 /*page=*/1, hci_spec::LMPFeature::kSecureConnectionsHostSupport) &&
994 peer_->features().HasBit(
995 /*page=*/2,
996 hci_spec::LMPFeature::kSecureConnectionsControllerSupport);
997 }
998
SetSecurityManagerChannel(l2cap::Channel::WeakPtr security_manager_channel)999 void SecureSimplePairingState::SetSecurityManagerChannel(
1000 l2cap::Channel::WeakPtr security_manager_channel) {
1001 if (!security_manager_channel.is_alive()) {
1002 return;
1003 }
1004 PW_CHECK(!security_manager_);
1005 security_manager_ = security_manager_factory_(
1006 link_,
1007 std::move(security_manager_channel),
1008 security_manager_delegate_.GetWeakPtr(),
1009 controller_remote_public_key_validation_supported_,
1010 dispatcher_,
1011 peer_);
1012 }
1013
1014 std::optional<sm::IdentityInfo> SecureSimplePairingState::
OnIdentityInformationRequest()1015 SecurityManagerDelegate::OnIdentityInformationRequest() {
1016 if (!ssp_state_->low_energy_address_delegate_->irk()) {
1017 bt_log(TRACE, "gap-bredr", "no local identity information to exchange");
1018 return std::nullopt;
1019 }
1020
1021 bt_log(DEBUG,
1022 "gap-bredr",
1023 "will distribute local identity information (peer: %s)",
1024 bt_str(ssp_state_->peer_id_));
1025 sm::IdentityInfo id_info;
1026 id_info.irk = *ssp_state_->low_energy_address_delegate_->irk();
1027 id_info.address =
1028 ssp_state_->low_energy_address_delegate_->identity_address();
1029 return id_info;
1030 }
1031
AttachInspect(inspect::Node & parent,std::string name)1032 void SecureSimplePairingState::AttachInspect(inspect::Node& parent,
1033 std::string name) {
1034 inspect_node_ = parent.CreateChild(name);
1035
1036 inspect_properties_.encryption_status = inspect_node_.CreateString(
1037 kInspectEncryptionStatusPropertyName,
1038 EncryptionStatusToString(link_->encryption_status()));
1039
1040 security_properties().AttachInspect(inspect_node_,
1041 kInspectSecurityPropertiesPropertyName);
1042 }
1043
OnCrossTransportKeyDerivationComplete(sm::Result<> result)1044 void SecureSimplePairingState::OnCrossTransportKeyDerivationComplete(
1045 sm::Result<> result) {
1046 if (result.is_error()) {
1047 // CTKD failures are not treated as failures of the main BR/EDR pairing.
1048 bt_log(INFO,
1049 "gap-bredr",
1050 "BR/EDR cross-transport key derivation failed: %s",
1051 bt_str(result.error_value()));
1052 }
1053 state_ = State::kIdle;
1054 SignalStatus(hci::Result<>(fit::ok()), __func__);
1055 }
1056
GetInitiatorPairingAction(IoCapability initiator_cap,IoCapability responder_cap)1057 PairingAction GetInitiatorPairingAction(IoCapability initiator_cap,
1058 IoCapability responder_cap) {
1059 if (initiator_cap == IoCapability::NO_INPUT_NO_OUTPUT) {
1060 return PairingAction::kAutomatic;
1061 }
1062 if (responder_cap == IoCapability::NO_INPUT_NO_OUTPUT) {
1063 if (initiator_cap == IoCapability::DISPLAY_YES_NO) {
1064 return PairingAction::kGetConsent;
1065 }
1066 return PairingAction::kAutomatic;
1067 }
1068 if (initiator_cap == IoCapability::KEYBOARD_ONLY) {
1069 return PairingAction::kRequestPasskey;
1070 }
1071 if (responder_cap == IoCapability::DISPLAY_ONLY) {
1072 if (initiator_cap == IoCapability::DISPLAY_YES_NO) {
1073 return PairingAction::kComparePasskey;
1074 }
1075 return PairingAction::kAutomatic;
1076 }
1077 return PairingAction::kDisplayPasskey;
1078 }
1079
GetResponderPairingAction(IoCapability initiator_cap,IoCapability responder_cap)1080 PairingAction GetResponderPairingAction(IoCapability initiator_cap,
1081 IoCapability responder_cap) {
1082 if (initiator_cap == IoCapability::NO_INPUT_NO_OUTPUT &&
1083 responder_cap == IoCapability::KEYBOARD_ONLY) {
1084 return PairingAction::kGetConsent;
1085 }
1086 if (initiator_cap == IoCapability::DISPLAY_YES_NO &&
1087 responder_cap == IoCapability::DISPLAY_YES_NO) {
1088 return PairingAction::kComparePasskey;
1089 }
1090 return GetInitiatorPairingAction(responder_cap, initiator_cap);
1091 }
1092
GetExpectedEvent(IoCapability local_cap,IoCapability peer_cap)1093 hci_spec::EventCode GetExpectedEvent(IoCapability local_cap,
1094 IoCapability peer_cap) {
1095 if (local_cap == IoCapability::NO_INPUT_NO_OUTPUT ||
1096 peer_cap == IoCapability::NO_INPUT_NO_OUTPUT) {
1097 return hci_spec::kUserConfirmationRequestEventCode;
1098 }
1099 if (local_cap == IoCapability::KEYBOARD_ONLY) {
1100 return hci_spec::kUserPasskeyRequestEventCode;
1101 }
1102 if (peer_cap == IoCapability::KEYBOARD_ONLY) {
1103 return hci_spec::kUserPasskeyNotificationEventCode;
1104 }
1105 return hci_spec::kUserConfirmationRequestEventCode;
1106 }
1107
IsPairingAuthenticated(IoCapability local_cap,IoCapability peer_cap)1108 bool IsPairingAuthenticated(IoCapability local_cap, IoCapability peer_cap) {
1109 if (local_cap == IoCapability::NO_INPUT_NO_OUTPUT ||
1110 peer_cap == IoCapability::NO_INPUT_NO_OUTPUT) {
1111 return false;
1112 }
1113 if (local_cap == IoCapability::DISPLAY_YES_NO &&
1114 peer_cap == IoCapability::DISPLAY_YES_NO) {
1115 return true;
1116 }
1117 if (local_cap == IoCapability::KEYBOARD_ONLY ||
1118 peer_cap == IoCapability::KEYBOARD_ONLY) {
1119 return true;
1120 }
1121 return false;
1122 }
1123
GetInitiatorAuthenticationRequirements(IoCapability local_cap)1124 AuthenticationRequirements GetInitiatorAuthenticationRequirements(
1125 IoCapability local_cap) {
1126 if (local_cap == IoCapability::NO_INPUT_NO_OUTPUT) {
1127 return AuthenticationRequirements::GENERAL_BONDING;
1128 }
1129 // inclusive-language: ignore
1130 return AuthenticationRequirements::MITM_GENERAL_BONDING;
1131 }
1132
GetResponderAuthenticationRequirements(IoCapability local_cap,IoCapability peer_cap)1133 AuthenticationRequirements GetResponderAuthenticationRequirements(
1134 IoCapability local_cap, IoCapability peer_cap) {
1135 if (IsPairingAuthenticated(local_cap, peer_cap)) {
1136 // inclusive-language: ignore
1137 return AuthenticationRequirements::MITM_GENERAL_BONDING;
1138 }
1139 return AuthenticationRequirements::GENERAL_BONDING;
1140 }
1141
1142 } // namespace bt::gap
1143