zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.87k stars 6.62k forks source link

BLE Mesh Provisioning generates value 0 outside of Specification for Blink, Beep, or Vibrate #34209

Closed dastarling closed 3 years ago

dastarling commented 3 years ago

Describe the bug The BLE Mesh spec v1.0.1 specifies: When the Authentication Method 0x02 (Authentication with Output OOB) is used and when Output OOB Action for the Authentication Action value is equal to Blink, Beep, or Vibrate, then the device shall select a random integer between 0 and 10 to the power of the Authentication Size exclusive.

To Reproduce Steps to reproduce the behavior:

  1. build mesh project that uses Authentication via Output Blink.

Expected behavior Blinks for output_size=1 to be between 1 and 9

Impact Violates mesh spec and when value 0 is produced the Authentication cannot be performed, must reset device and try again. On test device it constantly blinks instead of blinking the proper number.

Logs and console output 00> Booting Zephyr OS build v2.4.99-ncs1 00> Initializing... 00> I: 6 Sectors of 4096 bytes 00> I: alloc wra: 0, fc0 00> I: data wra: 0, 4c 00> I: HW Platform: Nordic Semiconductor (0x0002) 00> I: HW Variant: nRF52x (0x0002) 00> I: Firmware: Standard Bluetooth controller (0x00) Version 2.4 Build 99 00> I: No ID address. App must call settings_load() 00> Bluetooth initialized 00> D: CAP: output_size: 1 00> D: CAP: output_actions: 1 00> D: CAP: input_size: 0 00> D: CAP: input_actions: 0 00> Temperature sensor (TEMP_0) initiated 00> D: Sensor 0x004d 00> I: Identity: DE:80:69:C1:28:4D (random) 00> I: HCI: version 5.2 (0x0b) revision 0x0000, manufacturer 0x0059 00> I: LMP: version 5.2 (0x0b) subver 0xffff 00> 00> nrf_shell:~$ I: Device UUID: 00000000-0000-0080-2644-58cdf18cdc91 00> Mesh initialized 00> D: Local public key ready ... 00> D: xact_id 0x1 00> D: type 0x02 len 6 00> D: Algorithm: 0x00 00> D: Public Key: 0x00 00> D: Auth Method: 0x02 00> D: Auth Action: 0x00 00> D: Auth Size: 0x01 00> D: Blinking 7 times ... 00> D: Remote Public Key: 0132a4c2b46e773a63e308175b1b8bd3e4c927f06bd626fa97dda39cf9fb5bd5cb8078b9d073d5c0f26a8c88f6ec09690d2837f3d00558c78ab3af0a111cb7e9 ... 00> D: 2 bytes: 0005 00> D: type 0x00 len 2 00> D: Attention Duration: 5 seconds 00> D: 6 bytes: 020000020001 00> D: type 0x02 len 6 00> D: Algorithm: 0x00 00> D: Public Key: 0x00 00> D: Auth Method: 0x02 00> D: Auth Action: 0x00 00> D: Auth Size: 0x01 00> D: Blinking 9 times ... 00> D: conn 0x200017a8 00> D: 2 bytes: 0005 00> D: type 0x00 len 2 00> D: Attention Duration: 5 seconds 00> D: 6 bytes: 020000020001 00> D: type 0x02 len 6 00> D: Algorithm: 0x00 00> D: Public Key: 0x00 00> D: Auth Method: 0x02 00> D: Auth Action: 0x00 00> D: Auth Size: 0x01 00> D: Blinking 0 times

Environment (please complete the following information):

Additional context https://github.com/zephyrproject-rtos/zephyr/blob/master/subsys/bluetooth/mesh/prov.c Line 174 should have an additional condition based on blink, beep, or vibrate to eliminate the value 0 in the output, by choosing another number?

In addition, I think the line 176 has an issue too, since the authlink value does not match between this device and the provisioner on another processor. I double checked the other processor and it appears to be in big endian order, so I think the zephyr is not putting it in big endian order, but have not double checked it yet. I can write another case if needed.

dastarling commented 3 years ago

I can write up another case, but after rechecking the AuthValue, it does not appear to be in BE format:

00> D: ConfirmationKey 19a40d5be0334b3d07593d423f19e01e 00> D: RandomDevice acca9e3dd988f4c89c5876ad3b23dfea 00> D: AuthValue 00000000000000000000000000000003

The Provisioner on an ESP32 shows: D (14353) BLE_MESH: AuthValue 00000000000000000000000003000000

LingaoM commented 3 years ago

I can write up another case, but after rechecking the AuthValue, it does not appear to be in BE format:

00> D: ConfirmationKey 19a40d5be0334b3d07593d423f19e01e

00> D: RandomDevice acca9e3dd988f4c89c5876ad3b23dfea

00> D: AuthValue 00000000000000000000000000000003

The Provisioner on an ESP32 shows:

D (14353) BLE_MESH: AuthValue 00000000000000000000000003000000

Mesh Spec 1.0.1 Provisioning Authentication

For example, if the Authentication with Output OOB method is used with Output OOB Action as Blink and value outputted is 5, then the AuthValue shall be 0x00000000000000000000000000000005. The AuthValue is then encoded as defined in Section 5.1 in order to compute confirmation values, resulting in an array consisting of [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x05].

dastarling commented 3 years ago

I can write up another case, but after rechecking the AuthValue, it does not appear to be in BE format: 00> D: ConfirmationKey 19a40d5be0334b3d07593d423f19e01e 00> D: RandomDevice acca9e3dd988f4c89c5876ad3b23dfea 00> D: AuthValue 00000000000000000000000000000003 The Provisioner on an ESP32 shows: D (14353) BLE_MESH: AuthValue 00000000000000000000000003000000

Mesh Spec 1.0.1 Provisioning Authentication

For example, if the Authentication with Output OOB method is used with Output OOB Action as Blink and value outputted is 5, then the AuthValue shall be 0x00000000000000000000000000000005. The AuthValue is then encoded as defined in Section 5.1 in order to compute confirmation values, resulting in an array consisting of [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x05].

Interesting, I see that example in the Spec, but it also indicates BE in the spec as well, and in the code it uses sys_put_be32(num, &bt_mesh_prov_link.auth[12]);. It seems odd, but I'll see was Espressif says about the matter. But either way using provisioners/nodes from different vendors does not work as expected.

trond-snekvik commented 3 years ago

Hey, nice catch! This count=0 issue is definitely a bug, I'll make a PR. I'm not quite sure what's going on with the printed value in espressif. I just did a test, and the auth value appears to be encoded correctly in zephyr:

[00:00:26.579,315] <dbg> bt_mesh_prov: Auth output count 3
[00:00:26.580,688] <dbg> bt_mesh_prov_device: Auth 00000000000000000000000000000003

Espressif appears to have inherited the same blink=0 bug - it might be worth raising with them as well: https://github.com/espressif/esp-idf/blob/master/components/bt/esp_ble_mesh/mesh_core/prov.c#L754

dastarling commented 3 years ago

Hey, nice catch! This count=0 issue is definitely a bug, I'll make a PR. I'm not quite sure what's going on with the printed value in espressif. I just did a test, and the auth value appears to be encoded correctly in zephyr:

[00:00:26.579,315] <dbg> bt_mesh_prov: Auth output count 3
[00:00:26.580,688] <dbg> bt_mesh_prov_device: Auth 00000000000000000000000000000003

Espressif appears to have inherited the same blink=0 bug - it might be worth raising with them as well: https://github.com/espressif/esp-idf/blob/master/components/bt/esp_ble_mesh/mesh_core/prov.c#L754

Ok, will raise with them too. I had that issue when trying the pushbutton auth in the opposite direction, difficult to press the button 0 times :)

trond-snekvik commented 3 years ago

Yeah, it's a pretty corny bug :smile: PR: https://github.com/zephyrproject-rtos/zephyr/pull/34240

dastarling commented 3 years ago

Yeah, it's a pretty corny bug 😄 PR: #34240

Your fix should only affect the 3 output OOB (Blink, Beep, and Vibrate) and the 2 input OOB (Push and Twist) Otherwise you are limiting the values available for OOB Number (such as Input Numeric and Output Numeric) which are not limited from value 0 in the specification.

trond-snekvik commented 3 years ago

Of course, yes. Updated.