Pairing not working when "LE Secure connection only" mode is selected (nimble)
Checklist
- [x] Checked the issue tracker for similar issues to ensure this is not a duplicate
- [x] Read the documentation to confirm the issue is not addressed there and your configuration is set correctly
- [x] Tested with the latest version to ensure the issue hasn't been fixed
How often does this bug occurs?
always
Expected behavior
Pairing should work even when the "LE Secure connection only" mode (via parameter CONFIG_BT_NIMBLE_SM_SC_ONLY) is selected.
Actual behavior (suspected bug)
Pairing does not work when the "LE Secure connection only" mode is selected (via parameter CONFIG_BT_NIMBLE_SM_SC_ONLY).
The pairing request from initiator is received, but the processing of it stops at some point
The reason behind is a wrong implementation of security checks in function ble_sm_pair_req_rx from file ble_sm.c. As one can see below, if condition ble_hs_cfg.sm_sc_only is met, the code inside the last else section
won't be executed and unfortunately, it is the place where the pairing request will be further processed.
`
...
} else if (ble_hs_cfg.sm_sc_only) {
/* Fail if Secure Connections Only mode is on and remote does not
* meet key size requirements - MITM was checked in last step.
* Fail if SC is not supported by peer or key size is too small
*/
if (!(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) {
res->sm_err = BLE_SM_ERR_AUTHREQ;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ);
} else if (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX) {
res->sm_err = BLE_SM_ERR_ENC_KEY_SZ;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ);
}
}
...
} else {
/* The request looks good. Precalculate our pairing response and
* determine some properties of the imminent link. We need this
* information in case this is a repeated pairing attempt (i.e., we
* are already bonded to this peer). In that case, we include the
* information in a notification to the app.
*/
ble_sm_pair_rsp_fill(proc);
ble_sm_pair_cfg(proc);
proc_flags = proc->flags;
key_size = proc->key_size;
res->execute = 1;
}
`
The fix is rather simple, just modify the condition with someting like:
`
...
} else if (ble_hs_cfg.sm_sc_only && !(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) {
res->sm_err = BLE_SM_ERR_AUTHREQ;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ);
} else if (ble_hs_cfg.sm_sc_only && (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX)) {
res->sm_err = BLE_SM_ERR_ENC_KEY_SZ;
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ);
}
...
} else {
/* The request looks good. Precalculate our pairing response and
* determine some properties of the imminent link. We need this
* information in case this is a repeated pairing attempt (i.e., we
* are already bonded to this peer). In that case, we include the
* information in a notification to the app.
*/
ble_sm_pair_rsp_fill(proc);
ble_sm_pair_cfg(proc);
proc_flags = proc->flags;
key_size = proc->key_size;
res->execute = 1;
}
`
Error logs or terminal output
Steps to reproduce the behavior
- Build the bleprph sample application with esp-idf 5.3.2.
- Configure the application with DisplayYesNo, bonding, MITM and SC
- Configure also nimble SM options
CONFIG_BT_NIMBLE_SM_SC_ONLYandCONFIG_BT_NIMBLE_SM_LVto 4 - Launch the application and try to pair with any BLE client
Project release version
1.6.0
System architecture
Intel/AMD 64-bit (modern PC, older Mac)
Operating system
Linux
Operating system version
Ubuntu-20.4
Shell
Bash
Additional context
No response
Hi @fgaultierD4 ,
Please find patch that should help fix your issue. The fix goes in path $IDF_PATH/components/bt/host/nimble/nimble .
Hi @rahult-github ,
Thanks for the quick patch. There is however one small issue, with this patch, because there are actually two ways of activating the "LE Secure Connection Only" mode:
- By setting configuration parameter
CONFIG_BT_NIMBLE_SM_SC_ONLYto 1 - Or by manually setting in code the value of field
ble_hs_cfg.sm_sc_onlytotrue
Remark that by choosing option 1, you get also the field of option 2 set to true, because the field is initialized with .sm_sc_only = MYNEWT_VAL(BLE_SM_SC_ONLY), in file ble_hs_cfg.c.
The opposite is however not true, if you manually set field ble_hs_cfg.sm_sc_only to true, the parameter MYNEWT_VAL(BLE_SM_SC_ONLY) won't be set to true.
Change has been merged .Closing