• 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/sm/security_manager.h"
16 
17 #include <pw_assert/check.h>
18 
19 #include <cinttypes>
20 #include <memory>
21 #include <optional>
22 #include <type_traits>
23 #include <utility>
24 #include <variant>
25 
26 #include "lib/fit/function.h"
27 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
28 #include "pw_bluetooth_sapphire/internal/host/common/device_address.h"
29 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
30 #include "pw_bluetooth_sapphire/internal/host/common/random.h"
31 #include "pw_bluetooth_sapphire/internal/host/common/uint128.h"
32 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
33 #include "pw_bluetooth_sapphire/internal/host/hci-spec/link_key.h"
34 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connection.h"
35 #include "pw_bluetooth_sapphire/internal/host/sm/error.h"
36 #include "pw_bluetooth_sapphire/internal/host/sm/packet.h"
37 #include "pw_bluetooth_sapphire/internal/host/sm/pairing_phase.h"
38 #include "pw_bluetooth_sapphire/internal/host/sm/phase_1.h"
39 #include "pw_bluetooth_sapphire/internal/host/sm/phase_2_legacy.h"
40 #include "pw_bluetooth_sapphire/internal/host/sm/phase_2_secure_connections.h"
41 #include "pw_bluetooth_sapphire/internal/host/sm/phase_3.h"
42 #include "pw_bluetooth_sapphire/internal/host/sm/security_request_phase.h"
43 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
44 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
45 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
46 #include "pw_bluetooth_sapphire/internal/host/transport/error.h"
47 
48 namespace bt::sm {
49 
50 namespace {
51 
52 using PairingToken = gap::Peer::PairingToken;
53 
FeaturesToProperties(const PairingFeatures & features)54 SecurityProperties FeaturesToProperties(const PairingFeatures& features) {
55   return SecurityProperties(features.method == PairingMethod::kJustWorks
56                                 ? SecurityLevel::kEncrypted
57                                 : SecurityLevel::kAuthenticated,
58                             features.encryption_key_size,
59                             features.secure_connections);
60 }
61 }  // namespace
62 
63 class SecurityManagerImpl final : public SecurityManager,
64                                   public PairingPhase::Listener,
65                                   public PairingChannel::Handler {
66  public:
67   ~SecurityManagerImpl() override;
68   SecurityManagerImpl(hci::LowEnergyConnection::WeakPtr low_energy_link,
69                       hci::BrEdrConnection::WeakPtr bredr_link,
70                       l2cap::Channel::WeakPtr smp,
71                       IOCapability io_capability,
72                       Delegate::WeakPtr delegate,
73                       BondableMode bondable_mode,
74                       gap::LESecurityMode security_mode,
75                       bool is_controller_remote_public_key_validation_supported,
76                       pw::async::Dispatcher& dispatcher,
77                       bt::gap::Peer::WeakPtr peer);
78   // SecurityManager overrides:
79   void UpgradeSecurity(SecurityLevel level, PairingCallback callback) override;
80   void InitiateBrEdrCrossTransportKeyDerivation(
81       CrossTransportKeyDerivationResultCallback callback) override;
82   void Reset(IOCapability io_capability) override;
83   void Abort(ErrorCode ecode) override;
84 
85  private:
86   // Represents a pending request to update the security level.
87   struct PendingRequest {
88     PendingRequest(SecurityLevel level_in, PairingCallback callback_in);
89     PendingRequest(PendingRequest&&) = default;
90     PendingRequest& operator=(PendingRequest&&) = default;
91 
92     SecurityLevel level;
93     PairingCallback callback;
94   };
95 
96   // Pseudo-phase where we are waiting for BR/EDR pairing to complete.
97   struct WaitForBrEdrPairing {};
98 
99   // Pseudo-phase that indicates that encryption is being started while no other
100   // phase is in progress.
101   struct StartingEncryption {};
102 
103   // Called when we receive a peer security request as initiator, will start
104   // Phase 1.
105   void OnSecurityRequest(AuthReqField auth_req);
106 
107   // Called when we receive a peer pairing request as responder, will start
108   // Phase 1.
109   void OnPairingRequest(const PairingRequestParams& req_params);
110 
111   // Pulls the next PendingRequest off |request_queue_| and starts a security
112   // upgrade to that |level| by either sending a Pairing Request as initiator or
113   // a Security Request as responder.
114   void UpgradeSecurityInternal();
115 
116   // Creates the pairing phase responsible for sending the security upgrade
117   // request to the peer (a PairingRequest if we are initiator, otherwise a
118   // SecurityRequest). Returns fit::error(ErrorCode::
119   // kAuthenticationRequirements) if the local IOCapabilities are insufficient
120   // for SecurityLevel, otherwise returns fit::ok().
121   [[nodiscard]] fit::result<ErrorCode> RequestSecurityUpgrade(
122       SecurityLevel level);
123 
124   // Called when the feature exchange (Phase 1) completes and the relevant
125   // features of both sides have been resolved into `features`. `preq` and
126   // `pres` need to be retained for cryptographic calculations in Phase 2.
127   // Causes a state transition from Phase 1 to Phase 2
128   void OnFeatureExchange(PairingFeatures features,
129                          PairingRequestParams preq,
130                          PairingResponseParams pres);
131 
132   // Called when Phase 2 generates an encryption key, so the link can be
133   // encrypted with it.
134   void OnPhase2EncryptionKey(const UInt128& new_key);
135 
136   // Check if encryption using `current_ltk` will satisfy the current security
137   // requirements.
138   static bool CurrentLtkInsufficientlySecureForEncryption(
139       std::optional<LTK> current_ltk,
140       SecurityRequestPhase* security_request_phase,
141       gap::LESecurityMode mode);
142 
143   // Called when the encryption state of the LE link changes.
144   void OnEncryptionChange(hci::Result<bool> enabled_result);
145 
146   // Called when the link is encrypted at the end of pairing Phase 2.
147   void EndPhase2();
148 
149   // Cleans up pairing state, updates the current security level, and notifies
150   // parties that requested security of the link's updated security properties.
151   void OnLowEnergyPairingComplete(PairingData data);
152 
153   // Derives LE LTK, notifies clients, and resets pairing state.
154   void OnBrEdrPairingComplete(PairingData pairing_data);
155 
156   // After a call to UpgradeSecurity results in an increase of the link security
157   // level (through pairing completion or SMP Security Requested encryption),
158   // this method notifies all the callbacks associated with SecurityUpgrade
159   // requests.
160   void NotifySecurityCallbacks();
161 
162   // Assign the current security properties and notify the delegate of the
163   // change.
164   void SetSecurityProperties(const SecurityProperties& sec);
165 
166   // Directly assigns the current |ltk_| and the underlying |le_link_|'s link
167   // key. This function does not initiate link layer encryption and can be
168   // called during and outside of pairing.
169   void OnNewLongTermKey(const LTK& ltk);
170 
171   // PairingPhase::Listener overrides:
172   void OnPairingFailed(Error error) override;
173   std::optional<IdentityInfo> OnIdentityRequest() override;
174   void ConfirmPairing(ConfirmCallback confirm) override;
175   void DisplayPasskey(uint32_t passkey,
176                       Delegate::DisplayMethod method,
177                       ConfirmCallback cb) override;
178   void RequestPasskey(PasskeyResponseCallback respond) override;
179 
180   // PairingChannel::Handler overrides. SecurityManagerImpl is only the fallback
181   // handler, meaning these methods are only called by PairingChannel when no
182   // security upgrade is in progress:
183   void OnRxBFrame(ByteBufferPtr sdu) override;
184   void OnChannelClosed() override;
185 
186   // Starts the SMP timer. Stops and cancels any in-progress timers.
187   void StartNewTimer();
188   // Stops and resets the SMP Pairing Timer.
189   void StopTimer();
190   // Called when the pairing timer expires, forcing the pairing process to stop
191   void OnPairingTimeout();
192 
193   // Returns a std::pair<InitiatorAddress, ResponderAddress>. Will assert if
194   // called outside active pairing or before Phase 1 is complete.
195   std::pair<DeviceAddress, DeviceAddress> LEPairingAddresses();
196 
197   // Puts the class into a non-pairing state.
198   void ResetState();
199 
InPhase1() const200   bool InPhase1() const {
201     return std::holds_alternative<std::unique_ptr<Phase1>>(current_phase_);
202   }
203 
204   // Returns true if the pairing state machine is currently in Phase 2 of
205   // pairing.
InPhase2() const206   bool InPhase2() const {
207     return std::holds_alternative<Phase2Legacy>(current_phase_) ||
208            std::holds_alternative<Phase2SecureConnections>(current_phase_);
209   }
210 
SecurityUpgradeInProgress() const211   bool SecurityUpgradeInProgress() const {
212     return !std::holds_alternative<std::monostate>(current_phase_);
213   }
214 
215   // Validates that both SM and the link have stored LTKs, and that these values
216   // match. Disconnects the link if it finds an issue. Should only be called
217   // when an LTK is expected to exist.
218   Result<> ValidateExistingLocalLtk();
219 
220   // Returns true only if all security conditions are met for BR/EDR CTKD.
221   bool IsBrEdrCrossTransportKeyDerivationAllowed();
222 
223   std::optional<sm::LTK> GetExistingLtkFromPeerCache();
224 
225   // The role of the local device in pairing.
226   // LE roles are fixed for the lifetime of a connection, but BR/EDR roles can
227   // be changed after a connection is established, so we cannot cache it during
228   // construction.
role()229   Role role() {
230     pw::bluetooth::emboss::ConnectionRole conn_role =
231         pw::bluetooth::emboss::ConnectionRole::CENTRAL;
232     if (low_energy_link_.is_alive()) {
233       conn_role = low_energy_link_->role();
234     } else if (bredr_link_.is_alive()) {
235       conn_role = bredr_link_->role();
236     } else {
237       PW_CRASH("no active link");
238     }
239     return conn_role == pw::bluetooth::emboss::ConnectionRole::CENTRAL
240                ? Role::kInitiator
241                : Role::kResponder;
242   }
243 
244   pw::async::Dispatcher& pw_dispatcher_;
245 
246   // The ID that will be assigned to the next pairing operation.
247   PairingProcedureId next_pairing_id_;
248 
249   // The higher-level class acting as a delegate for operations outside of SMP.
250   Delegate::WeakPtr delegate_;
251 
252   // Data for the currently registered LE-U link, if any.
253   hci::LowEnergyConnection::WeakPtr low_energy_link_;
254 
255   hci::BrEdrConnection::WeakPtr bredr_link_;
256 
257   // Whether the controller performs remote public key validation for BR/EDR
258   // keys.
259   bool is_controller_remote_public_key_validation_supported_ = false;
260 
261   // The IO capabilities of the device
262   IOCapability low_energy_io_cap_;
263 
264   // The current LTK assigned to this connection. This can be assigned directly
265   // by calling AssignLongTermKey() or as a result of a pairing procedure.
266   std::optional<LTK> ltk_;
267 
268   // If a pairing is in progress and Phase 1 (feature exchange) has completed,
269   // this will store the result of that feature exchange. Otherwise, this will
270   // be std::nullopt.
271   std::optional<PairingFeatures> features_;
272 
273   // The pending security requests added via UpgradeSecurity().
274   std::queue<PendingRequest> request_queue_;
275 
276   CrossTransportKeyDerivationResultCallback
277       bredr_cross_transport_key_derivation_callback_ = nullptr;
278 
279   // Fixed SMP Channel used to send/receive packets
280   std::unique_ptr<PairingChannel> sm_chan_;
281 
282   SmartTask timeout_task_{pw_dispatcher_};
283 
284   // Set to a PairingToken when the current phase is not monostate (always null
285   // in monostate).
286   std::optional<PairingToken> pairing_token_;
287   bt::gap::Peer::WeakPtr peer_;
288 
289   // The presence of a particular phase in this variant indicates that a
290   // security upgrade is in progress at the stored phase. No security upgrade is
291   // in progress if std::monostate is present.
292   std::variant<std::monostate,
293                WaitForBrEdrPairing,
294                StartingEncryption,
295                SecurityRequestPhase,
296                std::unique_ptr<Phase1>,
297                Phase2Legacy,
298                Phase2SecureConnections,
299                Phase3>
300       current_phase_;
301 
302   WeakSelf<SecurityManagerImpl> weak_self_;
303   WeakSelf<PairingPhase::Listener> weak_listener_;
304   WeakSelf<PairingChannel::Handler> weak_handler_;
305 
306   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(SecurityManagerImpl);
307 };
308 
PendingRequest(SecurityLevel level_in,PairingCallback callback_in)309 SecurityManagerImpl::PendingRequest::PendingRequest(SecurityLevel level_in,
310                                                     PairingCallback callback_in)
311     : level(level_in), callback(std::move(callback_in)) {}
312 
~SecurityManagerImpl()313 SecurityManagerImpl::~SecurityManagerImpl() {
314   if (low_energy_link_.is_alive()) {
315     low_energy_link_->set_encryption_change_callback({});
316   }
317 }
318 
SecurityManagerImpl(hci::LowEnergyConnection::WeakPtr low_energy_link,hci::BrEdrConnection::WeakPtr bredr_link,l2cap::Channel::WeakPtr smp,IOCapability io_capability,Delegate::WeakPtr delegate,BondableMode bondable_mode,gap::LESecurityMode security_mode,bool is_controller_remote_public_key_validation_supported,pw::async::Dispatcher & dispatcher,bt::gap::Peer::WeakPtr peer)319 SecurityManagerImpl::SecurityManagerImpl(
320     hci::LowEnergyConnection::WeakPtr low_energy_link,
321     hci::BrEdrConnection::WeakPtr bredr_link,
322     l2cap::Channel::WeakPtr smp,
323     IOCapability io_capability,
324     Delegate::WeakPtr delegate,
325     BondableMode bondable_mode,
326     gap::LESecurityMode security_mode,
327     bool is_controller_remote_public_key_validation_supported,
328     pw::async::Dispatcher& dispatcher,
329     bt::gap::Peer::WeakPtr peer)
330     : SecurityManager(bondable_mode, security_mode),
331       pw_dispatcher_(dispatcher),
332       next_pairing_id_(0),
333       delegate_(std::move(delegate)),
334       low_energy_link_(std::move(low_energy_link)),
335       bredr_link_(std::move(bredr_link)),
336       is_controller_remote_public_key_validation_supported_(
337           is_controller_remote_public_key_validation_supported),
338       low_energy_io_cap_(io_capability),
339       sm_chan_(std::make_unique<PairingChannel>(
340           smp, fit::bind_member<&SecurityManagerImpl::StartNewTimer>(this))),
341       peer_(std::move(peer)),
342       weak_self_(this),
343       weak_listener_(this),
344       weak_handler_(this) {
345   PW_CHECK(delegate_.is_alive());
346   PW_CHECK(smp.is_alive());
347 
348   sm_chan_->SetChannelHandler(weak_handler_.GetWeakPtr());
349 
350   timeout_task_.set_function(
351       [this](pw::async::Context /*ctx*/, pw::Status status) {
352         if (status.ok()) {
353           OnPairingTimeout();
354         }
355       });
356 
357   if (smp->id() == l2cap::kLESMPChannelId) {
358     PW_CHECK(low_energy_link_.is_alive());
359     PW_CHECK(low_energy_link_->handle() == smp->link_handle());
360 
361     // Set up HCI encryption event.
362     low_energy_link_->set_encryption_change_callback(
363         fit::bind_member<&SecurityManagerImpl::OnEncryptionChange>(this));
364 
365     // Obtain existing pairing data, if any.
366     std::optional<sm::LTK> ltk = GetExistingLtkFromPeerCache();
367     if (ltk) {
368       bt_log(INFO,
369              "sm",
370              "starting encryption with existing LTK (peer: %s, handle: %#.4x)",
371              bt_str(peer_->identifier()),
372              low_energy_link_->handle());
373 
374       // Sets LTK in low_energy_link_
375       OnNewLongTermKey(*ltk);
376 
377       // The initiatior starts encryption when there is an LTK.
378       if (low_energy_link_->role() ==
379           pw::bluetooth::emboss::ConnectionRole::CENTRAL) {
380         current_phase_ = StartingEncryption();
381         PW_CHECK(low_energy_link_->StartEncryption());
382       }
383     }
384   }
385 }
386 
OnSecurityRequest(AuthReqField auth_req)387 void SecurityManagerImpl::OnSecurityRequest(AuthReqField auth_req) {
388   if (bredr_link_.is_alive()) {
389     sm_chan_->SendMessageNoTimerReset(kPairingFailed,
390                                       ErrorCode::kCommandNotSupported);
391     return;
392   }
393 
394   PW_CHECK(!SecurityUpgradeInProgress() ||
395            std::holds_alternative<WaitForBrEdrPairing>(current_phase_) ||
396            std::holds_alternative<StartingEncryption>(current_phase_));
397 
398   if (role() != Role::kInitiator) {
399     bt_log(
400         INFO,
401         "sm",
402         "Received spurious Security Request while not acting as SM initiator");
403     sm_chan_->SendMessageNoTimerReset(kPairingFailed,
404                                       ErrorCode::kCommandNotSupported);
405     return;
406   }
407 
408   SecurityLevel requested_level;
409   // inclusive-language: ignore
410   if (auth_req & AuthReq::kMITM) {
411     requested_level = SecurityLevel::kAuthenticated;
412   } else {
413     requested_level = SecurityLevel::kEncrypted;
414   }
415 
416   // "If pairing has been initiated by the local device on the BR/EDR transport,
417   // and a pairing request is received from the same remote device on the LE
418   // transport, the LE pairing shall be rejected with SMP error code BR/EDR
419   // Pairing in Progress if both sides support LE Secure Connections." (v6.0,
420   // Vol. 3, Part C, Sec. 14.2)
421   bool peer_supports_secure_connections = auth_req & kSC;
422   bool bredr_pairing_in_progress =
423       peer_->bredr() && peer_->bredr()->is_pairing();
424   if (peer_supports_secure_connections && bredr_pairing_in_progress) {
425     bt_log(INFO,
426            "sm",
427            "rejecting Security Request because BREDR pairing in progress");
428     sm_chan_->SendMessageNoTimerReset(kPairingFailed,
429                                       ErrorCode::kBREDRPairingInProgress);
430     return;
431   }
432 
433   // If we already have a LTK and its security properties satisfy the request,
434   // then we start link layer encryption (which will either encrypt the link or
435   // perform a key refresh). See Vol 3, Part H, Figure 2.7 for the algorithm.
436   if (ltk_ && (ltk_->security().level() >= requested_level) &&
437       (!(auth_req & AuthReq::kSC) || ltk_->security().secure_connections())) {
438     if (bt_is_error(
439             ValidateExistingLocalLtk(),
440             ERROR,
441             "sm",
442             "disconnecting link as it cannot be encrypted with LTK status")) {
443       return;
444     }
445     current_phase_ = StartingEncryption();
446     PW_CHECK(low_energy_link_->StartEncryption());
447     return;
448   }
449 
450   // V5.1 Vol. 3 Part H Section 3.4: "Upon [...] reception of the Security
451   // Request command, the Security Manager Timer shall be [...] restarted."
452   StartNewTimer();
453   if (fit::result result = RequestSecurityUpgrade(requested_level);
454       result.is_error()) {
455     // Per v5.3 Vol. 3 Part H 2.4.6, "When a Central receives a Security Request
456     // command it may
457     // [...] reject the request.", which we do here as we know we are unable to
458     // fulfill it.
459     sm_chan_->SendMessageNoTimerReset(kPairingFailed, result.error_value());
460     // If we fail to start pairing, we need to stop the timer.
461     StopTimer();
462   }
463 }
464 
UpgradeSecurity(SecurityLevel level,PairingCallback callback)465 void SecurityManagerImpl::UpgradeSecurity(SecurityLevel level,
466                                           PairingCallback callback) {
467   PW_CHECK(!bredr_link_.is_alive());
468 
469   if (SecurityUpgradeInProgress()) {
470     bt_log(TRACE,
471            "sm",
472            "LE security upgrade in progress; request for %s security queued",
473            LevelToString(level));
474     request_queue_.emplace(level, std::move(callback));
475     return;
476   }
477 
478   if (level <= security().level()) {
479     callback(fit::ok(), security());
480     return;
481   }
482 
483   // Secure Connections only mode only permits Secure Connections authenticated
484   // pairing with a 128- bit encryption key, so we force all security upgrade
485   // requests to that level.
486   if (security_mode() == gap::LESecurityMode::SecureConnectionsOnly) {
487     level = SecurityLevel::kSecureAuthenticated;
488   }
489 
490   // |request_queue| must be empty if there is no active security upgrade
491   // request, which is equivalent to being in idle phase with no pending
492   // security request.
493   PW_CHECK(request_queue_.empty());
494   request_queue_.emplace(level, std::move(callback));
495   UpgradeSecurityInternal();
496 }
497 
OnPairingRequest(const PairingRequestParams & req_params)498 void SecurityManagerImpl::OnPairingRequest(
499     const PairingRequestParams& req_params) {
500   // Only the initiator may send the Pairing Request (V5.0 Vol. 3 Part H 3.5.1).
501   if (role() != Role::kResponder) {
502     bt_log(INFO, "sm", "rejecting \"Pairing Request\" as initiator");
503     sm_chan_->SendMessageNoTimerReset(kPairingFailed,
504                                       ErrorCode::kCommandNotSupported);
505     return;
506   }
507 
508   // "If pairing has been initiated by the local device on the BR/EDR transport,
509   // and a pairing request is received from the same remote device on the LE
510   // transport, the LE pairing shall be rejected with SMP error code BR/EDR
511   // Pairing in Progress if both sides support LE Secure Connections." (v6.0,
512   // Vol. 3, Part C, Sec. 14.2)
513   bool peer_supports_secure_connections = req_params.auth_req & kSC;
514   bool le_secure_connections =
515       low_energy_link_.is_alive() && peer_supports_secure_connections;
516   bool bredr_pairing_in_progress =
517       peer_->bredr() && peer_->bredr()->is_pairing();
518   if (le_secure_connections && bredr_pairing_in_progress) {
519     bt_log(INFO,
520            "sm",
521            "LE: rejecting Pairing Request because BREDR pairing in progress");
522     sm_chan_->SendMessageNoTimerReset(kPairingFailed,
523                                       ErrorCode::kBREDRPairingInProgress);
524     return;
525   }
526 
527   // We only require authentication as Responder if there is a pending
528   // Security Request for it.
529   SecurityRequestPhase* security_req_phase =
530       std::get_if<SecurityRequestPhase>(&current_phase_);
531   auto required_level = security_req_phase
532                             ? security_req_phase->pending_security_request()
533                             : SecurityLevel::kEncrypted;
534 
535   // Secure Connections only mode only permits Secure Connections authenticated
536   // pairing with a 128- bit encryption key, so we force all security upgrade
537   // requests to that level.
538   if (security_mode() == gap::LESecurityMode::SecureConnectionsOnly) {
539     required_level = SecurityLevel::kSecureAuthenticated;
540   }
541 
542   if (bredr_link_.is_alive()) {
543     if (!IsBrEdrCrossTransportKeyDerivationAllowed()) {
544       bt_log(INFO,
545              "sm",
546              "BR/EDR: rejecting \"Pairing Request\" because CTKD not allowed");
547       sm_chan_->SendMessageNoTimerReset(
548           kPairingFailed, ErrorCode::kCrossTransportKeyDerivationNotAllowed);
549       return;
550     }
551   }
552 
553   if (!pairing_token_) {
554     if (low_energy_link_.is_alive()) {
555       pairing_token_ = peer_->MutLe().RegisterPairing();
556     } else {
557       pairing_token_ = peer_->MutBrEdr().RegisterPairing();
558     }
559   }
560 
561   // V5.1 Vol. 3 Part H Section 3.4: "Upon [...] reception of the Pairing
562   // Request command, the Security Manager Timer shall be reset and started."
563   StartNewTimer();
564 
565   current_phase_ = Phase1::CreatePhase1Responder(
566       sm_chan_->GetWeakPtr(),
567       weak_listener_.GetWeakPtr(),
568       req_params,
569       low_energy_io_cap_,
570       bondable_mode(),
571       required_level,
572       fit::bind_member<&SecurityManagerImpl::OnFeatureExchange>(this));
573   std::get<std::unique_ptr<Phase1>>(current_phase_)->Start();
574 }
575 
UpgradeSecurityInternal()576 void SecurityManagerImpl::UpgradeSecurityInternal() {
577   PW_CHECK(!bredr_link_.is_alive());
578   PW_CHECK(
579       !SecurityUpgradeInProgress(),
580       "cannot upgrade security while security upgrade already in progress!");
581   PW_CHECK(!request_queue_.empty());
582 
583   // "If a BR/EDR/LE device supports LE Secure Connections, then it shall
584   // initiate pairing on only one transport at a time to the same remote
585   // device." (v6.0, Vol 3, Part C, Sec. 14.2)
586   if (peer_->bredr() && peer_->bredr()->is_pairing()) {
587     bt_log(DEBUG,
588            "sm",
589            "Delaying security upgrade until BR/EDR pairing completes");
590     current_phase_ = WaitForBrEdrPairing();
591     peer_->MutBrEdr().add_pairing_completion_callback(
592         [self = weak_self_.GetWeakPtr()]() {
593           if (!self.is_alive() ||
594               !std::get_if<WaitForBrEdrPairing>(&self->current_phase_)) {
595             return;
596           }
597           self->ResetState();
598           if (self->request_queue_.empty()) {
599             return;
600           }
601           self->UpgradeSecurityInternal();
602         });
603     return;
604   }
605 
606   const PendingRequest& next_req = request_queue_.front();
607 
608   // BR/EDR cross-transport key derivation could have created a new LE LTK that
609   // meets the requirements of the next request. Only central can start
610   // encryption, so we skip this and request a security upgrade as peripheral.
611   if (low_energy_link_->role() ==
612       pw::bluetooth::emboss::ConnectionRole::CENTRAL) {
613     std::optional<sm::LTK> ltk = GetExistingLtkFromPeerCache();
614     // If the new LTK isn't going to satisfy the request anyway, we can ignore
615     // it and start pairing.
616     if (ltk && ltk != ltk_ && ltk->security().level() >= next_req.level) {
617       bt_log(INFO,
618              "sm",
619              "starting encryption with LTK from PeerCache (peer: %s, handle: "
620              "%#.4x)",
621              bt_str(peer_->identifier()),
622              low_energy_link_->handle());
623 
624       OnNewLongTermKey(*ltk);
625 
626       current_phase_ = StartingEncryption();
627       PW_CHECK(low_energy_link_->StartEncryption());
628       return;
629     }
630   }
631 
632   if (fit::result result = RequestSecurityUpgrade(next_req.level);
633       result.is_error()) {
634     next_req.callback(ToResult(result.error_value()), security());
635     request_queue_.pop();
636     if (!request_queue_.empty()) {
637       UpgradeSecurityInternal();
638     }
639   }
640 }
641 
RequestSecurityUpgrade(SecurityLevel level)642 fit::result<ErrorCode> SecurityManagerImpl::RequestSecurityUpgrade(
643     SecurityLevel level) {
644   PW_CHECK(!bredr_link_.is_alive());
645   if (level >= SecurityLevel::kAuthenticated &&
646       low_energy_io_cap_ == IOCapability::kNoInputNoOutput) {
647     bt_log(WARN,
648            "sm",
649            "cannot fulfill authenticated security request as IOCapabilities "
650            "are NoInputNoOutput");
651     return fit::error(ErrorCode::kAuthenticationRequirements);
652   }
653 
654   if (!pairing_token_) {
655     pairing_token_ = peer_->MutLe().RegisterPairing();
656   }
657 
658   if (role() == Role::kInitiator) {
659     current_phase_ = Phase1::CreatePhase1Initiator(
660         sm_chan_->GetWeakPtr(),
661         weak_listener_.GetWeakPtr(),
662         low_energy_io_cap_,
663         bondable_mode(),
664         level,
665         fit::bind_member<&SecurityManagerImpl::OnFeatureExchange>(this));
666     std::get<std::unique_ptr<Phase1>>(current_phase_)->Start();
667   } else {
668     current_phase_.emplace<SecurityRequestPhase>(
669         sm_chan_->GetWeakPtr(),
670         weak_listener_.GetWeakPtr(),
671         level,
672         bondable_mode(),
673         fit::bind_member<&SecurityManagerImpl::OnPairingRequest>(this));
674     std::get<SecurityRequestPhase>(current_phase_).Start();
675   }
676   return fit::ok();
677 }
678 
OnFeatureExchange(PairingFeatures features,PairingRequestParams preq,PairingResponseParams pres)679 void SecurityManagerImpl::OnFeatureExchange(PairingFeatures features,
680                                             PairingRequestParams preq,
681                                             PairingResponseParams pres) {
682   PW_CHECK(std::holds_alternative<std::unique_ptr<Phase1>>(current_phase_));
683   bt_log(DEBUG, "sm", "SMP feature exchange complete");
684   next_pairing_id_++;
685   features_ = features;
686 
687   auto self = weak_listener_.GetWeakPtr();
688   if (bredr_link_.is_alive()) {
689     if (!features_->generate_ct_key.has_value()) {
690       Abort(ErrorCode::kCrossTransportKeyDerivationNotAllowed);
691       return;
692     }
693 
694     // If there are no keys to distribute, skip Phase3
695     if (!HasKeysToDistribute(*features_, /*is_bredr=*/true)) {
696       OnBrEdrPairingComplete(PairingData());
697       return;
698     }
699 
700     // We checked the ltk before Phase1.
701     PW_CHECK(bredr_link_->ltk().has_value());
702     // Phase3 needs to know the security properties.
703     SecurityProperties bredr_security_properties(
704         bredr_link_->ltk_type().value());
705 
706     current_phase_.emplace<Phase3>(
707         sm_chan_->GetWeakPtr(),
708         self,
709         role(),
710         *features_,
711         bredr_security_properties,
712         fit::bind_member<&SecurityManagerImpl::OnBrEdrPairingComplete>(this));
713     std::get<Phase3>(current_phase_).Start();
714   } else if (features.secure_connections) {
715     const auto [initiator_addr, responder_addr] = LEPairingAddresses();
716     current_phase_.emplace<Phase2SecureConnections>(
717         sm_chan_->GetWeakPtr(),
718         self,
719         role(),
720         features,
721         preq,
722         pres,
723         initiator_addr,
724         responder_addr,
725         fit::bind_member<&SecurityManagerImpl::OnPhase2EncryptionKey>(this));
726     std::get<Phase2SecureConnections>(current_phase_).Start();
727   } else {
728     const auto [initiator_addr, responder_addr] = LEPairingAddresses();
729     auto preq_pdu = util::NewPdu(sizeof(PairingRequestParams)),
730          pres_pdu = util::NewPdu(sizeof(PairingResponseParams));
731     PacketWriter preq_writer(kPairingRequest, preq_pdu.get()),
732         pres_writer(kPairingResponse, pres_pdu.get());
733     *preq_writer.mutable_payload<PairingRequestParams>() = preq;
734     *pres_writer.mutable_payload<PairingRequestParams>() = pres;
735     current_phase_.emplace<Phase2Legacy>(
736         sm_chan_->GetWeakPtr(),
737         self,
738         role(),
739         features,
740         *preq_pdu,
741         *pres_pdu,
742         initiator_addr,
743         responder_addr,
744         fit::bind_member<&SecurityManagerImpl::OnPhase2EncryptionKey>(this));
745     std::get<Phase2Legacy>(current_phase_).Start();
746   }
747 }
748 
OnPhase2EncryptionKey(const UInt128 & new_key)749 void SecurityManagerImpl::OnPhase2EncryptionKey(const UInt128& new_key) {
750   PW_CHECK(!bredr_link_.is_alive());
751   PW_CHECK(low_energy_link_.is_alive());
752   PW_CHECK(features_);
753   PW_CHECK(InPhase2());
754   // EDiv and Rand values are 0 for Phase 2 keys generated by Legacy or Secure
755   // Connections (Vol 3, Part H, 2.4.4 / 2.4.4.1). Secure Connections generates
756   // an LTK, while Legacy generates an STK.
757   auto new_link_key = hci_spec::LinkKey(new_key, 0, 0);
758 
759   if (features_->secure_connections) {
760     OnNewLongTermKey(LTK(FeaturesToProperties(*features_), new_link_key));
761   } else {
762     // `set_le_ltk` sets the encryption key of the LE link (which is the STK for
763     // Legacy), not the long-term key that results from pairing (which is
764     // generated in Phase 3 for Legacy).
765     low_energy_link_->set_ltk(new_link_key);
766   }
767   // If we're the initiator, we encrypt the link. If we're the responder, we
768   // wait for the initiator to encrypt the link with the new key.|le_link_| will
769   // respond to the HCI "LTK request" event with the `new_link_key` assigned
770   // above, which should trigger OnEncryptionChange.
771   if (role() == Role::kInitiator) {
772     if (!low_energy_link_->StartEncryption()) {
773       bt_log(ERROR, "sm", "failed to start encryption");
774       Abort(ErrorCode::kUnspecifiedReason);
775     }
776   }
777 }
778 
CurrentLtkInsufficientlySecureForEncryption(std::optional<LTK> current_ltk,SecurityRequestPhase * security_request_phase,gap::LESecurityMode mode)779 bool SecurityManagerImpl::CurrentLtkInsufficientlySecureForEncryption(
780     std::optional<LTK> current_ltk,
781     SecurityRequestPhase* security_request_phase,
782     gap::LESecurityMode mode) {
783   SecurityLevel current_ltk_sec = current_ltk ? current_ltk->security().level()
784                                               : SecurityLevel::kNoSecurity;
785   return (security_request_phase &&
786           security_request_phase->pending_security_request() >
787               current_ltk_sec) ||
788          (mode == gap::LESecurityMode::SecureConnectionsOnly &&
789           current_ltk_sec != SecurityLevel::kSecureAuthenticated);
790 }
791 
OnEncryptionChange(hci::Result<bool> enabled_result)792 void SecurityManagerImpl::OnEncryptionChange(hci::Result<bool> enabled_result) {
793   PW_CHECK(!bredr_link_.is_alive());
794 
795   // First notify the delegate in case of failure.
796   if (bt_is_error(
797           enabled_result, ERROR, "sm", "link layer authentication failed")) {
798     PW_CHECK(delegate_.is_alive());
799     delegate_->OnAuthenticationFailure(
800         fit::error(enabled_result.error_value()));
801   }
802 
803   if (enabled_result.is_error() || !enabled_result.value()) {
804     bt_log(WARN,
805            "sm",
806            "encryption of link (handle: %#.4x) %s%s!",
807            low_energy_link_->handle(),
808            enabled_result.is_error()
809                ? bt_lib_cpp_string::StringPrintf("failed with %s",
810                                                  bt_str(enabled_result))
811                      .c_str()
812                : "disabled",
813            SecurityUpgradeInProgress() ? "" : " during security upgrade");
814     SetSecurityProperties(sm::SecurityProperties());
815     if (SecurityUpgradeInProgress()) {
816       Abort(ErrorCode::kUnspecifiedReason);
817     }
818     return;
819   }
820 
821   SecurityRequestPhase* security_request_phase =
822       std::get_if<SecurityRequestPhase>(&current_phase_);
823   if (CurrentLtkInsufficientlySecureForEncryption(
824           ltk_, security_request_phase, security_mode())) {
825     bt_log(WARN,
826            "sm",
827            "peer encrypted link with insufficiently secure key, disconnecting");
828     delegate_->OnAuthenticationFailure(
829         ToResult(HostError::kInsufficientSecurity));
830     sm_chan_->SignalLinkError();
831     return;
832   }
833 
834   bool wait_for_bredr_pairing_phase =
835       std::holds_alternative<WaitForBrEdrPairing>(current_phase_);
836   bool starting_encryption_phase =
837       std::holds_alternative<StartingEncryption>(current_phase_);
838 
839   if (!SecurityUpgradeInProgress() || security_request_phase ||
840       starting_encryption_phase || wait_for_bredr_pairing_phase) {
841     bt_log(DEBUG, "sm", "encryption enabled while not pairing");
842     if (bt_is_error(
843             ValidateExistingLocalLtk(),
844             ERROR,
845             "sm",
846             "disconnecting link as it cannot be encrypted with LTK status")) {
847       return;
848     }
849     // If encryption is enabled while not pairing, we update the security
850     // properties to those of `ltk_`. Otherwise, we let the EndPhase2 pairing
851     // function determine the security properties.
852     SetSecurityProperties(ltk_->security());
853 
854     if (security_request_phase) {
855       PW_CHECK(role() == Role::kResponder);
856       PW_CHECK(!request_queue_.empty());
857     }
858     if (starting_encryption_phase) {
859       ResetState();
860     }
861     NotifySecurityCallbacks();
862     return;
863   }
864 
865   if (InPhase2()) {
866     bt_log(DEBUG, "sm", "link encrypted with phase 2 generated key");
867     EndPhase2();
868   }
869 }
870 
EndPhase2()871 void SecurityManagerImpl::EndPhase2() {
872   PW_CHECK(features_.has_value());
873   PW_CHECK(InPhase2());
874   PW_CHECK(!bredr_link_.is_alive());
875 
876   SetSecurityProperties(FeaturesToProperties(*features_));
877   // If there are no keys to distribute, don't bother creating Phase 3
878   if (!HasKeysToDistribute(*features_, bredr_link_.is_alive())) {
879     OnLowEnergyPairingComplete(PairingData());
880     return;
881   }
882   auto self = weak_listener_.GetWeakPtr();
883   current_phase_.emplace<Phase3>(
884       sm_chan_->GetWeakPtr(),
885       self,
886       role(),
887       *features_,
888       security(),
889       fit::bind_member<&SecurityManagerImpl::OnLowEnergyPairingComplete>(this));
890   std::get<Phase3>(current_phase_).Start();
891 }
892 
OnLowEnergyPairingComplete(PairingData pairing_data)893 void SecurityManagerImpl::OnLowEnergyPairingComplete(PairingData pairing_data) {
894   // We must either be in Phase3 or Phase 2 with no keys to distribute if
895   // pairing has completed.
896   if (!std::holds_alternative<Phase3>(current_phase_)) {
897     PW_CHECK(InPhase2());
898     PW_CHECK(!HasKeysToDistribute(*features_, /*is_bredr=*/false));
899   }
900   PW_CHECK(delegate_.is_alive());
901   PW_CHECK(features_.has_value());
902   bt_log(DEBUG, "sm", "LE pairing complete");
903   delegate_->OnPairingComplete(fit::ok());
904   // In Secure Connections, the LTK will be generated in Phase 2, not exchanged
905   // in Phase 3, so we want to ensure that it is still put in the pairing_data.
906   if (features_->secure_connections) {
907     PW_CHECK(ltk_.has_value());
908     pairing_data.peer_ltk = pairing_data.local_ltk = ltk_;
909   } else {
910     // The SM-internal LTK is used to validate future encryption events on the
911     // existing link. Encryption with LTKs generated by LE legacy pairing uses
912     // the key received by the link-layer central - so as initiator, this is the
913     // peer key, and as responder, this is the local key.
914     const std::optional<LTK>& new_ltk = role() == Role::kInitiator
915                                             ? pairing_data.peer_ltk
916                                             : pairing_data.local_ltk;
917     if (new_ltk.has_value()) {
918       OnNewLongTermKey(*new_ltk);
919     }
920   }
921 
922   if (features_->generate_ct_key.has_value()) {
923     // If we are generating the CT key, we must be using secure connections, and
924     // as such the peer and local LTKs will be equivalent.
925     PW_CHECK(features_->secure_connections);
926     PW_CHECK(pairing_data.peer_ltk == pairing_data.local_ltk);
927     std::optional<UInt128> ct_key_value = util::LeLtkToBrEdrLinkKey(
928         ltk_->key().value(), features_->generate_ct_key.value());
929     if (ct_key_value) {
930       pairing_data.cross_transport_key =
931           sm::LTK(ltk_->security(), hci_spec::LinkKey(*ct_key_value, 0, 0));
932     } else {
933       bt_log(WARN, "sm", "failed to generate cross-transport key");
934     }
935   }
936 
937   if (features_->will_bond) {
938     std::optional<sm::LTK> ltk;
939     if (pairing_data.peer_ltk) {
940       ltk = pairing_data.peer_ltk;
941     } else {
942       ltk = pairing_data.local_ltk;
943     }
944 
945     if (ltk.has_value()) {
946       bt_log(
947           INFO,
948           "sm",
949           "new %s pairing data: [%s%s%s%s%s%s] (peer: %s)",
950           ltk->security().secure_connections() ? "secure connections"
951                                                : "legacy",
952           pairing_data.peer_ltk ? "peer_ltk " : "",
953           pairing_data.local_ltk ? "local_ltk " : "",
954           pairing_data.irk ? "irk " : "",
955           pairing_data.cross_transport_key ? "ct_key " : "",
956           pairing_data.identity_address
957               ? bt_lib_cpp_string::StringPrintf(
958                     "(identity: %s) ", bt_str(*pairing_data.identity_address))
959                     .c_str()
960               : "",
961           pairing_data.csrk ? "csrk " : "",
962           bt_str(peer_->identifier()));
963 
964       if (!peer_->MutLe().StoreBond(pairing_data)) {
965         bt_log(ERROR,
966                "sm",
967                "failed to cache bonding data (id: %s)",
968                bt_str(peer_->identifier()));
969       }
970     } else {
971       // Consider the pairing temporary if no link key was received. This
972       // means we'll remain encrypted with the STK without creating a bond and
973       // reinitiate pairing when we reconnect in the future.
974       bt_log(INFO,
975              "sm",
976              "temporarily paired with peer (peer: %s)",
977              bt_str(peer_->identifier()));
978     }
979 
980   } else {
981     bt_log(INFO,
982            "gap-le",
983            " %s pairing complete in non-bondable mode with [%s%s%s%s%s]",
984            features_->secure_connections ? "secure connections" : "legacy",
985            pairing_data.peer_ltk ? "peer_ltk " : "",
986            pairing_data.local_ltk ? "local_ltk " : "",
987            pairing_data.irk ? "irk " : "",
988            pairing_data.identity_address
989                ? bt_lib_cpp_string::StringPrintf(
990                      "(identity: %s) ", bt_str(*pairing_data.identity_address))
991                      .c_str()
992                : "",
993            pairing_data.csrk ? "csrk " : "");
994   }
995   // So we can pair again if need be.
996   ResetState();
997 
998   NotifySecurityCallbacks();
999 }
1000 
OnBrEdrPairingComplete(PairingData pairing_data)1001 void SecurityManagerImpl::OnBrEdrPairingComplete(PairingData pairing_data) {
1002   PW_CHECK(bredr_link_.is_alive());
1003   // We must either be in Phase3 or Phase1 with no keys to distribute if pairing
1004   // has completed.
1005   if (!std::holds_alternative<Phase3>(current_phase_)) {
1006     PW_CHECK(InPhase1());
1007     PW_CHECK(!HasKeysToDistribute(*features_, /*is_bredr=*/true));
1008   }
1009   PW_CHECK(features_.has_value());
1010   PW_CHECK(features_->generate_ct_key.has_value());
1011   PW_CHECK(delegate_.is_alive());
1012 
1013   bt_log(INFO, "sm", "BR/EDR cross-transport key derivation complete");
1014   delegate_->OnPairingComplete(fit::ok());
1015 
1016   std::optional<UInt128> ct_key_value = util::BrEdrLinkKeyToLeLtk(
1017       bredr_link_->ltk()->value(), features_->generate_ct_key.value());
1018   if (ct_key_value) {
1019     // The LE LTK will have the same security properties as the BR/EDR key.
1020     SecurityProperties bredr_properties(bredr_link_->ltk_type().value());
1021     sm::LTK le_ltk =
1022         sm::LTK(bredr_properties, hci_spec::LinkKey(*ct_key_value, 0, 0));
1023     pairing_data.local_ltk = le_ltk;
1024     pairing_data.peer_ltk = le_ltk;
1025   } else {
1026     bt_log(ERROR, "sm", "BR/EDR CTKD key generation failed");
1027     if (bredr_cross_transport_key_derivation_callback_) {
1028       bredr_cross_transport_key_derivation_callback_(
1029           ToResult(HostError::kFailed));
1030     }
1031     ResetState();
1032     return;
1033   }
1034 
1035   if (!peer_->MutLe().StoreBond(pairing_data)) {
1036     bt_log(ERROR,
1037            "sm",
1038            "failed to cache bonding data (id: %s)",
1039            bt_str(peer_->identifier()));
1040   }
1041 
1042   if (bredr_cross_transport_key_derivation_callback_) {
1043     bredr_cross_transport_key_derivation_callback_(fit::ok());
1044   }
1045 
1046   ResetState();
1047 }
1048 
NotifySecurityCallbacks()1049 void SecurityManagerImpl::NotifySecurityCallbacks() {
1050   // Separate out the requests that are satisfied by the current security level
1051   // from those that require a higher level. We'll retry pairing for the latter.
1052   std::queue<PendingRequest> satisfied;
1053   std::queue<PendingRequest> unsatisfied;
1054   while (!request_queue_.empty()) {
1055     auto& request = request_queue_.front();
1056     if (request.level <= security().level()) {
1057       satisfied.push(std::move(request));
1058     } else {
1059       unsatisfied.push(std::move(request));
1060     }
1061     request_queue_.pop();
1062   }
1063 
1064   request_queue_ = std::move(unsatisfied);
1065 
1066   // Notify the satisfied requests with success.
1067   while (!satisfied.empty()) {
1068     satisfied.front().callback(fit::ok(), security());
1069     satisfied.pop();
1070   }
1071 
1072   if (!request_queue_.empty()) {
1073     UpgradeSecurityInternal();
1074   }
1075 }
1076 
InitiateBrEdrCrossTransportKeyDerivation(CrossTransportKeyDerivationResultCallback callback)1077 void SecurityManagerImpl::InitiateBrEdrCrossTransportKeyDerivation(
1078     CrossTransportKeyDerivationResultCallback callback) {
1079   PW_CHECK(bredr_link_.is_alive());
1080   PW_CHECK(role() == Role::kInitiator);
1081 
1082   if (bredr_cross_transport_key_derivation_callback_ ||
1083       SecurityUpgradeInProgress()) {
1084     callback(ToResult(HostError::kInProgress));
1085     return;
1086   }
1087 
1088   if (!IsBrEdrCrossTransportKeyDerivationAllowed()) {
1089     callback(ToResult(HostError::kInsufficientSecurity));
1090     return;
1091   }
1092 
1093   bredr_cross_transport_key_derivation_callback_ = std::move(callback);
1094 
1095   if (!pairing_token_) {
1096     pairing_token_ = peer_->MutBrEdr().RegisterPairing();
1097   }
1098   current_phase_ = Phase1::CreatePhase1Initiator(
1099       sm_chan_->GetWeakPtr(),
1100       weak_listener_.GetWeakPtr(),
1101       IOCapability::kDisplayOnly,  // arbitrary
1102       BondableMode::Bondable,
1103       SecurityLevel::kEncrypted,  // arbitrary
1104       fit::bind_member<&SecurityManagerImpl::OnFeatureExchange>(this));
1105   std::get<std::unique_ptr<Phase1>>(current_phase_)->Start();
1106 }
1107 
Reset(IOCapability io_capability)1108 void SecurityManagerImpl::Reset(IOCapability io_capability) {
1109   Abort(ErrorCode::kUnspecifiedReason);
1110   low_energy_io_cap_ = io_capability;
1111   ResetState();
1112 }
1113 
ResetState()1114 void SecurityManagerImpl::ResetState() {
1115   StopTimer();
1116   features_.reset();
1117   sm_chan_->SetChannelHandler(weak_handler_.GetWeakPtr());
1118   pairing_token_.reset();
1119   current_phase_ = std::monostate{};
1120 }
1121 
SetSecurityProperties(const SecurityProperties & sec)1122 void SecurityManagerImpl::SetSecurityProperties(const SecurityProperties& sec) {
1123   if (sec != security()) {
1124     bt_log(DEBUG,
1125            "sm",
1126            "security properties changed - handle: %#.4x, new: %s, old: %s",
1127            low_energy_link_->handle(),
1128            bt_str(sec),
1129            bt_str(security()));
1130     set_security(sec);
1131     delegate_->OnNewSecurityProperties(security());
1132   }
1133 }
1134 
Abort(ErrorCode ecode)1135 void SecurityManagerImpl::Abort(ErrorCode ecode) {
1136   std::visit(
1137       [=](auto& arg) {
1138         using T = std::decay_t<decltype(arg)>;
1139         if constexpr (std::is_same_v<std::unique_ptr<Phase1>, T>) {
1140           arg->Abort(ecode);
1141         } else if constexpr (std::is_base_of_v<PairingPhase, T>) {
1142           arg.Abort(ecode);
1143         } else {
1144           bt_log(DEBUG,
1145                  "sm",
1146                  "Attempted to abort security upgrade while not in progress");
1147         }
1148       },
1149       current_phase_);
1150   // "Abort" should trigger OnPairingFailed.
1151 }
1152 
OnIdentityRequest()1153 std::optional<IdentityInfo> SecurityManagerImpl::OnIdentityRequest() {
1154   // This is called by the bearer to determine if we have local identity
1155   // information to distribute.
1156   PW_CHECK(delegate_.is_alive());
1157   return delegate_->OnIdentityInformationRequest();
1158 }
1159 
ConfirmPairing(ConfirmCallback confirm)1160 void SecurityManagerImpl::ConfirmPairing(ConfirmCallback confirm) {
1161   PW_CHECK(!bredr_link_.is_alive());
1162   PW_CHECK(delegate_.is_alive());
1163   delegate_->ConfirmPairing([id = next_pairing_id_,
1164                              self = weak_self_.GetWeakPtr(),
1165                              cb = std::move(confirm)](bool is_confirmed) {
1166     if (!self.is_alive() || self->next_pairing_id_ != id) {
1167       bt_log(TRACE,
1168              "sm",
1169              "ignoring user confirmation for expired pairing: id = %" PRIu64,
1170              id);
1171       return;
1172     }
1173     cb(is_confirmed);
1174   });
1175 }
1176 
DisplayPasskey(uint32_t passkey,Delegate::DisplayMethod method,ConfirmCallback confirm)1177 void SecurityManagerImpl::DisplayPasskey(uint32_t passkey,
1178                                          Delegate::DisplayMethod method,
1179                                          ConfirmCallback confirm) {
1180   PW_CHECK(!bredr_link_.is_alive());
1181   PW_CHECK(delegate_.is_alive());
1182   delegate_->DisplayPasskey(
1183       passkey,
1184       method,
1185       [id = next_pairing_id_,
1186        self = weak_self_.GetWeakPtr(),
1187        method,
1188        cb = std::move(confirm)](bool is_confirmed) {
1189         if (!self.is_alive() || self->next_pairing_id_ != id) {
1190           bt_log(TRACE,
1191                  "sm",
1192                  "ignoring %s response for expired pairing: id = %" PRIu64,
1193                  util::DisplayMethodToString(method).c_str(),
1194                  id);
1195           return;
1196         }
1197         cb(is_confirmed);
1198       });
1199 }
1200 
RequestPasskey(PasskeyResponseCallback respond)1201 void SecurityManagerImpl::RequestPasskey(PasskeyResponseCallback respond) {
1202   PW_CHECK(!bredr_link_.is_alive());
1203   PW_CHECK(delegate_.is_alive());
1204   delegate_->RequestPasskey([id = next_pairing_id_,
1205                              self = weak_self_.GetWeakPtr(),
1206                              cb = std::move(respond)](int64_t passkey) {
1207     if (!self.is_alive() || self->next_pairing_id_ != id) {
1208       bt_log(
1209           TRACE,
1210           "sm",
1211           "ignoring passkey input response for expired pairing: id = %" PRIx64,
1212           id);
1213       return;
1214     }
1215     cb(passkey);
1216   });
1217 }
1218 
OnRxBFrame(ByteBufferPtr sdu)1219 void SecurityManagerImpl::OnRxBFrame(ByteBufferPtr sdu) {
1220   fit::result<ErrorCode, ValidPacketReader> maybe_reader =
1221       ValidPacketReader::ParseSdu(sdu);
1222   if (maybe_reader.is_error()) {
1223     bt_log(INFO,
1224            "sm",
1225            "dropped SMP packet: %s",
1226            bt_str(ToResult(maybe_reader.error_value())));
1227     return;
1228   }
1229   ValidPacketReader reader = maybe_reader.value();
1230   Code smp_code = reader.code();
1231 
1232   if (smp_code == kPairingRequest) {
1233     OnPairingRequest(reader.payload<PairingRequestParams>());
1234   } else if (smp_code == kSecurityRequest) {
1235     OnSecurityRequest(reader.payload<AuthReqField>());
1236   } else {
1237     bt_log(INFO,
1238            "sm",
1239            "dropped unexpected SMP code %#.2X when not pairing",
1240            smp_code);
1241   }
1242 }
1243 
OnChannelClosed()1244 void SecurityManagerImpl::OnChannelClosed() {
1245   bt_log(DEBUG, "sm", "SMP channel closed while not pairing");
1246 }
1247 
OnPairingFailed(Error error)1248 void SecurityManagerImpl::OnPairingFailed(Error error) {
1249   std::string phase_status = std::visit(
1250       [=](auto& arg) {
1251         using T = std::decay_t<decltype(arg)>;
1252         std::string s;
1253         if constexpr (std::is_same_v<std::unique_ptr<Phase1>, T>) {
1254           s = arg->ToString();
1255         } else if constexpr (std::is_base_of_v<PairingPhase, T>) {
1256           s = arg.ToString();
1257         } else {
1258           PW_CRASH(
1259               "security upgrade cannot fail when current_phase_ is "
1260               "std::monostate!");
1261         }
1262         return s;
1263       },
1264       current_phase_);
1265   bt_log(ERROR,
1266          "sm",
1267          "LE pairing failed: %s. Current pairing phase: %s",
1268          bt_str(error),
1269          phase_status.c_str());
1270   StopTimer();
1271   // TODO(fxbug.dev/42172514): implement "waiting interval" to prevent repeated
1272   // attempts as described in Vol 3, Part H, 2.3.6.
1273 
1274   PW_CHECK(delegate_.is_alive());
1275   delegate_->OnPairingComplete(fit::error(error));
1276 
1277   auto requests = std::move(request_queue_);
1278   while (!requests.empty()) {
1279     requests.front().callback(fit::error(error), security());
1280     requests.pop();
1281   }
1282 
1283   if (SecurityUpgradeInProgress() && !bredr_link_.is_alive()) {
1284     PW_CHECK(low_energy_link_.is_alive());
1285     low_energy_link_->set_ltk(hci_spec::LinkKey());
1286   }
1287 
1288   if (bredr_cross_transport_key_derivation_callback_) {
1289     bredr_cross_transport_key_derivation_callback_(
1290         ToResult(HostError::kFailed));
1291   }
1292 
1293   ResetState();
1294   // Reset state before potentially disconnecting link to avoid causing pairing
1295   // phase to fail twice.
1296   if (error.is(HostError::kTimedOut)) {
1297     // Per v5.2 Vol. 3 Part H 3.4, after a pairing timeout "No further SMP
1298     // commands shall be sent over the L2CAP Security Manager Channel. A new
1299     // Pairing process shall only be performed when a new physical link has been
1300     // established."
1301     bt_log(WARN, "sm", "pairing timed out! disconnecting link");
1302     sm_chan_->SignalLinkError();
1303   }
1304 }
1305 
StartNewTimer()1306 void SecurityManagerImpl::StartNewTimer() {
1307   if (timeout_task_.is_pending()) {
1308     PW_CHECK(timeout_task_.Cancel());
1309   }
1310   timeout_task_.PostAfter(kPairingTimeout);
1311 }
1312 
StopTimer()1313 void SecurityManagerImpl::StopTimer() {
1314   if (timeout_task_.is_pending() && !timeout_task_.Cancel()) {
1315     bt_log(TRACE, "sm", "smp: failed to stop timer");
1316   }
1317 }
1318 
OnPairingTimeout()1319 void SecurityManagerImpl::OnPairingTimeout() {
1320   std::visit(
1321       [=](auto& arg) {
1322         using T = std::decay_t<decltype(arg)>;
1323         if constexpr (std::is_same_v<std::unique_ptr<Phase1>, T>) {
1324           arg->OnFailure(Error(HostError::kTimedOut));
1325         } else if constexpr (std::is_base_of_v<PairingPhase, T>) {
1326           arg.OnFailure(Error(HostError::kTimedOut));
1327         } else {
1328           PW_CRASH("cannot timeout when current_phase_ is std::monostate!");
1329         }
1330       },
1331       current_phase_);
1332 }
1333 
1334 std::pair<DeviceAddress, DeviceAddress>
LEPairingAddresses()1335 SecurityManagerImpl::LEPairingAddresses() {
1336   PW_CHECK(!bredr_link_.is_alive());
1337   PW_CHECK(SecurityUpgradeInProgress());
1338   const DeviceAddress *initiator = &low_energy_link_->local_address(),
1339                       *responder = &low_energy_link_->peer_address();
1340   if (role() == Role::kResponder) {
1341     std::swap(initiator, responder);
1342   }
1343   return std::make_pair(*initiator, *responder);
1344 }
1345 
OnNewLongTermKey(const LTK & ltk)1346 void SecurityManagerImpl::OnNewLongTermKey(const LTK& ltk) {
1347   ltk_ = ltk;
1348   low_energy_link_->set_ltk(ltk.key());
1349 }
1350 
ValidateExistingLocalLtk()1351 Result<> SecurityManagerImpl::ValidateExistingLocalLtk() {
1352   Result<> status = fit::ok();
1353   if (!ltk_.has_value()) {
1354     // Should always be present when this method is called.
1355     bt_log(ERROR, "sm", "SM LTK not found");
1356     status = fit::error(Error(HostError::kNotFound));
1357   } else if (!low_energy_link_->ltk().has_value()) {
1358     // Should always be present when this method is called.
1359     bt_log(ERROR, "sm", "Link LTK not found");
1360     status = fit::error(Error(HostError::kNotFound));
1361   } else if (low_energy_link_->ltk().value() != ltk_->key()) {
1362     // As only SM should ever change the LE Link encryption key, these two
1363     // values should always be in sync, i.e. something in the system is acting
1364     // unreliably if they get out of sync.
1365     bt_log(ERROR, "sm", "SM LTK differs from LE link LTK");
1366     status = fit::error(Error(HostError::kNotReliable));
1367   }
1368   if (status.is_error()) {
1369     // SM does not own the link, so although the checks above should never fail,
1370     // disconnecting the link (vs. ASSERTing these checks) is safer against
1371     // non-SM code potentially touching the key.
1372     delegate_->OnAuthenticationFailure(
1373         ToResult(pw::bluetooth::emboss::StatusCode::PIN_OR_KEY_MISSING));
1374     sm_chan_->SignalLinkError();
1375   }
1376   return status;
1377 }
1378 
IsBrEdrCrossTransportKeyDerivationAllowed()1379 bool SecurityManagerImpl::IsBrEdrCrossTransportKeyDerivationAllowed() {
1380   if (!is_controller_remote_public_key_validation_supported_) {
1381     bt_log(DEBUG,
1382            "sm",
1383            "%s: remote public key validation not supported",
1384            __FUNCTION__);
1385     return false;
1386   }
1387 
1388   if (bredr_link_->encryption_status() !=
1389       pw::bluetooth::emboss::EncryptionStatus::ON_WITH_AES_FOR_BREDR) {
1390     bt_log(DEBUG, "sm", "%s: encryption status not AES", __FUNCTION__);
1391     return false;
1392   }
1393 
1394   if (!bredr_link_->ltk().has_value() || !bredr_link_->ltk_type() ||
1395       !(bredr_link_->ltk_type().value() ==
1396             hci_spec::LinkKeyType::kUnauthenticatedCombination256 ||
1397         bredr_link_->ltk_type().value() ==
1398             hci_spec::LinkKeyType::kAuthenticatedCombination256)) {
1399     bt_log(DEBUG, "sm", "%s: Link Key has insufficient security", __FUNCTION__);
1400     return false;
1401   }
1402 
1403   // Do not derive LE LTK if existing LE LTK is stronger than current
1404   // BR/EDR link key.
1405   SecurityProperties bredr_security_props(bredr_link_->ltk_type().value());
1406   bool has_le_ltk = peer_->le() && peer_->le()->bond_data() &&
1407                     peer_->le()->bond_data()->local_ltk;
1408   if (has_le_ltk && !bredr_security_props.IsAsSecureAs(
1409                         peer_->le()->bond_data()->local_ltk->security())) {
1410     bt_log(DEBUG,
1411            "sm",
1412            "%s: LE LTK stronger than current BR/EDR link key",
1413            __FUNCTION__);
1414     return false;
1415   }
1416 
1417   // TODO(fxbug.dev/388607971): check for LE pairing in progress
1418 
1419   return true;
1420 }
1421 
GetExistingLtkFromPeerCache()1422 std::optional<sm::LTK> SecurityManagerImpl::GetExistingLtkFromPeerCache() {
1423   if (peer_->le() && peer_->le()->bond_data()) {
1424     // Legacy pairing allows both devices to generate and exchange LTKs. "The
1425     // Central must have the security information (LTK, EDIV, and Rand)
1426     // distributed by the Peripheral in LE legacy [...] to setup an encrypted
1427     // session" (v5.3, Vol. 3 Part H 2.4.4.2). For Secure Connections peer_ltk
1428     // and local_ltk will be equal, so this check is unnecessary but correct.
1429     if (low_energy_link_->role() ==
1430         pw::bluetooth::emboss::ConnectionRole::CENTRAL) {
1431       return peer_->le()->bond_data()->peer_ltk;
1432     }
1433     return peer_->le()->bond_data()->local_ltk;
1434   }
1435   return std::nullopt;
1436 }
1437 
CreateLE(hci::LowEnergyConnection::WeakPtr link,l2cap::Channel::WeakPtr smp,IOCapability io_capability,Delegate::WeakPtr delegate,BondableMode bondable_mode,gap::LESecurityMode security_mode,pw::async::Dispatcher & dispatcher,bt::gap::Peer::WeakPtr peer)1438 std::unique_ptr<SecurityManager> SecurityManager::CreateLE(
1439     hci::LowEnergyConnection::WeakPtr link,
1440     l2cap::Channel::WeakPtr smp,
1441     IOCapability io_capability,
1442     Delegate::WeakPtr delegate,
1443     BondableMode bondable_mode,
1444     gap::LESecurityMode security_mode,
1445     pw::async::Dispatcher& dispatcher,
1446     bt::gap::Peer::WeakPtr peer) {
1447   PW_CHECK(link.is_alive());
1448   return std::make_unique<SecurityManagerImpl>(
1449       std::move(link),
1450       hci::BrEdrConnection::WeakPtr(),
1451       std::move(smp),
1452       io_capability,
1453       std::move(delegate),
1454       bondable_mode,
1455       security_mode,
1456       /*is_controller_remote_public_key_validation_supported=*/false,
1457       dispatcher,
1458       std::move(peer));
1459 }
1460 
CreateBrEdr(hci::BrEdrConnection::WeakPtr link,l2cap::Channel::WeakPtr smp,Delegate::WeakPtr delegate,bool is_controller_remote_public_key_validation_supported,pw::async::Dispatcher & dispatcher,bt::gap::Peer::WeakPtr peer)1461 std::unique_ptr<SecurityManager> SecurityManager::CreateBrEdr(
1462     hci::BrEdrConnection::WeakPtr link,
1463     l2cap::Channel::WeakPtr smp,
1464     Delegate::WeakPtr delegate,
1465     bool is_controller_remote_public_key_validation_supported,
1466     pw::async::Dispatcher& dispatcher,
1467     bt::gap::Peer::WeakPtr peer) {
1468   PW_CHECK(smp.is_alive());
1469   PW_CHECK(smp->id() == l2cap::kSMPChannelId);
1470   return std::make_unique<SecurityManagerImpl>(
1471       hci::LowEnergyConnection::WeakPtr(),
1472       std::move(link),
1473       std::move(smp),
1474       IOCapability::kNoInputNoOutput,  // arbitrary, RFU in BR/EDR
1475       std::move(delegate),
1476       BondableMode::Bondable,      // BR/EDR is always "bondable".
1477       gap::LESecurityMode::Mode1,  // arbitrary, not used by
1478                                    // BR/EDR
1479       is_controller_remote_public_key_validation_supported,
1480       dispatcher,
1481       std::move(peer));
1482 }
1483 
SecurityManager(BondableMode bondable_mode,gap::LESecurityMode security_mode)1484 SecurityManager::SecurityManager(BondableMode bondable_mode,
1485                                  gap::LESecurityMode security_mode)
1486     : low_energy_bondable_mode_(bondable_mode),
1487       low_energy_security_mode_(security_mode) {}
1488 
1489 }  // namespace bt::sm
1490