• 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 
18 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
19 #include "pw_bluetooth_sapphire/internal/host/gap/peer.h"
20 #include "pw_bluetooth_sapphire/internal/host/hci/bredr_connection.h"
21 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connection.h"
22 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel.h"
23 #include "pw_bluetooth_sapphire/internal/host/sm/delegate.h"
24 #include "pw_bluetooth_sapphire/internal/host/sm/error.h"
25 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
26 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
27 
28 namespace bt::sm {
29 
30 // SecurityManager provides a per-peer interface to Security Manager Protocol
31 // functionality in v5.2 Vol. 3 Part H. The peer device must be a LE or
32 // BR/EDR/LE device. SecurityManager is an abstract class so that SM-dependent
33 // code can dependency-inject test doubles in unit tests.
34 //
35 // The production implementation of SecurityManager is the SecurityManagerImpl
36 // class, which implements the functionality detailed in README.md. Clients
37 // should obtain a production object through the SecurityManager::Create factory
38 // function.
39 //
40 // A SecurityManager test double can be obtained through
41 // `TestSecurityManager::Create`.
42 //
43 /// See README.md for more overview of this library.
44 class SecurityManager {
45  public:
46   // Factory function which returns a production LE SecurityManager instance:
47   // |link|: The LE logical link over which pairing procedures occur.
48   // |smp|: The L2CAP LE SMP fixed channel that operates over |link|.
49   // |io_capability|: The initial I/O capability.
50   // |delegate|: Delegate which handles SMP interactions with the rest of the
51   // Bluetooth stack.
52   // |bondable_mode|: the operating bondable mode of the device
53   // (see v5.2, Vol. 3, Part C 9.4).
54   // |security_mode|: the security mode of this SecurityManager (see v5.2, Vol.
55   // 3, Part C 10.2).
56   // |peer|: The peer that the SMP fixed channel corresponds to.
57   static std::unique_ptr<SecurityManager> CreateLE(
58       hci::LowEnergyConnection::WeakPtr link,
59       l2cap::Channel::WeakPtr smp,
60       IOCapability io_capability,
61       Delegate::WeakPtr delegate,
62       BondableMode bondable_mode,
63       gap::LESecurityMode security_mode,
64       pw::async::Dispatcher& dispatcher,
65       bt::gap::Peer::WeakPtr peer);
66 
67   // Factory function that returns a production BR/EDR SecurityManager object.
68   // |link|: The BR/EDR link over which the SMP channel operates.
69   // |smp|: The L2CAP BR/EDR SMP fixed channel.
70   // |delegate|: Delegate which handles SMP interactions with the rest of the
71   // Bluetooth stack.
72   // |is_controller_remote_public_key_validation_supported|: Indicates
73   // controller support for remote public key validation. |peer|: The peer that
74   // the link and SMP channel correspond to.
75   static std::unique_ptr<SecurityManager> CreateBrEdr(
76       hci::BrEdrConnection::WeakPtr link,
77       l2cap::Channel::WeakPtr smp,
78       Delegate::WeakPtr delegate,
79       bool is_controller_remote_public_key_validation_supported,
80       pw::async::Dispatcher& dispatcher,
81       bt::gap::Peer::WeakPtr peer);
82 
83   virtual ~SecurityManager() = default;
84 
85   // Attempt to raise the security level of the connection to the desired
86   // |level| and notify the result in |callback|.
87   //
88   // If the desired security properties are already satisfied, this procedure
89   // will succeed immediately (|callback| will be run with the current security
90   // properties).
91   //
92   // If a pairing procedure has already been initiated (either by us or the
93   // peer), the request will be queued and |callback| will be notified when the
94   // procedure completes. If the resulting security level does not satisfy
95   // |level|, pairing will be re-initiated. Note that this means security
96   // requests of different |level|s may not complete in the order they are made.
97   //
98   // If no pairing is in progress then the local device will initiate pairing.
99   //
100   // If pairing fails |callback| will be called with a |status| that represents
101   // the error.
102   using PairingCallback =
103       fit::function<void(Result<> status, const SecurityProperties& sec_props)>;
104   virtual void UpgradeSecurity(SecurityLevel level,
105                                PairingCallback callback) = 0;
106 
107   // Attempt to perform the BR/EDR cross-transport key derivation procedure.
108   // |callback| will be called on completion or failure. On success, the LE LTK
109   // will be delivered to Delegate::OnNewPairingData() in
110   // PairingData::cross_transport_key. Only 1 CTKD procedure is allowed at a
111   // time. Additional calls will return an error. Only the Central can initiate
112   // CTKD.
113   using CrossTransportKeyDerivationResultCallback =
114       fit::callback<void(Result<> result)>;
115   virtual void InitiateBrEdrCrossTransportKeyDerivation(
116       CrossTransportKeyDerivationResultCallback callback) = 0;
117 
118   // Assign I/O capabilities. This aborts any ongoing pairing procedure and sets
119   // up the I/O capabilities to use for future requests.
120   virtual void Reset(IOCapability io_capability) = 0;
121 
122   // Abort all ongoing pairing procedures and notify pairing callbacks with the
123   // provided error.
Abort()124   void Abort() { Abort(ErrorCode::kUnspecifiedReason); }
125   virtual void Abort(ErrorCode ecode) = 0;
126 
127   // Returns the current security properties of the LE link.
security()128   const SecurityProperties& security() const {
129     return low_energy_security_properties_;
130   }
131 
132   // Returns whether or not the SecurityManager is in bondable mode. Note that
133   // being in bondable mode does not guarantee that pairing will necessarily
134   // bond.
bondable_mode()135   BondableMode bondable_mode() const { return low_energy_bondable_mode_; }
136 
137   // Sets the bondable mode of the SecurityManager. Any in-progress pairings
138   // will not be affected - if bondable mode needs to be reset during a pairing
139   // Reset() or Abort() must be called first.
set_bondable_mode(sm::BondableMode mode)140   void set_bondable_mode(sm::BondableMode mode) {
141     low_energy_bondable_mode_ = mode;
142   }
143 
144   // Sets the LE Security mode of the SecurityManager - see enum definition for
145   // details of each mode. If a security upgrade is in-progress, only takes
146   // effect on the next security upgrade.
set_security_mode(gap::LESecurityMode mode)147   void set_security_mode(gap::LESecurityMode mode) {
148     low_energy_security_mode_ = mode;
149   }
security_mode()150   gap::LESecurityMode security_mode() { return low_energy_security_mode_; }
151 
152  protected:
153   SecurityManager(BondableMode bondable_mode,
154                   gap::LESecurityMode security_mode);
set_security(SecurityProperties security)155   void set_security(SecurityProperties security) {
156     low_energy_security_properties_ = security;
157   }
158 
159  private:
160   // The operating bondable mode of the device.
161   BondableMode low_energy_bondable_mode_ = BondableMode::Bondable;
162 
163   // The current GAP security mode of the device (v5.2 Vol. 3 Part C
164   // Section 10.2)
165   gap::LESecurityMode low_energy_security_mode_ = gap::LESecurityMode::Mode1;
166 
167   // Current security properties of the LE-U link.
168   SecurityProperties low_energy_security_properties_ = SecurityProperties();
169 };
170 
171 using SecurityManagerFactory =
172     std::function<decltype(sm::SecurityManager::CreateLE)>;
173 
174 using BrEdrSecurityManagerFactory =
175     std::function<decltype(sm::SecurityManager::CreateBrEdr)>;
176 
177 }  // namespace bt::sm
178