BLE Central, BT_SECURITY_ERR_AUTH_REQUIREMEN

Hello.

I keep trying to control my GoPro camera via BLE. At first I tried to do it using the old sdk, but it didn't work (devzone.nordicsemi.com/.../gopro-control-over-ble-write-char-issue).
I decided to try to do it using the new sdk. I also used the NUS Central example as a base.

My board - nrf52dk/nrf52832  (PCA10040)

Full project code - https://github.com/Sergey1560/nrf52_gopro_zephyr

There is a problem connecting to the camera. More precisely, with changing the security level. Here is the log:

** Booting nRF Connect SDK v3.0.2-89ba1294ac9b ***
*** Using Zephyr OS v4.0.99-f791c49f492c ***
[00:00:00.847,473] <inf> fs_nvs: 2 Sectors of 4096 bytes
[00:00:00.847,473] <inf> fs_nvs: alloc wra: 0, fc8
[00:00:00.847,473] <inf> fs_nvs: data wra: 0, 2c
[00:00:00.847,625] <inf> bt_sdc_hci_driver: SoftDevice Controller build revision: 
                                            89 9a 50 8a 95 01 9c 58  fc 39 d2 c1 10 04 ee 02 |..P....X .9......
                                            64 ce 25 be                                      |d.%.             
[00:00:00.851,409] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
[00:00:00.851,440] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
[00:00:00.851,470] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 137.20634 Build 2617349514
[00:00:00.851,837] <inf> bt_hci_core: No ID address. App must call settings_load()
[00:00:00.851,867] <inf> central_gopro: Bluetooth initialized
[00:00:00.852,600] <inf> bt_hci_core: Identity: DB:76:0F:4C:9A:35 (random)
[00:00:00.852,630] <inf> bt_hci_core: HCI: version 6.0 (0x0e) revision 0x10f3, manufacturer 0x0059
[00:00:00.852,661] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x10f3
[00:00:00.853,485] <inf> central_gopro: NUS Client module initialized
[00:00:00.853,515] <inf> central_gopro: Scan module initialized
[00:00:00.854,492] <inf> central_gopro: Scan started
[00:00:00.854,492] <inf> central_gopro: Starting Bluetooth Central sample

[00:00:01.049,041] <inf> central_gopro: Filters matched. Address: C0:3D:0B:EF:2F:77 (random) connectable: 1
[00:00:01.210,968] <inf> central_gopro: Connected: C0:3D:0B:EF:2F:77 (random)
[00:00:01.211,059] <inf> central_gopro: Change security to L2
[00:00:01.211,578] <err> central_gopro: Stop LE scan failed (err 0)
[00:00:01.362,579] <inf> central_gopro: MTU exchange done
[00:00:01.462,554] <err> bt_smp: pairing failed (peer reason 0x9)
[00:00:01.462,768] <wrn> central_gopro: Security failed: C0:3D:0B:EF:2F:77 (random) level 1 err 6 BT_SECURITY_ERR_PAIR_NOT_ALLOWED
[00:00:01.462,768] <inf> central_gopro: Start discovery
[00:00:01.462,982] <wrn> central_gopro: Pairing failed conn: C0:3D:0B:EF:2F:77 (random), reason 6 BT_SECURITY_ERR_PAIR_NOT_ALLOWED
[00:00:01.562,316] <inf> central_gopro: Service not found
[00:00:01.562,500] <inf> central_gopro: Disconnected: C0:3D:0B:EF:2F:77 (random), reason 0x13 
[00:00:01.563,446] <inf> central_gopro: Scan started

While the camera is not in pairing mode, I get an error BT_SECURITY_ERR_PAIR_NOT_ALLOWED. As you can see, scanning works, a device with the required service is found.
I turn on pairing mode on the camera:

00:00:13.547,943] <inf> central_gopro: Scan started
[00:00:13.564,514] <inf> central_gopro: Filters matched. Address: C0:3D:0B:EF:2F:77 (random) connectable: 1
[00:00:13.641,876] <inf> central_gopro: Connected: C0:3D:0B:EF:2F:77 (random)
[00:00:13.641,967] <inf> central_gopro: Change security to L2
[00:00:13.642,608] <err> central_gopro: Stop LE scan failed (err 0)
[00:00:13.793,487] <inf> central_gopro: MTU exchange done
[00:00:13.893,707] <wrn> central_gopro: Security failed: C0:3D:0B:EF:2F:77 (random) level 1 err 4 BT_SECURITY_ERR_AUTH_REQUIREMENT
[00:00:13.893,737] <inf> central_gopro: Start discovery
[00:00:13.893,920] <wrn> central_gopro: Pairing failed conn: C0:3D:0B:EF:2F:77 (random), reason 4 BT_SECURITY_ERR_AUTH_REQUIREMENT
[00:00:14.193,237] <inf> central_gopro: Service discovery completed
[00:00:14.193,237] <inf> central_gopro: Assign handles
[00:00:14.193,267] <err> nus_c: Missing NUS TX characteristic.
[00:00:14.193,298] <inf> central_gopro: Release data
[00:00:14.193,481] <inf> central_gopro: Disconnected: C0:3D:0B:EF:2F:77 (random), reason 0x13 

Why "Security failed level 1 err 4 BT_SECURITY_ERR_AUTH_REQUIREMENT" ? 

In the sniffer it looks like this:
(Full log from wireshark - gopro13_connection_fail.pcapng)

As far as I understand, the process starts with the packet highlighted in blue. The Master sends an AuthReq, the Client responds AuthReq, but then the master sends "Paiting Failed" with reason:
Opcode: Pairing Failed (0x05)
Reason: Authentication Requirements (0x03)

To change the security level, I use the code from the NUS example:

static void connected(struct bt_conn *conn, uint8_t conn_err)
{
	char addr[BT_ADDR_LE_STR_LEN];
	int err;

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	if (conn_err) {
		LOG_INF("Failed to connect to %s, 0x%02x %s", addr, conn_err, bt_hci_err_to_str(conn_err));

		if (default_conn == conn) {
			bt_conn_unref(default_conn);
			default_conn = NULL;

			(void)k_work_submit(&scan_work);
		}

		return;
	}

	LOG_INF("Connected: %s", addr);

	static struct bt_gatt_exchange_params exchange_params;

	exchange_params.func = exchange_func;
	err = bt_gatt_exchange_mtu(conn, &exchange_params);
	if (err) {
		LOG_WRN("MTU exchange failed (err %d)", err);
	}

	LOG_INF("Change security to L2");
	err = bt_conn_set_security(conn, BT_SECURITY_L2);
	if (err) {
		LOG_WRN("Failed to set security: %d", err);
		gatt_discover(conn);
	}

	err = bt_scan_stop();
	if ((!err) && (err != -EALREADY)) {
		LOG_ERR("Stop LE scan failed (err %d)", err);
	}
}

  • If I try BT_SECURITY_L3 or BT_SECURITY_L4, it fail with "Failed to set security: -22" and stay at BT_SECURITY_L1.

    [00:00:03.080,047] <inf> central_gopro: Service discovery completed
    [00:00:03.080,078] <inf> central_gopro: Security Level now: 1
    ATT[1]:  UUID: 0x2803 Handle: 0x0037 Value:
     Characteristic: 0xb5f90072-aa8d-11e3-9046-0002a5d5c51b Properties: 0x0008
    ATT[2]:  UUID: 0xb5f90072-aa8d-11e3-9046-0002a5d5c51b Handle: 0x0038 Value:
    ATT[3]:  UUID: 0x2803 Handle: 0x0039 Value:
     Characteristic: 0xb5f90073-aa8d-11e3-9046-0002a5d5c51b Properties: 0x0010
    ATT[4]:  UUID: 0xb5f90073-aa8d-11e3-9046-0002a5d5c51b Handle: 0x003A Value:
    ATT[5]:  UUID: 0x2902 Handle: 0x003B Value:
     CCCD
    ATT[6]:  UUID: 0x2803 Handle: 0x003C Value:
     Characteristic: 0xb5f90074-aa8d-11e3-9046-0002a5d5c51b Properties: 0x0008
    ATT[7]:  UUID: 0xb5f90074-aa8d-11e3-9046-0002a5d5c51b Handle: 0x003D Value:
    ATT[8]:  UUID: 0x2803 Handle: 0x003E Value:
     Characteristic: 0xb5f90075-aa8d-11e3-9046-0002a5d5c51b Properties: 0x0010
    ATT[9]:  UUID: 0xb5f90075-aa8d-11e3-9046-0002a5d5c51b Handle: 0x003F Value:
    ATT[10]:  UUID: 0x2902 Handle: 0x0040 Value:
     CCCD
    ATT[11]:  UUID: 0x2803 Handle: 0x0041 Value:
     Characteristic: 0xb5f90076-aa8d-11e3-9046-0002a5d5c51b Properties: 0x0008
    ATT[12]:  UUID: 0xb5f90076-aa8d-11e3-9046-0002a5d5c51b Handle: 0x0042 Value:
    ATT[13]:  UUID: 0x2803 Handle: 0x0043 Value:
     Characteristic: 0xb5f90077-aa8d-11e3-9046-0002a5d5c51b Properties: 0x0010
    ATT[14]:  UUID: 0xb5f90077-aa8d-11e3-9046-0002a5d5c51b Handle: 0x0044 Value:
    ATT[15]:  UUID: 0x2902 Handle: 0x0045 Value:
     CCCD
    ATT[16]:  UUID: 0x2803 Handle: 0x0046 Value:
     Characteristic: 0xb5f90078-aa8d-11e3-9046-0002a5d5c51b Properties: 0x0008
    ATT[17]:  UUID: 0xb5f90078-aa8d-11e3-9046-0002a5d5c51b Handle: 0x0047 Value:
    ATT[18]:  UUID: 0x2803 Handle: 0x0048 Value:
     Characteristic: 0xb5f90079-aa8d-11e3-9046-0002a5d5c51b Properties: 0x0010
    ATT[19]:  UUID: 0xb5f90079-aa8d-11e3-9046-0002a5d5c51b Handle: 0x0049 Value:
    ATT[20]:  UUID: 0x2902 Handle: 0x004A Value:
     CCCD
    [00:00:03.082,794] <inf> central_gopro: Assign handles
    [00:00:03.082,824] <inf> nus_c: Found handle for GoPro Notify characteristic.
    [00:00:03.082,855] <inf> nus_c: Found handle for CCC of GoPro Notify characteristic.
    [00:00:03.082,885] <inf> nus_c: Found handle for GoPro Write characteristic.
    

    Ok, Chars discovered. But if I try to send data, I get error:

    [00:02:31.743,438] <inf> central_gopro: Button pressed at 4972329
    
    [00:02:31.743,530] <inf> central_gopro: GET Data to send:
                                            03 01 01 01                                      |....             
    [00:02:31.743,530] <inf> nus_c: Send handle: 0x38 4 bytes
    [00:02:31.893,920] <wrn> central_gopro: Data send timeout
    [00:02:31.980,163] <wrn> central_gopro: ATT error code: 0x05
    [00:02:31.980,285] <wrn> central_gopro: Security failed: C0:3D:0B:EF:2F:77 (random) level 1 err 4 BT_SECURITY_ERR_AUTH_REQUIREMENT
    [00:02:31.980,285] <inf> central_gopro: Start discovery
    [00:02:31.980,499] <wrn> central_gopro: Pairing failed conn: C0:3D:0B:EF:2F:77 (random), reason 4 BT_SECURITY_ERR_AUTH_REQUIREMENT
    [00:02:32.129,852] <inf> central_gopro: Service not found
    [00:02:32.130,004] <inf> central_gopro: Disconnected: C0:3D:0B:EF:2F:77 (random), reason 0x13 
    

    Sniffer:

    Opcode: Write Request (0x12)
    Handle: 0x0038 (Unknown)
    Value: 03010101

    Opcode: Error Response (0x01)
    Request Opcode in Error: Write Request (0x12)
    Handle in Error: 0x0038 (Unknown)
    Error Code: Insufficient Authentication (0x05)

  • Hi,

    The nRF Connect SDK / Zephyr samples are now configured to not support the less secure legacy pairing by default. However, the sniffer trace shows that the GoPro does not support LE Secure Connections pairing. Solution to this is to add CONFIG_BT_SMP_SC_PAIR_ONLY=n to your project configuration (prj.conf)

    Best regards,

    Vidar

Related