Pairing/Bonding errors with a nRF MCU to a Windows laptop

I've written a GUI in python on a windows laptop which communicates fine with an nRF MCU when using open broadcast and no security. I'm using python's bleak library to connect and read/write gatt characteristics. I now want to implement security. I have copied much of the code from lesson 2 in the sdk fundamentals. I've modified it to use a static passkey for security level 4 connections. It still uses the filter accept list and pairing button. 

It works fine on the nRF connect app. I connect, then write to one of the characteristics, which then prompts an input for the static passkey. However, on windows, this is not the case. I'm doing pairing outside of the python program as I don't believe bleak supports that functionality. I intend to use the GUI after pairing. When connecting, it says "connecting..." on windows, the 'on_connected' callback executes on the MCU, then it errors out on both the laptop and mcu after about 15 seconds. No bonding occurs and no messages are sent/received.

Errors seen:

[00:09:16.687,164] <inf> BLE_Main: Security failed: 58:A0:23:A6:35:0A (public) level 1 err 9

[00:09:16.687,377] <inf> BLE_Main: Disconnected (reason 8)

My Bluetooth drivers:

Error 9 on security fail is BT_SECURITY_ERR_UNSPECIFIED. Is the issue that the windows laptop has no means of entering the static passkey? Or could it be that LE Secure Connections is not natively supported?

Help is much appreciated.

Parents
  • Hi Austin, 
    As you already found error 9 doesn't give much info about the error. I would suggest to use a sniffer to capture the bonding process. 
    You can find the sniffer guide in the same Bluetooth course. Please send us the sniffer trace for further investigation. 
    Could you describe how you do static passkey. As far as I understand it's not recommended to use static passkey with LE Secure Connection. It only takes 20 trials to crack it. 

  • Here are the logs and sniffer packets before the sniffer halts and no longer captures packets. Upon disconnect, it's configured to automatically start advertising again and the RPA then changes. 

    BLE_Secure_Windows_Error.csv

    8741.BLE_Windows_Secure_Error.pcapng

    With the nRF connect mobile app I can properly us the SC LTK to decode encrypted messages in Wireshark. I see no issues there.

    I was planning to use a static passkey and static MAC address for pairing. The device has only a button so the user is to click the button which puts it in advertising mode briefly. An app/gui initiates a pair request then the user enters the key and address. Are there better alternative secure pairing options? OOB with NFC is feasible, but I believe adds unnecessary complication.

    As for actually setting the passkey, I have CONFIG_BT_FIXED_PASSKEY=y in prj.conf and bt_passkey_set(PASSKEY); called on initialization.

  • What the BLE standard can offer for you in this case is LESC with Just Works pairing, which is ok for protecting against eavesdropping attackers. Assuming no input/output capabilities, unless you use OOB pairing, the BLE standard does unfortunately not offer any Man-in-the-middle protection pairing variants. Homekit and Matter standards use their own Password-authenticated key agreement (PAKE) on top of normal unencrypted BLE using a QR code sticker as a workaround in order to get MITM and eavesdropper protection.

    In any case, you should upload more sniffer logs from more attempts than just a single one. It appears the central Bluetooth controller fails and drops the connection upon receiving the LL_PHY_REQ from the peripheral, which seems to be a bug in the central Bluetooth controller. You should file a bug report to Intel if you can repeatedly reproduce this.

    One question though to the Nordic team is why the peripheral sends an additional feature request to the central when it moments ago already received the feature set from the central.

  • Thanks Emil,

    It seems these are my options for pairing at this point to get MITM protection:

    1. QR Code

    2. NFC

    3. Some custom encryption??

    QR code seems like the least amount of overhead in terms of hardware, firmware, and software. How exactly does this provide more security than a static code? Can't the QR also be brute-forced? What information is encoded? Where can I read about how to implement this?

    Regarding the PHY updates, I captured the packets for pairing 3 more times. Out of the four total, two fail after the LL_PHY_REQ (peripheral -> central) and two fail after LL_PHY_UPDATE_IND (central -> peripheral) so it appears it's not just an issue with the central. 

    BLE_Windows_Secure_Error_2.pcapngBLE_Windows_Secure_Error_3.pcapngBLE_Windows_Secure_Error_4.pcapng

  • In the LL_PHY_UPDATE_IND, we can see that the Instant is set to 0, which is not valid (or at least not a sane value, since it represents an event in the past). It feels like they forgot to assign the value a proper value. So please report this bug to Intel who makes the Bluetooth chip in your computer. Or maybe see if there is a firmware update for your Bluetooth chip on your PC?

    A QR code typically just contains a static passkey as well, but for another protocol than the standard BLE passkey pairing protocol. BLE's passkey protocol is really stupid an inefficient but on the other hand only requires the AES-ECB and ECDH (P-256 curve) crypto primitives, which makes it relatively simple to implement. The reason it doesn't work for static passkeys is because after a failed attempt, you get to know which bit of the 20 bits in the passkey that was wrong. That way you can flip that bit in your attempted passkey and try again, max 20 tries to crack and 10 on average. If you use a random passkey for every attempt this does not cause any security issues since even if you learn a particular bit that was wrong after a failed attempt, it's already too late since that passkey is now discarded.

    Contrary to what BLE is using, there are properly designed pairing protocols for the use case where a short shared secret is used (like a 6-digit passkey or a password), see https://en.wikipedia.org/wiki/Password-authenticated_key_agreement. The Matter smart home standard for example uses SPAKE2+ which you will find in that list. The idea of a PAKE is that it should require one real online attempt to test whether a passkey is correct. Even if an attacker sniffs a session between two legitimate parties successfully performing pairing, it should not be possible within reasonable time to brute-force the passkey used using the packet logs. This is specifically not the case for BLE's passkey protocol since an eavesdropper immediately learns the passkey that was used after a successful pairing attempt. Note that a solution based on a PAKE is not trivial to implement from scratch since you must both implement the PAKE protocol itself as well as the subsequent encryption and authentication signatures of packets using the established secret as key with e.g. AES-CCM as cipher, so I wouldn't recommend anyone doing that unless that person knows exactly what he/she is doing. If you're interested, read e.g. §3.10 of the Matter standard (https://leconiot.com/matter/1.2/index.html#ref_Pake).

    I guess in the real world, product designers just take the simple route and use JustWorks pairing with BLE since the probability that an attacker would be around that has the capabilities doing a MITM attack is expected to be quite low, and users prefer simple pairing than scanning QR codes. After all, the Bluetooth spec designers thought JustWorks was enough and didn't bother to add any static passkey option using a proper PAKE.

Reply
  • In the LL_PHY_UPDATE_IND, we can see that the Instant is set to 0, which is not valid (or at least not a sane value, since it represents an event in the past). It feels like they forgot to assign the value a proper value. So please report this bug to Intel who makes the Bluetooth chip in your computer. Or maybe see if there is a firmware update for your Bluetooth chip on your PC?

    A QR code typically just contains a static passkey as well, but for another protocol than the standard BLE passkey pairing protocol. BLE's passkey protocol is really stupid an inefficient but on the other hand only requires the AES-ECB and ECDH (P-256 curve) crypto primitives, which makes it relatively simple to implement. The reason it doesn't work for static passkeys is because after a failed attempt, you get to know which bit of the 20 bits in the passkey that was wrong. That way you can flip that bit in your attempted passkey and try again, max 20 tries to crack and 10 on average. If you use a random passkey for every attempt this does not cause any security issues since even if you learn a particular bit that was wrong after a failed attempt, it's already too late since that passkey is now discarded.

    Contrary to what BLE is using, there are properly designed pairing protocols for the use case where a short shared secret is used (like a 6-digit passkey or a password), see https://en.wikipedia.org/wiki/Password-authenticated_key_agreement. The Matter smart home standard for example uses SPAKE2+ which you will find in that list. The idea of a PAKE is that it should require one real online attempt to test whether a passkey is correct. Even if an attacker sniffs a session between two legitimate parties successfully performing pairing, it should not be possible within reasonable time to brute-force the passkey used using the packet logs. This is specifically not the case for BLE's passkey protocol since an eavesdropper immediately learns the passkey that was used after a successful pairing attempt. Note that a solution based on a PAKE is not trivial to implement from scratch since you must both implement the PAKE protocol itself as well as the subsequent encryption and authentication signatures of packets using the established secret as key with e.g. AES-CCM as cipher, so I wouldn't recommend anyone doing that unless that person knows exactly what he/she is doing. If you're interested, read e.g. §3.10 of the Matter standard (https://leconiot.com/matter/1.2/index.html#ref_Pake).

    I guess in the real world, product designers just take the simple route and use JustWorks pairing with BLE since the probability that an attacker would be around that has the capabilities doing a MITM attack is expected to be quite low, and users prefer simple pairing than scanning QR codes. After all, the Bluetooth spec designers thought JustWorks was enough and didn't bother to add any static passkey option using a proper PAKE.

Children
Related