• 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 #pragma once
16 #include <memory>
17 #include <queue>
18 #include <variant>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/assert.h"
21 #include "pw_bluetooth_sapphire/internal/host/common/device_address.h"
22 #include "pw_bluetooth_sapphire/internal/host/common/uint128.h"
23 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
24 #include "pw_bluetooth_sapphire/internal/host/hci-spec/link_key.h"
25 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connection.h"
26 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel.h"
27 #include "pw_bluetooth_sapphire/internal/host/sm/delegate.h"
28 #include "pw_bluetooth_sapphire/internal/host/sm/error.h"
29 #include "pw_bluetooth_sapphire/internal/host/sm/pairing_phase.h"
30 #include "pw_bluetooth_sapphire/internal/host/sm/phase_1.h"
31 #include "pw_bluetooth_sapphire/internal/host/sm/phase_2_legacy.h"
32 #include "pw_bluetooth_sapphire/internal/host/sm/phase_2_secure_connections.h"
33 #include "pw_bluetooth_sapphire/internal/host/sm/phase_3.h"
34 #include "pw_bluetooth_sapphire/internal/host/sm/security_request_phase.h"
35 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
36 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
37 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
38 
39 namespace bt::sm {
40 
41 // SecurityManager provides a per-peer interface to Security Manager Protocol
42 // functionality in v5.2 Vol. 3 Part H. The peer device must be a LE or
43 // BR/EDR/LE device. SecurityManager is an abstract class so that SM-dependent
44 // code can dependency-inject test doubles in unit tests.
45 //
46 // The production implementation of SecurityManager is the SecurityManagerImpl
47 // class, which implements the functionality detailed in README.md. Clients
48 // should obtain a production object through the SecurityManager::Create factory
49 // function.
50 //
51 // A SecurityManager test double can be obtained through
52 // `TestSecurityManager::Create`.
53 //
54 /// See README.md for more overview of this library.
55 class SecurityManager {
56  public:
57   // Factory function which returns a production SecurityManager instance:
58   // |link|: The LE logical link over which pairing procedures occur.
59   // |smp|: The L2CAP LE SMP fixed channel that operates over |link|.
60   // |io_capability|: The initial I/O capability.
61   // |delegate|: Delegate which handles SMP interactions with the rest of the
62   // Bluetooth stack. |bondable_mode|: the operating bondable mode of the device
63   // (see v5.2, Vol. 3, Part C 9.4). |security_mode|: the security mode of this
64   // SecurityManager (see v5.2, Vol. 3, Part C 10.2).
65   static std::unique_ptr<SecurityManager> Create(
66       hci::LowEnergyConnection::WeakPtr link,
67       l2cap::Channel::WeakPtr smp,
68       IOCapability io_capability,
69       Delegate::WeakPtr delegate,
70       BondableMode bondable_mode,
71       gap::LESecurityMode security_mode,
72       pw::async::Dispatcher& dispatcher);
73   virtual ~SecurityManager() = default;
74   // Assigns the requested |ltk| to this connection, adopting the security
75   // properties of |ltk|. If the local device is the central of the underlying
76   // link, then the link layer authentication procedure will be initiated.
77   //
78   // Returns false if a pairing procedure is in progress when this method is
79   // called. If the link layer authentication procedure fails, then the link
80   // will be disconnected by the controller (Vol 2, Part E, 7.8.24;
81   // hci::Connection guarantees this by severing the link directly).
82   //
83   // This function is mainly intended to assign an existing LTK to a connection
84   // (e.g. from bonding data). This function overwrites any previously assigned
85   // LTK.
86   virtual bool AssignLongTermKey(const LTK& ltk) = 0;
87 
88   // TODO(fxbug.dev/42130294): Add function to register a BR/EDR link and SMP
89   // channel.
90 
91   // Attempt to raise the security level of the connection to the desired
92   // |level| and notify the result in |callback|.
93   //
94   // If the desired security properties are already satisfied, this procedure
95   // will succeed immediately (|callback| will be run with the current security
96   // properties).
97   //
98   // If a pairing procedure has already been initiated (either by us or the
99   // peer), the request will be queued and |callback| will be notified when the
100   // procedure completes. If the resulting security level does not satisfy
101   // |level|, pairing will be re-initiated. Note that this means security
102   // requests of different |level|s may not complete in the order they are made.
103   //
104   // If no pairing is in progress then the local device will initiate pairing.
105   //
106   // If pairing fails |callback| will be called with a |status| that represents
107   // the error.
108   using PairingCallback =
109       fit::function<void(Result<> status, const SecurityProperties& sec_props)>;
110   virtual void UpgradeSecurity(SecurityLevel level,
111                                PairingCallback callback) = 0;
112 
113   // Assign I/O capabilities. This aborts any ongoing pairing procedure and sets
114   // up the I/O capabilities to use for future requests.
115   virtual void Reset(IOCapability io_capability) = 0;
116 
117   // Abort all ongoing pairing procedures and notify pairing callbacks with the
118   // provided error.
Abort()119   void Abort() { Abort(ErrorCode::kUnspecifiedReason); }
120   virtual void Abort(ErrorCode ecode) = 0;
121 
122   // Returns the current security properties of the LE link.
security()123   const SecurityProperties& security() const { return le_sec_; }
124 
125   // Returns whether or not the SecurityManager is in bondable mode. Note that
126   // being in bondable mode does not guarantee that pairing will necessarily
127   // bond.
bondable_mode()128   BondableMode bondable_mode() const { return bondable_mode_; }
129 
130   // Sets the bondable mode of the SecurityManager. Any in-progress pairings
131   // will not be affected - if bondable mode needs to be reset during a pairing
132   // Reset() or Abort() must be called first.
set_bondable_mode(sm::BondableMode mode)133   void set_bondable_mode(sm::BondableMode mode) { bondable_mode_ = mode; }
134 
135   // Sets the LE Security mode of the SecurityManager - see enum definition for
136   // details of each mode. If a security upgrade is in-progress, only takes
137   // effect on the next security upgrade.
set_security_mode(gap::LESecurityMode mode)138   void set_security_mode(gap::LESecurityMode mode) { security_mode_ = mode; }
security_mode()139   gap::LESecurityMode security_mode() { return security_mode_; }
140 
141  protected:
142   SecurityManager(BondableMode bondable_mode,
143                   gap::LESecurityMode security_mode);
set_security(SecurityProperties security)144   void set_security(SecurityProperties security) { le_sec_ = security; }
145 
146  private:
147   // The operating bondable mode of the device.
148   BondableMode bondable_mode_ = BondableMode::Bondable;
149 
150   // The current GAP security mode of the device (v5.2 Vol. 3 Part C
151   // Section 10.2)
152   gap::LESecurityMode security_mode_ = gap::LESecurityMode::Mode1;
153 
154   // Current security properties of the LE-U link.
155   SecurityProperties le_sec_ = SecurityProperties();
156 };
157 
158 using SecurityManagerFactory =
159     std::function<decltype(sm::SecurityManager::Create)>;
160 
161 }  // namespace bt::sm
162