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>(¤t_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>(¤t_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