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