Bonding Troubles

I've been working for months to try and figure out exactly how to get my application to bond the way I want it to.

I'm using nrf connect sdk 2.4.2 on an nrf52832.  I used the nordic uart service peripheral project as a base.  The uart service works great but I'm having a great amount of difficulty adding any measure of security to the project.

I would like the device to behave like this:

  1. Only permit usage of application characteristics (TX and RX) when bonded with the connected phone
  2. Only permit bonding when a user presses a button on the device
  3. When bonding is started do not present a passcode dialog to the user on the phone

I gather the best way to do this is something like the following though i've tried many permutations:

prj.conf:

CONFIG_BT_NUS_SECURITY_ENABLED=y
CONFIG_BT_NUS_AUTHEN=y
CONFIG_BT_SMP_APP_PAIRING_ACCEPT=n
CONFIG_BT_SMP=y
CONFIG_BT_FIXED_PASSKEY=n
CONFIG_BT_BONDABLE=y
CONFIG_BT_KEYS_OVERWRITE_OLDEST=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_DEBUG_SMP=y
CONFIG_BT_SMP_ENFORCE_MITM=n
CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y
main.c:
{
static void connected(struct bt_conn *conn, uint8_t err)

    char addr[BT_ADDR_LE_STR_LEN];

    if (err) {
        LOG_ERR("Connection failed (err %u)", err);
        return;
    }

    connection_status = TRUE;
    current_conn = bt_conn_ref(conn);

    bt_conn_set_security(current_conn, BT_SECURITY_L2);
    if (err) {
        LOG_ERR("Failed to set security: %d", err);
    }
   
    exchange_mtu(conn);

    bt_conn_le_param_update(conn, &conn_params);
}
struct bt_conn_auth_cb conn_auth_callbacks = {
#if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
    .pairing_accept = NULL,
#endif
    .passkey_display = NULL,
#if defined(CONFIG_BT_PASSKEY_KEYPRESS)
    .passkey_display_keypress = NULL,
#endif
    .passkey_entry = NULL,
    .passkey_confirm = NULL,
    .oob_data_request = NULL,
    .cancel = auth_cancel,
    .pairing_confirm = auth_pairing_confirm,
#if defined(CONFIG_BT_BREDR)
    .pincode_entry = NULL,
#endif
};
 
static void auth_pairing_confirm(struct bt_conn *conn)
{
    LOG_ERR("Pairing confirmation requested");
    auth_conn = bt_conn_ref(conn);
    awaiting_pairing_confirm = true;
    pair_timeout = PAIR_TIMEOUT_INIT;
}
Then I've implemented a button press I'm sure is working:
void gpio_callback_function(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    if(auth_conn)
    {
        if (awaiting_pairing_confirm) {
            bt_conn_auth_pairing_confirm(auth_conn);
            bt_conn_unref(auth_conn);
            auth_conn = NULL;
            awaiting_pairing_confirm = false;
            pair_timeout = PAIR_TIMEOUT_INIT;
            // Stop LED indication if any
        }
    }
}

Results:
When using this setup the phone still shows a passcode on it that is meant to be entered on the device and I see that upon entering security level 2 the device immediately disconnects.  I believe the security level change is necessary to protect the tx and rx characteristics and to match the settings I already made in the prj.conf though I've tried disabling that as well and it doesn't improve bonding.   Here is a log I have taken:

00> [00:00:08.972,015] <inf> bt_hci_core: hci_vs_init: HW Variant: nRF52x (0x0002)
00> [00:00:08.972,045] <inf> bt_hci_core: hci_vs_init: Firmware: Standard Bluetooth controller (0x00) Version 224.11902 Build 2231721665
00> [00:00:08.972,503] <dbg> bt_smp: bt_smp_init: LE SC enabled
00> [00:00:08.972,900] <inf> bt_hci_core: bt_init: No ID address. App must call settings_load()
00> [00:00:08.972,930] <inf> peripheral_uart: sys_init: Bluetooth initialized
00> [00:00:08.976,593] <inf> bt_hci_core: bt_dev_show_info: Identity: D9:9D:3A:4F:B5:5D (random)
00> [00:00:08.976,654] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.4 (0x0d) revision 0x1077, manufacturer 0x0059
00> [00:00:08.976,684] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.4 (0x0d) subver 0x1077
00> [00:00:09.009,796] <dbg> bt_smp: bt_smp_pkey_ready:
00> [00:00:22.874,633] <dbg> bt_smp: bt_smp_accept: conn 0x20002460 handle 0
00> [00:00:22.874,664] <dbg> bt_smp: bt_smp_connected: chan 0x20002828 cid 0x0006
00> [00:00:22.877,380] <dbg> bt_smp: smp_send_security_req:
00> [00:00:22.877,868] <dbg> bt_smp: smp_init: prnd 60b6727878064e85c9b81dcdd5327006
00> [00:00:22.878,173] <inf> peripheral_uart: connected: Connected 74:74:46:D6:E9:45 (public)
00> [00:00:23.068,756] <dbg> bt_smp: bt_smp_recv: Received SMP code 0x01 len 6
00> [00:00:23.068,786] <dbg> bt_smp: smp_pairing_req: req: io_capability 0x04, oob_flag 0x00, auth_req 0x2D, max_key_size 0x10, init_key_dist 0x0F, resp_key_dist 0x0F
00> [00:00:23.068,817] <dbg> bt_smp: smp_pairing_complete: got status 0x3
00> [00:00:23.068,847] <dbg> bt_smp: bt_smp_encrypt_change: chan 0x20002828 conn 0x20002460 handle 0 encrypt 0x00 hci status 0x1f
00> [00:00:23.069,061] <wrn> peripheral_uart: security_changed: Security failed: 74:74:46:D6:E9:45 (public) level 1 err 4
00> [00:00:23.069,244] <inf> peripheral_uart: pairing_failed: Pairing failed conn: 74:74:46:D6:E9:45 (public), reason 4
00> [00:00:23.113,555] <inf> peripheral_uart: exchange_func: MTU exchange done 498
00> [00:00:35.813,995] <dbg> bt_smp: bt_smp_disconnected: chan 0x20002828 cid 0x0006
00> [00:00:35.814,392] <inf> peripheral_uart: disconnected: Disconnected: 74:74:46:D6:E9:45 (public) (reason 19)
00> [00:00:37.795,745] <dbg> bt_smp: bt_smp_accept: conn 0x20002460 handle 0
00> [00:00:37.795,776] <dbg> bt_smp: bt_smp_connected: chan 0x20002828 cid 0x0006
00> [00:00:37.798,461] <dbg> bt_smp: smp_send_security_req:
00> [00:00:37.798,980] <dbg> bt_smp: smp_init: prnd fa720263f0156e232722fea23591b8cd
Any help would be much appreciated.  I feel like I've looked everywhere to try and find a solution but I'm just not finding the information I need.
Thanks in advance!
Parents
  • Hi jnenick,

    Firstly, let me address each of your requirement.

    Only permit usage of application characteristics (TX and RX) when bonded with the connected phone

    You need to add security requirement to the characteristic. The NUS supports Authentication requirement by enabling CONFIG_BT_NUS_AUTHEN

    If you need other level of security requirement, you will need to run your own custom BLE service. We have instructions to do that in our BLE Fundamentals online course.

    Only permit bonding when a user presses a button on the device

    Does the device also support a display that can display a 6-digit number?

    If yes, and the bonding peer is a mobile device, then you can support pairing with keys.

    If not, I am afraid the only solution is to use Just Works pairing. The device only allows pairing/bonding in a specific state that is entered via the button. This state could be entered after a button pressed, or only when the button is held; and it could be exited by timeout, or via another button press.

    For more information, please refer to Bluetooth specification, Vol 3, Part H, section 2.3. You can also refer to the online lesson I linked above for an overview.

    When bonding is started do not present a passcode dialog to the user on the phone

    After a bond is formed, future pairing will not require passkey entry.

    The uart service works great but I'm having a great amount of difficulty adding any measure of security to the project.

    The Peripheral UART sample supports adding security via the sample specific Kconfig CONFIG_BT_NUS_SECURITY_ENABLED. You can try this first.

    Otherwise, the online course I linked have an extensive step by step guide to implement security into an application.

    Hieu

Reply
  • Hi jnenick,

    Firstly, let me address each of your requirement.

    Only permit usage of application characteristics (TX and RX) when bonded with the connected phone

    You need to add security requirement to the characteristic. The NUS supports Authentication requirement by enabling CONFIG_BT_NUS_AUTHEN

    If you need other level of security requirement, you will need to run your own custom BLE service. We have instructions to do that in our BLE Fundamentals online course.

    Only permit bonding when a user presses a button on the device

    Does the device also support a display that can display a 6-digit number?

    If yes, and the bonding peer is a mobile device, then you can support pairing with keys.

    If not, I am afraid the only solution is to use Just Works pairing. The device only allows pairing/bonding in a specific state that is entered via the button. This state could be entered after a button pressed, or only when the button is held; and it could be exited by timeout, or via another button press.

    For more information, please refer to Bluetooth specification, Vol 3, Part H, section 2.3. You can also refer to the online lesson I linked above for an overview.

    When bonding is started do not present a passcode dialog to the user on the phone

    After a bond is formed, future pairing will not require passkey entry.

    The uart service works great but I'm having a great amount of difficulty adding any measure of security to the project.

    The Peripheral UART sample supports adding security via the sample specific Kconfig CONFIG_BT_NUS_SECURITY_ENABLED. You can try this first.

    Otherwise, the online course I linked have an extensive step by step guide to implement security into an application.

    Hieu

Children
No Data
Related