diff options
author | Sven Gothel <[email protected]> | 2020-11-12 10:13:26 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-11-12 10:13:26 +0100 |
commit | 6e7502a297204a6acb375ea4ad8f35d5658634db (patch) | |
tree | 927fd2ef1e6a47f1c1abab207210abe9205a7c72 | |
parent | af6b2aad01c23231830de7ad4c9df7f1c40fc243 (diff) |
Add SMPPairingState and PairingMode mapping: getBestPairingMode(SMPAuthReqs, SMPIOCapability, SMPOOBDataFlag), getComplyingPairingModes(SMPAuthReqs)
-rw-r--r-- | api/direct_bt/SMPTypes.hpp | 74 | ||||
-rw-r--r-- | src/direct_bt/SMPTypes.cpp | 74 |
2 files changed, 148 insertions, 0 deletions
diff --git a/api/direct_bt/SMPTypes.hpp b/api/direct_bt/SMPTypes.hpp index 87bb8c4f..a91be5a2 100644 --- a/api/direct_bt/SMPTypes.hpp +++ b/api/direct_bt/SMPTypes.hpp @@ -36,6 +36,7 @@ #include <jau/basic_types.hpp> #include "OctetTypes.hpp" +#include "BTTypes.hpp" /** * - - - - - - - - - - - - - - - @@ -91,6 +92,59 @@ namespace direct_bt { /** + * SMP Pairing Process state definition + * <pre> + * Vol 3, Part H (SM): APPENDIX C MESSAGE SEQUENCE CHARTS + * </pre> + * @see PairingMode + */ + enum class SMPPairingState : uint8_t { + /** No pairing in process. Current PairingMode shall be PairingMode::NONE. */ + NONE = 0, + + /** Pairing failed. Current PairingMode shall be PairingMode::NONE. */ + FAILED = 1, + + /** + * Phase 0: Pairing requested by responding (slave) device via SMPSecurityReqMsg.<br> + * Signals initiating (host) device to start the Pairing Feature Exchange.<br> + * Current PairingMode shall be PairingMode::NEGOTIATING. + */ + REQUESTED_BY_RESPONDER = 2, + + /** + * Phase 1: Pairing requested by initiating (master) device via SMPPairingMsg.<br> + * Starts the Pairing Feature Exchange.<br> + * Current PairingMode shall be PairingMode::NEGOTIATING. + */ + FEATURE_EXCHANGE_STARTED = 3, + + /** + * Phase 1: Pairing responded by responding (slave) device via SMPPairingMsg.<br> + * Completes the Pairing Feature Exchange. Optional user input shall be given for Phase 2.<br> + * Current PairingMode shall be set to a definitive value. + */ + FEATURE_EXCHANGE_COMPLETED = 4, + + /** Phase 2: Authentication (MITM) PASSKEY expected, see PairingMode::PASSKEY_ENTRY */ + PASSKEY_EXPECTED = 5, + /** Phase 2: Authentication (MITM) Numeric Comparison Reply expected, see PairingMode::NUMERIC_COMPARISON */ + NUMERIC_REPLY_EXPECTED = 6, + /** Phase 2: Authentication (MITM) OOB data expected, see PairingMode::OUT_OF_BAND */ + OOB_EXPECTED = 7, + + /** Phase 2: Pairing process started by SMPPairConfirmMsg or SMPPairPubKeyMsg (LE Secure Connection) exchange between initiating (master) and responding (slave) device. */ + PROCESS_STARTED = 8, + + /** + * Phase 2: Pairing process is completed by responding (slave) device sending SMPPairRandMsg.<br> + * The link is assumed to be encrypted from here on. + */ + PROCESS_COMPLETED = 9 + }; + std::string getSMPPairingStateString(const SMPPairingState state) noexcept; + + /** * Vol 3, Part H, 2.3.2 IO capabilities */ enum class SMPIOCapability : uint8_t { @@ -221,6 +275,26 @@ namespace direct_bt { std::string getSMPAuthReqMaskString(const SMPAuthReqs mask) noexcept; /** + * Returns the PairingMode derived from the given SMPAuthReqs + * <pre> + * BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.1 Security Properties + * BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.5.1 Selecting key generation method + * BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.5.6.2 Authentication stage 1 – Just Works or Numeric Comparison + * BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.5.6.3 Authentication stage 1 – Passkey Entry + * BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.5.6.4 Authentication stage 1 – Out of Band + * </pre> + */ + PairingMode getBestPairingMode(const SMPAuthReqs mask, const SMPIOCapability ioCap, const SMPOOBDataFlag oobFlag) noexcept; + + /** + * Returns a list of complying PairingMode derived from the given SMPAuthReqs + * <pre> + * BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.1 Security Properties + * </pre> + */ + std::vector<PairingMode> getComplyingPairingModes(const SMPAuthReqs mask) noexcept; + + /** * Handles the Security Manager Protocol (SMP) using Protocol Data Unit (PDU) * encoded messages over L2CAP channel. * <p> diff --git a/src/direct_bt/SMPTypes.cpp b/src/direct_bt/SMPTypes.cpp index 0984bc40..a8a859e9 100644 --- a/src/direct_bt/SMPTypes.cpp +++ b/src/direct_bt/SMPTypes.cpp @@ -36,6 +36,29 @@ using namespace direct_bt; +#define PAIRSTATE_ENUM(X) \ + X(NONE) \ + X(FAILED) \ + X(REQUESTED_BY_RESPONDER) \ + X(FEATURE_EXCHANGE_STARTED) \ + X(FEATURE_EXCHANGE_COMPLETED) \ + X(PASSKEY_EXPECTED) \ + X(NUMERIC_REPLY_EXPECTED) \ + X(OOB_EXPECTED) \ + X(PROCESS_STARTED) \ + X(PROCESS_COMPLETED) + +#define CASE_TO_STRING_PAIRSTATE(V) case SMPPairingState::V: return #V; + +std::string direct_bt::getSMPPairingStateString(const SMPPairingState state) noexcept { + switch(state) { + PAIRSTATE_ENUM(CASE_TO_STRING_PAIRSTATE) + default: ; // fall through intended + } + return "Unknown SMP PairingState"; +} + + #define AUTHREQ_ENUM(X) \ X(NONE) \ X(BONDING) \ @@ -73,6 +96,57 @@ std::string direct_bt::getSMPAuthReqMaskString(const SMPAuthReqs mask) noexcept return out; } +PairingMode direct_bt::getBestPairingMode(const SMPAuthReqs mask, const SMPIOCapability ioCap, const SMPOOBDataFlag oobFlag) noexcept { + // BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.1 Security Properties + // BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.5.1 Selecting key generation method Table 2.6 + + // Authenticated MITM + if( SMPAuthReqs::NONE != ( mask & SMPAuthReqs::MITM ) ) { + // One of: + // - PairingMode::PASSKEY_ENTRY best + // - PairingMode::NUMERIC_COMPARISON good + // - PairingMode::OUT_OF_BAND good, depending on the OOB data + if( SMPOOBDataFlag::OOB_AUTH_DATA_REMOTE_PRESENT == oobFlag ) { + return PairingMode::OUT_OF_BAND; + } + switch( ioCap ) { + case SMPIOCapability::KEYBOARD_DISPLAY: + return PairingMode::PASSKEY_ENTRY; + + case SMPIOCapability::DISPLAY_YES_NO: + return PairingMode::NUMERIC_COMPARISON; + + case SMPIOCapability::DISPLAY_ONLY: + [[fallthrough]]; + case SMPIOCapability::KEYBOARD_ONLY: + [[fallthrough]]; + case SMPIOCapability::NO_INPUT_NO_OUTPUT: + [[fallthrough]]; + default: + // impossible to comply + return PairingMode::NONE; + } + } + // Unauthenticated pairing + return PairingMode::JUST_WORKS; +} + +std::vector<PairingMode> direct_bt::getComplyingPairingModes(const SMPAuthReqs mask) noexcept { + // BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.1 Security Properties + // BT Core Spec v5.2: Vol 3, Part H (SM): 2.3.5.1 Selecting key generation method Table 2.6 + std::vector<PairingMode> res; + + // Authenticated MITM + if( SMPAuthReqs::NONE != ( mask & SMPAuthReqs::MITM ) ) { + res.push_back(PairingMode::PASSKEY_ENTRY); + res.push_back(PairingMode::NUMERIC_COMPARISON); + res.push_back(PairingMode::OUT_OF_BAND); + return res; + } + // Unauthenticated pairing + res.push_back(PairingMode::JUST_WORKS); + return res; +} #define OPCODE_ENUM(X) \ X(UNDEFINED) \ |