blob: 78af05e4c269ad68c6196977a27a040c993dbba1 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_SM_SECURITY_MANAGER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_SM_SECURITY_MANAGER_H_
#include <zircon/assert.h>
#include <memory>
#include <queue>
#include <variant>
#include "src/connectivity/bluetooth/core/bt-host/common/device_address.h"
#include "src/connectivity/bluetooth/core/bt-host/common/uint128.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/gap.h"
#include "src/connectivity/bluetooth/core/bt-host/hci-spec/link_key.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/connection.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/channel.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/delegate.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/pairing_phase.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/phase_1.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/phase_2_legacy.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/phase_2_secure_connections.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/phase_3.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/security_request_phase.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/smp.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/status.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/types.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/util.h"
namespace bt::sm {
// SecurityManager provides a per-peer interface to Security Manager Protocol functionality in v5.2
// Vol. 3 Part H. The peer device must be a LE or BR/EDR/LE device. SecurityManager is an abstract
// class so that SM-dependent code can dependency-inject test doubles in unit tests.
//
// The production implementation of SecurityManager is the SecurityManagerImpl class, which
// implements the functionality detailed in README.md. Clients should obtain a production object
// through the SecurityManager::Create factory function.
//
// A SecurityManager test double can be obtained through `TestSecurityManager::Create`.
//
/// See README.md for more overview of this library.
class SecurityManager {
public:
// Factory function which returns a production SecurityManager instance:
// |link|: The LE logical link over which pairing procedures occur.
// |smp|: The L2CAP LE SMP fixed channel that operates over |link|.
// |io_capability|: The initial I/O capability.
// |delegate|: Delegate which handles SMP interactions with the rest of the Bluetooth stack.
// |bondable_mode|: the operating bondable mode of the device (see v5.2, Vol. 3, Part C 9.4).
// |security_mode|: the security mode of this SecurityManager (see v5.2, Vol. 3, Part C 10.2).
static std::unique_ptr<SecurityManager> Create(fxl::WeakPtr<hci::Connection> link,
fbl::RefPtr<l2cap::Channel> smp,
IOCapability io_capability,
fxl::WeakPtr<Delegate> delegate,
BondableMode bondable_mode,
gap::LeSecurityMode security_mode);
virtual ~SecurityManager() = default;
// Assigns the requested |ltk| to this connection, adopting the security properties of |ltk|. If
// the local device is the master of the underlying link, then the link layer authentication
// procedure will be initiated.
//
// Returns false if a pairing procedure is in progress when this method is called. If the link
// layer authentication procedure fails, then the link will be disconnected by the controller
// (Vol 2, Part E, 7.8.24; hci::Connection guarantees this by severing the link directly).
//
// This function is mainly intended to assign an existing LTK to a connection (e.g. from bonding
// data). This function overwrites any previously assigned LTK.
virtual bool AssignLongTermKey(const LTK& ltk) = 0;
// TODO(fxbug.dev/52937): Add function to register a BR/EDR link and SMP channel.
// Attempt to raise the security level of the connection to the desired |level| and notify the
// result in |callback|.
//
// If the desired security properties are already satisfied, this procedure will succeed
// immediately (|callback| will be run with the current security properties).
//
// If a pairing procedure has already been initiated (either by us or the peer), the request will
// be queued and |callback| will be notified when the procedure completes. If the resulting
// security level does not satisfy |level|, pairing will be re-initiated. Note that this means
// security requests of different |level|s may not complete in the order they are made.
//
// If no pairing is in progress then the local device will initiate pairing.
//
// If pairing fails |callback| will be called with a |status| that represents the error.
using PairingCallback = fit::function<void(Status status, const SecurityProperties& sec_props)>;
virtual void UpgradeSecurity(SecurityLevel level, PairingCallback callback) = 0;
// Assign I/O capabilities. This aborts any ongoing pairing procedure and sets
// up the I/O capabilities to use for future requests.
virtual void Reset(IOCapability io_capability) = 0;
// Abort all ongoing pairing procedures and notify pairing callbacks with the provided error.
void Abort() { Abort(ErrorCode::kUnspecifiedReason); }
virtual void Abort(ErrorCode ecode) = 0;
// Returns the current security properties of the LE link.
const SecurityProperties& security() const { return le_sec_; }
// Returns whether or not the SecurityManager is in bondable mode. Note that being in bondable
// mode does not guarantee that pairing will necessarily bond.
BondableMode bondable_mode() const { return bondable_mode_; }
// Sets the bondable mode of the SecurityManager. Any in-progress pairings will not be affected -
// if bondable mode needs to be reset during a pairing Reset() or Abort() must be called first.
void set_bondable_mode(sm::BondableMode mode) { bondable_mode_ = mode; }
// Sets the LE Security mode of the SecurityManager - see enum definition for details of each
// mode. If a security upgrade is in-progress, only takes effect on the next security upgrade.
void set_security_mode(gap::LeSecurityMode mode) { security_mode_ = mode; }
gap::LeSecurityMode security_mode() { return security_mode_; }
protected:
SecurityManager(BondableMode bondable_mode, gap::LeSecurityMode security_mode);
void set_security(SecurityProperties security) { le_sec_ = security; }
private:
// The operating bondable mode of the device.
BondableMode bondable_mode_ = BondableMode::Bondable;
// The current GAP security mode of the device (v5.2 Vol. 3 Part C Section 10.2)
gap::LeSecurityMode security_mode_ = gap::LeSecurityMode::Mode1;
// Current security properties of the LE-U link.
SecurityProperties le_sec_ = SecurityProperties();
};
using SecurityManagerFactory = std::function<decltype(sm::SecurityManager::Create)>;
} // namespace bt::sm
#endif // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_SM_SECURITY_MANAGER_H_