aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-11-12 10:13:26 +0100
committerSven Gothel <[email protected]>2020-11-12 10:13:26 +0100
commit6e7502a297204a6acb375ea4ad8f35d5658634db (patch)
tree927fd2ef1e6a47f1c1abab207210abe9205a7c72
parentaf6b2aad01c23231830de7ad4c9df7f1c40fc243 (diff)
Add SMPPairingState and PairingMode mapping: getBestPairingMode(SMPAuthReqs, SMPIOCapability, SMPOOBDataFlag), getComplyingPairingModes(SMPAuthReqs)
-rw-r--r--api/direct_bt/SMPTypes.hpp74
-rw-r--r--src/direct_bt/SMPTypes.cpp74
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) \