• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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