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