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