ble_sm: add Secure Connections Only mode
Added mode allowing to enforce pairing only in SC mode 1 level 4. This mode is required to pass
GAP/SEC/SEM/BI testcases. Added BLE_SM_SC_LVL config to allow pairing only in selected levels.
diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c
index 0cfbc7d..7b2611a 100644
--- a/nimble/host/src/ble_att_svr.c
+++ b/nimble/host/src/ble_att_svr.c
@@ -284,6 +284,16 @@
}
ble_att_svr_get_sec_state(conn_handle, &sec_state);
+ /* In SC Only mode all characteristics requiring security
+ * require it on level 4
+ */
+ if (MYNEWT_VAL(BLE_SM_SC_ONLY)) {
+ if (sec_state.key_size != 128 ||
+ !sec_state.authenticated ||
+ !sec_state.encrypted) {
+ return BLE_ATT_ERR_INSUFFICIENT_KEY_SZ;
+ }
+ }
if ((enc || authen) && !sec_state.encrypted) {
ble_hs_lock();
conn = ble_hs_conn_find(conn_handle);
diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c
index b4e8096..c63af40 100644
--- a/nimble/host/src/ble_sm.c
+++ b/nimble/host/src/ble_sm.c
@@ -1726,17 +1726,23 @@
}
static bool
-ble_sm_verify_auth_requirements(uint8_t authreq)
+ble_sm_verify_auth_requirements(uint8_t cmd)
{
/* For now we check only SC only mode. I.e.: when remote indicates
* to not support SC pairing, let us make sure legacy pairing is supported
* on our side. If not, we can fail right away.
*/
- if (!(authreq & BLE_SM_PAIR_AUTHREQ_SC)) {
+ if (!(cmd & BLE_SM_PAIR_AUTHREQ_SC)) {
if (MYNEWT_VAL(BLE_SM_LEGACY) == 0) {
return false;
}
}
+ /* Fail if Secure Connections level forces MITM protection and remote does not
+ * support it
+ */
+ if (MYNEWT_VAL(BLE_SM_SC_LVL) >= 3 && !(cmd & BLE_SM_PAIR_AUTHREQ_MITM)) {
+ return false;
+ }
return true;
}
@@ -1817,12 +1823,21 @@
if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) {
res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP);
+ } else if (MYNEWT_VAL(BLE_SM_SC_LVL) == 1) {
+ res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP;
+ res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP);
} else if (req->max_enc_key_size < BLE_SM_PAIR_KEY_SZ_MIN) {
res->sm_err = BLE_SM_ERR_ENC_KEY_SZ;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ);
} else if (req->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) {
res->sm_err = BLE_SM_ERR_INVAL;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL);
+ } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX)) {
+ /* Fail if Secure Connections Only mode is on and remote does not meet
+ * key size requirements - MITM was checked in last step
+ */
+ res->sm_err = BLE_SM_ERR_ENC_KEY_SZ;
+ res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ);
} else if (!ble_sm_verify_auth_requirements(req->authreq)) {
res->sm_err = BLE_SM_ERR_AUTHREQ;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ);
@@ -1886,6 +1901,12 @@
} else if (rsp->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) {
res->sm_err = BLE_SM_ERR_INVAL;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL);
+ } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && (rsp->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX)) {
+ /* Fail if Secure Connections Only mode is on and remote does not meet
+ * key size requirements - MITM was checked in last step
+ */
+ res->sm_err = BLE_SM_ERR_ENC_KEY_SZ;
+ res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ);
} else if (!ble_sm_verify_auth_requirements(rsp->authreq)) {
res->sm_err = BLE_SM_ERR_AUTHREQ;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ);
diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml
index e72e8d5..c814ba5 100644
--- a/nimble/host/syscfg.yml
+++ b/nimble/host/syscfg.yml
@@ -133,6 +133,34 @@
description: 'Security manager secure connections (4.2).'
value: 0
+ BLE_SM_SC_ONLY:
+ description: >
+ Force global Secure Connections Pairing Only mode. This means
+ that only SC pairing mode 1 level 4 shall be used, and all
+ characteristics will require it to access, except these
+ requiring mode 1 level 1.
+ value: 0
+ restrictions:
+ - 'BLE_SM_SC_LVL == 4 if 1'
+
+ BLE_SM_SC_LVL:
+ description: >
+ Force global Secure Connections mode 1 level. This level
+ describes requirements for pairing response/request received
+ to accept pairing:
+ - 1 - do not pair; only access to characteristics with no
+ authentication requirements is granted
+ - 2 - allow to pair despite MITM being on or off
+ - 3 - allow to pair only when MITM protection is on
+ - 4 - allow to pair only when 128 bit key is used and MITM is on
+ When set to 0 level is no forced and pairing is allowed for all
+ requests/responses with valid values (for example pairing will be
+ rejected with key longer than 128 bits). Successful pairing with
+ insufficient security will still cause denying access to protected
+ GATT characteristics.
+ value: 0
+ range: 0..4
+
BLE_SM_MAX_PROCS:
description: >
The maximum number of concurrent security manager procedures.
diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h
index 99939f2..8363336 100644
--- a/porting/examples/linux/include/syscfg/syscfg.h
+++ b/porting/examples/linux/include/syscfg/syscfg.h
@@ -735,6 +735,14 @@
#define MYNEWT_VAL_BLE_SM_SC (0)
#endif
+#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY
+#define MYNEWT_VAL_BLE_SM_SC_ONLY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_SC_LVL
+#define MYNEWT_VAL_BLE_SM_SC_LVL (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS
#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0)
#endif
diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h
index 9aac106..a3df8b6 100644
--- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h
+++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h
@@ -738,6 +738,14 @@
#define MYNEWT_VAL_BLE_SM_SC (1)
#endif
+#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY
+#define MYNEWT_VAL_BLE_SM_SC_ONLY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_SC_LVL
+#define MYNEWT_VAL_BLE_SM_SC_LVL (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS
#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0)
#endif
diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h
index ff73312..c8ad4e4 100644
--- a/porting/examples/nuttx/include/syscfg/syscfg.h
+++ b/porting/examples/nuttx/include/syscfg/syscfg.h
@@ -785,6 +785,14 @@
#define MYNEWT_VAL_BLE_SM_SC (1)
#endif
+#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY
+#define MYNEWT_VAL_BLE_SM_SC_ONLY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_SC_LVL
+#define MYNEWT_VAL_BLE_SM_SC_LVL (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS
#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0)
#endif
diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h
index c4b70db..cfc10ed 100644
--- a/porting/nimble/include/syscfg/syscfg.h
+++ b/porting/nimble/include/syscfg/syscfg.h
@@ -734,6 +734,14 @@
#define MYNEWT_VAL_BLE_SM_SC (0)
#endif
+#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY
+#define MYNEWT_VAL_BLE_SM_SC_ONLY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_SC_LVL
+#define MYNEWT_VAL_BLE_SM_SC_LVL (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS
#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0)
#endif
diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h
index f7406f0..e3d282e 100644
--- a/porting/npl/riot/include/syscfg/syscfg.h
+++ b/porting/npl/riot/include/syscfg/syscfg.h
@@ -1487,6 +1487,14 @@
#define MYNEWT_VAL_BLE_SM_SC (0)
#endif
+#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY
+#define MYNEWT_VAL_BLE_SM_SC_ONLY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_SC_LVL
+#define MYNEWT_VAL_BLE_SM_SC_LVL (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS
#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0)
#endif