blob: 7aa9cc625566fbfb3742d340ed13376a0abb4f79 [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 GARNET_DRIVERS_BLUETOOTH_LIB_SM_TYPES_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_SM_TYPES_H_
#include <optional>
#include "garnet/drivers/bluetooth/lib/common/uint128.h"
#include "garnet/drivers/bluetooth/lib/hci/hci_constants.h"
#include "garnet/drivers/bluetooth/lib/hci/link_key.h"
#include "garnet/drivers/bluetooth/lib/sm/smp.h"
namespace btlib {
namespace sm {
// Represents the features exchanged during Pairing Phase 1.
struct PairingFeatures final {
PairingFeatures();
PairingFeatures(bool initiator, bool sc, PairingMethod method,
uint8_t enc_key_size, KeyDistGenField local_kd,
KeyDistGenField remote_kd);
// True if the local device is in the "initiator" role.
bool initiator;
// True if LE Secure Connections pairing should be used. Otherwise, LE Legacy
// Pairing should be used.
bool secure_connections;
// Indicates the key generation model used for Phase 2.
PairingMethod method;
// The negotiated encryption key size.
uint8_t encryption_key_size;
// The keys that we must distribute to the peer.
KeyDistGenField local_key_distribution;
// The keys that will be distributed to us by the peer.
KeyDistGenField remote_key_distribution;
};
enum class SecurityLevel {
// No encryption
kNoSecurity = 0,
// Encrypted without MITM protection (unauthenticated)
kEncrypted = 1,
// Encrypted with MITM protection (authenticated)
kAuthenticated = 2,
};
// Returns a string representation of |level| for debug messages.
const char* LevelToString(SecurityLevel level);
// Represents the security properties of a key. The security properties of a
// connection's LTK defines the security properties of the connection.
class SecurityProperties final {
public:
SecurityProperties();
SecurityProperties(SecurityLevel level, size_t enc_key_size,
bool secure_connections);
// Build from a BR/EDR Link Key that resulted from pairing. |lk_type| should
// not be kChangedCombination, because that means that the link key is the
// same type as before it was changed.
//
// Legacy pairing keys will be considered to have security level kNoSecurity
// because legacy pairing is superceded by Secure Simple Pairing in Core Spec
// v2.1 + EDR in 2007. Backwards compatiblity is optional per v5.0, Vol 3,
// Part C, Section 5. Furthermore, the last Core Spec with only legacy pairing
// (v2.0 + EDR) is to be withdrawn by Bluetooth SIG on 2019-01-28.
explicit SecurityProperties(hci::LinkKeyType lk_type);
SecurityLevel level() const { return level_; }
size_t enc_key_size() const { return enc_key_size_; }
bool secure_connections() const { return sc_; }
bool authenticated() const { return level_ == SecurityLevel::kAuthenticated; }
// Returns a string representation of these properties.
std::string ToString() const;
// Compare two properties for equality.
bool operator==(const SecurityProperties& other) const {
return level_ == other.level_ && enc_key_size_ == other.enc_key_size_ &&
sc_ == other.sc_;
}
private:
SecurityLevel level_;
size_t enc_key_size_;
bool sc_;
};
// Represents a reusable long term key for a specific transport.
class LTK final {
public:
LTK() = default;
LTK(const SecurityProperties& security, const hci::LinkKey& key);
const SecurityProperties& security() const { return security_; }
const hci::LinkKey& key() const { return key_; }
bool operator==(const LTK& other) const {
return security() == other.security() && key() == other.key();
}
private:
SecurityProperties security_;
hci::LinkKey key_;
};
// Represents a 128-bit key.
class Key final {
public:
Key() = default;
Key(const SecurityProperties& security, const common::UInt128& value);
const SecurityProperties& security() const { return security_; }
const common::UInt128& value() const { return value_; }
bool operator==(const Key& other) const {
return security() == other.security() && value() == other.value();
}
private:
SecurityProperties security_;
common::UInt128 value_;
};
// Container for LE pairing data.
struct PairingData final {
// The identity address.
std::optional<common::DeviceAddress> identity_address;
// The long term key used for link encryption.
std::optional<sm::LTK> ltk;
// The identity resolving key used to resolve RPAs to |identity|.
std::optional<sm::Key> irk;
// The connection signature resolving key used in LE security mode 2.
std::optional<sm::Key> csrk;
bool operator==(const PairingData& other) const {
return identity_address == other.identity_address && ltk == other.ltk &&
irk == other.irk && csrk == other.csrk;
}
};
} // namespace sm
} // namespace btlib
#endif // GARNET_DRIVERS_BLUETOOTH_LIB_SM_TYPES_H_