This is an automated email from the ASF dual-hosted git repository. rymek pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
The following commit(s) were added to refs/heads/master by this push: new 4ad4395 ble_sm: add Secure Connections Only mode 4ad4395 is described below commit 4ad4395d7ca0de9607f766700f5b85708ae7b7a1 Author: Krzysztof Kopyściński <krzysztof.kopyscin...@codecoup.pl> AuthorDate: Thu Mar 18 13:15:02 2021 +0100 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. --- nimble/host/src/ble_att_svr.c | 10 ++++++++ nimble/host/src/ble_sm.c | 25 +++++++++++++++++-- nimble/host/syscfg.yml | 28 ++++++++++++++++++++++ porting/examples/linux/include/syscfg/syscfg.h | 8 +++++++ .../examples/linux_blemesh/include/syscfg/syscfg.h | 8 +++++++ porting/examples/nuttx/include/syscfg/syscfg.h | 8 +++++++ porting/nimble/include/syscfg/syscfg.h | 8 +++++++ porting/npl/riot/include/syscfg/syscfg.h | 8 +++++++ 8 files changed, 101 insertions(+), 2 deletions(-) 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_check_perms(uint16_t conn_handle, int is_read, } 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 @@ err: } 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 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, 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 @@ ble_sm_pair_rsp_rx(uint16_t conn_handle, struct os_mbuf **om, } 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 @@ syscfg.defs: 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