mynewt-nimble icon indicating copy to clipboard operation
mynewt-nimble copied to clipboard

Passkey/password pairing with NimBLE?

Open freeride01 opened this issue 2 years ago • 7 comments

Hello, I have the following question. I have a BLE device based on ESP32. It does not have input or output capabilities. I am using ESP-IDF and the NimBLE stack, which I'm very pleased with so far. I want to do password authentication as follows:

  1. User pairs to the ESP32 device from a smartphone app.
  2. User generates a passkey or password and sends it to the ESP32 device, which in turn sets it as a password for pairing.
  3. The next time a user wants to connect, the ESP32 device sends him a request for password.
  4. If he enters the correct password, he pairs to the device. If not, he cannot pair.

Is this possible with the NimBLE stack and is there example code for this scenario? Thank you in advance.

P.S. obviously I read the part about security in BLE user guide (https://mynewt.apache.org/latest/network/ble_sec.html), but there were no examples on exactly how to implement passkey pairing.

freeride01 avatar Feb 25 '22 11:02 freeride01

No replies, so I guess this is not possible. In that case, has anyone had any success in modifying the BLE peripheral API to include a password for pairing?

freeride01 avatar Feb 28 '22 11:02 freeride01

Hi,

You can check btshell, it implements all pairing models

sjanc avatar Feb 28 '22 11:02 sjanc

Hi,

You can check btshell, it implements all pairing models

As far as I can see, when you have a "no input/no output" device (as I do), you can't set a passkey.

freeride01 avatar Feb 28 '22 15:02 freeride01

yes, no input/no output iocapa doesn't allow for authenticated pairing

sjanc avatar Feb 28 '22 16:02 sjanc

So is there a way to temporarily disable all gatt services/characteristics except one (for the password) and when the user enters it, they are enabled again?

freeride01 avatar Feb 28 '22 16:02 freeride01

Let me rephrase the question: in the project I am using for a template, the GATT server is started with gatt_svr_init().

  1. How do I stop it during runtime, since I can't find a gatt_svr_deinit() function?
  2. Can I initialize GATT with a custom array of services, something like ble_gatts_add_svcs(my_custom_array)?

freeride01 avatar Mar 01 '22 12:03 freeride01

You can used a (semi-)fixed passkey and print it on the device, or, as described in OP's original design, have some kind of enrollment mode where the passkey is set.

The iocap of the device should be set to Display Only. If the initiator has Keyboard capabilities (like a phone), this results in the authentication mode where the responder will display the passkey (the fixed passkey, so one doesn't need an actual display here) and then the initiator will request entry of the matching passkey. See BT Core, Version 5.3, Vol 3, Part H, §2.3.5.1, specifically Table 2.8.

The fixed passkey is not nearly as secure as a random one used for each pairing attempt. But it's better than no passkey.

xyzzy42 avatar Jan 10 '24 03:01 xyzzy42